Example #1
0
 def test_password_access(self):
     self.assertEqual(0, get_media_for_record(self.record, user=self.user).count())
     AccessControl.objects.create(user=self.user, content_object=self.presentation_password, read=True)
     self.assertEqual(0, get_media_for_record(self.record, user=self.user).count())
     passwords = dict(((self.presentation_password.id, 'test'),))
     self.assertEqual(1, get_media_for_record(self.record, user=self.user, passwords=passwords).count())
     AccessControl.objects.filter(user=self.user).delete()
Example #2
0
 def test_password_access(self):
     self.assertEqual(0, get_media_for_record(self.record, user=self.user).count())
     AccessControl.objects.create(user=self.user, content_object=self.presentation_password, read=True)
     self.assertEqual(0, get_media_for_record(self.record, user=self.user).count())
     passwords = dict(((self.presentation_password.id, 'test'),))
     self.assertEqual(1, get_media_for_record(self.record, user=self.user, passwords=passwords).count())
     AccessControl.objects.filter(user=self.user).delete()
Example #3
0
 def test_simple_presentation_access(self):
     self.assertEqual(0, get_media_for_record(self.record, user=self.user).count())
     AccessControl.objects.create(user=self.user, content_object=self.presentation_broken, read=True)
     self.assertEqual(0, get_media_for_record(self.record, user=self.user).count())
     AccessControl.objects.create(user=self.user, content_object=self.presentation_ok, read=True)
     self.assertEqual(1, get_media_for_record(self.record, user=self.user).count())
     AccessControl.objects.filter(user=self.user).delete()
Example #4
0
 def test_simple_presentation_access(self):
     self.assertEqual(0, get_media_for_record(self.record, user=self.user).count())
     AccessControl.objects.create(user=self.user, content_object=self.presentation_broken, read=True)
     self.assertEqual(0, get_media_for_record(self.record, user=self.user).count())
     AccessControl.objects.create(user=self.user, content_object=self.presentation_ok, read=True)
     self.assertEqual(1, get_media_for_record(self.record, user=self.user).count())
     AccessControl.objects.filter(user=self.user).delete()
Example #5
0
 def test_direct_access(self):
     self.assertEqual(0, get_media_for_record(
         self.record, user=self.user).count())
     AccessControl.objects.create(
         user=self.user, content_object=self.collection, read=True)
     self.assertEqual(1, get_media_for_record(
         self.record, user=self.user).count())
     AccessControl.objects.filter(user=self.user).delete()
Example #6
0
 def test_standalone_record_access(self):
     self.assertEqual(0, get_media_for_record(
         self.record_standalone, user=self.user).count())
     AccessControl.objects.create(
         user=self.user,
         content_object=self.presentation_standalone_record,
         read=True
     )
     self.assertEqual(1, get_media_for_record(
         self.record_standalone, user=self.user).count())
Example #7
0
 def test_hidden_presentation_access(self):
     self.assertEqual(0, get_media_for_record(self.record, user=self.user).count())
     AccessControl.objects.create(user=self.user, content_object=self.presentation_hidden, read=True)
     self.assertEqual(0, get_media_for_record(self.record, user=self.user).count())
     self.presentation_hidden.hidden = False
     self.presentation_hidden.save()
     self.assertEqual(1, get_media_for_record(self.record, user=self.user).count())
     AccessControl.objects.filter(user=self.user).delete()
     self.presentation_hidden.hidden = True
     self.presentation_hidden.save()
Example #8
0
 def test_hidden_presentation_access(self):
     self.assertEqual(0, get_media_for_record(self.record, user=self.user).count())
     AccessControl.objects.create(user=self.user, content_object=self.presentation_hidden, read=True)
     self.assertEqual(0, get_media_for_record(self.record, user=self.user).count())
     self.presentation_hidden.hidden = False
     self.presentation_hidden.save()
     self.assertEqual(1, get_media_for_record(self.record, user=self.user).count())
     AccessControl.objects.filter(user=self.user).delete()
     self.presentation_hidden.hidden = True
     self.presentation_hidden.save()
