diff --git a/apps/documents/__init__.py b/apps/documents/__init__.py index 9c287635f0..f8fd9496e8 100644 --- a/apps/documents/__init__.py +++ b/apps/documents/__init__.py @@ -77,13 +77,17 @@ document_page_rotate_left = {'text': _('rotate left'), 'view': 'document_page_ro document_missing_list = {'text': _('Find missing document files'), 'view': 'document_missing_list', 'famfam': 'folder_page', 'permissions': {'namespace': 'documents', 'permissions': [PERMISSION_DOCUMENT_VIEW]}} +metadata_group_link = {'text': _('group actions'), 'view': 'metadatagroup_view', 'famfam': 'page_go', 'permissions': {'namespace': 'documents', 'permissions': [PERMISSION_DOCUMENT_VIEW]}} +metadata_group_back_to_document = {'text': _('return to document'), 'view': 'document_view_simple', 'args': 'ref_object.id', 'famfam': 'page', 'permissions': {'namespace': 'documents', 'permissions': [PERMISSION_DOCUMENT_VIEW]}} +metadata_group_create_sibling = {'text': _('upload new document using same metadata'), 'view': 'document_create_sibling', 'args': 'ref_object.id', 'famfam': 'page_copy', 'permissions': {'namespace': 'documents', 'permissions': [PERMISSION_DOCUMENT_CREATE]}} + staging_file_preview = {'text': _('preview'), 'class': 'fancybox-noscaling', 'view': 'staging_file_preview', 'args': 'object.id', 'famfam': 'drive_magnify'} 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]) register_links(Document, [document_create_sibling], menu_name='sidebar') -register_multi_item_links(['document_list', 'document_list_recent'], [document_multiple_clear_transformations, document_multiple_edit_metadata, document_multiple_delete]) +register_multi_item_links(['metadatagroup_view', 'document_list', 'document_list_recent'], [document_multiple_clear_transformations, document_multiple_edit_metadata, document_multiple_delete]) if ENABLE_SINGLE_DOCUMENT_UPLOAD: 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') @@ -107,6 +111,8 @@ register_links(['document_page_transformation_edit', 'document_page_transformati register_links(StagingFile, [staging_file_preview, staging_file_delete]) +register_links(['metadatagroup_view'], [metadata_group_back_to_document, metadata_group_create_sibling], menu_name='sidebar') + register_diagnostic('documents', _(u'Documents'), document_missing_list) diff --git a/apps/documents/forms.py b/apps/documents/forms.py index 82df934e49..e9d79758b1 100644 --- a/apps/documents/forms.py +++ b/apps/documents/forms.py @@ -6,6 +6,7 @@ from django.utils.http import urlencode from django.core.urlresolvers import reverse from django.utils.safestring import mark_safe from django.forms.formsets import formset_factory +from django.template.defaultfilters import capfirst from staging import StagingFile @@ -320,8 +321,22 @@ class DocumentCreateWizard(BoundFormWizard): class MetaDataImageWidget(forms.widgets.Widget): def render(self, name, value, attrs=None): output = [] + if value['links']: + output.append(u'') + output.append( - u'
%s
' % + u'%s
' % ugettext(u'Total documents: %s') % len(value['group_data'])) output.append(u'
') @@ -360,6 +375,7 @@ class MetaDataImageWidget(forms.widgets.Widget): class MetaDataGroupForm(forms.Form): def __init__(self, *args, **kwargs): groups = kwargs.pop('groups', None) + links = kwargs.pop('links', None) current_document = kwargs.pop('current_document', None) super(MetaDataGroupForm, self).__init__(*args, **kwargs) for group, data in groups.items(): @@ -369,6 +385,7 @@ class MetaDataGroupForm(forms.Form): initial={ 'group': group, 'group_data': data, - 'current_document': current_document + 'current_document': current_document, + 'links': links } ) diff --git a/apps/documents/models.py b/apps/documents/models.py index f7beb30c26..aca6899cb2 100644 --- a/apps/documents/models.py +++ b/apps/documents/models.py @@ -159,8 +159,8 @@ class Document(models.Model): def get_metadata_string(self): return u', '.join([u'%s - %s' % (metadata.metadata_type, metadata.value) for metadata in self.documentmetadata_set.select_related('metadata_type', 'document').defer('document__document_type', 'document__file', 'document__description', 'document__file_filename', 'document__uuid', 'document__date_added', 'document__date_updated', 'document__file_mimetype', 'document__file_mime_encoding')]) - def get_metadata_groups(self): - return MetadataGroup.objects.get_groups_for(self) + def get_metadata_groups(self, group_obj=None): + return MetadataGroup.objects.get_groups_for(self, group_obj) def apply_default_transformations(self): #Only apply default transformations on new documents @@ -280,38 +280,46 @@ class DocumentPage(models.Model): class MetadataGroupManager(models.Manager): - def get_groups_for(self, document): + def get_groups_for(self, document, group_obj=None): errors = [] metadata_groups = {} - if MetadataGroup.objects.all().count(): - metadata_dict = {} - for document_metadata in document.documentmetadata_set.all(): - metadata_dict['metadata_%s' % document_metadata.metadata_type.name] = document_metadata.value + metadata_dict = {} + for document_metadata in document.documentmetadata_set.all(): + metadata_dict['metadata_%s' % document_metadata.metadata_type.name] = document_metadata.value + + if group_obj: + groups_qs = MetadataGroup.objects.filter((Q(document_type=document.document_type) | Q(document_type=None)) & Q(enabled=True) & Q(pk=group_obj.pk)) + else: + groups_qs = MetadataGroup.objects.filter((Q(document_type=document.document_type) | Q(document_type=None)) & Q(enabled=True)) - for group in MetadataGroup.objects.filter((Q(document_type=document.document_type) | Q(document_type=None)) & Q(enabled=True)): - total_query = Q() - for item in group.metadatagroupitem_set.filter(enabled=True): - try: - value_query = Q(**{'value__%s' % item.operator: eval(item.expression, metadata_dict)}) - if item.negated: - query = (Q(metadata_type__id=item.metadata_type_id) & ~value_query) - else: - query = (Q(metadata_type__id=item.metadata_type_id) & value_query) + for group in groups_qs: + total_query = Q() + for item in group.metadatagroupitem_set.filter(enabled=True): + try: + value_query = Q(**{'value__%s' % item.operator: eval(item.expression, metadata_dict)}) + if item.negated: + query = (Q(metadata_type__id=item.metadata_type_id) & ~value_query) + else: + query = (Q(metadata_type__id=item.metadata_type_id) & value_query) - if item.inclusion == INCLUSION_AND: - total_query &= query - elif item.inclusion == INCLUSION_OR: - total_query |= query - except Exception, e: - errors.append(e) - value_query = Q() - query = Q() + if item.inclusion == INCLUSION_AND: + total_query &= query + elif item.inclusion == INCLUSION_OR: + total_query |= query + except Exception, e: + errors.append(e) + value_query = Q() + query = Q() - if total_query: - document_id_list = DocumentMetadata.objects.filter(total_query).values_list('document', flat=True) - else: - document_id_list = [] + if total_query: + document_id_list = DocumentMetadata.objects.filter(total_query).values_list('document', flat=True) metadata_groups[group] = Document.objects.filter(Q(id__in=document_id_list)).order_by('file_filename') or [] + else: + metadata_groups[group] = [] + + if group_obj: + return metadata_groups[group_obj], errors + return metadata_groups, errors diff --git a/apps/documents/urls.py b/apps/documents/urls.py index 7ab697452f..c90615c1e0 100644 --- a/apps/documents/urls.py +++ b/apps/documents/urls.py @@ -35,6 +35,8 @@ urlpatterns = patterns('documents.views', url(r'^document/(?P\d+)/create/siblings/$', 'document_create_sibling', {'multiple': True if ENABLE_SINGLE_DOCUMENT_UPLOAD == False else False}, 'document_create_sibling'), url(r'^document/(?P\d+)/find_duplicates/$', 'document_find_duplicates', (), 'document_find_duplicates'), url(r'^document/(?P\d+)/clear_transformations/$', 'document_clear_transformations', (), 'document_clear_transformations'), + url(r'^document/(?P\d+)/group/(?P\d+)/$', 'metadatagroup_view', (), 'metadatagroup_view'), + url(r'^document/multiple/clear_transformations/$', 'document_multiple_clear_transformations', (), 'document_multiple_clear_transformations'), url(r'^duplicates/$', 'document_find_all_duplicates', (), 'document_find_all_duplicates'), @@ -60,4 +62,6 @@ urlpatterns = patterns('documents.views', url(r'^document/page/transformation/(?P\d+)/delete/$', 'document_page_transformation_delete', (), 'document_page_transformation_delete'), url(r'^document/missing/list/$', 'document_missing_list', (), 'document_missing_list'), + + url(r'^metadatagroup_action/action/$', 'metadatagroup_action', (), 'metadatagroup_action'), ) diff --git a/apps/documents/views.py b/apps/documents/views.py index 3596db6840..077110c8e7 100644 --- a/apps/documents/views.py +++ b/apps/documents/views.py @@ -59,10 +59,11 @@ 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, RecentDocument + DocumentPage, DocumentPageTransformation, RecentDocument, \ + MetadataGroup from staging import StagingFile from utils import document_save_to_temp_dir - +from documents import metadata_group_link PICTURE_ERROR_SMALL = u'picture_error.png' PICTURE_ERROR_MEDIUM = u'1297211435_error.png' @@ -282,12 +283,6 @@ def document_view(request, document_id): {'label': _(u'Pages'), 'field': lambda x: x.documentpage_set.count()}, ]) - metadata_groups, errors = document.get_metadata_groups() - if (request.user.is_staff or request.user.is_superuser) and errors: - for error in errors: - messages.warning(request, _(u'Metadata group query error: %s' % error)) - - preview_form = DocumentPreviewForm(document=document) form_list = [ { @@ -324,8 +319,11 @@ def document_view(request, document_id): subtemplates_dict.append( { 'title':_(u'metadata groups'), - 'form': MetaDataGroupForm(groups=metadata_groups, current_document=document), + 'form': MetaDataGroupForm(groups=metadata_groups, current_document=document, links=[ + metadata_group_link]), 'name': 'generic_form_subtemplate.html', + 'form_action': reverse('metadatagroup_action'), + 'submit_method': 'GET', } ) @@ -871,11 +869,14 @@ def document_view_simple(request, document_id): subtemplates_dict.append( { 'title':_(u'metadata groups'), - 'form': MetaDataGroupForm(groups=metadata_groups, current_document=document), + 'form': MetaDataGroupForm(groups=metadata_groups, current_document=document, links=[ + metadata_group_link]), 'name': 'generic_form_subtemplate.html', + 'form_action': reverse('metadatagroup_action'), + 'submit_method': 'GET', } ) - + return render_to_response('generic_detail.html', { 'form_list': form_list, 'object': document, @@ -1081,3 +1082,30 @@ def document_page_rotate_left(request, document_page_id): document_page_id, rotation_function = lambda x: (x - ROTATION_STEP) % 360 ) + + +def metadatagroup_action(request): + action = request.GET.get('action', None) + + if not action: + messages.error(request, _(u'No action selected.')) + return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) + + return HttpResponseRedirect(action) + + +def metadatagroup_view(request, document_id, metadata_group_id): + check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_VIEW]) + + document = get_object_or_404(Document, pk=document_id) + metadata_group = get_object_or_404(MetadataGroup, pk=metadata_group_id) + + object_list, errors = document.get_metadata_groups(metadata_group) + + return render_to_response('generic_list.html', { + 'object_list': object_list, + 'title': _(u'documents in group: %s, for document: %s') % (metadata_group, document), + 'multi_select_as_buttons': True, + 'hide_links': True, + 'ref_object': document + }, context_instance=RequestContext(request))