diff --git a/apps/sources/__init__.py b/apps/sources/__init__.py index ad34940468..3257c12c1e 100644 --- a/apps/sources/__init__.py +++ b/apps/sources/__init__.py @@ -5,6 +5,8 @@ from navigation.api import register_links, \ from permissions.api import register_permission, set_namespace_title from common.utils import encapsulate from project_setup.api import register_setup +from documents.models import Document +from documents import PERMISSION_DOCUMENT_CREATE from sources.staging import StagingFile from sources.models import WebForm, StagingFolder, SourceTransformation, \ @@ -41,6 +43,8 @@ setup_source_transformation_delete = {'text': _(u'delete'), 'view': 'setup_sourc source_list = {'text': _(u'Document sources'), 'view': 'setup_web_form_list', 'famfam': 'page_add', 'children_url_regex': [r'sources/setup']} +upload_interactive_version = {'text': _(u'upload new version'), 'view': 'upload_interactive_version', 'args': 'object.pk', 'famfam': 'page_add', 'permissions': [PERMISSION_DOCUMENT_CREATE]} + register_links(StagingFile, [staging_file_delete]) register_links(SourceTransformation, [setup_source_transformation_edit, setup_source_transformation_delete]) @@ -61,6 +65,9 @@ register_links(StagingFolder, [setup_source_transformation_list, setup_source_ed register_links(WatchFolder, [setup_web_form_list, setup_staging_folder_list, setup_watch_folder_list], menu_name='form_header') register_links(WatchFolder, [setup_source_transformation_list, setup_source_edit, setup_source_delete]) +# Document version +register_links(Document, [upload_interactive_version]) + register_links(['setup_source_transformation_create', 'setup_source_transformation_edit', 'setup_source_transformation_delete', 'setup_source_transformation_list'], [setup_source_transformation_create], menu_name='sidebar') source_views = ['setup_web_form_list', 'setup_staging_folder_list', 'setup_watch_folder_list', 'setup_source_edit', 'setup_source_delete', 'setup_source_create', 'setup_source_transformation_list', 'setup_source_transformation_edit', 'setup_source_transformation_delete', 'setup_source_transformation_create'] diff --git a/apps/sources/forms.py b/apps/sources/forms.py index de9b7ee1ce..4b046994cf 100644 --- a/apps/sources/forms.py +++ b/apps/sources/forms.py @@ -37,7 +37,7 @@ class StagingDocumentForm(DocumentForm): staging_list_index = self.fields.keyOrder.index('staging_file_id') staging_list = self.fields.keyOrder.pop(staging_list_index) self.fields.keyOrder.insert(0, staging_list) - + staging_file_id = forms.ChoiceField(label=_(u'Staging file')) class Meta(DocumentForm.Meta): @@ -45,6 +45,8 @@ class StagingDocumentForm(DocumentForm): class WebFormForm(DocumentForm): + file = forms.FileField(label=_(u'File')) + def __init__(self, *args, **kwargs): show_expand = kwargs.pop('show_expand', False) self.source = kwargs.pop('source') @@ -56,6 +58,10 @@ class WebFormForm(DocumentForm): help_text=ugettext(u'Upload a compressed file\'s contained files as individual documents') ) + # Move the file filed to the top + self.fields.keyOrder.remove('file') + self.fields.keyOrder.insert(0, 'file') + def clean_file(self): data = self.cleaned_data['file'] validate_whitelist_blacklist(data.name, self.source.whitelist.split(','), self.source.blacklist.split(',')) diff --git a/apps/sources/models.py b/apps/sources/models.py index c97f2f4ca4..44822ee0ba 100644 --- a/apps/sources/models.py +++ b/apps/sources/models.py @@ -52,7 +52,7 @@ class BaseModel(models.Model): def get_transformation_list(self): return SourceTransformation.transformations.get_for_object_as_list(self) - def upload_file(self, file_object, filename=None, document_type=None, expand=False, metadata_dict_list=None, user=None): + def upload_file(self, file_object, filename=None, document_type=None, expand=False, metadata_dict_list=None, user=None, document=None, new_version_data=None): if expand: try: cf = CompressedFile(file_object) @@ -63,31 +63,39 @@ class BaseModel(models.Model): except NotACompressedFile: self.upload_single_file(file_object, filename, document_type, metadata_dict_list, user) else: - self.upload_single_file(file_object, filename, document_type, metadata_dict_list, user) + self.upload_single_file(file_object, filename, document_type, metadata_dict_list, user, document, new_version_data) file_object.close() - def upload_single_file(self, file_object, filename=None, document_type=None, metadata_dict_list=None, user=None): - transformations, errors = self.get_transformation_list() - document = Document(file=file_object) - if document_type: - document.document_type = document_type - document.save() + def upload_single_file(self, file_object, filename=None, document_type=None, metadata_dict_list=None, user=None, document=None, new_version_data=None): + if not document: + document = Document() + if document_type: + document.document_type = document_type + document.save() + + if metadata_dict_list: + save_metadata_list(metadata_dict_list, document, create=True) + warnings = update_indexes(document) + + if user: + document.add_as_recent_document_for_user(user) + create_history(HISTORY_DOCUMENT_CREATED, document, {'user': user}) + else: + create_history(HISTORY_DOCUMENT_CREATED, document) + + if not new_version_data: + new_version_data = {} + + new_version = document.new_version(file=file_object, **new_version_data) if filename: - document.file_filename = filename - document.save() + new_version.filename = filename + new_version.save() - document.apply_default_transformations(transformations) + transformations, errors = self.get_transformation_list() - if metadata_dict_list: - save_metadata_list(metadata_dict_list, document, create=True) - warnings = update_indexes(document) - - if user: - document.add_as_recent_document_for_user(user) - create_history(HISTORY_DOCUMENT_CREATED, document, {'user': user}) - else: - create_history(HISTORY_DOCUMENT_CREATED, document) + new_version.apply_default_transformations(transformations) + #TODO: new HISTORY for version updates class Meta: ordering = ('title',) diff --git a/apps/sources/urls.py b/apps/sources/urls.py index b75573382d..cd42328138 100644 --- a/apps/sources/urls.py +++ b/apps/sources/urls.py @@ -8,8 +8,11 @@ urlpatterns = patterns('sources.views', url(r'^staging_file/type/(?P\w+)/(?P\d+)/(?P\w+)/delete/$', 'staging_file_delete', (), 'staging_file_delete'), url(r'^staging_file/type/staging_folder/(?P\d+)/(?P\w+)/thumbnail/$', 'staging_file_thumbnail', (), 'staging_file_thumbnail'), - url(r'^upload/interactive/(?P\w+)/(?P\d+)/$', 'upload_interactive', (), 'upload_interactive'), - url(r'^upload/interactive/$', 'upload_interactive', (), 'upload_interactive'), + url(r'^upload/document/new/interactive/(?P\w+)/(?P\d+)/$', 'upload_interactive', (), 'upload_interactive'), + url(r'^upload/document/new/interactive/$', 'upload_interactive', (), 'upload_interactive'), + + url(r'^upload/document/(?P\d+)/version/interactive/(?P\w+)/(?P\d+)/$', 'upload_interactive', (), 'upload_interactive_version'), + url(r'^upload/document/(?P\d+)/version/interactive/$', 'upload_interactive', (), 'upload_interactive_version'), #Setup views diff --git a/apps/sources/views.py b/apps/sources/views.py index c2cde5e7d8..c668b23909 100644 --- a/apps/sources/views.py +++ b/apps/sources/views.py @@ -8,7 +8,7 @@ from django.utils.translation import ugettext from django.utils.safestring import mark_safe from documents.literals import PERMISSION_DOCUMENT_CREATE -from documents.models import DocumentType +from documents.models import DocumentType, Document from documents.conf.settings import THUMBNAIL_SIZE from metadata.api import decode_metadata_from_url, metadata_repr_as_list from permissions.api import check_permissions @@ -35,30 +35,34 @@ def return_function(obj): return lambda context: context['source'].source_type == obj.source_type and context['source'].pk == obj.pk -def get_active_tab_links(): - tab_links = [] +def get_tab_link_for_source(source, document=None): + if document: + view = u'upload_interactive_version' + args = [document.pk, u'"%s"' % source.source_type, source.pk] + else: + view = u'upload_interactive' + args = [u'"%s"' % source.source_type, source.pk] + + return { + 'text': source.title, + 'view': view, + 'args': args, + 'famfam': source.icon, + 'keep_query': True, + 'conditional_highlight': return_function(source), + } + +def get_active_tab_links(document=None): + tab_links = [] + web_forms = WebForm.objects.filter(enabled=True) for web_form in web_forms: - tab_links.append({ - 'text': web_form.title, - 'view': 'upload_interactive', - 'args': [u'"%s"' % web_form.source_type, web_form.pk], - 'famfam': web_form.icon, - 'keep_query': True, - 'conditional_highlight': return_function(web_form), - }) + tab_links.append(get_tab_link_for_source(web_form, document)) staging_folders = StagingFolder.objects.filter(enabled=True) for staging_folder in staging_folders: - tab_links.append({ - 'text': staging_folder.title, - 'view': 'upload_interactive', - 'args': [u'"%s"' % staging_folder.source_type, staging_folder.pk], - 'famfam': staging_folder.icon, - 'keep_query': True, - 'conditional_highlight': return_function(staging_folder), - }) + tab_links.append(get_tab_link_for_source(staging_folder, document)) return { 'tab_links': tab_links, @@ -66,15 +70,19 @@ def get_active_tab_links(): SOURCE_CHOICE_STAGING: staging_folders } - -def upload_interactive(request, source_type=None, source_id=None): +def upload_interactive(request, source_type=None, source_id=None, document_pk=None): check_permissions(request.user, [PERMISSION_DOCUMENT_CREATE]) subtemplates_list = [] - context = {} + if document_pk: + document = get_object_or_404(Document, pk=document_pk) + results = get_active_tab_links(document) + else: + document = None + results = get_active_tab_links() - results = get_active_tab_links() + context = {} if results[SOURCE_CHOICE_WEB_FORM].count() == 0 and results[SOURCE_CHOICE_STAGING].count() == 0: source_setup_link = mark_safe('%s' % (reverse('setup_web_form_list'), ugettext(u'here'))) @@ -113,43 +121,57 @@ def upload_interactive(request, source_type=None, source_id=None): if request.method == 'POST': form = WebFormForm(request.POST, request.FILES, document_type=document_type, - show_expand=(web_form.uncompress == SOURCE_UNCOMPRESS_CHOICE_ASK), - source=web_form + show_expand=(web_form.uncompress == SOURCE_UNCOMPRESS_CHOICE_ASK) and not document, + source=web_form, + instance=document ) if form.is_valid(): - try: + #try: + if document: + expand = False + else: if web_form.uncompress == SOURCE_UNCOMPRESS_CHOICE_ASK: - expand = form.cleaned_data['expand'] + expand = form.cleaned_data.get('expand') else: if web_form.uncompress == SOURCE_UNCOMPRESS_CHOICE_Y: expand = True else: expand = False - - new_filename = get_form_filename(form) - web_form.upload_file(request.FILES['file'], - new_filename, document_type=document_type, - expand=expand, - metadata_dict_list=decode_metadata_from_url(request.GET), - user=request.user - ) + + new_filename = get_form_filename(form) + web_form.upload_file(request.FILES['file'], + new_filename, document_type=document_type, + expand=expand, + metadata_dict_list=decode_metadata_from_url(request.GET), + user=request.user, + document=document, + new_version_data=form.cleaned_data.get('new_version_data') + ) + #except Exception, e: + # messages.error(request, _(u'Unhandled exception: %s') % e) + if document: + messages.success(request, _(u'Document version uploaded successfully.')) + return HttpResponseRedirect(reverse('document_view_simple', args=[document.pk])) + else: messages.success(request, _(u'Document uploaded successfully.')) - except Exception, e: - messages.error(request, e) - - return HttpResponseRedirect(request.get_full_path()) + return HttpResponseRedirect(request.get_full_path()) else: form = WebFormForm( - show_expand=(web_form.uncompress == SOURCE_UNCOMPRESS_CHOICE_ASK), + show_expand=(web_form.uncompress == SOURCE_UNCOMPRESS_CHOICE_ASK) and not document, document_type=document_type, - source=web_form + source=web_form, + instance=document ) - + if document: + title = _(u'upload a new version from source: %s') % web_form.title + else: + title = _(u'upload a local document from source: %s') % web_form.title + subtemplates_list.append({ 'name': 'generic_form_subtemplate.html', 'context': { 'form': form, - 'title': _(u'upload a local document from source: %s') % web_form.title, + 'title': title, }, }) elif source_type == SOURCE_CHOICE_STAGING: @@ -159,41 +181,54 @@ def upload_interactive(request, source_type=None, source_id=None): if request.method == 'POST': form = StagingDocumentForm(request.POST, request.FILES, cls=StagingFile, document_type=document_type, - show_expand=(staging_folder.uncompress == SOURCE_UNCOMPRESS_CHOICE_ASK), - source=staging_folder + show_expand=(staging_folder.uncompress == SOURCE_UNCOMPRESS_CHOICE_ASK) and not document, + source=staging_folder, + instance=document ) if form.is_valid(): - try: - staging_file = StagingFile.get(form.cleaned_data['staging_file_id']) + #try: + staging_file = StagingFile.get(form.cleaned_data['staging_file_id']) + if document: + expand = False + else: if staging_folder.uncompress == SOURCE_UNCOMPRESS_CHOICE_ASK: - expand = form.cleaned_data['expand'] + expand = form.cleaned_dataget('expand') else: if staging_folder.uncompress == SOURCE_UNCOMPRESS_CHOICE_Y: expand = True else: expand = False - new_filename = get_form_filename(form) - staging_folder.upload_file(staging_file.upload(), - new_filename, document_type=document_type, - expand=expand, - metadata_dict_list=decode_metadata_from_url(request.GET), - user=request.user - ) + + new_filename = get_form_filename(form) + staging_folder.upload_file(staging_file.upload(), + new_filename, document_type=document_type, + expand=expand, + metadata_dict_list=decode_metadata_from_url(request.GET), + user=request.user, + document=document, + new_version_data=form.cleaned_data.get('new_version_data') + ) + if document: + messages.success(request, _(u'Document version from staging file: %s, uploaded successfully.') % staging_file.filename) + else: messages.success(request, _(u'Staging file: %s, uploaded successfully.') % staging_file.filename) - if staging_folder.delete_after_upload: - transformations, errors = staging_folder.get_transformation_list() - staging_file.delete(preview_size=staging_folder.get_preview_size(), transformations=transformations) - messages.success(request, _(u'Staging file: %s, deleted successfully.') % staging_file.filename) - except Exception, e: - messages.error(request, e) - - return HttpResponseRedirect(request.get_full_path()) + if staging_folder.delete_after_upload: + transformations, errors = staging_folder.get_transformation_list() + staging_file.delete(preview_size=staging_folder.get_preview_size(), transformations=transformations) + messages.success(request, _(u'Staging file: %s, deleted successfully.') % staging_file.filename) + #except Exception, e: + # messages.error(request, _(u'Unhandled exception: %s') % e) + if document: + return HttpResponseRedirect(reverse('document_view_simple', args=[document.pk])) + else: + return HttpResponseRedirect(request.get_full_path()) else: form = StagingDocumentForm(cls=StagingFile, document_type=document_type, - show_expand=(staging_folder.uncompress == SOURCE_UNCOMPRESS_CHOICE_ASK), - source=staging_folder + show_expand=(staging_folder.uncompress == SOURCE_UNCOMPRESS_CHOICE_ASK) and not document, + source=staging_folder, + instance=document ) try: staging_filelist = StagingFile.get_all() @@ -201,12 +236,17 @@ def upload_interactive(request, source_type=None, source_id=None): messages.error(request, e) staging_filelist = [] finally: + if document: + title = _(u'upload a new version from staging source: %s') % staging_folder.title + else: + title = _(u'upload a document from staging source: %s') % staging_folder.title + subtemplates_list = [ { 'name': 'generic_form_subtemplate.html', 'context': { 'form': form, - 'title': _(u'upload a document from staging source: %s') % staging_folder.title, + 'title': title, } }, { @@ -219,20 +259,40 @@ def upload_interactive(request, source_type=None, source_id=None): }, ] + if document: + context['object'] = document + context.update({ 'document_type_id': document_type_id, 'subtemplates_list': subtemplates_list, - 'sidebar_subtemplates_list': [ - { - 'name': 'generic_subtemplate.html', - 'context': { - 'title': _(u'Current metadata'), - 'paragraphs': metadata_repr_as_list(decode_metadata_from_url(request.GET)), - 'side_bar': True, - } - }], - 'temporary_navigation_links': {'form_header': {'upload_interactive': {'links': results['tab_links']}}}, + 'temporary_navigation_links': { + 'form_header': { + 'upload_interactive_version': { + 'links': results['tab_links'] + }, + 'upload_interactive': { + 'links': results['tab_links'] + } + } + }, }) + + if not document: + context.update( + { + 'sidebar_subtemplates_list': [ + { + 'name': 'generic_subtemplate.html', + 'context': { + 'title': _(u'Current metadata'), + 'paragraphs': metadata_repr_as_list(decode_metadata_from_url(request.GET)), + 'side_bar': True, + } + } + ], + } + ) + return render_to_response('generic_form.html', context, context_instance=RequestContext(request))