diff --git a/apps/documents/__init__.py b/apps/documents/__init__.py index a6bb737d5f..5055d00152 100644 --- a/apps/documents/__init__.py +++ b/apps/documents/__init__.py @@ -10,7 +10,8 @@ from tags.widgets import get_tags_inline_widget_simple from documents.models import Document, DocumentPage, DocumentPageTransformation from documents.staging import StagingFile -from documents.conf.settings import ENABLE_SINGLE_DOCUMENT_UPLOAD +from documents.conf.settings import USE_STAGING_DIRECTORY +from documents.conf.settings import PER_USER_STAGING_DIRECTORY from documents.literals import PERMISSION_DOCUMENT_CREATE, \ PERMISSION_DOCUMENT_PROPERTIES_EDIT, PERMISSION_DOCUMENT_VIEW, \ PERMISSION_DOCUMENT_DELETE, PERMISSION_DOCUMENT_DOWNLOAD, \ @@ -31,8 +32,8 @@ 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': _(u'upload a new document'), 'view': 'document_create', 'famfam': 'page_add', 'permissions': {'namespace': 'documents', 'permissions': [PERMISSION_DOCUMENT_CREATE]}} -document_create_multiple = {'text': _(u'upload multiple new documents'), 'view': 'document_create_multiple', 'famfam': 'page_add', 'permissions': {'namespace': 'documents', 'permissions': [PERMISSION_DOCUMENT_CREATE]}} -document_create_sibling = {'text': _(u'upload new document using same metadata'), 'view': 'document_create_sibling', 'args': 'object.id', 'famfam': 'page_copy', 'permissions': {'namespace': 'documents', 'permissions': [PERMISSION_DOCUMENT_CREATE]}} +document_create_multiple = {'text': _(u'upload new documents'), 'view': 'document_create_multiple', 'famfam': 'page_add', 'permissions': {'namespace': 'documents', 'permissions': [PERMISSION_DOCUMENT_CREATE]}} +document_create_sibling = {'text': _(u'upload new documents using same metadata'), 'view': 'document_create_sibling', 'args': 'object.id', 'famfam': 'page_copy', 'permissions': {'namespace': 'documents', 'permissions': [PERMISSION_DOCUMENT_CREATE]}} document_view_simple = {'text': _(u'details (simple)'), 'view': 'document_view_simple', 'args': 'object.id', 'famfam': 'page', 'permissions': {'namespace': 'documents', 'permissions': [PERMISSION_DOCUMENT_VIEW]}} document_view_advanced = {'text': _(u'details (advanced)'), 'view': 'document_view_advanced', 'args': 'object.id', 'famfam': 'page', 'permissions': {'namespace': 'documents', 'permissions': [PERMISSION_DOCUMENT_VIEW]}} document_delete = {'text': _(u'delete'), 'view': 'document_delete', 'args': 'object.id', 'famfam': 'page_delete', 'permissions': {'namespace': 'documents', 'permissions': [PERMISSION_DOCUMENT_DELETE]}} @@ -68,18 +69,19 @@ document_page_rotate_left = {'text': _(u'rotate left'), 'class': 'no-parent-hist document_missing_list = {'text': _(u'Find missing document files'), 'view': 'document_missing_list', 'famfam': 'folder_page', 'permissions': {'namespace': 'documents', 'permissions': [PERMISSION_DOCUMENT_VIEW]}} -staging_file_preview = {'text': _(u'preview'), 'class': 'fancybox-noscaling', 'view': 'staging_file_preview', 'args': 'object.id', 'famfam': 'drive_magnify'} -staging_file_delete = {'text': _(u'delete'), 'view': 'staging_file_delete', 'args': 'object.id', 'famfam': 'drive_delete'} +upload_document_from_local = {'text': _(u'local'), 'view': 'upload_document_from_local', 'famfam': 'drive_disk', 'keep_query': True} +upload_document_from_staging = {'text': _(u'staging'), 'view': 'upload_document_from_staging', 'famfam': 'drive_network', 'keep_query': True, 'condition': lambda x: USE_STAGING_DIRECTORY} +upload_document_from_user_staging = {'text': _(u'user staging'), 'view': 'upload_document_from_user_staging', 'famfam': 'drive_user', 'keep_query': True, 'condition': lambda x: PER_USER_STAGING_DIRECTORY} + +staging_file_preview = {'text': _(u'preview'), 'class': 'fancybox-noscaling', 'view': 'staging_file_preview', 'args': ['source', 'object.id'], 'famfam': 'drive_magnify'} +staging_file_delete = {'text': _(u'delete'), 'view': 'staging_file_delete', 'args': ['source', 'object.id'], 'famfam': 'drive_delete'} register_links(Document, [document_view_simple, document_view_advanced, document_edit, document_print, document_delete, document_download, document_find_duplicates, document_clear_transformations]) register_links(Document, [document_create_sibling], menu_name='sidebar') register_multi_item_links(['document_group_view', 'document_list', 'document_list_recent'], [document_multiple_clear_transformations, document_multiple_delete]) -if ENABLE_SINGLE_DOCUMENT_UPLOAD: - register_links(['document_list_recent', 'document_list', 'document_create', 'document_create_multiple', 'upload_document', 'upload_document_multiple'], [document_list_recent, document_list, document_create, document_create_multiple], menu_name='sidebar') -else: - register_links(['document_list_recent', 'document_list', 'document_create', 'document_create_multiple', 'upload_document', 'upload_document_multiple'], [document_list_recent, document_list, document_create_multiple], menu_name='sidebar') +register_links(['document_list_recent', 'document_list', 'document_create', 'document_create_multiple', 'upload_document', 'upload_document_from_local', 'upload_document_from_staging', 'upload_document_from_user_staging'], [document_list_recent, document_list, document_create_multiple], menu_name='sidebar') register_links(DocumentPage, [ document_page_transformation_list, document_page_view, @@ -93,6 +95,10 @@ register_links(DocumentPage, [ register_links(['document_page_view'], [document_page_rotate_left, document_page_rotate_right, document_page_zoom_in, document_page_zoom_out], menu_name='form_header') +# Upload sources +register_links(['upload_document_from_local', 'upload_document_from_staging', 'upload_document_from_user_staging'], [upload_document_from_local, upload_document_from_staging, upload_document_from_user_staging], menu_name='form_header') + + register_links(DocumentPageTransformation, [document_page_transformation_edit, document_page_transformation_delete]) register_links(DocumentPageTransformation, [document_page_transformation_page_edit, document_page_transformation_page_view], menu_name='sidebar') register_links('document_page_transformation_list', [document_page_transformation_create], menu_name='sidebar') @@ -132,15 +138,7 @@ register_model_list_columns(Document, [ }, ]) -if ENABLE_SINGLE_DOCUMENT_UPLOAD: - register_menu([ - {'text': _(u'documents'), 'view': 'document_list_recent', 'links': [ - document_list_recent, document_list, document_create, \ - document_create_multiple - - ], 'famfam': 'page', 'position': 1}]) -else: - register_menu([ - {'text': _(u'documents'), 'view': 'document_list_recent', 'links': [ - document_list_recent, document_list, document_create_multiple - ], 'famfam': 'page', 'position': 1}]) +register_menu([ + {'text': _(u'documents'), 'view': 'document_list_recent', 'links': [ + document_list_recent, document_list, document_create_multiple + ], 'famfam': 'page', 'position': 1}]) diff --git a/apps/documents/conf/settings.py b/apps/documents/conf/settings.py index 14c08a31ad..e98e8ecc34 100644 --- a/apps/documents/conf/settings.py +++ b/apps/documents/conf/settings.py @@ -34,7 +34,6 @@ register_settings( {'name': u'USER_STAGING_DIRECTORY_EXPRESSION', 'global_name': u'DOCUMENTS_USER_STAGING_DIRECTORY_EXPRESSION', 'default': u'user.username'}, {'name': u'DELETE_STAGING_FILE_AFTER_UPLOAD', 'global_name': u'DOCUMENTS_DELETE_STAGING_FILE_AFTER_UPLOAD', 'default': False}, {'name': u'STAGING_FILES_PREVIEW_SIZE', 'global_name': u'DOCUMENTS_STAGING_FILES_PREVIEW_SIZE', 'default': u'640x480'}, - {'name': u'ENABLE_SINGLE_DOCUMENT_UPLOAD', 'global_name': u'DOCUMENTS_ENABLE_SINGLE_DOCUMENT_UPLOAD', 'default': True}, {'name': u'UNCOMPRESS_COMPRESSED_LOCAL_FILES', 'global_name': u'DOCUMENTS_UNCOMPRESS_COMPRESSED_LOCAL_FILES', 'default': True}, {'name': u'UNCOMPRESS_COMPRESSED_STAGING_FILES', 'global_name': u'DOCUMENTS_UNCOMPRESS_COMPRESSED_STAGING_FILES', 'default': True}, # Saving diff --git a/apps/documents/forms.py b/apps/documents/forms.py index 613c77e2a5..eae58dd596 100644 --- a/apps/documents/forms.py +++ b/apps/documents/forms.py @@ -6,12 +6,10 @@ from django.core.urlresolvers import reverse from django.utils.safestring import mark_safe from django.conf import settings -from common.wizard import BoundFormWizard from common.forms import DetailForm from common.literals import PAGE_SIZE_CHOICES, PAGE_ORIENTATION_CHOICES from common.conf.settings import DEFAULT_PAPER_SIZE from common.conf.settings import DEFAULT_PAGE_ORIENTATION -from common.utils import urlquote from metadata.models import MetadataSet, MetadataType from metadata.forms import MetadataFormSet @@ -245,82 +243,6 @@ class DocumentTypeSelectForm(forms.Form): document_type = forms.ModelChoiceField(queryset=DocumentType.objects.all(), label=(u'Document type'), required=False) -class DocumentCreateWizard(BoundFormWizard): - def generate_metadata_initial_values(self): - initial = [] - for metadata_type in self.metadata_types: - initial.append({ - 'metadata_type': metadata_type, - }) - - for metadata_set in self.metadata_sets: - for metadata_set_item in metadata_set.metadatasetitem_set.all(): - data = { - 'metadata_type': metadata_set_item.metadata_type, - } - if data not in initial: - initial.append(data) - - return initial - - def __init__(self, *args, **kwargs): - self.query_dict = {} - self.multiple = kwargs.pop('multiple', True) - self.step_titles = kwargs.pop('step_titles', [ - _(u'step 1 of 3: Document type'), - _(u'step 2 of 3: Metadata selection'), - _(u'step 3 of 3: Document metadata'), - ]) - self.document_type = kwargs.pop('document_type', None) - - super(DocumentCreateWizard, self).__init__(*args, **kwargs) - - if self.document_type: - self.initial = {0: self.generate_metadata_initial_values()} - - def render_template(self, request, form, previous_fields, step, context=None): - context = {'step_title': self.extra_context['step_titles'][step]} - return super(DocumentCreateWizard, self).render_template( - request, form, previous_fields, step, context - ) - - def parse_params(self, request, *args, **kwargs): - self.extra_context = {'step_titles': self.step_titles} - - def process_step(self, request, form, step): - if isinstance(form, DocumentTypeSelectForm): - self.document_type = form.cleaned_data['document_type'] - - if isinstance(form, MetadataSelectionForm): - self.metadata_sets = form.cleaned_data['metadata_sets'] - self.metadata_types = form.cleaned_data['metadata_types'] - initial_data = self.generate_metadata_initial_values() - self.initial = {2: initial_data} - if not initial_data: - # If there is no metadata selected end wizard - self.form_list = [DocumentTypeSelectForm, MetadataSelectionForm] - - if isinstance(form, MetadataFormSet): - for identifier, metadata in enumerate(form.cleaned_data): - self.query_dict['metadata%s_id' % identifier] = metadata['id'] - self.query_dict['metadata%s_value' % identifier] = metadata['value'] - - def get_template(self, step): - return 'generic_wizard.html' - - def done(self, request, form_list): - if self.multiple: - view = 'upload_document_multiple' - else: - view = 'upload_document' - - if self.document_type: - self.query_dict['document_type_id'] = self.document_type.pk - - url = urlquote(reverse(view), self.query_dict) - return HttpResponseRedirect(url) - - class PrintForm(forms.Form): page_size = forms.ChoiceField(choices=PAGE_SIZE_CHOICES, initial=DEFAULT_PAPER_SIZE, label=_(u'Page size'), required=False) custom_page_width = forms.CharField(label=_(u'Custom page width'), required=False) diff --git a/apps/documents/literals.py b/apps/documents/literals.py index 975661d9e8..74d9373de4 100644 --- a/apps/documents/literals.py +++ b/apps/documents/literals.py @@ -11,3 +11,7 @@ PERMISSION_DOCUMENT_DELETE = 'document_delete' PERMISSION_DOCUMENT_DOWNLOAD = 'document_download' PERMISSION_DOCUMENT_TRANSFORM = 'document_transform' PERMISSION_DOCUMENT_TOOLS = 'document_tools' + +UPLOAD_SOURCE_LOCAL = u'local' +UPLOAD_SOURCE_STAGING = u'staging' +UPLOAD_SOURCE_USER_STAGING = u'user_staging' diff --git a/apps/documents/staging.py b/apps/documents/staging.py index 8c0ed517d7..64387b9c42 100644 --- a/apps/documents/staging.py +++ b/apps/documents/staging.py @@ -5,29 +5,55 @@ import hashlib from django.core.files.base import File from django.core.exceptions import ObjectDoesNotExist from django.utils.translation import ugettext +from django.contrib import messages +from django.utils.translation import ugettext_lazy as _ + +from converter import TRANFORMATION_CHOICES +from converter.api import convert, cache_cleanup from documents.conf.settings import STAGING_DIRECTORY from documents.conf.settings import DEFAULT_TRANSFORMATIONS from documents.conf.settings import STAGING_FILES_PREVIEW_SIZE -from converter import TRANFORMATION_CHOICES -from converter.api import convert, cache_cleanup +from documents.conf.settings import USER_STAGING_DIRECTORY_ROOT +from documents.conf.settings import USER_STAGING_DIRECTORY_EXPRESSION + +from documents.literals import UPLOAD_SOURCE_LOCAL, \ + UPLOAD_SOURCE_STAGING, UPLOAD_SOURCE_USER_STAGING HASH_FUNCTION = lambda x: hashlib.sha256(x).hexdigest() #TODO: Do benchmarks #func = lambda:[StagingFile.get_all() is None for i in range(100)] #t1=time.time();func();t2=time.time();print '%s took %0.3f ms' % (func.func_name, (t2-t1)*1000.0) +STAGING_FILE_FUNCTIONS = { + UPLOAD_SOURCE_STAGING: lambda x: STAGING_DIRECTORY, + UPLOAD_SOURCE_USER_STAGING: lambda x: os.path.join(USER_STAGING_DIRECTORY_ROOT, eval(USER_STAGING_DIRECTORY_EXPRESSION, {'user': x.user})) +} + +def evaluate_user_staging_path(request, source): + try: + return STAGING_FILE_FUNCTIONS[source](request) + except Exception, exc: + messages.error(request, _(u'Error evaluating user staging directory expression; %s') % exc) + return u'' + def get_all_files(path): try: return sorted([os.path.normcase(f) for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))]) except OSError, exc: raise OSError(ugettext(u'Unable get list of staging files: %s') % exc) - - -def create_staging_file_class(): + + +def _return_new_class(): return type('StagingFile', (StagingFile,), dict(StagingFile.__dict__)) + +def create_staging_file_class(request, source): + cls = _return_new_class() + cls.set_path(evaluate_user_staging_path(request, source)) + return cls + class StagingFile(object): """ diff --git a/apps/documents/urls.py b/apps/documents/urls.py index 4b88aace3e..4fac1607b3 100644 --- a/apps/documents/urls.py +++ b/apps/documents/urls.py @@ -1,23 +1,26 @@ from django.conf.urls.defaults import patterns, url +from converter.api import QUALITY_HIGH, QUALITY_PRINT + from documents.conf.settings import PREVIEW_SIZE from documents.conf.settings import PRINT_SIZE from documents.conf.settings import THUMBNAIL_SIZE from documents.conf.settings import DISPLAY_SIZE from documents.conf.settings import MULTIPAGE_PREVIEW_SIZE -from documents.conf.settings import ENABLE_SINGLE_DOCUMENT_UPLOAD - -from converter.api import QUALITY_HIGH, QUALITY_PRINT +from documents.literals import UPLOAD_SOURCE_LOCAL, \ + UPLOAD_SOURCE_STAGING, UPLOAD_SOURCE_USER_STAGING 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/upload/single/$', 'upload_document_with_type', {'multiple': False}, 'upload_document'), - url(r'^document/type/upload/multiple/$', 'upload_document_with_type', {'multiple': True}, 'upload_document_multiple'), - url(r'^document/(?P\d+)/$', 'document_view_advanced', (), 'document_view_advanced'), - url(r'^document/(?P\d+)/simple/$', 'document_view_simple', (), 'document_view_simple'), + url(r'^document/create/from/local/multiple/$', 'document_create', (), 'document_create_multiple'), + + url(r'^document/upload/local/$', 'upload_document_with_type', {'source': UPLOAD_SOURCE_LOCAL}, 'upload_document_from_local'), + url(r'^document/upload/staging/$', 'upload_document_with_type', {'source': UPLOAD_SOURCE_STAGING}, 'upload_document_from_staging'), + url(r'^document/upload/staging/user/$', 'upload_document_with_type', {'source': UPLOAD_SOURCE_USER_STAGING}, 'upload_document_from_user_staging'), + + url(r'^document/(?P\d+)/view/advanced/$', 'document_view_advanced', (), 'document_view_advanced'), + url(r'^document/(?P\d+)/view/$', 'document_view_simple', (), 'document_view_simple'), url(r'^document/(?P\d+)/delete/$', 'document_delete', (), 'document_delete'), url(r'^document/multiple/delete/$', 'document_multiple_delete', (), 'document_multiple_delete'), url(r'^document/(?P\d+)/edit/$', 'document_edit', (), 'document_edit'), @@ -31,15 +34,15 @@ urlpatterns = patterns('documents.views', url(r'^document/(?P\d+)/display/print/$', 'get_document_image', {'size': PRINT_SIZE, 'quality': QUALITY_PRINT}, 'document_display_print'), url(r'^document/(?P\d+)/download/$', 'document_download', (), 'document_download'), - 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+)/create/siblings/$', 'document_create_sibling', '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/multiple/clear_transformations/$', 'document_multiple_clear_transformations', (), 'document_multiple_clear_transformations'), url(r'^duplicates/$', 'document_find_all_duplicates', (), 'document_find_all_duplicates'), - url(r'^staging_file/(?P\w+)/preview/$', 'staging_file_preview', (), 'staging_file_preview'), - url(r'^staging_file/(?P\w+)/delete/$', 'staging_file_delete', (), 'staging_file_delete'), + url(r'^staging_file/type/(?P\w+)/(?P\w+)/preview/$', 'staging_file_preview', (), 'staging_file_preview'), + url(r'^staging_file/type/(?P\w+)/(?P\w+)/delete/$', 'staging_file_delete', (), 'staging_file_delete'), url(r'^document/page/(?P\d+)/$', 'document_page_view', (), 'document_page_view'), url(r'^document/page/(?P\d+)/text/$', 'document_page_text', (), 'document_page_text'), diff --git a/apps/documents/views.py b/apps/documents/views.py index c5bbca1909..b9fa5064b9 100644 --- a/apps/documents/views.py +++ b/apps/documents/views.py @@ -39,8 +39,6 @@ from document_indexing.api import update_indexes, delete_indexes from documents.conf.settings import DELETE_STAGING_FILE_AFTER_UPLOAD from documents.conf.settings import USE_STAGING_DIRECTORY from documents.conf.settings import PER_USER_STAGING_DIRECTORY -from documents.conf.settings import USER_STAGING_DIRECTORY_ROOT -from documents.conf.settings import USER_STAGING_DIRECTORY_EXPRESSION from documents.conf.settings import PREVIEW_SIZE from documents.conf.settings import THUMBNAIL_SIZE @@ -60,19 +58,21 @@ from documents.literals import PERMISSION_DOCUMENT_CREATE, \ PERMISSION_DOCUMENT_TRANSFORM, \ PERMISSION_DOCUMENT_EDIT -from documents.forms import DocumentTypeSelectForm, DocumentCreateWizard, \ +from documents.forms import DocumentTypeSelectForm, \ DocumentForm, DocumentForm_edit, DocumentForm_view, \ StagingDocumentForm, DocumentPreviewForm, \ DocumentPageForm, DocumentPageTransformationForm, \ DocumentContentForm, DocumentPageForm_edit, \ DocumentPageForm_text, PrintForm, MetadataSelectionForm - +from documents.wizards import DocumentCreateWizard from documents.models import Document, DocumentType, DocumentPage, \ DocumentPageTransformation, RecentDocument from documents.staging import create_staging_file_class from documents.literals import PICTURE_ERROR_SMALL, PICTURE_ERROR_MEDIUM, \ PICTURE_UNKNOWN_SMALL, PICTURE_UNKNOWN_MEDIUM - +from documents.literals import UPLOAD_SOURCE_LOCAL, \ + UPLOAD_SOURCE_STAGING, UPLOAD_SOURCE_USER_STAGING + def document_list(request, object_list=None, title=None): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_VIEW]) @@ -85,15 +85,15 @@ def document_list(request, object_list=None, title=None): }, context_instance=RequestContext(request)) -def document_create(request, multiple=True): +def document_create(request): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_CREATE]) - wizard = DocumentCreateWizard(form_list=[DocumentTypeSelectForm, MetadataSelectionForm, MetadataFormSet], multiple=multiple) + wizard = DocumentCreateWizard(form_list=[DocumentTypeSelectForm, MetadataSelectionForm, MetadataFormSet]) return wizard(request) -def document_create_sibling(request, document_id, multiple=True): +def document_create_sibling(request, document_id): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_CREATE]) document = get_object_or_404(Document, pk=document_id) @@ -102,15 +102,10 @@ def document_create_sibling(request, document_id, multiple=True): query_dict['metadata%s_id' % pk] = metadata.metadata_type_id query_dict['metadata%s_value' % pk] = metadata.value - if multiple: - view = 'upload_document_multiple' - else: - view = 'upload_document' - if document.document_type_id: query_dict['document_type_id'] = document.document_type_id - url = reverse(view) + url = reverse('upload_document_from_local') return HttpResponseRedirect('%s?%s' % (url, urlencode(query_dict))) @@ -152,57 +147,41 @@ def _handle_zip_file(request, uploaded_file, document_type): return False -def upload_document_with_type(request, multiple=True): +def upload_document_with_type(request, source): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_CREATE]) - + document_type_id = request.GET.get('document_type_id', None) if document_type_id: - document_type = get_object_or_404(DocumentType, pk=document_type_id) + document_type = get_object_or_404(DocumentType, pk=document_type_id[0]) else: document_type = None - - local_form = DocumentForm(prefix='local', initial={'document_type': document_type}) - if USE_STAGING_DIRECTORY: - StagingFile = create_staging_file_class() - - staging_form = StagingDocumentForm(prefix='staging', - cls=StagingFile, - initial={'document_type': document_type}) - - if PER_USER_STAGING_DIRECTORY: - UserStagingFile = create_staging_file_class() - UserStagingFile.set_path('/tmp/mayan/staging/users/admin') - user_staging_form = StagingDocumentForm(prefix='user_staging', - cls=UserStagingFile, - initial={'document_type': document_type}) if request.method == 'POST': - if 'local-submit' in request.POST.keys(): - local_form = DocumentForm(request.POST, request.FILES, - prefix='local', initial={'document_type': document_type}) - if local_form.is_valid(): + if source == UPLOAD_SOURCE_LOCAL: + form = DocumentForm(request.POST, request.FILES, + initial={'document_type': document_type}) + if form.is_valid(): try: - if (not UNCOMPRESS_COMPRESSED_LOCAL_FILES) or (UNCOMPRESS_COMPRESSED_LOCAL_FILES and not _handle_zip_file(request, request.FILES['local-file'], document_type)): - instance = local_form.save() - _handle_save_document(request, instance, local_form) + if (not UNCOMPRESS_COMPRESSED_LOCAL_FILES) or (UNCOMPRESS_COMPRESSED_LOCAL_FILES and not _handle_zip_file(request, request.FILES['file'], document_type)): + instance = form.save() + _handle_save_document(request, instance, form) messages.success(request, _(u'Document uploaded successfully.')) except Exception, e: messages.error(request, e) - if multiple: - return HttpResponseRedirect(request.get_full_path()) - else: - return HttpResponseRedirect(reverse('document_list')) - elif 'staging-submit' in request.POST.keys() and USE_STAGING_DIRECTORY: - staging_form = StagingDocumentForm(request.POST, request.FILES, - prefix='staging', initial={'document_type': document_type}) - if staging_form.is_valid(): + return HttpResponseRedirect(request.get_full_path()) + elif (USE_STAGING_DIRECTORY and source == UPLOAD_SOURCE_STAGING) or (PER_USER_STAGING_DIRECTORY and source == UPLOAD_SOURCE_USER_STAGING): + StagingFile = create_staging_file_class(request, source) + form = StagingDocumentForm(request.POST, + request.FILES, cls=StagingFile, + initial={'document_type': document_type}) + if form.is_valid(): try: - staging_file = StagingFile.get(staging_form.cleaned_data['staging_file_id']) + staging_file = StagingFile.get(form.cleaned_data['staging_file_id']) if (not UNCOMPRESS_COMPRESSED_STAGING_FILES) or (UNCOMPRESS_COMPRESSED_STAGING_FILES and not _handle_zip_file(request, staging_file.upload(), document_type)): document = Document(file=staging_file.upload(), document_type=document_type) document.save() - _handle_save_document(request, document, staging_form) + _handle_save_document(request, document, form) messages.success(request, _(u'Staging file: %s, uploaded successfully.') % staging_file.filename) if DELETE_STAGING_FILE_AFTER_UPLOAD: @@ -211,98 +190,60 @@ def upload_document_with_type(request, multiple=True): except Exception, e: messages.error(request, e) - if multiple: - return HttpResponseRedirect(request.META['HTTP_REFERER']) - else: - return HttpResponseRedirect(reverse('document_list')) + return HttpResponseRedirect(request.META['HTTP_REFERER']) + else: + if source == UPLOAD_SOURCE_LOCAL: + form = DocumentForm(initial={'document_type': document_type}) + elif (USE_STAGING_DIRECTORY and source == UPLOAD_SOURCE_STAGING) or (PER_USER_STAGING_DIRECTORY and source == UPLOAD_SOURCE_USER_STAGING): + StagingFile = create_staging_file_class(request, source) + form = StagingDocumentForm(cls=StagingFile, + initial={'document_type': document_type}) + subtemplates_list = [] - local_upload_form = { - 'name': 'generic_form_subtemplate.html', - 'context': { - 'form': local_form, - 'title': _(u'upload a local document'), - }, - } - if USE_STAGING_DIRECTORY or PER_USER_STAGING_DIRECTORY: - local_upload_form.update({'grid': 12}) - subtemplates_list.append(local_upload_form) + if source == UPLOAD_SOURCE_LOCAL: + subtemplates_list.append({ + 'name': 'generic_form_subtemplate.html', + 'context': { + 'form': form, + 'title': _(u'upload a local document'), + }, + }) - if PER_USER_STAGING_DIRECTORY: - try: - user_filelist = UserStagingFile.get_all() - except Exception, e: - messages.error(request, e) - filelist = [] - finally: - subtemplates_list.append( - { - 'name': 'generic_form_subtemplate.html', - 'grid': 6, - #'grid_clear': False, - 'context': { - 'form': user_staging_form, - 'title': _(u'upload a document from user staging'), - } - }, - ) - - if USE_STAGING_DIRECTORY: - try: - staging_filelist = StagingFile.get_all() - except Exception, e: - messages.error(request, e) - filelist = [] - finally: - subtemplates_list.append( - { - 'name': 'generic_form_subtemplate.html', - 'grid': 6, - #'grid_clear': False, - 'context': { - 'form': staging_form, - 'title': _(u'upload a document from staging'), - } - }, - ) - - if PER_USER_STAGING_DIRECTORY: - subtemplates_list.append( + elif (USE_STAGING_DIRECTORY and source == UPLOAD_SOURCE_STAGING) or (PER_USER_STAGING_DIRECTORY and source == UPLOAD_SOURCE_USER_STAGING): + if source == UPLOAD_SOURCE_STAGING: + form_title = _(u'upload a document from staging') + list_title = _(u'files in staging') + else: + form_title = _(u'upload a document from user staging') + list_title = _(u'files in user staging') + try: + staging_filelist = StagingFile.get_all() + except Exception, e: + messages.error(request, e) + staging_filelist = [] + finally: + subtemplates_list = [ { - 'name': 'generic_list_subtemplate.html', - 'grid': 6, - + 'name': 'generic_form_subtemplate.html', 'context': { - 'title': _(u'files in user staging'), - 'object_list': user_filelist, - 'hide_link': True, + 'form': form, + 'title': form_title, } }, - ) - - - if USE_STAGING_DIRECTORY: - subtemplates_list.append( { 'name': 'generic_list_subtemplate.html', - 'grid': 6, - 'grid_clear': True, - 'context': { - 'title': _(u'files in staging'), + 'title': list_title, 'object_list': staging_filelist, 'hide_link': True, } }, - ) - - - else: - subtemplates_list.append(local_upload_form) - + ] context = { + 'source': source, 'document_type_id': document_type_id, 'subtemplates_list': subtemplates_list, 'sidebar_subtemplates_list': [ @@ -310,7 +251,6 @@ def upload_document_with_type(request, multiple=True): 'name': 'generic_subtemplate.html', 'context': { 'title': _(u'Current metadata'), - #'content': metadata_repr(decode_metadata_from_url(request.GET)), 'paragraphs': metadata_repr_as_list(decode_metadata_from_url(request.GET)) } }] @@ -322,7 +262,10 @@ def upload_document_with_type(request, multiple=True): 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) + #document = get_object_or_404(Document.objects.select_related(), pk=document_id) + # Triggers a 404 error on documents uploaded via local upload + # TODO: investigate + document = get_object_or_404(Document, pk=document_id) RecentDocument.objects.add_document_for_user(request.user, document) @@ -387,7 +330,10 @@ def document_view_simple(request, document_id): def document_view_advanced(request, document_id): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_VIEW]) - document = get_object_or_404(Document.objects.select_related(), pk=document_id) + #document = get_object_or_404(Document.objects.select_related(), pk=document_id) + # Triggers a 404 error on documents uploaded via local upload + # TODO: investigate + document = get_object_or_404(Document, pk=document_id) RecentDocument.objects.add_document_for_user(request.user, document) @@ -653,10 +599,9 @@ def document_download(request, document_id): return HttpResponseRedirect(request.META['HTTP_REFERER']) -def staging_file_preview(request, staging_file_id): +def staging_file_preview(request, source, staging_file_id): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_CREATE]) - StagingFile = create_staging_file_class() - + StagingFile = create_staging_file_class(request, source) try: output_file, errors = StagingFile.get(staging_file_id).preview() if errors and (request.user.is_staff or request.user.is_superuser): @@ -680,9 +625,9 @@ def staging_file_preview(request, staging_file_id): return sendfile.sendfile(request, output_file) -def staging_file_delete(request, staging_file_id): +def staging_file_delete(request, source, staging_file_id): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_CREATE]) - StagingFile = create_staging_file_class() + StagingFile = create_staging_file_class(request, source) staging_file = StagingFile.get(staging_file_id) next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', None))) @@ -697,6 +642,7 @@ def staging_file_delete(request, staging_file_id): return HttpResponseRedirect(next) return render_to_response('generic_confirm.html', { + 'source': source, 'delete_view': True, 'object': staging_file, 'next': next, diff --git a/apps/documents/wizards.py b/apps/documents/wizards.py new file mode 100644 index 0000000000..cb7e2524fd --- /dev/null +++ b/apps/documents/wizards.py @@ -0,0 +1,85 @@ +from django.utils.translation import ugettext_lazy as _ +from django.core.urlresolvers import reverse +from django.http import HttpResponseRedirect + +from common.wizard import BoundFormWizard +from common.utils import urlquote + +from documents.forms import DocumentTypeSelectForm, \ + MetadataSelectionForm, MetadataFormSet + + +class DocumentCreateWizard(BoundFormWizard): + def generate_metadata_initial_values(self): + initial = [] + for metadata_type in self.metadata_types: + initial.append({ + 'metadata_type': metadata_type, + }) + + for metadata_set in self.metadata_sets: + for metadata_set_item in metadata_set.metadatasetitem_set.all(): + data = { + 'metadata_type': metadata_set_item.metadata_type, + } + if data not in initial: + initial.append(data) + + return initial + + def __init__(self, *args, **kwargs): + self.query_dict = {} + self.multiple = kwargs.pop('multiple', True) + self.step_titles = kwargs.pop('step_titles', [ + _(u'step 1 of 3: Document type'), + _(u'step 2 of 3: Metadata selection'), + _(u'step 3 of 3: Document metadata'), + ]) + self.document_type = kwargs.pop('document_type', None) + + super(DocumentCreateWizard, self).__init__(*args, **kwargs) + + if self.document_type: + self.initial = {0: self.generate_metadata_initial_values()} + + def render_template(self, request, form, previous_fields, step, context=None): + context = {'step_title': self.extra_context['step_titles'][step]} + return super(DocumentCreateWizard, self).render_template( + request, form, previous_fields, step, context + ) + + def parse_params(self, request, *args, **kwargs): + self.extra_context = {'step_titles': self.step_titles} + + def process_step(self, request, form, step): + if isinstance(form, DocumentTypeSelectForm): + self.document_type = form.cleaned_data['document_type'] + + if isinstance(form, MetadataSelectionForm): + self.metadata_sets = form.cleaned_data['metadata_sets'] + self.metadata_types = form.cleaned_data['metadata_types'] + initial_data = self.generate_metadata_initial_values() + self.initial = {2: initial_data} + if not initial_data: + # If there is no metadata selected end wizard + self.form_list = [DocumentTypeSelectForm, MetadataSelectionForm] + + if isinstance(form, MetadataFormSet): + for identifier, metadata in enumerate(form.cleaned_data): + self.query_dict['metadata%s_id' % identifier] = metadata['id'] + self.query_dict['metadata%s_value' % identifier] = metadata['value'] + + def get_template(self, step): + return 'generic_wizard.html' + + def done(self, request, form_list): + if self.multiple: + view = 'upload_document_from_local' + else: + view = 'upload_document' + + if self.document_type: + self.query_dict['document_type_id'] = self.document_type.pk + + url = urlquote(reverse(view), self.query_dict) + return HttpResponseRedirect(url)