Example #1
0
 def render_change_form(self, request, context, add=False, change=False,
                        form_url='', obj=None):
     extra_context = {'show_delete': True,
                      'is_popup': popup_status(request),
                      'select_folder': selectfolder_status(request),}
     context.update(extra_context)
     return super(FileAdmin, self).render_change_form(
                 request=request, context=context, add=False, change=False,
                 form_url=form_url, obj=obj)
 def render_change_form(self, request, context, add=False, change=False,
                        form_url='', obj=None):
     extra_context = {'show_delete': True,
                      'is_popup': popup_status(request),
                      'select_folder': selectfolder_status(request),}
     context.update(extra_context)
     return super(FolderAdmin, self).render_change_form(
                     request=request, context=context, add=False,
                     change=False, form_url=form_url, obj=obj)
    def delete_files_or_folders(self, request, files_queryset, folders_queryset):
        """
        Action which deletes the selected files and/or folders.

        This action first displays a confirmation page whichs shows all the
        deleteable files and/or folders, or, if the user has no permission on one of the related
        childs (foreignkeys), a "permission denied" message.

        Next, it delets all selected files and/or folders and redirects back to the folder.
        """
        opts = self.model._meta
        app_label = opts.app_label

        # Check that the user has delete permission for the actual model
        if not self.has_delete_permission(request):
            raise PermissionDenied

        current_folder = self._get_current_action_folder(request, files_queryset, folders_queryset)

        all_protected = []

        # Populate deletable_objects, a data structure of all related objects that
        # will also be deleted.
        # Hopefully this also checks for necessary permissions.
        # TODO: Check if permissions are really verified
        (args, varargs, keywords, defaults) = inspect.getargspec(get_deleted_objects)
        if 'levels_to_root' in args:
            # Django 1.2
            deletable_files, perms_needed_files = get_deleted_objects(files_queryset, files_queryset.model._meta, request.user, self.admin_site, levels_to_root=2)
            deletable_folders, perms_needed_folders = get_deleted_objects(folders_queryset, folders_queryset.model._meta, request.user, self.admin_site, levels_to_root=2)
        else:
            # Django 1.3
            using = router.db_for_write(self.model)
            deletable_files, perms_needed_files, protected_files = get_deleted_objects(files_queryset, files_queryset.model._meta, request.user, self.admin_site, using)
            deletable_folders, perms_needed_folders, protected_folders = get_deleted_objects(folders_queryset, folders_queryset.model._meta, request.user, self.admin_site, using)
            all_protected.extend(protected_files)
            all_protected.extend(protected_folders)

        all_deletable_objects = [deletable_files, deletable_folders]
        all_perms_needed = perms_needed_files.union(perms_needed_folders)

        # The user has already confirmed the deletion.
        # Do the deletion and return a None to display the change list view again.
        if request.POST.get('post'):
            if all_perms_needed:
                raise PermissionDenied
            n = files_queryset.count() + folders_queryset.count()
            if n:
                # delete all explicitly selected files
                for f in files_queryset:
                    self.log_deletion(request, f, force_unicode(f))
                    f.delete()
                # delete all files in all selected folders and their children
                # This would happen automatically by ways of the delete cascade, but then the individual .delete()
                # methods won't be called and the files won't be deleted from the filesystem.
                folder_ids = set()
                for folder in folders_queryset:
                    folder_ids.add(folder.id)
                    folder_ids.update(folder.get_descendants().values_list('id', flat=True))
                for f in File.objects.filter(folder__in=folder_ids):
                    self.log_deletion(request, f, force_unicode(f))
                    f.delete()
                # delete all folders
                for f in folders_queryset:
                    self.log_deletion(request, f, force_unicode(f))
                    f.delete()
                self.message_user(request, _("Successfully deleted %(count)d files and/or folders.") % {
                    "count": n,
                })
            # Return None to display the change list page again.
            return None

        if all_perms_needed or all_protected:
            title = _("Cannot delete files and/or folders")
        else:
            title = _("Are you sure?")

        context = {
            "title": title,
            "instance": current_folder,
            "breadcrumbs_action": _("Delete files and/or folders"),
            "deletable_objects": all_deletable_objects,
            "files_queryset": files_queryset,
            "folders_queryset": folders_queryset,
            "perms_lacking": all_perms_needed,
            "protected": all_protected,
            "opts": opts,
            'is_popup': popup_status(request),
            'select_folder': selectfolder_status(request),
            "root_path": reverse('admin:index'),
            "app_label": app_label,
            "action_checkbox_name": helpers.ACTION_CHECKBOX_NAME,
        }

        # Display the destination folder selection page
        return render_to_response([
            "admin/filer/delete_selected_files_confirmation.html"
        ], context, context_instance=template.RequestContext(request))
    def directory_listing(self, request, folder_id=None, viewtype=None):
        clipboard = tools.get_user_clipboard(request.user)
        if viewtype == 'images_with_missing_data':
            folder = ImagesWithMissingData()
        elif viewtype == 'unfiled_images':
            folder = UnfiledImages()
        elif folder_id == None:
            folder = FolderRoot()
        else:
            try:
                folder = Folder.objects.get(id=folder_id)
            except Folder.DoesNotExist:
                raise Http404

        # Check actions to see if any are available on this changelist
        actions = self.get_actions(request)

        # Remove action checkboxes if there aren't any actions available.
        list_display = list(self.list_display)
        if not actions:
            try:
                list_display.remove('action_checkbox')
            except ValueError:
                pass

        # search
        def filter_folder(qs, terms=[]):
            for term in terms:
                qs = qs.filter(Q(name__icontains=term) | \
                               Q(owner__username__icontains=term) | \
                               Q(owner__first_name__icontains=term) | \
                               Q(owner__last_name__icontains=term))
            return qs

        def filter_file(qs, terms=[]):
            for term in terms:
                qs = qs.filter(Q(name__icontains=term) | \
                               Q(description__icontains=term) | \
                               Q(original_filename__icontains=term) | \
                               Q(owner__username__icontains=term) | \
                               Q(owner__first_name__icontains=term) | \
                               Q(owner__last_name__icontains=term))
            return qs
        q = request.GET.get('q', None)
        if q:
            search_terms = unquote(q).split(" ")
        else:
            search_terms = []
            q = ''
        limit_search_to_folder = request.GET.get('limit_search_to_folder',
                                                 False) in (True, 'on')

        if len(search_terms) > 0:
            if folder and limit_search_to_folder and not folder.is_root:
                folder_qs = folder.get_descendants()
                file_qs = File.objects.filter(
                                        folder__in=folder.get_descendants())
            else:
                folder_qs = Folder.objects.all()
                file_qs = File.objects.all()
            folder_qs = filter_folder(folder_qs, search_terms)
            file_qs = filter_file(file_qs, search_terms)

            show_result_count = True
        else:
            folder_qs = folder.children.all()
            file_qs = folder.files.all()
            show_result_count = False

        folder_qs = folder_qs.order_by('name')
        file_qs = file_qs.order_by('name')

        folder_children = []
        folder_files = []
        if folder.is_root:
            folder_children += folder.virtual_folders
        for f in folder_qs:
            f.perms = userperms_for_request(f, request)
            if hasattr(f, 'has_read_permission'):
                if f.has_read_permission(request):
                    folder_children.append(f)
                else:
                    pass
            else:
                folder_children.append(f)
        for f in file_qs:
            f.perms = userperms_for_request(f, request)
            if hasattr(f, 'has_read_permission'):
                if f.has_read_permission(request):
                    folder_files.append(f)
                else:
                    pass
            else:
                folder_files.append(f)
        try:
            permissions = {
                'has_edit_permission': folder.has_edit_permission(request),
                'has_read_permission': folder.has_read_permission(request),
                'has_add_children_permission': \
                                folder.has_add_children_permission(request),
            }
        except:
            permissions = {}
        folder_files.sort()
        items = folder_children + folder_files
        paginator = Paginator(items, FILER_PAGINATE_BY)

        # Make sure page request is an int. If not, deliver first page.
        try:
            page = int(request.GET.get('page', '1'))
        except ValueError:
            page = 1

        # Are we moving to clipboard?
        if request.method == 'POST' and '_save' not in request.POST:
            for f in folder_files:
                if "move-to-clipboard-%d" % (f.id,) in request.POST:
                    clipboard = tools.get_user_clipboard(request.user)
                    if f.has_edit_permission(request):
                        tools.move_file_to_clipboard([f], clipboard)
                        return HttpResponseRedirect(request.get_full_path())
                    else:
                        raise PermissionDenied

        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)

        # Actions with no confirmation
        if (actions and request.method == 'POST' and
                'index' in request.POST and '_save' not in request.POST):
            if selected:
                response = self.response_action(request, files_queryset=file_qs, folders_queryset=folder_qs)
                if response:
                    return response
            else:
                msg = _("Items must be selected in order to perform "
                        "actions on them. No items have been changed.")
                self.message_user(request, msg)

        # Actions with confirmation
        if (actions and request.method == 'POST' and
                helpers.ACTION_CHECKBOX_NAME in request.POST and
                'index' not in request.POST and '_save' not in request.POST):
            if selected:
                response = self.response_action(request, files_queryset=file_qs, folders_queryset=folder_qs)
                if response:
                    return response

        # Build the action form and populate it with available actions.
        if actions:
            action_form = self.action_form(auto_id=None)
            action_form.fields['action'].choices = self.get_action_choices(request)
        else:
            action_form = None

        selection_note_all = ungettext('%(total_count)s selected',
            'All %(total_count)s selected', paginator.count)

        # If page request (9999) is out of range, deliver last page of results.
        try:
            paginated_items = paginator.page(page)
        except (EmptyPage, InvalidPage):
            paginated_items = paginator.page(paginator.num_pages)
        return render_to_response(
            'admin/filer/folder/directory_listing.html',
            {
                'folder': folder,
                'clipboard_files': File.objects.filter(
                    in_clipboards__clipboarditem__clipboard__user=request.user
                    ).distinct(),
                'paginator': paginator,
                'paginated_items': paginated_items,
                'permissions': permissions,
                'permstest': userperms_for_request(folder, request),
                'current_url': request.path,
                'title': u'Directory listing for %s' % folder.name,
                'search_string': ' '.join(search_terms),
                'q': urlencode(q),
                'show_result_count': show_result_count,
                'limit_search_to_folder': limit_search_to_folder,
                'is_popup': popup_status(request),
                'select_folder': selectfolder_status(request),
                # needed in the admin/base.html template for logout links
                'root_path': reverse('admin:index'),
                'action_form': action_form,
                'actions_on_top': self.actions_on_top,
                'actions_on_bottom': self.actions_on_bottom,
                'actions_selection_counter': self.actions_selection_counter,
                'selection_note': _('0 of %(cnt)s selected') % {'cnt': len(paginated_items.object_list)},
                'selection_note_all': selection_note_all % {'total_count': paginator.count},
                'media': self.media,
                'enable_permissions': settings.FILER_ENABLE_PERMISSIONS
        }, context_instance=RequestContext(request))
