diff --git a/apps/documents/__init__.py b/apps/documents/__init__.py index 8ddfd297d4..df96344f71 100644 --- a/apps/documents/__init__.py +++ b/apps/documents/__init__.py @@ -37,6 +37,7 @@ register_permissions('documents', [ ]) document_list = {'text': _(u'documents list'), 'view': 'document_list', 'famfam': 'page', 'permissions': {'namespace': 'documents', 'permissions': [PERMISSION_DOCUMENT_VIEW]}} +document_list_recent = {'text': _(u'recent documents list'), 'view': 'document_list_recent', 'famfam': 'page', 'permissions': {'namespace': 'documents', 'permissions': [PERMISSION_DOCUMENT_VIEW]}} document_create = {'text': _('upload a new document'), 'view': 'document_create', 'famfam': 'page_add', 'permissions': {'namespace': 'documents', 'permissions': [PERMISSION_DOCUMENT_CREATE]}} document_create_multiple = {'text': _('upload multiple new documents'), 'view': 'document_create_multiple', 'famfam': 'page_add', 'permissions': {'namespace': 'documents', 'permissions': [PERMISSION_DOCUMENT_CREATE]}} document_create_sibling = {'text': _('upload new document using same metadata'), 'view': 'document_create_sibling', 'args': 'object.id', 'famfam': 'page_copy', 'permissions': {'namespace': 'documents', 'permissions': [PERMISSION_DOCUMENT_CREATE]}} @@ -73,13 +74,13 @@ staging_file_preview = {'text': _('preview'), 'class': 'fancybox-noscaling', 'vi staging_file_delete = {'text': _('delete'), 'view': 'staging_file_delete', 'args': 'object.id', 'famfam': 'drive_delete'} register_links(Document, [document_view_simple, document_view, document_edit, document_edit_metadata, document_delete, document_download, document_find_duplicates, document_clear_transformations], menu_name='sidebar') -register_links(Document, [document_list, document_create, document_create_multiple, document_create_sibling], menu_name='sidebar') +register_links(Document, [document_list_recent, document_list, document_create, document_create_multiple, document_create_sibling], menu_name='sidebar') register_multi_item_links(['document_list'], [document_multiple_clear_transformations, document_multiple_edit_metadata, document_multiple_delete]) if ENABLE_SINGLE_DOCUMENT_UPLOAD: - register_links(['document_list', 'document_create', 'document_create_multiple', 'upload_document_with_type', 'upload_multiple_documents_with_type'], [document_list, document_create, document_create_multiple], menu_name='sidebar') + register_links(['document_list_recent', 'document_list', 'document_create', 'document_create_multiple', 'upload_document_with_type', 'upload_multiple_documents_with_type'], [document_list_recent, document_list, document_create, document_create_multiple], menu_name='sidebar') else: - register_links(['document_list', 'document_create', 'document_create_multiple', 'upload_document_with_type', 'upload_multiple_documents_with_type'], [document_list, document_create_multiple], menu_name='sidebar') + register_links(['document_list_recent', 'document_list', 'document_create', 'document_create_multiple', 'upload_document_with_type', 'upload_multiple_documents_with_type'], [document_list_recent, document_list, document_create_multiple], menu_name='sidebar') register_links(DocumentPage, [document_page_transformation_list, document_page_edit, document_page_view, document_page_navigation_previous, document_page_navigation_next]) @@ -117,10 +118,11 @@ register_model_list_columns(Document, [ if ENABLE_SINGLE_DOCUMENT_UPLOAD: register_menu([ {'text': _('documents'), 'view': 'document_create', 'links': [ - document_create, document_create_multiple, document_list + document_create, document_create_multiple, document_list,\ + document_list_recent ], 'famfam': 'page', 'position': 1}]) else: register_menu([ {'text': _('documents'), 'view': 'document_create_multiple', 'links': [ - document_create_multiple, document_list + document_create_multiple, document_list, document_list_recent ], 'famfam': 'page', 'position': 1}]) diff --git a/apps/documents/admin.py b/apps/documents/admin.py index 16dc2d53c8..3cf196bbd3 100644 --- a/apps/documents/admin.py +++ b/apps/documents/admin.py @@ -3,7 +3,7 @@ from django.contrib import admin from models import MetadataType, DocumentType, Document, \ DocumentTypeMetadataType, DocumentMetadata, DocumentTypeFilename, \ MetadataIndex, DocumentPage, MetadataGroup, \ - MetadataGroupItem, DocumentPageTransformation + MetadataGroupItem, DocumentPageTransformation, RecentDocument from filesystem_serving.admin import DocumentMetadataIndexInline @@ -71,11 +71,19 @@ class MetadataGroupItemInline(admin.StackedInline): class MetadataGroupAdmin(admin.ModelAdmin): inlines = [MetadataGroupItemInline] filter_horizontal = ['document_type'] + +class RecentDocumentAdmin(admin.ModelAdmin): + model = RecentDocument + list_display = ('user', 'document', 'datetime_accessed') + readonly_fields = ('user', 'document', 'datetime_accessed') + list_filter = ('user',) + date_hierarchy = 'datetime_accessed' + admin.site.register(MetadataType, MetadataTypeAdmin) admin.site.register(DocumentType, DocumentTypeAdmin) admin.site.register(Document, DocumentAdmin) admin.site.register(MetadataGroup, MetadataGroupAdmin) admin.site.register(DocumentPageTransformation, DocumentPageTransformationAdmin) - +admin.site.register(RecentDocument, RecentDocumentAdmin) diff --git a/apps/documents/conf/settings.py b/apps/documents/conf/settings.py index 6c7cb78574..af47ce2654 100644 --- a/apps/documents/conf/settings.py +++ b/apps/documents/conf/settings.py @@ -54,6 +54,7 @@ MULTIPAGE_PREVIEW_SIZE = getattr(settings, 'DOCUMENTS_MULTIPAGE_PREVIEW_SIZE', ' THUMBNAIL_SIZE = getattr(settings, 'DOCUMENTS_THUMBNAIL_SIZE', '50x50') DISPLAY_SIZE = getattr(settings, 'DOCUMENTS_DISPLAY_SIZE', '1200') TRANFORMATION_PREVIEW_SIZE = getattr(settings, 'DOCUMENTS_TRANFORMATION_PREVIEW_SIZE', '640x480') +RECENT_COUNT = getattr(settings, 'DOCUMENTS_RECENT_COUNT', 20) # Transformations AVAILABLE_TRANSFORMATIONS = getattr(settings, 'DOCUMENTS_AVAILABLE_TRANSFORMATIONS', available_transformations) diff --git a/apps/documents/models.py b/apps/documents/models.py index 3b3923c06d..6971cd3889 100644 --- a/apps/documents/models.py +++ b/apps/documents/models.py @@ -7,6 +7,7 @@ from django.conf import settings from django.db import models from django.utils.translation import ugettext_lazy as _ from django.db.models import Q +from django.contrib.auth.models import User from python_magic import magic @@ -21,6 +22,7 @@ from documents.conf.settings import UUID_FUNCTION from documents.conf.settings import STORAGE_BACKEND from documents.conf.settings import AVAILABLE_TRANSFORMATIONS from documents.conf.settings import DEFAULT_TRANSFORMATIONS +from documents.conf.settings import RECENT_COUNT def get_filename_from_uuid(instance, filename): @@ -383,5 +385,31 @@ class DocumentPageTransformation(models.Model): verbose_name_plural = _(u'document page transformations') +class RecentDocumentManager(models.Manager): + def add_document_for_user(self, user, document): + new_recent, _ = RecentDocument.objects.get_or_create(user=user, document=document, defaults={'datetime_accessed': datetime.now()}) + new_recent.datetime_accessed = datetime.now() + new_recent.save() + to_delete = RecentDocument.objects.filter(user=user)[RECENT_COUNT:] + for recent_to_delete in to_delete: + recent_to_delete.delete() + + +class RecentDocument(models.Model): + user = models.ForeignKey(User, verbose_name=_(u'user'), editable=False) + document = models.ForeignKey(Document, verbose_name=_(u'document'), editable=False) + datetime_accessed = models.DateTimeField(verbose_name=_(u'accessed'), db_index=True) + + objects = RecentDocumentManager() + + def __unicode__(self): + return unicode(self.document) + + class Meta: + ordering = ('-datetime_accessed',) + verbose_name = _(u'recent document') + verbose_name_plural = _(u'recent documents') + + register(Document, _(u'document'), ['document_type__name', 'file_mimetype', 'file_filename', 'file_extension', 'documentmetadata__value', 'documentpage__content', 'description']) #register(Document, _(u'document'), ['document_type__name', 'file_mimetype', 'file_extension', 'documentmetadata__value', 'documentpage__content', 'description', {'field_name':'file_filename', 'comparison':'iexact'}]) diff --git a/apps/documents/urls.py b/apps/documents/urls.py index 86f08b5328..4dc8498424 100644 --- a/apps/documents/urls.py +++ b/apps/documents/urls.py @@ -14,6 +14,7 @@ from converter.api import QUALITY_HIGH urlpatterns = patterns('documents.views', url(r'^document/list/$', 'document_list', (), 'document_list'), + url(r'^document/list/recent/$', 'document_list_recent', (), 'document_list_recent'), url(r'^document/create/from/local/single/$', 'document_create', {'multiple': False}, 'document_create'), url(r'^document/create/from/local/multiple/$', 'document_create', {'multiple': True}, 'document_create_multiple'), url(r'^document/type/(?P\d+)/upload/single/$', 'upload_document_with_type', {'multiple': False}, 'upload_document_with_type'), diff --git a/apps/documents/views.py b/apps/documents/views.py index 2d7cd673fd..e833c37d9c 100644 --- a/apps/documents/views.py +++ b/apps/documents/views.py @@ -54,7 +54,7 @@ from forms import DocumentTypeSelectForm, DocumentCreateWizard, \ from metadata import save_metadata_list, \ decode_metadata_from_url, metadata_repr_as_list from models import Document, DocumentMetadata, DocumentType, MetadataType, \ - DocumentPage, DocumentPageTransformation + DocumentPage, DocumentPageTransformation, RecentDocument from staging import StagingFile from utils import document_save_to_temp_dir @@ -115,6 +115,8 @@ def document_create_sibling(request, document_id, multiple=True): def _handle_save_document(request, document, form=None): + RecentDocument.objects.add_document_for_user(request.user, document) + if form and 'document_type_available_filenames' in form.cleaned_data: if form.cleaned_data['document_type_available_filenames']: document.file_filename = form.cleaned_data['document_type_available_filenames'].filename @@ -253,6 +255,9 @@ def document_view(request, document_id): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_VIEW]) document = get_object_or_404(Document.objects.select_related(), pk=document_id) + + RecentDocument.objects.add_document_for_user(request.user, document) + form = DocumentForm_view(instance=document, extra_fields=[ {'label': _(u'Filename'), 'field': 'file_filename'}, {'label': _(u'File extension'), 'field': 'file_extension'}, @@ -391,6 +396,9 @@ def document_edit(request, document_id): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_PROPERTIES_EDIT]) document = get_object_or_404(Document, pk=document_id) + + RecentDocument.objects.add_document_for_user(request.user, document) + if request.method == 'POST': form = DocumentForm_edit(request.POST, initial={'document_type': document.document_type}) if form.is_valid(): @@ -450,6 +458,8 @@ def document_edit_metadata(request, document_id=None, document_id_list=None): metadata = {} for document in documents: + RecentDocument.objects.add_document_for_user(request.user, document) + for item in DocumentTypeMetadataType.objects.filter(document_type=document.document_type): value = document.documentmetadata_set.get(metadata_type=item.metadata_type).value if document.documentmetadata_set.filter(metadata_type=item.metadata_type) else u'' if item.metadata_type in metadata: @@ -809,7 +819,9 @@ def document_view_simple(request, document_id): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_VIEW]) document = get_object_or_404(Document.objects.select_related(), pk=document_id) - + + RecentDocument.objects.add_document_for_user(request.user, document) + content_form = DocumentContentForm(document=document) metadata_groups, errors = document.get_metadata_groups() @@ -964,3 +976,25 @@ def document_page_navigation_previous(request, document_page_id): else: document_page = get_object_or_404(DocumentPage, document=document_page.document, page_number=document_page.page_number - 1) return HttpResponseRedirect(reverse(view, args=[document_page.pk])) + + +def document_list_recent(request): + check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_VIEW]) + + + return render_to_response('generic_list.html', { + 'object_list': [recent_document.document for recent_document in RecentDocument.objects.all()], + 'title': _(u'recent documents'), + 'multi_select_as_buttons': True, + }, context_instance=RequestContext(request)) + + + return object_list( + request, + queryset=[recent_document.document for recent_document in RecentDocument.objects.all()], + template_name='generic_list.html', + extra_context={ + 'title': _(u'recent documents'), + 'multi_select_as_buttons': True, + }, + ) diff --git a/apps/main/views.py b/apps/main/views.py index 03f7f50b34..dc399146d9 100644 --- a/apps/main/views.py +++ b/apps/main/views.py @@ -54,6 +54,7 @@ def check_settings(request): {'name': 'DOCUMENTS_GROUP_SHOW_THUMBNAIL', 'value': documents_settings.GROUP_SHOW_THUMBNAIL, 'description': documents_settings.setting_description}, + {'name': 'DOCUMENTS_RECENT_COUNT', 'value': documents_settings.RECENT_COUNT}, #Filesystem_serving {'name': 'FILESYSTEM_FILESERVING_ENABLE', 'value': filesystem_serving_settings.FILESERVING_ENABLE}, diff --git a/settings.py b/settings.py index 202943c564..db701b80f9 100644 --- a/settings.py +++ b/settings.py @@ -193,6 +193,7 @@ TEMPLATE_CONTEXT_PROCESSORS = ( #DOCUMENTS_TRANFORMATION_PREVIEW_SIZE = '640x480' #DOCUMENTS_AVAILABLE_TRANSFORMATIONS = {} #example: DOCUMENTS_DEFAULT_TRANSFORMATIONS = [{'name':'rotate', 'arguments':"{'degrees':270}"}] +#DOCUMENTS_RECENT_COUNT = 20 # Groups #DOCUMENTS_GROUP_MAX_RESULTS = 20