Example #9
0
 def test_direct_access(self):
     self.assertEqual(
         0,
         get_media_for_record(self.record, user=self.user).count())
     AccessControl.objects.create(user=self.user,
                                  content_object=self.collection,
                                  read=True)
     self.assertEqual(
         1,
         get_media_for_record(self.record, user=self.user).count())
     AccessControl.objects.filter(user=self.user).delete()
Example #10
0
 def test_presentation_must_contain_record(self):
     self.assertEqual(0, get_media_for_record(
         self.record, user=self.user).count())
     AccessControl.objects.create(
         user=self.user,
         content_object=self.presentation_no_record,
         read=True
     )
     self.assertEqual(0, get_media_for_record(
         self.record, user=self.user).count())
     AccessControl.objects.filter(user=self.user).delete()
Example #11
0
 def test_presentation_must_contain_record(self):
     self.assertEqual(
         0,
         get_media_for_record(self.record, user=self.user).count())
     AccessControl.objects.create(
         user=self.user,
         content_object=self.presentation_no_record,
         read=True)
     self.assertEqual(
         0,
         get_media_for_record(self.record, user=self.user).count())
     AccessControl.objects.filter(user=self.user).delete()
Example #12
0
 def test_standalone_record_access(self):
     self.assertEqual(
         0,
         get_media_for_record(self.record_standalone,
                              user=self.user).count())
     AccessControl.objects.create(
         user=self.user,
         content_object=self.presentation_standalone_record,
         read=True)
     self.assertEqual(
         1,
         get_media_for_record(self.record_standalone,
                              user=self.user).count())
Example #13
0
def retrieve_pseudostream(request, recordid, record, mediaid, media):

    mediaobj = get_media_for_record(recordid, request.user).get(id=mediaid)

    q = dict()
    start = request.GET.get('start', '')
    if start.isdigit():
        q['start'] = start
    end = request.GET.get('end', '')
    if end.isdigit():
        q['end'] = end
    client = request.GET.get('client')
    if client:
        q['client'] = client

    url = mediaobj.storage.urlbase
    url = url + ('/' if not url.endswith('/') else '') + \
        mediaobj.url.replace('\\', '/')
    if q:
        url = url + '?' + urlencode(q)

    try:
        result = urlopen(url)
        response = HttpResponse(
            FileWrapper(result),
            content_type=result.info().get('Content-Type')
        )
        response['Content-Length'] = result.info().get('Content-Length')
        return response
    except HTTPError, e:
        return HttpResponse(status=e.errno)
def retrieve_pseudostream(request, recordid, record, mediaid, media):

    mediaobj = get_media_for_record(recordid, request.user).get(id=mediaid)

    q = dict()
    start = request.GET.get('start', '')
    if start.isdigit():
        q['start'] = start
    end = request.GET.get('end', '')
    if end.isdigit():
        q['end'] = end
    client = request.GET.get('client')
    if client:
        q['client'] = client

    url = mediaobj.storage.urlbase
    url = url + ('/' if not url.endswith('/') else '') + \
        mediaobj.url.replace('\\', '/')
    if q:
        url = url + '?' + urlencode(q)

    try:
        result = urlopen(url)
        response = HttpResponse(FileWrapper(result),
                                content_type=result.info().get('Content-Type'))
        response['Content-Length'] = result.info().get('Content-Length')
        return response
    except HTTPError, e:
        return HttpResponse(status=e.errno)