Example #5
0
    def directory_listing(self, request, folder_id=None, viewtype=None):
        clipboard = tools.get_user_clipboard(request.user)
        if viewtype == "images_with_missing_data":
            folder = ImagesWithMissingData()
        elif viewtype == "unfiled_images":
            folder = UnfiledImages()
        elif viewtype == "last":
            last_folder_id = request.session.get("filer_last_folder_id")
            try:
                Folder.objects.get(id=last_folder_id)
            except Folder.DoesNotExist:
                url = reverse("admin:filer-directory_listing-root")
                url = "%s%s%s" % (url, popup_param(request), selectfolder_param(request, "&"))
            else:
                url = reverse("admin:filer-directory_listing", kwargs={"folder_id": last_folder_id})
                url = "%s%s%s" % (url, popup_param(request), selectfolder_param(request, "&"))
            return HttpResponseRedirect(url)
        elif folder_id == None:
            folder = FolderRoot()
        else:
            folder = get_object_or_404(Folder, id=folder_id)
        request.session["filer_last_folder_id"] = folder_id

        # Check actions to see if any are available on this changelist
        actions = self.get_actions(request)

        # Remove action checkboxes if there aren't any actions available.
        list_display = list(self.list_display)
        if not actions:
            try:
                list_display.remove("action_checkbox")
            except ValueError:
                pass

        # search
        def filter_folder(qs, terms=[]):
            for term in terms:
                qs = qs.filter(
                    Q(name__icontains=term)
                    | Q(owner__username__icontains=term)
                    | Q(owner__first_name__icontains=term)
                    | Q(owner__last_name__icontains=term)
                )
            return qs

        def filter_file(qs, terms=[]):
            for term in terms:
                qs = qs.filter(
                    Q(name__icontains=term)
                    | Q(description__icontains=term)
                    | Q(original_filename__icontains=term)
                    | Q(owner__username__icontains=term)
                    | Q(owner__first_name__icontains=term)
                    | Q(owner__last_name__icontains=term)
                )
            return qs

        q = request.GET.get("q", None)
        if q:
            search_terms = unquote(q).split(" ")
        else:
            search_terms = []
            q = ""
        limit_search_to_folder = request.GET.get("limit_search_to_folder", False) in (True, "on")

        if len(search_terms) > 0:
            if folder and limit_search_to_folder and not folder.is_root:
                folder_qs = folder.get_descendants()
                file_qs = File.objects.filter(folder__in=folder.get_descendants())
            else:
                folder_qs = Folder.objects.all()
                file_qs = File.objects.all()
            folder_qs = filter_folder(folder_qs, search_terms)
            file_qs = filter_file(file_qs, search_terms)

            show_result_count = True
        else:
            folder_qs = folder.children.all()
            file_qs = folder.files.all()
            show_result_count = False

        folder_qs = folder_qs.order_by("name")
        file_qs = file_qs.order_by("name")

        folder_children = []
        folder_files = []
        if folder.is_root:
            folder_children += folder.virtual_folders
        for f in folder_qs:
            f.perms = userperms_for_request(f, request)
            if hasattr(f, "has_read_permission"):
                if f.has_read_permission(request):
                    folder_children.append(f)
                else:
                    pass
            else:
                folder_children.append(f)
        for f in file_qs:
            f.perms = userperms_for_request(f, request)
            if hasattr(f, "has_read_permission"):
                if f.has_read_permission(request):
                    folder_files.append(f)
                else:
                    pass
            else:
                folder_files.append(f)
        try:
            permissions = {
                "has_edit_permission": folder.has_edit_permission(request),
                "has_read_permission": folder.has_read_permission(request),
                "has_add_children_permission": folder.has_add_children_permission(request),
            }
        except:
            permissions = {}
        folder_files.sort()
        items = folder_children + folder_files
        paginator = Paginator(items, FILER_PAGINATE_BY)

        # Are we moving to clipboard?
        if request.method == "POST" and "_save" not in request.POST:
            for f in folder_files:
                if "move-to-clipboard-%d" % (f.id,) in request.POST:
                    clipboard = tools.get_user_clipboard(request.user)
                    if f.has_edit_permission(request):
                        tools.move_file_to_clipboard([f], clipboard)
                        return HttpResponseRedirect(request.get_full_path())
                    else:
                        raise PermissionDenied

        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)

        # Actions with no confirmation
        if actions and request.method == "POST" and "index" in request.POST and "_save" not in request.POST:
            if selected:
                response = self.response_action(request, files_queryset=file_qs, folders_queryset=folder_qs)
                if response:
                    return response
            else:
                msg = _("Items must be selected in order to perform " "actions on them. No items have been changed.")
                self.message_user(request, msg)

        # Actions with confirmation
        if (
            actions
            and request.method == "POST"
            and helpers.ACTION_CHECKBOX_NAME in request.POST
            and "index" not in request.POST
            and "_save" not in request.POST
        ):
            if selected:
                response = self.response_action(request, files_queryset=file_qs, folders_queryset=folder_qs)
                if response:
                    return response

        # Build the action form and populate it with available actions.
        if actions:
            action_form = self.action_form(auto_id=None)
            action_form.fields["action"].choices = self.get_action_choices(request)
        else:
            action_form = None

        selection_note_all = ungettext("%(total_count)s selected", "All %(total_count)s selected", paginator.count)

        # If page request (9999) is out of range, deliver last page of results.
        try:
            paginated_items = paginator.page(request.GET.get("page", 1))
        except PageNotAnInteger:
            paginated_items = paginator.page(1)
        except EmptyPage:
            paginated_items = paginator.page(paginator.num_pages)
        return render_to_response(
            "admin/filer/folder/directory_listing.html",
            {
                "folder": folder,
                "clipboard_files": File.objects.filter(
                    in_clipboards__clipboarditem__clipboard__user=request.user
                ).distinct(),
                "paginator": paginator,
                "paginated_items": paginated_items,
                "permissions": permissions,
                "permstest": userperms_for_request(folder, request),
                "current_url": request.path,
                "title": u"Directory listing for %s" % folder.name,
                "search_string": " ".join(search_terms),
                "q": urlencode(q),
                "show_result_count": show_result_count,
                "limit_search_to_folder": limit_search_to_folder,
                "is_popup": popup_status(request),
                "select_folder": selectfolder_status(request),
                # needed in the admin/base.html template for logout links
                "root_path": reverse("admin:index"),
                "action_form": action_form,
                "actions_on_top": self.actions_on_top,
                "actions_on_bottom": self.actions_on_bottom,
                "actions_selection_counter": self.actions_selection_counter,
                "selection_note": _("0 of %(cnt)s selected") % {"cnt": len(paginated_items.object_list)},
                "selection_note_all": selection_note_all % {"total_count": paginator.count},
                "media": self.media,
                "enable_permissions": settings.FILER_ENABLE_PERMISSIONS,
            },
            context_instance=RequestContext(request),
        )