Got upload view working, staging preview and delete working ok

This commit is contained in:
Roberto Rosario
2011-07-06 01:31:27 -04:00
parent 7417fca835
commit 2816c1f86f
16 changed files with 520 additions and 85 deletions

View File

@@ -13,9 +13,6 @@ from metadata.api import get_metadata_string
from documents.models import Document, DocumentPage, \
DocumentPageTransformation, DocumentType, DocumentTypeFilename
from documents.staging import StagingFile
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, \
@@ -107,13 +104,6 @@ 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': [PERMISSION_DOCUMENT_VIEW]}
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'}
# Document type related links
document_type_list = {'text': _(u'document type list'), 'view': 'document_type_list', 'famfam': 'layout', 'permissions': [PERMISSION_DOCUMENT_VIEW]}
document_type_document_list = {'text': _(u'documents of this type'), 'view': 'document_type_document_list', 'args': 'object.id', 'famfam': 'page_go', 'permissions': [PERMISSION_DOCUMENT_VIEW]}
@@ -141,7 +131,7 @@ register_links(['document_type_filename_edit', 'document_type_filename_delete'],
register_links(Document, [document_edit, document_print, document_delete, document_download, document_find_duplicates, document_clear_transformations, document_create_siblings])
register_multi_item_links(['folder_view', 'index_instance_list', 'document_type_document_list', 'search', 'results', 'document_group_view', 'document_list', 'document_list_recent'], [document_multiple_clear_transformations, document_multiple_delete])
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_find_duplicates'], [document_list_recent, document_list, document_create_multiple], menu_name='secondary_menu')
register_links(['document_list_recent', 'document_list', 'document_create', 'document_create_multiple', 'upload_interactive', 'document_find_duplicates'], [document_list_recent, document_list, document_create_multiple], menu_name='secondary_menu')
# Document page links
register_links(DocumentPage, [
@@ -157,17 +147,12 @@ 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')
register_links('document_page_transformation_create', [document_page_transformation_create], menu_name='sidebar')
register_links(['document_page_transformation_edit', 'document_page_transformation_delete'], [document_page_transformation_page_transformation_list], menu_name='sidebar')
register_links(StagingFile, [staging_file_preview, staging_file_delete])
register_diagnostic('documents', _(u'Documents'), document_missing_list)
register_tool(document_find_all_duplicates, namespace='documents', title=_(u'documents'))

View File

@@ -27,13 +27,13 @@ register_settings(
module=u'documents.conf.settings',
settings=[
# Upload
{'name': u'USE_STAGING_DIRECTORY', 'global_name': u'DOCUMENTS_USE_STAGING_DIRECTORY', 'default': False},
{'name': u'STAGING_DIRECTORY', 'global_name': u'DOCUMENTS_STAGING_DIRECTORY', 'default': u'/tmp/mayan/staging', 'exists': True},
{'name': u'PER_USER_STAGING_DIRECTORY', 'global_name': u'DOCUMENTS_PER_USER_STAGING_DIRECTORY', 'default': False},
{'name': u'USER_STAGING_DIRECTORY_ROOT', 'global_name': u'DOCUMENTS_USER_STAGING_DIRECTORY_ROOT', 'default': u'/tmp/mayan/staging/users', 'exists': True},
{'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'USE_STAGING_DIRECTORY', 'global_name': u'DOCUMENTS_USE_STAGING_DIRECTORY', 'default': False},
#{'name': u'STAGING_DIRECTORY', 'global_name': u'DOCUMENTS_STAGING_DIRECTORY', 'default': u'/tmp/mayan/staging', 'exists': True},
#{'name': u'PER_USER_STAGING_DIRECTORY', 'global_name': u'DOCUMENTS_PER_USER_STAGING_DIRECTORY', 'default': False},
#{'name': u'USER_STAGING_DIRECTORY_ROOT', 'global_name': u'DOCUMENTS_USER_STAGING_DIRECTORY_ROOT', 'default': u'/tmp/mayan/staging/users', 'exists': True},
#{'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'},
# Saving
{'name': u'CHECKSUM_FUNCTION', 'global_name': u'DOCUMENTS_CHECKSUM_FUNCTION', 'default': default_checksum},
{'name': u'UUID_FUNCTION', 'global_name': u'DOCUMENTS_UUID_FUNCTION', 'default': default_uuid},

View File

@@ -265,7 +265,7 @@ class PrintForm(forms.Form):
page_orientation = forms.ChoiceField(choices=PAGE_ORIENTATION_CHOICES, initial=DEFAULT_PAGE_ORIENTATION, label=_(u'Page orientation'), required=True)
page_range = forms.CharField(label=_(u'Page range'), required=False)
'''
class StagingDocumentForm(DocumentForm):
"""
Form that show all the files in the staging folder specified by the
@@ -290,7 +290,7 @@ class StagingDocumentForm(DocumentForm):
class Meta(DocumentForm.Meta):
exclude = ('description', 'file', 'document_type', 'tags')
'''
class DocumentTypeForm(forms.ModelForm):
"""

View File

@@ -18,10 +18,6 @@ PERMISSION_DOCUMENT_TYPE_EDIT = {'namespace': 'documents', 'name': 'document_typ
PERMISSION_DOCUMENT_TYPE_DELETE = {'namespace': 'documents', 'name': 'document_type_delete', 'label': _(u'Delete document types')}
PERMISSION_DOCUMENT_TYPE_CREATE = {'namespace': 'documents', 'name': 'document_type_create', 'label': _(u'Create document types')}
UPLOAD_SOURCE_LOCAL = u'local'
UPLOAD_SOURCE_STAGING = u'staging'
UPLOAD_SOURCE_USER_STAGING = u'user_staging'
HISTORY_DOCUMENT_CREATED = {
'namespace': 'documents', 'name': 'document_created',
'label': _(u'Document creation'),

View File

@@ -1,151 +0,0 @@
import errno
import os
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 documents.conf.settings import USER_STAGING_DIRECTORY_ROOT
from documents.conf.settings import USER_STAGING_DIRECTORY_EXPRESSION
from documents.literals import 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 _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):
"""
Simple class to encapsulate the files in a directory and hide the
specifics to the view
"""
path = STAGING_DIRECTORY
@classmethod
def set_path(cls, path):
cls.path = path
@classmethod
def get_all(cls):
"""
Return a list of StagingFile instances corresponding to the
current path
"""
staging_files = []
for filename in get_all_files(cls.path):
staging_files.append(StagingFile(
filepath=os.path.join(cls.path, filename)))
return staging_files
@classmethod
def get(cls, id):
"""
Return a single StagingFile instance corresponding to the id
given as argument
"""
files_dict = dict([(file.id, file) for file in cls.get_all()])
if id in files_dict:
return files_dict[id]
else:
raise ObjectDoesNotExist
def __init__(self, filepath):
self.filepath = filepath
self.filename = os.path.basename(filepath)
self._id = HASH_FUNCTION(open(filepath).read())
def __unicode__(self):
return self.filename
def __repr__(self):
return self.__unicode__()
def __getattr__(self, name):
if name == 'id':
return self._id
else:
raise AttributeError
def upload(self):
"""
Return a StagingFile encapsulated in a File class instance to
allow for easier upload a staging files
"""
try:
return File(file(self.filepath, 'rb'), name=self.filename)
except Exception, exc:
raise Exception(ugettext(u'Unable to upload staging file: %s') % exc)
def delete(self):
tranformation_string, errors = get_transformation_string(DEFAULT_TRANSFORMATIONS)
cache_cleanup(self.filepath, size=STAGING_FILES_PREVIEW_SIZE, extra_options=tranformation_string)
try:
os.unlink(self.filepath)
except OSError, exc:
if exc.errno == errno.ENOENT:
pass
else:
raise OSError(ugettext(u'Unable to delete staging file: %s') % exc)
def preview(self):
tranformation_string, errors = get_transformation_string(DEFAULT_TRANSFORMATIONS)
output_file = convert(self.filepath, size=STAGING_FILES_PREVIEW_SIZE, extra_options=tranformation_string, cleanup_files=False)
return output_file, errors
def get_transformation_string(transformations):
transformation_list = []
errors = []
for transformation in transformations:
try:
if transformation['name'] in TRANFORMATION_CHOICES:
output = TRANFORMATION_CHOICES[transformation['name']] % eval(transformation['arguments'])
transformation_list.append(output)
except Exception, e:
errors.append(e)
tranformation_string = ' '.join(transformation_list)
return tranformation_string, errors

View File

@@ -7,18 +7,14 @@ 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.literals import UPLOAD_SOURCE_LOCAL, \
UPLOAD_SOURCE_STAGING, UPLOAD_SOURCE_USER_STAGING
#from documents.literals import UPLOAD_SOURCE_LOCAL, \
# UPLOAD_SOURCE_STAGING, UPLOAD_SOURCE_USER_STAGING
urlpatterns = patterns('documents.views',
url(r'^list/$', 'document_list', (), 'document_list'),
url(r'^list/recent/$', 'document_list_recent', (), 'document_list_recent'),
url(r'^create/from/local/multiple/$', 'document_create', (), 'document_create_multiple'),
url(r'^upload/local/$', 'upload_document_with_type', {'source': UPLOAD_SOURCE_LOCAL}, 'upload_document_from_local'),
url(r'^upload/staging/$', 'upload_document_with_type', {'source': UPLOAD_SOURCE_STAGING}, 'upload_document_from_staging'),
url(r'^upload/staging/user/$', 'upload_document_with_type', {'source': UPLOAD_SOURCE_USER_STAGING}, 'upload_document_from_user_staging'),
url(r'^(?P<document_id>\d+)/view/$', 'document_view', (), 'document_view_simple'),
url(r'^(?P<document_id>\d+)/view/advanced/$', 'document_view', {'advanced': True}, 'document_view_advanced'),
url(r'^(?P<document_id>\d+)/delete/$', 'document_delete', (), 'document_delete'),
@@ -41,9 +37,6 @@ urlpatterns = patterns('documents.views',
url(r'^multiple/clear_transformations/$', 'document_multiple_clear_transformations', (), 'document_multiple_clear_transformations'),
url(r'^duplicates/list/$', 'document_find_all_duplicates', (), 'document_find_all_duplicates'),
url(r'^staging_file/type/(?P<source>\w+)/(?P<staging_file_id>\w+)/preview/$', 'staging_file_preview', (), 'staging_file_preview'),
url(r'^staging_file/type/(?P<source>\w+)/(?P<staging_file_id>\w+)/delete/$', 'staging_file_delete', (), 'staging_file_delete'),
url(r'^page/(?P<document_page_id>\d+)/$', 'document_page_view', (), 'document_page_view'),
url(r'^page/(?P<document_page_id>\d+)/text/$', 'document_page_text', (), 'document_page_text'),
url(r'^page/(?P<document_page_id>\d+)/edit/$', 'document_page_edit', (), 'document_page_edit'),

View File

@@ -36,10 +36,6 @@ from permissions.api import check_permissions
from document_indexing.api import update_indexes, delete_indexes
from history.api import create_history
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 PREVIEW_SIZE
from documents.conf.settings import THUMBNAIL_SIZE
from documents.conf.settings import STORAGE_BACKEND
@@ -61,7 +57,7 @@ from documents.literals import HISTORY_DOCUMENT_CREATED, \
from documents.forms import DocumentTypeSelectForm, \
DocumentForm, DocumentForm_edit, DocumentPropertiesForm, \
StagingDocumentForm, DocumentPreviewForm, \
DocumentPreviewForm, \
DocumentPageForm, DocumentPageTransformationForm, \
DocumentContentForm, DocumentPageForm_edit, \
DocumentPageForm_text, PrintForm, DocumentTypeForm, \
@@ -69,11 +65,8 @@ from documents.forms import DocumentTypeSelectForm, \
from documents.wizards import DocumentCreateWizard
from documents.models import Document, DocumentType, DocumentPage, \
DocumentPageTransformation, RecentDocument, DocumentTypeFilename
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
# Document type permissions
from documents.literals import PERMISSION_DOCUMENT_TYPE_EDIT, \
@@ -116,10 +109,10 @@ def document_create_siblings(request, document_id):
if document.document_type_id:
query_dict['document_type_id'] = document.document_type_id
url = reverse('upload_document_from_local')
url = reverse('upload_interactive')
return HttpResponseRedirect('%s?%s' % (url, urlencode(query_dict)))
'''
def _handle_save_document(request, document, form=None):
RecentDocument.objects.add_document_for_user(request.user, document)
@@ -279,7 +272,7 @@ def upload_document_with_type(request, source):
}
return render_to_response('generic_form.html', context,
context_instance=RequestContext(request))
'''
def document_view(request, document_id, advanced=False):
check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW])
@@ -545,7 +538,7 @@ def document_download(request, document_id):
messages.error(request, e)
return HttpResponseRedirect(request.META['HTTP_REFERER'])
'''
def staging_file_preview(request, source, staging_file_id):
check_permissions(request.user, [PERMISSION_DOCUMENT_CREATE])
StagingFile = create_staging_file_class(request, source)
@@ -596,7 +589,7 @@ def staging_file_delete(request, source, staging_file_id):
'previous': previous,
'form_icon': u'drive_delete.png',
}, context_instance=RequestContext(request))
'''
def document_page_transformation_list(request, document_page_id):
check_permissions(request.user, [PERMISSION_DOCUMENT_TRANSFORM])

View File

@@ -30,7 +30,6 @@ class DocumentCreateWizard(BoundFormWizard):
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'),
@@ -75,13 +74,8 @@ class DocumentCreateWizard(BoundFormWizard):
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)
url = urlquote(reverse('upload_interactive'), self.query_dict)
return HttpResponseRedirect(url)