Example #15
0
def retrieve(request, recordid, record, mediaid, media):
    # check if media exists
    mediaobj = get_media_for_record(recordid, request.user).filter(id=mediaid)

    # check download status
    if not mediaobj or not mediaobj[0].is_downloadable_by(request.user):
        return HttpResponseForbidden()
    mediaobj = mediaobj[0]

    # Allow passing in an argument to prevent setting "attachment" content
    # disposition, which keeps e.g. the PDF viewer built into Google Chrome
    # from working
    inline = request.GET.has_key('inline')
    name = smart_str(mediaobj.url)

    if mediaobj.is_local():  # support byte range requests

        try:
            content_file = mediaobj.get_absolute_file_path()
        except IOError:
            logging.error(
                "mediaobj.get_absolute_file_path() failed for media.id %s" %
                mediaid)
            raise Http404()

        retval = RangedFileResponse(request,
                                    open(content_file, 'r'),
                                    content_type=str(mediaobj.mimetype))

    else:

        try:
            content = mediaobj.load_file()
        except IOError:
            logging.error("mediaobj.load_file() failed for media.id %s" %
                          mediaid)
            raise Http404()

        if content:
            retval = HttpResponse(content=content,
                                  content_type=str(mediaobj.mimetype))
        else:
            inline = True
            retval = HttpResponseRedirect(mediaobj.get_absolute_url())

    if not inline:
        retval["Content-Disposition"] = \
            'attachment; filename="%s"' % name

    Activity.objects.create(event='media-download',
                            request=request,
                            content_object=mediaobj)
    return retval
Example #16
0
def retrieve(request, recordid, record, mediaid, media):
    # check if media exists
    mediaobj = get_media_for_record(recordid, request.user).filter(id=mediaid)

    # check download status
    if not mediaobj or not mediaobj[0].is_downloadable_by(request.user):
        return HttpResponseForbidden()
    mediaobj = mediaobj[0]

    try:
        content = mediaobj.load_file()
    except IOError:
        raise Http404()

    Activity.objects.create(event='media-download',
                            request=request,
                            content_object=mediaobj)
    if content:
        return HttpResponse(content=content, mimetype=str(mediaobj.mimetype))
    else:
        return HttpResponseRedirect(mediaobj.get_absolute_url())
Example #17
0
def retrieve(request, recordid, record, mediaid, media):
    print 'retrieve'
    # check if media exists
    mediaobj = get_media_for_record(recordid, request.user).filter(id=mediaid)

    # check download status
    if not mediaobj or not mediaobj[0].is_downloadable_by(request.user):
        return HttpResponseForbidden()
    mediaobj = mediaobj[0]

    try:
        content = mediaobj.load_file()
    except IOError:
        raise Http404()

    Activity.objects.create(event='media-download',
                            request=request,
                            content_object=mediaobj)
    if content:
        return HttpResponse(content=content, mimetype=str(mediaobj.mimetype))
    else:
        return HttpResponseRedirect(mediaobj.get_absolute_url())
Example #18
0
def slide_manifest(request, slide, owner, offline=False):

    fieldvalues = slide.get_fieldvalues(owner=owner)
    title = slide.title_from_fieldvalues(fieldvalues) or 'Untitled',
    id = get_id(request, 'slide', 'canvas', 'slide%d' % slide.id)
    image = slide.record.get_image_url(
        force_reprocess=False,
        handler='storage-retrieve-iiif-image',
    )

    metadata = get_metadata(fieldvalues)
    if slide.annotation:
        metadata.insert(0, dict(label='Annotation', value=slide.annotation))

    passwords = request.session.get('passwords', dict())
    media = get_media_for_record(slide.record, request.user, passwords)
    if len(media):
        media = media[0]
        media.identify(lazy=True)
        canvas_width = width = media.width or 1600
        canvas_height = height = media.height or 1200
    else:
        width = height = None
        canvas_width = 1200
        canvas_height = 1200

    while canvas_height < 1200 or canvas_width < 1200:
        canvas_height *= 2
        canvas_width *= 2

    if width and height:

        resource = {
            '@id': image,
            '@type': 'dctypes:Image',
            'format': 'image/jpeg',
            "height": height,
            "width": width
        }

        if not offline:
            resource['service'] = {
                '@context': 'http://iiif.io/api/image/2/context.json',
                '@id': image,
                'profile': 'http://iiif.io/api/image/2/level1.json'
            }

        images = [{
            '@type': 'oa:Annotation',
            'motivation': 'sc:painting',
            'resource': resource,
            'on': id,
        }]

    else:

        return special_slide(
            request,
            kind='missing',
            label='Missing image',
            index=slide.id,
            offline=offline,
        )

    result = {
        '@id': id,
        '@type': 'sc:Canvas',
        'label': title,
        "height": canvas_height,
        "width": canvas_width,
        'images': images,
        'metadata': metadata,
    }

    if offline:
        result['thumbnail'] = {
            '@id': '/thumbs' + image,
        }

    return result
