Ejemplo n.º 1
0
def press_gallery(request):
    """If POST, either add to or remove from press gallery.  If GET,
    redirect to the browse page w/ a properly formed press gallery
    query."""
    press_gallery_path = settings.PRESS_GALLERY_PATH
    if request.method == 'POST':
        if not request.user.has_perm('gallery.can_review'):
            raise PermissionDenied
        photo = models.Photo.objects.get(id=request.POST.get('id'))
        if photo is None:
            return handler400(request)
        if not os.path.exists(press_gallery_path):
            os.makedirs(press_gallery_path)
        action = request.POST.get('press_gallery', '').lower()
        filename = os.path.split(photo.image.name)[-1]
        press_photo_path = '%s%s' % (press_gallery_path, filename)
        if action == 'remove':
            if os.path.exists(press_photo_path):
                os.remove(press_photo_path)
            photo.in_press_gallery = False
            photo.save()
            request.notifications.add(_('Image removed from press gallery.'))
        elif action == 'add':
            shutil.copy(photo.image.file.name, press_photo_path)
            photo.in_press_gallery = True
            photo.save()
            request.notifications.add(_('Image added to press gallery.'))
        return HttpResponseRedirect(photo.get_absolute_url())
    # Redirect to a browse page query
    if not request.user.has_perm('gallery.can_see_press_gallery'):
        raise PermissionDenied
    url =  '%s?press_gallery=true' % reverse('bm.gallery.views.browse')
    return HttpResponseRedirect(url)
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
def browse(request):
    """Render the browse page.  This page supports a wide variety of
    query parameters, some of which are restricted to those w/ certain
    permissions."""
    klass = media_klass_from_request(request)
    filter_args, filter_kwargs = filter_args_from_request(request)
    press_gallery = request.GET.get('press_gallery', '')
    press_gallery = press_gallery.lower() == 'true'
    if press_gallery:
        if not request.user.has_perm('gallery.can_see_press_gallery'):
            raise PermissionDenied
        # for now we only allow photos in the press gallery, not
        # artifacts or any other types.  it's okay if the search query
        # doesn't specify a type, or if it specifies the photo type,
        # but we disallow other types of searches.  it's a little ugly
        # to be doing explicit type checking, but expedience demands
        # it :P
        if klass is models.MediaBase:
            klass = models.Photo
        if klass is not models.Photo:
            return handler400(request)
        filter_kwargs['in_press_gallery'] = True
    status = request.GET.get('status')
    if not status:
        filter_kwargs['status'] = 'approved'
    elif status != 'approved':
        if not request.user.has_perm('gallery.can_review'):
            # only reviewers can arbitrarily query based on status;
            # non-reviewers are restricted to seeing their own
            # submissions if they search on a status other than
            # 'approved'
            if request.user.is_anonymous():
                raise PermissionDenied
            filter_kwargs['owner'] = request.user
        filter_kwargs['status'] = status
    else:
        filter_kwargs['status'] = status

    full_results = klass.objects.filter(*filter_args, **filter_kwargs)
    # reverse the order so most recent is first
    full_results = full_results.order_by('id').reverse()
    tag = request.GET.get('tag')
    if tag:
        full_results = tagmodels.TaggedItem.objects.get_by_model(full_results,
                                                                 tag)
    text = request.GET.get('text')
    if text:
        full_results = apply_searchable_text_filter(full_results, text)
    paginator = BetterPaginator(full_results, settings.PAGINATION_BATCH_SIZE)
    try:
        page = int(request.GET.get('page', '1'))
    except ValueError:
        page = 1
    try:
        page_results = paginator.page(page)
    except (InvalidPage, EmptyPage):
        page_results = paginator.page(paginator.num_pages)
    query_string = request.META.get('QUERY_STRING')
    # remove 'page' from query string so it doesn't get used in the template
    query_map = parse_qs(query_string)
    query_map.pop('page', None)
    query_string = urlencode(query_map, doseq=True)
    for extra_filter in ('owner', 'tag', 'press_gallery'):
        if extra_filter in query_map:
            del(query_map[extra_filter])
    qs_no_extra_filters = urlencode(query_map, doseq=True)
    no_extra_filters_url = reverse('bm.gallery.views.browse')
    if qs_no_extra_filters:
        no_extra_filters_url = '%s?%s' % (no_extra_filters_url,
                                          qs_no_extra_filters)
    template_map = {'page_results': page_results,
                    'total_count': full_results.count(),
                    'query_string': query_string,
                    'no_extra_filters_url': no_extra_filters_url,
                    'paginator': paginator.get_context(page),
                    'page': page}
    owner_username = request.GET.get('owner')
    if owner_username:
        template_map['owner'] = authmodels.User.objects.get(username=owner_username)
    if tag:
        template_map['tag'] = tag
    if press_gallery:
        template_map['press_gallery'] = True
    context = RequestContext(request, template_map)
    return render_to_response('gallery/browse.html', context)