def _id_lookup(request, mediatype, fieldname): mediatype_plural = mediatype mediatype = mediatype_deplural.get(mediatype_plural) klass = models.mediatype_map.get(mediatype, {}).get('klass') if not klass: return HttpResponseNotFound() id_ = request.GET.get('id') if not id_: from bm.gallery.views import handler400 return handler400(request) resource = get_object_or_404(klass, **{fieldname: id_}) username = resource.owner.username if request.GET.get('full_image', '').lower() == 'true': extension = resource.image.file.name.split('.')[-1] url = '/g/scaled/%s/%s/%s_full_image.%s' % (mediatype_plural, username, resource.slug, extension) else: url = reverse('bm.gallery.views.media_view', kwargs=dict(mediatype=mediatype_plural, username=username, slug=resource.slug)) if request.GET.get('geturl', '').lower() == 'true': return HttpResponse(url) return HttpResponseRedirect(url)
def image_full(request, mediatype, username, slug): if not request.user.has_perm('gallery.can_see_fullsize'): raise PermissionDenied user = get_object_or_404(authmodels.User, username=username) mediatype_plural = mediatype mediatype = mediatype_deplural.get(mediatype_plural) klass = models.mediatype_map.get(mediatype, {}).get('klass') if not klass: return HttpResponseNotFound() resource = klass.objects.get(owner=user, slug=slug) query_string = request.META.get('QUERY_STRING') template_map = dict(image=resource, query_string=query_string) context = RequestContext(request, template_map) return render_to_response('gallery/image_full_size.html', context_instance=context)
def media_feature(request, mediatype, username, slug): if not request.user.has_perm('gallery.can_review'): raise PermissionDenied user = get_object_or_404(authmodels.User, username=username) mediatype_plural = mediatype mediatype = mediatype_deplural.get(mediatype_plural) klass = models.mediatype_map.get(mediatype, {}).get('klass') if not klass: return HttpResponseNotFound() resource = get_object_or_404(klass, owner=user, slug=slug) if request.method == 'POST': if request.POST.get('feature'): featured = models.FeaturedMedia(media=resource) featured.save() request.notifications.add(_('Item featured.')) return HttpResponseRedirect(reverse('bm.gallery.views.media_view', kwargs=dict(mediatype=mediatype_plural, username=username, slug=slug)))
def media_submit(request, mediatype, username, slug): user = get_object_or_404(authmodels.User, username=username) if not request.user == user: raise PermissionDenied mediatype_plural = mediatype mediatype = mediatype_deplural.get(mediatype_plural) klass = models.mediatype_map.get(mediatype, {}).get('klass') if not klass: return HttpResponseNotFound() resource = get_object_or_404(klass, owner=user, slug=slug) if request.method == 'POST': new_status = request.POST.get('new_status') if new_status: new_status = status_map.get(new_status) if new_status: resource.status = new_status resource.save() return HttpResponseRedirect(reverse('bm.gallery.views.media_view', kwargs=dict(mediatype=mediatype_plural, username=username, slug=slug)))
def media_moderate(request, mediatype, username, slug): if not request.user.has_perm('gallery.can_review'): raise PermissionDenied user = get_object_or_404(authmodels.User, username=username) mediatype_plural = mediatype mediatype = mediatype_deplural.get(mediatype_plural) klass = models.mediatype_map.get(mediatype, {}).get('klass') if not klass: return HttpResponseNotFound() resource = get_object_or_404(klass, owner=user, slug=slug) if request.method == 'POST': new_status = request.POST.get('new_status') if new_status: new_status = status_map.get(new_status) if new_status: resource.status = new_status resource.save() request.notifications.add(_('Resource %s.' % new_status)) return HttpResponseRedirect(reverse('bm.gallery.views.media_view', kwargs=dict(mediatype=mediatype_plural, username=username, slug=slug)))
def media_view(request, mediatype, username, slug, piston=False): log.debug('media_view: %s, %s, %s, %s', mediatype, username, slug, piston) user = get_object_or_404(authmodels.User, username=username) mediatype_plural = mediatype mediatype = mediatype_deplural.get(mediatype_plural) klass = models.mediatype_map.get(mediatype, {}).get('klass') if not klass: return HttpResponseNotFound() filter_args, filter_kwargs = filter_args_from_request(request) resource = get_object_or_404(klass, owner=user, slug=slug) show_set_context = True # default to showing a search context status = request.GET.get('status') # The code below is the meat of the security policy, deciding # whether or not a user can view a particular piece of media. # It's fairly straightforward, I think. Still, edit with care, # lest you end up exposing pages that aren't supposed to be # exposed. log.debug('checking perm for %s', request.user) can_review = request.user.has_perm('gallery.can_review') log.debug('checked perm: %s', can_review) if not status: # if there aren't any other search parameters, don't use a # search context if (not any([arg in request.GET for arg in extra_filter_args]) and not filter_args and not filter_kwargs): show_set_context = False # status isn't specified as a search parameter, default to # only showing approved items, which everyone can see if resource.status == 'approved': filter_kwargs['status'] = 'approved' elif (not can_review and getattr(resource, 'full_image_available', False)): # it's not approved, but the full size image is explicitly # made available so we're allowed to see it; restrict the # query to only this object filter_kwargs['id'] = resource.id else: # object isn't in approved state, no status was specified # in the search parameters, user must either be the owner # or have review privs if (request.user != user and not can_review): raise PermissionDenied if not can_review: # we're a non-privileged user looking at one of our # own images, enforce a query that is limited to # resources we own filter_kwargs['owner'] = user elif not request.user.has_perm('gallery.can_upload'): # status is specified as a search parameter but user isn't a # contributor; not allowed raise PermissionDenied else: # status is specified as search arg; user is a contributor so # we allow it filter_kwargs['status'] = status # however, if the user doesn't have review privs, she'll be # limited to seeing her own images if not can_review: filter_kwargs['owner'] = user # now we create a query set which represents the search context # within which the item exists (i.e. the full set of queried # objects of which the one we are viewing is a single element) if 'mediatype' in request.GET: # mediatype is specified, has to be the current type if request.GET['mediatype'] != mediatype: return handler400(request) query_klass = klass else: # mediatype isn't specified, search all content query_klass = models.MediaBase resource_qs = query_klass.objects.filter(*filter_args, **filter_kwargs) tag = request.GET.get('tag') if tag: resource_qs = tagmodels.TaggedItem.objects.get_by_model(resource_qs, tag) text = request.GET.get('text') if text: resource_qs = apply_searchable_text_filter(resource_qs, text) try: # verify that resource we're looking at is IN the query set resource_qs.get(owner=user, slug=slug) except query_klass.DoesNotExist: # if not, something is weird so we don't allow it raise PermissionDenied except query_klass.MultipleObjectsReturned: # possible edge case where we're searching over all media # types, and two objects of different types have same owner # and slug; check to see if the object is in the result set if resource not in [r.get_child_instance() for r in resource_qs.filter(owner=user, slug=slug)]: raise PermissionDenied # for piston calls, we just want the resource, no template rendering needed. if piston: log.debug('returning piston resource: %s', resource) return resource # we will reverse, but not yet resource_qs = resource_qs.order_by('id') # generate prev and next link URLs query_string = request.META.get('QUERY_STRING') template_map = dict(resource=resource, query_string=query_string, show_set_context=show_set_context, mediatype_plural=mediatype_plural) if show_set_context: # since we go in reverse order, prev is newer prev = resource_qs.filter(id__gt=resource.id) prevurl = None if prev.count(): try: prevurl = prev[0].get_absolute_url() except models.ImageBase.DoesNotExist, models.MediaBase.DoesNotExist: pass # next is older (i.e. lower id) next = resource_qs.filter(id__lt=resource.id).reverse() nexturl = None if next.count(): try: nexturl = next[0].get_absolute_url() except models.ImageBase.DoesNotExist, models.MediaBase.DoesNotExist: pass
def media_edit(request, mediatype, username, slug): """Generic media edit view. Handles some existence and permission checks that apply to all media types, then delegates to a more type specific implementation.""" # verify the object exists and fetch it, if so user = get_object_or_404(authmodels.User, username=username) mediatype = mediatype_deplural.get(mediatype) klass = models.mediatype_map.get(mediatype, {}).get('klass') if not klass: return HttpResponseNotFound() resource = get_object_or_404(klass, owner=user, slug=slug) # permission check edit_perm = 'gallery.change_%s' % klass.__name__.lower() if not request.user.has_perm(edit_perm): # not a special privs account, have to check for ownership and # status if (request.user != resource.owner or resource.status not in ('uploaded', 'submitted')): # nope. REJECTED! raise PermissionDenied template_map = dict(image=resource) try: resource.clean_fields(exclude=['caption']) except ValidationError: pass else: template_map['can_cancel'] = True batch_length = request.REQUEST.get('batch_length') ids = request.REQUEST.get('ids', []) if batch_length: # we're in a batch upload process template_map['batch_length'] = batch_length if ids: ids = [int(i) for i in ids.split(',')] if resource.id in ids: ids.remove(resource.id) if ids: template_map['ids'] = ','.join([str(i) for i in ids]) template_map['num_remaining'] = len(ids) + 1 form_klass = mediatype_forms.get(mediatype) if request.method == 'POST': if 'cancel' in request.POST: request.notifications.add(_('Edit canceled.')) return HttpResponseRedirect(resource.get_absolute_url()) form = form_klass(request.POST, request.FILES, instance=resource) try: form.save() except ValueError: request.notifications.add(_('Save failed.')) # falls through to the template rendering else: request.notifications.add(_('%s edited.' % resource.title)) if ids: next_resource = None for id_ in ids: try: next_resource = klass.objects.get(id=id_) except klass.DoesNotExist: continue break if next_resource is not None: url = '%s/edit' % next_resource.get_absolute_url() url = '%s?batch_length=%s&ids=%s' % (url, batch_length, template_map['ids']) return HttpResponseRedirect(url) elif batch_length: # last one in the series, redirect to unsubmitted view url = reverse('bm.gallery.views.browse') url = '%s?status=uploaded&owner=%s' % (url, request.user.username) return HttpResponseRedirect(url) return HttpResponseRedirect(resource.get_absolute_url()) else: form = form_klass(instance=resource) template_map['form'] = form context = RequestContext(request, template_map) return render_to_response('gallery/image_edit.html', context_instance=context)