示例#1
0
def remove_tag(request, type, id):
    tag = request.GET.get('tag')
    if request.method == 'POST':
        ownedwrapper = OwnedWrapper.objects.get_for_object(user=request.user,
                                                           type=type,
                                                           object_id=id)
        Tag.objects.update_tags(
            ownedwrapper, ' '.join([
                '"%s"' % s
                for s in Tag.objects.get_for_object(ownedwrapper).exclude(
                    name=tag).values_list('name')
            ]))
        if request.is_ajax():
            return HttpResponse(simplejson.dumps(dict(result='ok')),
                                content_type='application/javascript')
        else:
            messages.add_message(request,
                                 messages.INFO,
                                 message="Tag removed successfully.")
            return HttpResponseRedirect(
                validate_next_link(request.GET.get('next'), '/'))

    return render(request, 'ui_tag_remove.html', {
        'tag': tag,
        'next': validate_next_link(request.GET.get('next')),
    })
示例#2
0
def delete_selected_records(request):

    selected = list(request.session['selected_records'])
    deletable_items = []
    for record in Record.filter_by_access(request.user, *selected):
        if record.editable_by(request.user):
            deletable_items.append(record)

    if request.method == 'POST':
        for record in deletable_items:
            if record.id in selected:
                selected.remove(record.id)
            record.delete()
        request.session['selected_records'] = selected

        from rooibos.middleware import HistoryMiddleware
        return HttpResponseRedirect(
            validate_next_link(
                request.GET.get('next'),
                HistoryMiddleware.go_back(
                    request,
                    to_before=reverse('ui-delete-selected'),
                    default=reverse('solr-selected'))))

    return render(request, 'ui_delete_selected.html', {
        'items': deletable_items,
    })
示例#3
0
def media_delete(request, mediaid, medianame):
    media = get_object_or_404(Media, id=mediaid)
    if not media.editable_by(request.user):
        raise Http404()
    if request.method == 'POST':
        media.delete()
        return HttpResponseRedirect(
            validate_next_link(request.GET.get('next'), '.'))
    else:
        return HttpResponseNotAllowed(['POST'])
示例#4
0
def media_upload(request, recordid, record):
    record = Record.get_or_404(recordid, request.user)
    if not record.editable_by(request.user):
        raise Http404()

    if request.method == 'POST':

        upload_file_form = media_upload_form(request)
        if not upload_file_form:
            raise Http404()

        form = upload_file_form(request.POST, request.FILES)
        if form.is_valid():

            storage = Storage.objects.get(
                id=form.cleaned_data['storage'].split(',')[0])
            file = request.FILES['file']
            mimetype = mimetypes.guess_type(file.name)[0] or file.content_type

            limit = storage.get_upload_limit(request.user)
            if limit > 0 and file.size > limit * 1024:
                messages.add_message(request,
                                     messages.INFO,
                                     message="The uploaded file is too large.")
                return HttpResponseRedirect(
                    validate_next_link(request.GET.get('next'),
                                       reverse('main')))

            media = Media.objects.create(record=record,
                                         name=os.path.splitext(file.name)[0],
                                         storage=storage,
                                         mimetype=mimetype)
            media.save_file(file.name, file)

            return HttpResponseRedirect(
                validate_next_link(request.GET.get('next'), reverse('main')))
        else:
            # Invalid form submission
            raise Http404()
    else:
        return HttpResponseNotAllowed(['POST'])
示例#5
0
def save_collection_visibility_preferences(request):
    form = get_collection_visibility_prefs_form(request.user)(request.POST)

    if form.is_valid():
        if set_collection_visibility_preferences(
                request.user, form.cleaned_data['show_or_hide'],
                form.cleaned_data['collections']):
            messages.add_message(
                request,
                messages.INFO,
                message="Collection visibility preferences saved.")

    next = validate_next_link(request.GET.get('next'), reverse('main'))
    return HttpResponseRedirect(next)
