Added support for metadata group actions

This commit is contained in:
Roberto Rosario
2011-04-22 07:36:35 -04:00
parent f3faf00315
commit d81e784167
5 changed files with 105 additions and 42 deletions

View File

@@ -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]}} 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_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'} 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_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_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: 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') 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(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) register_diagnostic('documents', _(u'Documents'), document_missing_list)

View File

@@ -6,6 +6,7 @@ from django.utils.http import urlencode
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.forms.formsets import formset_factory from django.forms.formsets import formset_factory
from django.template.defaultfilters import capfirst
from staging import StagingFile from staging import StagingFile
@@ -320,8 +321,22 @@ class DocumentCreateWizard(BoundFormWizard):
class MetaDataImageWidget(forms.widgets.Widget): class MetaDataImageWidget(forms.widgets.Widget):
def render(self, name, value, attrs=None): def render(self, name, value, attrs=None):
output = [] output = []
if value['links']:
output.append(u'<div class="group navform wat-cf">')
for link in value['links']:
output.append(u'''
<button class="button" type="submit" name="action" value="%(action)s">
<span class="famfam active famfam-%(famfam)s"></span>%(text)s
</button>
''' % {
'famfam': link.get('famfam', 'link'),
'text': capfirst(link['text']),
'action': reverse('metadatagroup_view', args=[value['current_document'].pk, value['group'].pk])
})
output.append(u'</div>')
output.append( output.append(
u'<br /><span class="famfam active famfam-page_copy"></span>%s<br />' % u'<span class="famfam active famfam-page_copy"></span>%s<br />' %
ugettext(u'Total documents: %s') % len(value['group_data'])) ugettext(u'Total documents: %s') % len(value['group_data']))
output.append(u'<div style="white-space:nowrap; overflow: auto;">') output.append(u'<div style="white-space:nowrap; overflow: auto;">')
@@ -360,6 +375,7 @@ class MetaDataImageWidget(forms.widgets.Widget):
class MetaDataGroupForm(forms.Form): class MetaDataGroupForm(forms.Form):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
groups = kwargs.pop('groups', None) groups = kwargs.pop('groups', None)
links = kwargs.pop('links', None)
current_document = kwargs.pop('current_document', None) current_document = kwargs.pop('current_document', None)
super(MetaDataGroupForm, self).__init__(*args, **kwargs) super(MetaDataGroupForm, self).__init__(*args, **kwargs)
for group, data in groups.items(): for group, data in groups.items():
@@ -369,6 +385,7 @@ class MetaDataGroupForm(forms.Form):
initial={ initial={
'group': group, 'group': group,
'group_data': data, 'group_data': data,
'current_document': current_document 'current_document': current_document,
'links': links
} }
) )

View File

@@ -159,8 +159,8 @@ class Document(models.Model):
def get_metadata_string(self): 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')]) 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): def get_metadata_groups(self, group_obj=None):
return MetadataGroup.objects.get_groups_for(self) return MetadataGroup.objects.get_groups_for(self, group_obj)
def apply_default_transformations(self): def apply_default_transformations(self):
#Only apply default transformations on new documents #Only apply default transformations on new documents
@@ -280,38 +280,46 @@ class DocumentPage(models.Model):
class MetadataGroupManager(models.Manager): class MetadataGroupManager(models.Manager):
def get_groups_for(self, document): def get_groups_for(self, document, group_obj=None):
errors = [] errors = []
metadata_groups = {} metadata_groups = {}
if MetadataGroup.objects.all().count(): metadata_dict = {}
metadata_dict = {} for document_metadata in document.documentmetadata_set.all():
for document_metadata in document.documentmetadata_set.all(): metadata_dict['metadata_%s' % document_metadata.metadata_type.name] = document_metadata.value
metadata_dict['metadata_%s' % document_metadata.metadata_type.name] = document_metadata.value
for group in MetadataGroup.objects.filter((Q(document_type=document.document_type) | Q(document_type=None)) & Q(enabled=True)): if group_obj:
total_query = Q() groups_qs = MetadataGroup.objects.filter((Q(document_type=document.document_type) | Q(document_type=None)) & Q(enabled=True) & Q(pk=group_obj.pk))
for item in group.metadatagroupitem_set.filter(enabled=True): else:
try: groups_qs = MetadataGroup.objects.filter((Q(document_type=document.document_type) | Q(document_type=None)) & Q(enabled=True))
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: for group in groups_qs:
total_query &= query total_query = Q()
elif item.inclusion == INCLUSION_OR: for item in group.metadatagroupitem_set.filter(enabled=True):
total_query |= query try:
except Exception, e: value_query = Q(**{'value__%s' % item.operator: eval(item.expression, metadata_dict)})
errors.append(e) if item.negated:
value_query = Q() query = (Q(metadata_type__id=item.metadata_type_id) & ~value_query)
query = Q() else:
query = (Q(metadata_type__id=item.metadata_type_id) & value_query)
if total_query: if item.inclusion == INCLUSION_AND:
document_id_list = DocumentMetadata.objects.filter(total_query).values_list('document', flat=True) total_query &= query
else: elif item.inclusion == INCLUSION_OR:
document_id_list = [] 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)
metadata_groups[group] = Document.objects.filter(Q(id__in=document_id_list)).order_by('file_filename') or [] 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 return metadata_groups, errors