Example #19
0
def record(
    request,
    id,
    name,
    contexttype=None,
    contextid=None,
    contextname=None,
    edit=False,
    customize=False,
    personal=False,
    copy=False,
    copyid=None,
    copyname=None,
):

    writable_collections = list(accessible_ids(request.user, Collection, write=True))
    readable_collections = list(accessible_ids(request.user, Collection))
    can_edit = request.user.is_authenticated()
    can_manage = False

    if id and name:
        record = Record.get_or_404(id, request.user)

        # if the user passes the first test
        if record:
            # if the user can't see an image, and there is one, then
            # don't let them see the record
            passwords = request.session.get("passwords", dict())
            media = get_media_for_record(record, request.user, passwords)
            unfiltered_media = Media.objects.filter(record__id=record.id)
            if not media and unfiltered_media:
                raise Http404()

        can_edit = can_edit and record.editable_by(request.user)
        can_manage = record.manageable_by(request.user)
    else:
        if request.user.is_authenticated() and (writable_collections or (personal and readable_collections)):
            record = Record()
            if personal:
                record.owner = request.user
        else:
            raise Http404()

    if record.owner:
        valid_collections = set(readable_collections) | set(writable_collections)
    else:
        valid_collections = writable_collections

    context = None
    if contexttype and contextid:
        app_label, model = contexttype.split(".")
        model_class = get_object_or_404(ContentType, app_label=app_label, model=model).model_class()
        context = get_object_or_404(filter_by_access(request.user, model_class), id=contextid)

    media = Media.objects.select_related().filter(record=record, storage__id__in=accessible_ids(request.user, Storage))
    # Only list media that is downloadable or editable
    for m in media:
        # Calculate permissions and store with object for later use in template
        m.downloadable_in_template = m.is_downloadable_by(request.user)
        m.editable_in_template = m.editable_by(request.user)
    media = filter(lambda m: m.downloadable_in_template or m.editable_in_template, media)

    edit = edit and request.user.is_authenticated()

    copyrecord = Record.get_or_404(copyid, request.user) if copyid else None

    class FieldSetForm(forms.Form):
        fieldset = FieldSetChoiceField(user=request.user, default_label="Default" if not edit else None)

    fieldsetform = FieldSetForm(request.GET)
    if fieldsetform.is_valid():
        fieldset = (
            FieldSet.for_user(request.user).get(id=fieldsetform.cleaned_data["fieldset"])
            if fieldsetform.cleaned_data["fieldset"]
            else None
        )
    elif (edit or customize) and (id and name):
        # if we're editing, touch all the data (no default fieldset)
        fieldset = None
    else:
        # use default fieldset settings
        if settings.DEFAULT_FIELDSET and isinstance(settings.DEFAULT_FIELDSET, basestring):
            default_fieldset = settings.DEFAULT_FIELDSET
        else:  # yes, it's a default default setting
            default_fieldset = "dc"
        fieldset = FieldSet.objects.get(name=default_fieldset)

    collection_items = collectionformset = None

    if edit:

        if not can_edit and not customize and not context:
            return HttpResponseRedirect(reverse("data-record", kwargs=dict(id=id, name=name)))

        def _field_choices():
            fsf = list(
                FieldSetField.objects.select_related("fieldset", "field")
                .all()
                .order_by("fieldset__name", "order", "field__label")
            )
            grouped = {}
            for f in fsf:
                grouped.setdefault((f.fieldset.title, f.fieldset.id), []).append(f.field)
            others = list(
                Field.objects.exclude(id__in=[f.field.id for f in fsf]).order_by("label").values_list("id", "label")
            )
            choices = [("", "-" * 10)] + [
                (set[0], [(f.id, f.label) for f in fields])
                for set, fields in sorted(grouped.iteritems(), key=lambda s: s[0][0])
            ]
            if others:
                choices.append(("Others", others))
            return choices

        class FieldValueForm(forms.ModelForm):
            def __init__(self, *args, **kwargs):
                super(FieldValueForm, self).__init__(*args, **kwargs)

            def clean_field(self):
                return Field.objects.get(id=self.cleaned_data["field"])

            def clean_context_type(self):
                context = self.cleaned_data.get("context_type")
                if context:
                    context = ContentType.objects.get(id=context)
                return context

            def clean(self):
                cleaned_data = self.cleaned_data
                return cleaned_data

            field = forms.ChoiceField(choices=_field_choices())
            value = forms.CharField(widget=forms.Textarea, required=False)
            context_type = forms.IntegerField(widget=forms.HiddenInput, required=False)
            context_id = forms.IntegerField(widget=forms.HiddenInput, required=False)
            index_value = forms.CharField(widget=forms.HiddenInput, required=False)

            class Meta:
                model = FieldValue
                exclude = []

        class CollectionForm(forms.Form):

            id = forms.IntegerField(widget=forms.HiddenInput)
            title = forms.CharField(widget=DisplayOnlyTextWidget)
            member = forms.BooleanField(required=False)
            shared = forms.BooleanField(required=False)

        fieldvalues_readonly = []
        if customize or context:
            fieldvalues = record.get_fieldvalues(owner=request.user, context=context, hidden=True).filter(
                owner=request.user
            )
        else:
            fieldvalues = record.get_fieldvalues(hidden=True)

        FieldValueFormSet = modelformset_factory(
            FieldValue, form=FieldValueForm, exclude=FieldValueForm.Meta.exclude, can_delete=True, extra=3
        )

        CollectionFormSet = formset_factory(CollectionForm, extra=0)

        if request.method == "POST":
            formset = FieldValueFormSet(request.POST, request.FILES, queryset=fieldvalues, prefix="fv")
            collectionformset = (
                CollectionFormSet(request.POST, request.FILES, prefix="c") if not (customize or context) else None
            )
            if formset.is_valid() and (
                customize or context or collectionformset.is_valid()
            ):  # or metadataform.is_valid()):

                record.save()

                if not (customize or context):
                    collections = dict(
                        (c["id"], c) for c in collectionformset.cleaned_data if c["id"] in valid_collections
                    )
                    for item in record.collectionitem_set.filter(collection__in=valid_collections):
                        if collections.has_key(item.collection_id):
                            if not collections[item.collection_id]["member"]:
                                item.delete()
                            elif collections[item.collection_id]["shared"] == item.hidden:
                                item.hidden = not item.hidden
                                item.save()
                            del collections[item.collection_id]
                    for coll in collections.values():
                        if coll["member"]:
                            CollectionItem.objects.create(
                                record=record, collection_id=coll["id"], hidden=not coll["shared"]
                            )

                instances = formset.save(commit=False)
                o1 = fieldvalues and max(v.order for v in fieldvalues) or 0
                o2 = instances and max(v.order for v in instances) or 0
                order = max(o1, o2, 0)
                for instance in instances:
                    if not instance.value:
                        if instance.id:
                            instance.delete()
                        continue
                    instance.record = record
                    if instance.order == 0:
                        order += 1
                        instance.order = order
                    if customize or context:
                        instance.owner = request.user
                    if context:
                        instance.context = context
                    instance.save()
                request.user.message_set.create(message="Record saved successfully.")

                url = reverse(
                    "data-record-edit-customize" if customize else "data-record-edit",
                    kwargs=dict(id=record.id, name=record.name),
                )

                next = request.GET.get("next", reverse("data-record", kwargs=dict(id=record.id, name=record.name)))

                return HttpResponseRedirect(url if request.POST.has_key("save_and_continue") else next)
        else:

            if copyrecord:
                initial = []
                for fv in copyrecord.get_fieldvalues(hidden=True):
                    initial.append(
                        dict(
                            label=fv.label,
                            field=fv.field_id,
                            refinement=fv.refinement,
                            value=fv.value,
                            date_start=fv.date_start,
                            date_end=fv.date_end,
                            numeric_value=fv.numeric_value,
                            language=fv.language,
                            order=fv.order,
                            group=fv.group,
                            hidden=fv.hidden,
                        )
                    )
                FieldValueFormSet.extra = len(initial) + 3
            elif fieldset:
                needed = (
                    fieldset.fields.filter(~Q(id__in=[fv.field_id for fv in fieldvalues]))
                    .order_by("fieldsetfield__order")
                    .values_list("id", flat=True)
                )
                initial = [{}] * len(fieldvalues) + [{"field": id} for id in needed]
                FieldValueFormSet.extra = len(needed) + 3
            else:
                initial = []

            formset = FieldValueFormSet(queryset=fieldvalues, prefix="fv", initial=initial)
            if not (customize or context):

                collections = dict(
                    (
                        (coll.id, dict(id=coll.id, title=coll.title))
                        for coll in Collection.objects.filter(id__in=valid_collections)
                    )
                )

                for item in (copyrecord or record).collectionitem_set.all():
                    collections.get(item.collection_id, {}).update(dict(member=True, shared=not item.hidden))

                collections = sorted(collections.values(), key=lambda c: c["title"])

                collectionformset = CollectionFormSet(prefix="c", initial=collections)

    else:
        fieldvalues_readonly = record.get_fieldvalues(owner=request.user, fieldset=fieldset)
        formset = None
        q = Q() if record.owner == request.user or request.user.is_superuser else Q(hidden=False)
        collection_items = record.collectionitem_set.filter(q, collection__in=readable_collections)

    if can_edit:
        from rooibos.storage.views import media_upload_form

        UploadFileForm = media_upload_form(request)
        upload_form = UploadFileForm() if UploadFileForm else None
    else:
        upload_form = None

    # handle uploading over secure URLs: in the view, offer link to insecure
    insecure_url = None
    if request.is_secure() and settings.INSECURE_UPLOAD:
        request_url = request.build_absolute_uri(request.get_full_path())
        insecure_url = request_url.replace("https://", "http://")

    record_usage = record.presentationitem_set.values("presentation").distinct().count() if can_edit else 0

    return render_to_response(
        "data_record.html",
        {
            "record": record,
            "media": media,
            "fieldsetform": fieldsetform,
            "fieldset": fieldset,
            "fieldvalues": fieldvalues_readonly,
            "context": context,
            "customize": customize,
            "fv_formset": formset,
            "c_formset": collectionformset,
            "can_edit": can_edit,
            "can_manage": can_manage,
            "next": request.GET.get("next"),
            "collection_items": collection_items,
            "upload_form": upload_form,
            "upload_url": (
                "%s?sidebar&next=%s"
                % (reverse("storage-media-upload", args=(record.id, record.name)), request.get_full_path())
            )
            if record.id
            else None,
            "insecure_url": insecure_url,
            "record_usage": record_usage,
        },
        context_instance=RequestContext(request),
    )