示例#6
0
def add_tags(request, type, id):
    if request.method != 'POST':
        return HttpResponseNotAllowed(['POST'])
    tags = request.POST.get('tags')
    if '"' in tags:
        new_tags = parse_tag_input(tags)
    else:
        new_tags = [_f for _f in [s.strip() for s in tags.split(',')] if _f]
    ownedwrapper = OwnedWrapper.objects.get_for_object(user=request.user,
                                                       type=type,
                                                       object_id=id)
    for tag in new_tags:
        Tag.objects.add_tag(ownedwrapper, '"%s"' % tag)
    return HttpResponseRedirect(
        validate_next_link(request.GET.get('next'), '/'))
示例#7
0
def password(request, id, name):

    presentation = get_object_or_404(
        filter_by_access(request.user, Presentation)
        .filter(Presentation.published_q(request.user), id=id)
    )

    class PasswordForm(forms.Form):
        password = forms.CharField(widget=forms.PasswordInput)

        def clean_password(self):
            p = self.cleaned_data.get('password')
            if p != presentation.password:
                raise forms.ValidationError("Password is not correct.")
            return p

    if request.method == 'POST':
        form = PasswordForm(request.POST)
        if form.is_valid():
            request.session.setdefault(
                'passwords', dict()
            )[presentation.id] = form.cleaned_data.get('password')
            request.session.modified = True
            return HttpResponseRedirect(validate_next_link(
                request.GET.get('next'), reverse('presentation-browse')))
    else:
        form = PasswordForm()

    return render(
        request,
        'presentation_password.html',
        {
            'form': form,
            'presentation': presentation,
            'next': request.GET.get('next', reverse('presentation-browse')),
        }
    )
示例#8
0
def clear_selected_records(request):
    request.session['selected_records'] = ()
    return HttpResponseRedirect(
        validate_next_link(request.GET.get('next'), reverse('solr-search')))
示例#9
0
def create(request):

    existing_tags = Tag.objects.usage_for_model(
        OwnedWrapper,
        filters=dict(
            user=request.user,
            content_type=OwnedWrapper.t(Presentation)
        )
    )

    selected = request.session.get('selected_records', ())
    next = validate_next_link(
        request.GET.get('next'), reverse('presentation-manage'))

    custom_permissions = getattr(settings, 'PRESENTATION_PERMISSIONS', None)

    class CreatePresentationForm(forms.Form):
        title = forms.CharField(
            label='Title',
            max_length=Presentation._meta.get_field('title').max_length
        )
        add_selected = forms.BooleanField(
            label='Add selected records immediately',
            required=False,
            initial=True
        )
        auth_access = forms.BooleanField(
            label='Set default permissions',
            required=False,
            initial=True
        )

    if request.method == "POST":
        form = CreatePresentationForm(request.POST)
        if form.is_valid():
            hidden = getattr(settings, 'PRESENTATION_HIDE_ON_CREATE', False)
            presentation = Presentation.objects.create(
                title=form.cleaned_data['title'],
                owner=request.user,
                hidden=hidden,
            )
            if form.cleaned_data['add_selected']:
                add_selected_items(request, presentation)

            if form.cleaned_data['auth_access']:
                if not custom_permissions:
                    g = ExtendedGroup.objects.filter(type=AUTHENTICATED_GROUP)
                    g = g[0] if g else ExtendedGroup.objects.create(
                        type=AUTHENTICATED_GROUP, name='Authenticated Users')
                    AccessControl.objects.create(
                        content_object=presentation, usergroup=g, read=True)
                else:
                    for name in custom_permissions:
                        g = ExtendedGroup.objects.filter(name=name)
                        if len(g) == 0:
                            g = Group.objects.filter(name=name)
                        if len(g) == 0:
                            continue
                        AccessControl.objects.create(
                            content_object=presentation,
                            usergroup=g[0],
                            read=True
                        )

            update_actionbar_tags(request, presentation)

            return HttpResponseRedirect(
                reverse(
                    'presentation-edit',
                    kwargs={
                        'id': presentation.id,
                        'name': presentation.name
                    }
                )
            )
    else:
        form = CreatePresentationForm()

    return render(
        request,
        'presentation_create.html',
        {
            'form': form,
            'next': next,
            'selected': selected,
            'existing_tags': existing_tags,
            'can_publish': request.user.has_perm(
                'presentation.publish_presentations'),
            'custom_permissions': custom_permissions,
        }
    )