View File

@@ -35,6 +35,8 @@ urlpatterns = patterns('documents.views',
url(r'^document/(?P<document_id>\d+)/create/siblings/$', 'document_create_sibling', {'multiple': True if ENABLE_SINGLE_DOCUMENT_UPLOAD == False else False}, 'document_create_sibling'), url(r'^document/(?P<document_id>\d+)/create/siblings/$', 'document_create_sibling', {'multiple': True if ENABLE_SINGLE_DOCUMENT_UPLOAD == False else False}, 'document_create_sibling'),
url(r'^document/(?P<document_id>\d+)/find_duplicates/$', 'document_find_duplicates', (), 'document_find_duplicates'), url(r'^document/(?P<document_id>\d+)/find_duplicates/$', 'document_find_duplicates', (), 'document_find_duplicates'),
url(r'^document/(?P<document_id>\d+)/clear_transformations/$', 'document_clear_transformations', (), 'document_clear_transformations'), url(r'^document/(?P<document_id>\d+)/clear_transformations/$', 'document_clear_transformations', (), 'document_clear_transformations'),
url(r'^document/(?P<document_id>\d+)/group/(?P<metadata_group_id>\d+)/$', 'metadatagroup_view', (), 'metadatagroup_view'),
url(r'^document/multiple/clear_transformations/$', 'document_multiple_clear_transformations', (), 'document_multiple_clear_transformations'), 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'), 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<document_page_transformation_id>\d+)/delete/$', 'document_page_transformation_delete', (), 'document_page_transformation_delete'), url(r'^document/page/transformation/(?P<document_page_transformation_id>\d+)/delete/$', 'document_page_transformation_delete', (), 'document_page_transformation_delete'),
url(r'^document/missing/list/$', 'document_missing_list', (), 'document_missing_list'), url(r'^document/missing/list/$', 'document_missing_list', (), 'document_missing_list'),
url(r'^metadatagroup_action/action/$', 'metadatagroup_action', (), 'metadatagroup_action'),
) )

View File

@@ -59,10 +59,11 @@ from forms import DocumentTypeSelectForm, DocumentCreateWizard, \
from metadata import save_metadata_list, \ from metadata import save_metadata_list, \
decode_metadata_from_url, metadata_repr_as_list decode_metadata_from_url, metadata_repr_as_list
from models import Document, DocumentMetadata, DocumentType, MetadataType, \ from models import Document, DocumentMetadata, DocumentType, MetadataType, \
DocumentPage, DocumentPageTransformation, RecentDocument DocumentPage, DocumentPageTransformation, RecentDocument, \
MetadataGroup
from staging import StagingFile from staging import StagingFile
from utils import document_save_to_temp_dir from utils import document_save_to_temp_dir
from documents import metadata_group_link
PICTURE_ERROR_SMALL = u'picture_error.png' PICTURE_ERROR_SMALL = u'picture_error.png'
PICTURE_ERROR_MEDIUM = u'1297211435_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()}, {'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) preview_form = DocumentPreviewForm(document=document)
form_list = [ form_list = [
{ {
@@ -324,8 +319,11 @@ def document_view(request, document_id):
subtemplates_dict.append( subtemplates_dict.append(
{ {
'title':_(u'metadata groups'), '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', 'name': 'generic_form_subtemplate.html',
'form_action': reverse('metadatagroup_action'),
'submit_method': 'GET',
} }
) )
@@ -871,8 +869,11 @@ def document_view_simple(request, document_id):
subtemplates_dict.append( subtemplates_dict.append(
{ {
'title':_(u'metadata groups'), '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', 'name': 'generic_form_subtemplate.html',
'form_action': reverse('metadatagroup_action'),
'submit_method': 'GET',
} }
) )
@@ -1081,3 +1082,30 @@ def document_page_rotate_left(request, document_page_id):
document_page_id, document_page_id,
rotation_function = lambda x: (x - ROTATION_STEP) % 360 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))