307 lines
13 KiB
Python
307 lines
13 KiB
Python
|
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 .image import get_image_instance, other
|
||
|
from .infoviews import get_wrapper_instance as get_infoview_wrapper_instance
|
||
|
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
|
||
|
from pygal.views.image import mm_image
|
||
|
|
||
|
|
||
|
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)
|
||
|
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
|
||
|
rel_path='', # the current help_page to identify which taskbar entry has to be highlighted
|
||
|
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)
|
||
|
|
||
|
context = Context(request) # needs to be executed first because of time mesurement
|
||
|
context_adaption(context, request, '', title=_('Help'))
|
||
|
return help_data(request, 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, wrapper_instance=w)
|
||
|
#
|
||
|
if w.may_read():
|
||
|
context.set_additional_title(w.name)
|
||
|
return w.render(context)
|
||
|
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 = mm_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})
|
||
|
context['THUMBNAIL_SIZES'] = settings.THUMBNAIL_SIZES
|
||
|
context['thumbnail_size'] = current_thumbnail_size
|
||
|
context['WEBNAIL_SIZES'] = settings.WEBNAIL_SIZES
|
||
|
context['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,
|
||
|
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['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['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,
|
||
|
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['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['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)
|