示例#10
0
def record(request,
           id,
           name,
           contexttype=None,
           contextid=None,
           contextname=None,
           edit=False,
           customize=False,
           personal=False,
           copy=False,
           copyid=None,
           copyname=None):

    collections = apply_collection_visibility_preferences(
        request.user, Collection.objects.all())
    writable_collections = list(
        filter_by_access(request.user, collections,
                         write=True).values_list('id', flat=True))
    readable_collections = list(
        filter_by_access(request.user, collections).values_list('id',
                                                                flat=True))
    personal_collections = None
    can_edit = request.user.is_authenticated()
    can_manage = False

    if id and name:
        record = Record.get_or_404(id, request.user)
        can_edit = can_edit and record.editable_by(request.user)
        can_manage = record.manageable_by(request.user)
    else:
        if request.user.is_authenticated():
            if personal:
                personal_collections = \
                    get_allowed_collections_for_personal_records(
                        request.user, readable_collections)
            if writable_collections or (personal and personal_collections):
                record = Record()
                if personal:
                    record.owner = request.user
            else:
                raise Http404()
        else:
            raise Http404()

    if record.owner:
        if personal_collections is None:
            personal_collections = \
                get_allowed_collections_for_personal_records(
                    request.user, readable_collections)
        valid_collections = (set(personal_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__in=filter_by_access(
                                                      request.user, Storage))

    # Can any media be downloaded?
    download_image = False

    # 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)
        download_image = download_image or \
            m.is_downloadable_by(request.user, original=False)

    media = [
        m for m in media
        if m.downloadable_in_template or m.editable_in_template
    ]

    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():
        if fieldsetform.cleaned_data['fieldset']:
            fieldset = FieldSet.for_user(
                request.user).get(id=fieldsetform.cleaned_data['fieldset'])
        else:
            fieldset = None
    elif edit:
        default_fieldset_name = getattr(settings, 'RECORD_DEFAULT_FIELDSET',
                                        'dc')
        # Creating new record, use DC fieldset by default
        fieldset = FieldSet.objects.get(name=default_fieldset_name)
    else:
        fieldset = None

    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(iter(grouped.items()),
                                                      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)
            browse_value = forms.CharField(widget=forms.HiddenInput,
                                           required=False)

            class Meta:
                model = FieldValue
                fields = "__all__"

        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)

        field_value_formset = modelformset_factory(
            FieldValue,
            form=FieldValueForm,
            fields=FieldValueForm.Meta.fields,
            can_delete=True,
            extra=3)

        collection_formset = formset_factory(CollectionForm, extra=0)

        if request.method == 'POST':
            formset = field_value_formset(request.POST,
                                          request.FILES,
                                          queryset=fieldvalues,
                                          prefix='fv')
            if not (customize or context):
                collectionformset = collection_formset(request.POST,
                                                       request.FILES,
                                                       prefix='c')
            else:
                collectionformset = None
            if formset.is_valid() and (customize or context
                                       or collectionformset.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 item.collection_id in collections:
                            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 list(collections.values()):
                        if coll['member']:
                            CollectionItem.objects.create(
                                record=record,
                                collection_id=coll['id'],
                                hidden=not coll['shared'])

                instances = formset.save(commit=False)
                # Explicitly remove deleted objects
                for instance in formset.deleted_objects:
                    instance.delete()
                o1 = fieldvalues and max(v.order or 0
                                         for v in fieldvalues) or 0
                o2 = instances and max(v.order or 0 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()

                messages.add_message(request,
                                     messages.INFO,
                                     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 = validate_next_link(
                    request.GET.get('next'),
                    reverse('data-record',
                            kwargs=dict(id=record.id, name=record.name)))

                return HttpResponseRedirect(url if 'save_and_continue' in
                                            request.POST 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,
                        ))
                field_value_formset.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 = [{'field': id2} for id2 in needed]
                field_value_formset.extra = len(needed) + 3
            else:
                initial = []

            formset = field_value_formset(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 = list(collections.values())

                collectionformset = collection_formset(prefix='c',
                                                       initial=collections)

        part_of_works = None
        related_works = None

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

        part_of_works = []
        related_works = []

        works = FieldValue.objects.filter(
            record=record,
            field__name='relation',
            field__standard__prefix='dc',
            owner=None,
        ).values_list('value', 'refinement')

        for work, refinement in works:
            if refinement and refinement.lower() == 'ispartof':
                part_of_works.append(work)
            elif not refinement:
                related_works.append(work)

    if can_edit:
        from rooibos.storage.views import media_upload_form
        upload_file_form = media_upload_form(request)
        upload_form = upload_file_form() if upload_file_form else None
    else:
        upload_form = None

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

    back_url = HistoryMiddleware.go_back(
        request,
        to_before=reverse('data-record-back-helper-url'),
    )

    if record.id:
        upload_url = (
            "%s?sidebar&next=%s" %
            (reverse('storage-media-upload', args=(record.id, record.name)),
             request.get_full_path() + '?refreshthumb=1'))
    else:
        upload_url = None

    # In edit mode, optionally hide fieldset dropdown
    if formset and getattr(settings, 'HIDE_RECORD_FIELDSETS', False):
        fieldsetform = None

    return render(
        request, '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': validate_next_link(request.GET.get('next')),
            'collection_items': collection_items,
            'upload_form': upload_form,
            'upload_url': upload_url,
            'record_usage': record_usage,
            'back_url': back_url,
            'download_image': download_image,
            'part_of_works': part_of_works,
            'related_works': related_works,
        })
示例#11
0
def import_files(request):

    available_storage = get_list_or_404(
        filter_by_access(request.user, Storage, write=True).order_by('title'))
    available_collections = get_list_or_404(
        filter_by_access(request.user, Collection))
    writable_collection_ids = list(
        filter_by_access(request.user, Collection,
                         write=True).values_list('id', flat=True))

    storage_choices = [
        make_storage_select_choice(s, request.user) for s in available_storage
    ]

    class UploadFileForm(forms.Form):
        collection = forms.ChoiceField(choices=(
            (c.id, '%s%s' %
             ('*' if c.id in writable_collection_ids else '', c.title))
            for c in available_collections))
        storage = forms.ChoiceField(choices=storage_choices)
        file = forms.FileField()
        create_records = forms.BooleanField(required=False)
        replace_files = forms.BooleanField(required=False,
                                           label='Replace files of same type')
        multiple_files = forms.BooleanField(
            required=False, label='Allow multiple files of same type')
        personal_records = forms.BooleanField(required=False)
        response_type = forms.CharField(required=False,
                                        widget=forms.HiddenInput)

        def clean(self):
            cleaned_data = self.cleaned_data
            if any(self.errors):
                return cleaned_data
            personal = cleaned_data['personal_records']
            if not personal:
                if int(cleaned_data['collection']) not in \
                        writable_collection_ids:
                    self._errors['collection'] = \
                        ErrorList([
                            "Can only add personal records "
                            "to selected collection"
                        ])
                    del cleaned_data['collection']
            return cleaned_data

    if request.method == 'POST':

        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():

            create_records = form.cleaned_data['create_records']
            replace_files = form.cleaned_data['replace_files']
            multiple_files = form.cleaned_data['multiple_files']
            personal_records = form.cleaned_data['personal_records']

            collection = get_object_or_404(
                filter_by_access(request.user,
                                 Collection.objects.filter(
                                     id=form.cleaned_data['collection']),
                                 write=True if not personal_records else None))
            storage = get_object_or_404(
                filter_by_access(
                    request.user,
                    Storage.objects.filter(
                        id=form.cleaned_data['storage'].split(',')[0]),
                    write=True))
            file = request.FILES['file']
            record = None

            limit = storage.get_upload_limit(request.user)
            if limit > 0 and file.size > limit * 1024:
                result = "The uploaded file is too large (%d>%d)." % (
                    file.size, limit * 1024)
            else:

                mimetype = mimetypes.guess_type(file.name)[0] or \
                    file.content_type

                owner = request.user if personal_records else None
                id = os.path.splitext(file.name)[0]

                # find record by identifier
                titlefield = standardfield('title')
                idfield = standardfield('identifier')

                # Match identifiers that are either full file name
                # (with extension) or just base name match
                records = find_record_by_identifier(
                    (
                        id,
                        file.name,
                    ),
                    collection,
                    owner=owner,
                    ignore_suffix=multiple_files)
                result = "File skipped."

                if len(records) == 1:
                    # Matching record found
                    record = records[0]
                    media = record.media_set.filter(storage=storage,
                                                    mimetype=mimetype)
                    media_same_id = media.filter(name=id)
                    if len(media) == 0 or \
                            (len(media_same_id) == 0 and multiple_files):
                        # No media yet
                        media = Media.objects.create(record=record,
                                                     name=id,
                                                     storage=storage,
                                                     mimetype=mimetype)
                        media.save_file(file.name, file)
                        result = "File added (Identifier '%s')." % id
                    elif len(media_same_id) > 0 and multiple_files:
                        # Replace existing media with same name and mimetype
                        media = media_same_id[0]
                        media.delete_file()
                        media.save_file(file.name, file)
                        result = "File replaced (Identifier '%s')." % id
                    elif replace_files:
                        # Replace existing media with same mimetype
                        media = media[0]
                        media.delete_file()
                        media.save_file(file.name, file)
                        result = "File replaced (Identifier '%s')." % id
                    else:
                        result = "File skipped, media files already attached."
                elif len(records) == 0:
                    # No matching record found
                    if create_records:
                        # Create a record
                        record = Record.objects.create(name=id, owner=owner)
                        CollectionItem.objects.create(collection=collection,
                                                      record=record)
                        FieldValue.objects.create(record=record,
                                                  field=idfield,
                                                  value=id,
                                                  order=0)
                        FieldValue.objects.create(record=record,
                                                  field=titlefield,
                                                  value=id,
                                                  order=1)
                        media = Media.objects.create(record=record,
                                                     name=id,
                                                     storage=storage,
                                                     mimetype=mimetype)
                        media.save_file(file.name, file)
                        result = \
                            "File added to new record (Identifier '%s')." % id
                    else:
                        result = \
                            "File skipped, no matching record found " \
                            "(Identifier '%s')." % id
                else:
                    result = \
                        "File skipped, multiple matching records found " \
                        "(Identifier '%s')." % id
                    # Multiple matching records found
                    pass

            if form.cleaned_data['response_type'] == 'json':
                return HttpResponse(content=simplejson.dumps(
                    dict(status='ok', message=result)),
                                    content_type='application/json')

            messages.add_message(request, messages.INFO, message=result)
            next = validate_next_link(request.GET.get('next'),
                                      request.get_full_path())
            return HttpResponseRedirect(next)

        else:
            pass

    else:
        form = UploadFileForm()

    return render(request, 'storage_import_files.html', {
        'upload_form': form,
    })