from ..context import context_adaption from django.conf import settings from django.contrib import messages from django.contrib.auth.decorators import login_required from django.http import FileResponse, HttpResponseNotAllowed from django.shortcuts import render, HttpResponse, redirect from django.urls.base import reverse from django.utils.translation import gettext as _ from ..forms import TagForm import fstools from ..help import help_pages from .xnail import get_image_instance, other from .infoviews import get_wrapper_instance as get_infoview_wrapper_instance import media import mimetypes from ..models import get_item_by_rel_path, get_item_type, TYPE_IMAGE, Tag, Item import os import pygal from ..queries import search_result_query import tempfile from themes import Context from users.views import profile_pre_actions, profile_post_actions from users.forms import UserProfileFormLanguageOnly from .userviews import get_wrapper_instance as get_userview_wrapper_instance import zipfile from pygal.views.userviews import query_view, ItemDoesNotEsistWithinParent def pygal_item_does_not_exist(request, context): context.set_additional_title(_('Page does not exist!')) messages.error(request, _('The Item for the given URL does not exist.')) return render(request, 'pygal/empty.html', context=context) def pygal_access_denied(request, context): context.set_additional_title(_('Access denied!')) messages.error(request, _('Access Denied: You don\'t have access rights.')) return render(request, 'pygal/empty.html', context=context) def get_next(request): if not request.POST: return request.GET.get('next', '/') else: return request.POST.get('next', '/') def pygal_responses(request, responsetype=pygal.RESP_TYPE_USERVIEW, datatype=pygal.DATA_TYPE_SEARCH, rel_path=''): # raw and scaled items if responsetype in [pygal.RESP_TYPE_RAWITEM, pygal.RESP_TYPE_WEBNAIL, pygal.RESP_TYPE_THUMBNAIL]: return pygal_item(request, responsetype, rel_path) # userview and infoview for items elif responsetype in [pygal.RESP_TYPE_USERVIEW, pygal.RESP_TYPE_INFOVIEW] and datatype == pygal.DATA_TYPE_ITEM: return pygal_userview_infoview(request, responsetype, rel_path) # download elif responsetype == pygal.RESP_TYPE_DOWNLOAD: return pygal_download(request, datatype, rel_path) # search elif responsetype in [pygal.RESP_TYPE_USERVIEW, pygal.RESP_TYPE_INFOVIEW] and datatype == pygal.DATA_TYPE_SEARCH: if not rel_path: return pygal_search(request, rel_path) else: return pygal_userview_infoview(request, responsetype, rel_path) else: d = { 'responsetype': responsetype, 'datatype': datatype, } messages.error(request, _('No response implemented in pygal.views.pygal_responses for responsetype="%(responsetype)s" and datatype="%(datatype)s".') % d) return redirect('/') def pygal_search(request, rel_path): context = Context(request) # needs to be executed first because of time mesurement w = query_view(request, search_result_query(request)) context_adaption( context, request, wrapper_instance=w ) context.set_additional_title(w.name) return w.render(context) def pygal_download(request, datatype, rel_path): full_path = pygal.get_full_path(rel_path) if os.path.isfile(full_path): # Download a file temp = open(full_path, 'rb') fn = os.path.basename(full_path) else: if pygal.is_favouriteview(request) or pygal.is_searchview(request) and rel_path == '': if pygal.is_favouriteview(request): fn = 'favourites.zip' else: fn = 'search.zip' # Download the favourites or search results fp_list = [] for i in search_result_query(request): if i.may_read(request.user): fp_list.append(pygal.get_full_path(i.rel_path)) else: # Download the folder full_path fn = (os.path.basename(full_path) or 'root') + '.zip' fp_list = [] for i in get_item_by_rel_path(rel_path).all_itemslist(): if i.may_read(request.user): fp_list.append(pygal.get_full_path(i.rel_path)) # # Create the Archive from fp_list # flat = pygal.is_flat(request) if not os.path.exists(settings.TEMP_ROOT): fstools.mkdir(settings.TEMP_ROOT) temp = tempfile.TemporaryFile(dir=settings.TEMP_ROOT) archive = zipfile.ZipFile(temp, 'w', zipfile.ZIP_STORED) for fp in fp_list: archive.write(fp, os.path.basename(pygal.get_rel_path(fp)) if flat else pygal.get_rel_path(fp)) archive.close() temp.seek(0) # # return file response # response = FileResponse(temp, content_type=mimetypes.types_map.get(os.path.splitext(fn)[1])) response['Content-Disposition'] = 'attachment; filename="%s"' % fn return response def pygal_helpview(request, page='main'): context = Context(request) # needs to be executed first because of time mesurement help_content = help_pages[page] context_adaption( context, # the base context request, # the request object to be used in context_adaption title=_('Help'), # the title for the page (template) current_help_page=page, ) context['help_content'] = help_content # the help content itself (template) return render(request, 'pygal/help.html', context=context) def pygal_userview_infoview(request, responsetype, rel_path): context = Context(request) # needs to be executed first because of time mesurement full_path = pygal.get_full_path(rel_path) try: if responsetype == pygal.RESP_TYPE_INFOVIEW: w = get_infoview_wrapper_instance(full_path, request) else: w = get_userview_wrapper_instance(full_path, request) except LookupError: context_adaption(context, request) return pygal_item_does_not_exist(request, context) context_adaption( context, request, rel_path=rel_path, wrapper_instance=w ) # if w.may_read(): context.set_additional_title(w.name) try: return w.render(context) except ItemDoesNotEsistWithinParent: return redirect('?'.join([request.META['PATH_INFO'].replace(rel_path, ''), request.META['QUERY_STRING']])) else: return pygal_access_denied(request, context) def pygal_item(request, responsetype, rel_path): full_path = pygal.get_full_path(rel_path) i = get_item_by_rel_path(rel_path) if not i.may_read(request.user): im = other(full_path, request) # This will return a mime icon instead of the image itself else: im = get_image_instance(full_path, request) # if responsetype == pygal.RESP_TYPE_THUMBNAIL: return HttpResponse(im.thumbnail_picture(), content_type=im.mime_type_xnails) elif responsetype == pygal.RESP_TYPE_WEBNAIL: return HttpResponse(im.webnail_picture(), content_type=im.mime_type_xnails) else: if i.may_read(request.user): mimetypes.init() mime_type = mimetypes.types_map.get(os.path.splitext(full_path)[1]) data = open(full_path, 'rb').read() return HttpResponse(data, content_type=mime_type) else: im = media.image(os.path.join(os.path.dirname(__file__), 'forbidden.png')) if responsetype == pygal.RESP_TYPE_THUMBNAIL: im.resize(int(pygal.get_thumbnail_size(request) * .75)) return HttpResponse(im.image_data(), content_type='image/png') @login_required def pygal_profile(request): context = Context(request) # needs to be executed first because of time mesurement current_thumbnail_size = pygal.get_thumbnail_size(request) current_webnail_size = pygal.get_webnail_size(request) profile_pre_actions(request, context, UserProfileFormLanguageOnly) context_adaption( context, request, title=_('Profile for %(username)s') % {'username': request.user.username}, # THUMBNAIL_SIZES=settings.THUMBNAIL_SIZES, thumbnail_size=current_thumbnail_size, WEBNAIL_SIZES=settings.WEBNAIL_SIZES, webnail_size=current_webnail_size ) if request.POST: # store thumbnail size, if changed thumbnail_size = int(request.POST.get('thumbnail_size')) if current_thumbnail_size != thumbnail_size: pygal.set_thumbnail_size(request, thumbnail_size) current_thumbnail_size = thumbnail_size messages.info(request, _('The Thumbnail Size was set to "%d"') % (thumbnail_size)) # store webnail size, if changed webnail_size = int(request.POST.get('webnail_size')) if current_webnail_size != webnail_size: pygal.set_webnail_size(request, webnail_size) current_webnail_size = webnail_size messages.info(request, _('The Webnail Size was set to "%d"') % (webnail_size)) return profile_post_actions(request, context) else: return render(request, 'pygal/profile.html', context=context) def tag_context_adaption(context, w, request, enable_tag_area_selection): context['item'] = w context['next'] = get_next(request) context['enable_tag_area_selection'] = enable_tag_area_selection if enable_tag_area_selection: i_w, i_h = w.width, w.height max_size = int(pygal.get_webnail_size(request) / 2) factor_to_original = max(i_w, i_h) / max_size context['factor_to_original'] = factor_to_original context['tag_img_width'] = int(i_w / factor_to_original) context['tag_img_height'] = int(i_h / factor_to_original) def pygal_addtag(request, rel_path): context = Context(request) # needs to be executed first because of time mesurement full_path = pygal.get_full_path(rel_path) w = get_userview_wrapper_instance(full_path, request) if not w.may_modify(): messages.error(request, _('You don\'t have the rights to add a Tag to this Item.')) return redirect(get_next(request)) else: context_adaption( context, request, rel_path=rel_path, title=_('Add Tag for %s') % w.name ) tag_context_adaption(context, w, request, get_item_type(full_path) in [TYPE_IMAGE]) if request.POST: tag = Tag(item=w.item) form = TagForm(request.POST, instance=tag, factor_to_original=context.get('factor_to_original')) if form.is_valid(): form.save() messages.info(request, _('Thanks for adding a Tag to %s') % w.name) return redirect(get_next(request)) else: form = TagForm(factor_to_original=context.get('factor_to_original')) context['form'] = form return render(request, 'pygal/tagedit.html', context=context) def pygal_tagedit(request, tag_id): context = Context(request) # needs to be executed first because of time mesurement try: t = Tag.objects.get(pk=tag_id) except Tag.DoesNotExist: messages.error(request, _('Tag %d does not exist!') % tag_id) return redirect(get_next(request)) if not t.item.may_modify(request.user): messages.error(request, _('You don\'t have the rights to change Tag %(tag_id)d.') % {'tag_id': tag_id}) return redirect(get_next(request)) else: w = get_userview_wrapper_instance(pygal.get_full_path(t.item.rel_path), request) context_adaption( context, request, rel_path=t.item.rel_path, title=_('Edit Tag %(tag_id)d for %(item_name)s') % {'tag_id': tag_id, 'item_name': w.name} ) tag_context_adaption(context, w, request, t.item.type in [TYPE_IMAGE]) context['enable_delete_button'] = True if request.POST: if request.POST.get('save'): form = TagForm(request.POST, instance=t, factor_to_original=context.get('factor_to_original')) if form.is_valid(): form.save() messages.info(request, _('Thanks for editing Tag %(tag_id)d to %(item_name)s') % {'tag_id': tag_id, 'item_name': w.name}) return redirect(get_next(request)) else: t.delete() messages.info(request, _('Tag %(tag_id)d of %(item_name)s has been deleted.') % {'tag_id': tag_id, 'item_name': w.name}) return redirect(get_next(request)) else: form = TagForm(instance=t, factor_to_original=context.get('factor_to_original')) context['form'] = form return render(request, 'pygal/tagedit.html', context=context) def pygal_favourite(request, set_favourite, rel_path): nxt = request.GET.get('next', '/') item = get_item_by_rel_path(rel_path) if not set_favourite and request.user in item.favourite_of.all(): item.favourite_of.remove(request.user) item.save() if nxt.startswith(pygal.url_favouriteview(request)): nxt = pygal.url_favouriteview(request) elif set_favourite and request.user not in item.favourite_of.all(): item.favourite_of.add(request.user) item.save() else: messages.error(request, 'Favourite setting is already in targetstate!') return redirect(nxt + '#%s' % item.name)