Merge branch 'smart_staging' into master_merge_test

Conflicts:
	apps/common/__init__.py
	requirements/development.txt
	requirements/production.txt
This commit is contained in:
Roberto Rosario
2011-07-21 03:55:21 -04:00
66 changed files with 2596 additions and 998 deletions

View File

@@ -2,6 +2,7 @@ from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse
from django.conf import settings
from common.utils import validate_path
from navigation.api import register_links, register_top_menu, \
register_model_list_columns, register_multi_item_links, \
register_sidebar_template
@@ -13,9 +14,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, \
@@ -27,30 +25,9 @@ from documents.literals import HISTORY_DOCUMENT_CREATED, \
HISTORY_DOCUMENT_EDITED, HISTORY_DOCUMENT_DELETED
from documents.conf.settings import ZOOM_MAX_LEVEL
from documents.conf.settings import ZOOM_MIN_LEVEL
from documents.conf.settings import CACHE_PATH
from documents.widgets import document_thumbnail
# Permission setup
set_namespace_title('documents', _(u'Documents'))
register_permission(PERMISSION_DOCUMENT_CREATE)
register_permission(PERMISSION_DOCUMENT_PROPERTIES_EDIT)
register_permission(PERMISSION_DOCUMENT_EDIT)
register_permission(PERMISSION_DOCUMENT_VIEW)
register_permission(PERMISSION_DOCUMENT_DELETE)
register_permission(PERMISSION_DOCUMENT_DOWNLOAD)
register_permission(PERMISSION_DOCUMENT_TRANSFORM)
register_permission(PERMISSION_DOCUMENT_TOOLS)
# Document type permissions
register_permission(PERMISSION_DOCUMENT_TYPE_EDIT)
register_permission(PERMISSION_DOCUMENT_TYPE_DELETE)
register_permission(PERMISSION_DOCUMENT_TYPE_CREATE)
# History setup
register_history_type(HISTORY_DOCUMENT_CREATED)
register_history_type(HISTORY_DOCUMENT_EDITED)
register_history_type(HISTORY_DOCUMENT_DELETED)
# Document page links expressions
def is_first_page(context):
return context['object'].page_number <= 1
@@ -67,6 +44,28 @@ def is_min_zoom(context):
def is_max_zoom(context):
return context['zoom'] >= ZOOM_MAX_LEVEL
# Permission setup
set_namespace_title('documents', _(u'Documents'))
register_permission(PERMISSION_DOCUMENT_CREATE)
register_permission(PERMISSION_DOCUMENT_PROPERTIES_EDIT)
register_permission(PERMISSION_DOCUMENT_EDIT)
register_permission(PERMISSION_DOCUMENT_VIEW)
register_permission(PERMISSION_DOCUMENT_DELETE)
register_permission(PERMISSION_DOCUMENT_DOWNLOAD)
register_permission(PERMISSION_DOCUMENT_TRANSFORM)
register_permission(PERMISSION_DOCUMENT_TOOLS)
# Document type permissions
set_namespace_title('documents_setup', _(u'Documents setup'))
register_permission(PERMISSION_DOCUMENT_TYPE_EDIT)
register_permission(PERMISSION_DOCUMENT_TYPE_DELETE)
register_permission(PERMISSION_DOCUMENT_TYPE_CREATE)
# History setup
register_history_type(HISTORY_DOCUMENT_CREATED)
register_history_type(HISTORY_DOCUMENT_EDITED)
register_history_type(HISTORY_DOCUMENT_DELETED)
document_list = {'text': _(u'all documents'), 'view': 'document_list', 'famfam': 'page', 'permissions': [PERMISSION_DOCUMENT_VIEW]}
document_list_recent = {'text': _(u'recent documents'), 'view': 'document_list_recent', 'famfam': 'page', 'permissions': [PERMISSION_DOCUMENT_VIEW]}
document_create_multiple = {'text': _(u'upload new documents'), 'view': 'document_create_multiple', 'famfam': 'page_add', 'permissions': [PERMISSION_DOCUMENT_CREATE]}
@@ -107,13 +106,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]}
@@ -139,9 +131,12 @@ register_links(['document_type_filename_edit', 'document_type_filename_delete'],
# Register document links
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_multi_item_links(['document_find_duplicates', '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')
secondary_menu_links = [document_list_recent, document_list, document_create_multiple]
register_links(['document_list_recent', 'document_list', 'document_create', 'document_create_multiple', 'upload_interactive', 'staging_file_delete'], secondary_menu_links, menu_name='secondary_menu')
#register_links(Document, secondary_menu_links, menu_name='sidebar')
# Document page links
register_links(DocumentPage, [
@@ -157,17 +152,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'))
@@ -209,3 +199,5 @@ register_sidebar_template(['document_type_list'], 'document_types_help.html')
register_links(Document, [document_view_simple], menu_name='form_header', position=0)
register_links(Document, [document_view_advanced], menu_name='form_header', position=1)
register_links(Document, [document_history_view], menu_name='form_header')
validate_path(CACHE_PATH)

View File

@@ -2,8 +2,10 @@
import hashlib
import uuid
import os
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from storage.backends.filebasedstorage import FileBasedStorage
from smart_settings.api import register_settings
@@ -18,30 +20,15 @@ def default_uuid():
"""unicode(uuid.uuid4())"""
return unicode(uuid.uuid4())
available_transformations = {
'rotate': {'label': _(u'Rotate [degrees]'), 'arguments': [{'name': 'degrees'}]}
}
register_settings(
namespace=u'documents',
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'},
# 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},
# Storage
{'name': u'STORAGE_BACKEND', 'global_name': u'DOCUMENTS_STORAGE_BACKEND', 'default': FileBasedStorage},
# Transformations
{'name': u'AVAILABLE_TRANSFORMATIONS', 'global_name': u'DOCUMENTS_AVAILABLE_TRANSFORMATIONS', 'default': available_transformations},
{'name': u'DEFAULT_TRANSFORMATIONS', 'global_name': u'DOCUMENTS_DEFAULT_TRANSFORMATIONS', 'default': []},
# Usage
{'name': u'PREVIEW_SIZE', 'global_name': u'DOCUMENTS_PREVIEW_SIZE', 'default': u'640x480'},
{'name': u'PRINT_SIZE', 'global_name': u'DOCUMENTS_PRINT_SIZE', 'default': u'1400'},
@@ -53,5 +40,7 @@ register_settings(
{'name': u'ZOOM_MAX_LEVEL', 'global_name': u'DOCUMENTS_ZOOM_MAX_LEVEL', 'default': 200, 'description': _(u'Maximum amount in percent (%) to allow user to zoom in a document page interactively.')},
{'name': u'ZOOM_MIN_LEVEL', 'global_name': u'DOCUMENTS_ZOOM_MIN_LEVEL', 'default': 50, 'description': _(u'Minimum amount in percent (%) to allow user to zoom out a document page interactively.')},
{'name': u'ROTATION_STEP', 'global_name': u'DOCUMENTS_ROTATION_STEP', 'default': 90, 'description': _(u'Amount in degrees to rotate a document page per user interaction.')},
#
{'name': u'CACHE_PATH', 'global_name': u'DOCUMENTS_CACHE_PATH', 'default': os.path.join(settings.PROJECT_ROOT, 'image_cache'), 'exists': True},
]
)

View File

@@ -186,21 +186,11 @@ class DocumentForm(forms.ModelForm):
queryset=filenames_qs,
required=False,
label=_(u'Quick document rename'))
# Put the expand field last in the field order list
expand_field_index = self.fields.keyOrder.index('expand')
expand_field = self.fields.keyOrder.pop(expand_field_index)
self.fields.keyOrder.append(expand_field)
new_filename = forms.CharField(
label=_('New document filename'), required=False
)
expand = forms.BooleanField(
label=_(u'Expand compressed files'), required=False,
help_text=ugettext(u'Upload a compressed file\'s contained files as individual documents')
)
class DocumentForm_edit(DocumentForm):
"""
@@ -208,12 +198,7 @@ class DocumentForm_edit(DocumentForm):
"""
class Meta:
model = Document
exclude = ('file', 'document_type', 'tags', 'expand')
def __init__(self, *args, **kwargs):
super(DocumentForm_edit, self).__init__(*args, **kwargs)
self.fields.pop('expand')
exclude = ('file', 'document_type', 'tags')
class DocumentPropertiesForm(DetailForm):
@@ -266,32 +251,6 @@ class PrintForm(forms.Form):
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
StagingFile class passed as 'cls' argument
"""
def __init__(self, *args, **kwargs):
cls = kwargs.pop('cls')
super(StagingDocumentForm, self).__init__(*args, **kwargs)
try:
self.fields['staging_file_id'].choices = [
(staging_file.id, staging_file) for staging_file in cls.get_all()
]
except:
pass
# Put staging_list field first in the field order list
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):
exclude = ('description', 'file', 'document_type', 'tags')
class DocumentTypeForm(forms.ModelForm):
"""
Model class form to create or edit a document type

View File

@@ -14,13 +14,9 @@ PERMISSION_DOCUMENT_DOWNLOAD = {'namespace': 'documents', 'name': 'document_down
PERMISSION_DOCUMENT_TRANSFORM = {'namespace': 'documents', 'name': 'document_transform', 'label': _(u'Transform documents')}
PERMISSION_DOCUMENT_TOOLS = {'namespace': 'documents', 'name': 'document_tools', 'label': _(u'Execute document modifying tools')}
PERMISSION_DOCUMENT_TYPE_EDIT = {'namespace': 'documents', 'name': 'document_type_edit', 'label': _(u'Edit document types')}
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'
PERMISSION_DOCUMENT_TYPE_EDIT = {'namespace': 'documents_setup', 'name': 'document_type_edit', 'label': _(u'Edit document types')}
PERMISSION_DOCUMENT_TYPE_DELETE = {'namespace': 'documents_setup', 'name': 'document_type_delete', 'label': _(u'Delete document types')}
PERMISSION_DOCUMENT_TYPE_CREATE = {'namespace': 'documents_setup', 'name': 'document_type_create', 'label': _(u'Create document types')}
HISTORY_DOCUMENT_CREATED = {
'namespace': 'documents', 'name': 'document_created',

View File

@@ -13,3 +13,24 @@ class RecentDocumentManager(models.Manager):
to_delete = self.model.objects.filter(user=user)[RECENT_COUNT:]
for recent_to_delete in to_delete:
recent_to_delete.delete()
class DocumentPageTransformationManager(models.Manager):
def get_for_document_page(self, document_page):
return self.model.objects.filter(document_page=document_page)
def get_for_document_page_as_list(self, document_page):
warnings = []
transformations = []
for transformation in self.get_for_document_page(document_page).values('transformation', 'arguments'):
try:
transformations.append(
{
'transformation': transformation['transformation'],
'arguments': eval(transformation['arguments'], {})
}
)
except Exception, e:
warnings.append(e)
return transformations, warnings

View File

@@ -1,26 +1,39 @@
import os
import tempfile
import hashlib
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User
from django.contrib.contenttypes import generic
from django.contrib.comments.models import Comment
from django.conf import settings
from taggit.managers import TaggableManager
from dynamic_search.api import register
from converter.api import get_page_count
from converter import TRANFORMATION_CHOICES
from converter.api import get_available_transformations_choices
from converter.api import create_image_cache_filename, convert
from converter.exceptions import UnknownFormat, UnkownConvertError
from documents.utils import get_document_mimetype
from documents.conf.settings import CHECKSUM_FUNCTION
from documents.conf.settings import UUID_FUNCTION
from documents.conf.settings import STORAGE_BACKEND
from documents.conf.settings import AVAILABLE_TRANSFORMATIONS
from documents.conf.settings import DEFAULT_TRANSFORMATIONS
from documents.managers import RecentDocumentManager
from documents.conf.settings import PREVIEW_SIZE
from documents.conf.settings import THUMBNAIL_SIZE
from documents.conf.settings import CACHE_PATH
available_transformations = ([(name, data['label']) for name, data in AVAILABLE_TRANSFORMATIONS.items()])
from documents.managers import RecentDocumentManager, \
DocumentPageTransformationManager
from documents.utils import document_save_to_temp_dir
from documents.literals import PICTURE_ERROR_SMALL, PICTURE_ERROR_MEDIUM, \
PICTURE_UNKNOWN_SMALL, PICTURE_UNKNOWN_MEDIUM
from converter.literals import DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION, \
DEFAULT_FILE_FORMAT, DEFAULT_PAGE_NUMBER
# document image cache name hash function
HASH_FUNCTION = lambda x: hashlib.sha256(x).hexdigest()
def get_filename_from_uuid(instance, filename):
@@ -92,7 +105,7 @@ class Document(models.Model):
mimetype, page count and transformation when originally created
"""
new_document = not self.pk
transformations = kwargs.pop('transformations', None)
super(Document, self).save(*args, **kwargs)
if new_document:
@@ -101,7 +114,8 @@ class Document(models.Model):
self.update_mimetype(save=False)
self.save()
self.update_page_count(save=False)
self.apply_default_transformations()
if transformations:
self.apply_default_transformations(transformations)
@models.permalink
def get_absolute_url(self):
@@ -195,21 +209,43 @@ class Document(models.Model):
exists in storage
"""
return self.file.storage.exists(self.file.path)
def apply_default_transformations(self):
def apply_default_transformations(self, transformations):
#Only apply default transformations on new documents
if DEFAULT_TRANSFORMATIONS and reduce(lambda x, y: x + y, [page.documentpagetransformation_set.count() for page in self.documentpage_set.all()]) == 0:
for transformation in DEFAULT_TRANSFORMATIONS:
if 'name' in transformation:
for document_page in self.documentpage_set.all():
page_transformation = DocumentPageTransformation(
document_page=document_page,
order=0,
transformation=transformation['name'])
if 'arguments' in transformation:
page_transformation.arguments = transformation['arguments']
if reduce(lambda x, y: x + y, [page.documentpagetransformation_set.count() for page in self.documentpage_set.all()]) == 0:
for transformation in transformations:
for document_page in self.documentpage_set.all():
page_transformation = DocumentPageTransformation(
document_page=document_page,
order=0,
transformation=transformation.get('transformation'),
arguments=transformation.get('arguments')
)
page_transformation.save()
page_transformation.save()
def get_image_cache_name(self, page):
document_page = self.documentpage_set.get(page_number=page)
transformations, warnings = document_page.get_transformation_list()
hash_value = HASH_FUNCTION(u''.join([self.checksum, unicode(page), unicode(transformations)]))
cache_file_path = os.path.join(CACHE_PATH, hash_value)
if os.path.exists(cache_file_path):
return cache_file_path
else:
document_file = document_save_to_temp_dir(self, self.checksum)
return convert(document_file, output_filepath=cache_file_path, page=page, transformations=transformations)
def get_image(self, size=PREVIEW_SIZE, page=DEFAULT_PAGE_NUMBER, zoom=DEFAULT_ZOOM_LEVEL, rotation=DEFAULT_ROTATION):
try:
image_cache_name = self.get_image_cache_name(page=page)
output_file = convert(image_cache_name, cleanup_files=False, size=size, zoom=zoom, rotation=rotation)
except UnknownFormat:
output_file = os.path.join(settings.MEDIA_ROOT, u'images', PICTURE_UNKNOWN_SMALL)
except UnkownConvertError:
output_file = os.path.join(settings.MEDIA_ROOT, u'images', PICTURE_ERROR_SMALL)
except Exception, e:
output_file = os.path.join(settings.MEDIA_ROOT, u'images', PICTURE_ERROR_SMALL)
return output_file
class DocumentTypeFilename(models.Model):
@@ -251,26 +287,13 @@ class DocumentPage(models.Model):
verbose_name = _(u'document page')
verbose_name_plural = _(u'document pages')
def get_transformation_list(self):
return DocumentPageTransformation.objects.get_for_document_page_as_list(self)
@models.permalink
def get_absolute_url(self):
return ('document_page_view', [self.pk])
def get_transformation_string(self):
transformation_list = []
warnings = []
for page_transformation in self.documentpagetransformation_set.all():
try:
if page_transformation.transformation in TRANFORMATION_CHOICES:
transformation_list.append(
TRANFORMATION_CHOICES[page_transformation.transformation] % eval(
page_transformation.arguments
)
)
except Exception, e:
warnings.append(e)
return u' '.join(transformation_list), warnings
class DocumentPageTransformation(models.Model):
"""
@@ -279,9 +302,11 @@ class DocumentPageTransformation(models.Model):
"""
document_page = models.ForeignKey(DocumentPage, verbose_name=_(u'document page'))
order = models.PositiveIntegerField(default=0, blank=True, null=True, verbose_name=_(u'order'), db_index=True)
transformation = models.CharField(choices=available_transformations, max_length=128, verbose_name=_(u'transformation'))
transformation = models.CharField(choices=get_available_transformations_choices(), max_length=128, verbose_name=_(u'transformation'))
arguments = models.TextField(blank=True, null=True, verbose_name=_(u'arguments'), help_text=_(u'Use dictionaries to indentify arguments, example: {\'degrees\':90}'))
objects = DocumentPageTransformationManager()
def __unicode__(self):
return u'"%s" for %s' % (self.get_transformation_display(), unicode(self.document_page))

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

@@ -1,6 +1,6 @@
from django.template import Library, Node, Variable
from converter.api import get_document_dimensions, QUALITY_PRINT
from converter.api import get_document_dimensions
from documents.views import calculate_converter_arguments
from documents.conf.settings import PRINT_SIZE
@@ -14,8 +14,7 @@ class GetImageSizeNode(Node):
def render(self, context):
document = Variable(self.document).resolve(context)
arguments, warnings = calculate_converter_arguments(document, size=PRINT_SIZE, quality=QUALITY_PRINT)
width, height = get_document_dimensions(document, **arguments)
width, height = get_document_dimensions(document)
context[u'document_width'], context['document_height'] = width, height
context[u'document_aspect'] = float(width) / float(height)
return u''

View File

@@ -1,24 +1,16 @@
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.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'),
@@ -30,8 +22,8 @@ urlpatterns = patterns('documents.views',
url(r'^(?P<document_id>\d+)/display/preview/$', 'get_document_image', {'size': PREVIEW_SIZE}, 'document_preview'),
url(r'^(?P<document_id>\d+)/display/preview/multipage/$', 'get_document_image', {'size': MULTIPAGE_PREVIEW_SIZE}, 'document_preview_multipage'),
url(r'^(?P<document_id>\d+)/display/thumbnail/$', 'get_document_image', {'size': THUMBNAIL_SIZE}, 'document_thumbnail'),
url(r'^(?P<document_id>\d+)/display/$', 'get_document_image', {'size': DISPLAY_SIZE, 'quality': QUALITY_HIGH}, 'document_display'),
url(r'^(?P<document_id>\d+)/display/print/$', 'get_document_image', {'size': PRINT_SIZE, 'quality': QUALITY_PRINT}, 'document_display_print'),
url(r'^(?P<document_id>\d+)/display/$', 'get_document_image', {'size': DISPLAY_SIZE}, 'document_display'),
url(r'^(?P<document_id>\d+)/display/print/$', 'get_document_image', {'size': PRINT_SIZE}, 'document_display_print'),
url(r'^(?P<document_id>\d+)/download/$', 'document_download', (), 'document_download'),
url(r'^(?P<document_id>\d+)/create/siblings/$', 'document_create_siblings', (), 'document_create_siblings'),
@@ -41,9 +33,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

@@ -1,6 +1,6 @@
import os
from common import TEMPORARY_DIRECTORY
from common.conf.settings import TEMPORARY_DIRECTORY
try:
from python_magic import magic

View File

@@ -1,5 +1,4 @@
import os
import zipfile
import urlparse
import copy
@@ -13,7 +12,6 @@ from django.core.urlresolvers import reverse
from django.views.generic.create_update import delete_object, update_object
from django.conf import settings
from django.utils.http import urlencode
from django.core.files.uploadedfile import SimpleUploadedFile
import sendfile
from common.utils import pretty_size, parse_range, urlquote, \
@@ -22,10 +20,8 @@ from common.widgets import two_state_template
from common.literals import PAGE_SIZE_DIMENSIONS, \
PAGE_ORIENTATION_PORTRAIT, PAGE_ORIENTATION_LANDSCAPE
from common.conf.settings import DEFAULT_PAPER_SIZE
from converter.api import convert_document, QUALITY_DEFAULT
from converter.exceptions import UnkownConvertError, UnknownFormat
from converter.api import DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION, \
DEFAULT_FILE_FORMAT, QUALITY_PRINT
from converter.literals import DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION, \
DEFAULT_FILE_FORMAT, DEFAULT_PAGE_NUMBER
from filetransfers.api import serve_file
from grouping.utils import get_document_group_subtemplate
from metadata.api import save_metadata_list, \
@@ -36,10 +32,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 +53,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 +61,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,171 +105,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)
if form:
if form.cleaned_data['new_filename']:
document.file_filename = form.cleaned_data['new_filename']
document.save()
if form and 'document_type_available_filenames' in form.cleaned_data:
if form.cleaned_data['document_type_available_filenames']:
document.file_filename = form.cleaned_data['document_type_available_filenames'].filename
document.save()
save_metadata_list(decode_metadata_from_url(request.GET), document, create=True)
warnings = update_indexes(document)
if request.user.is_staff or request.user.is_superuser:
for warning in warnings:
messages.warning(request, warning)
create_history(HISTORY_DOCUMENT_CREATED, document, {'user': request.user})
def _handle_zip_file(request, uploaded_file, document_type=None):
filename = getattr(uploaded_file, 'filename', getattr(uploaded_file, 'name', ''))
if filename.lower().endswith('zip'):
zfobj = zipfile.ZipFile(uploaded_file)
for filename in zfobj.namelist():
if not filename.endswith('/'):
zip_document = Document(file=SimpleUploadedFile(
name=filename, content=zfobj.read(filename)))
if document_type:
zip_document.document_type = document_type
zip_document.save()
_handle_save_document(request, zip_document)
messages.success(request, _(u'Extracted file: %s, uploaded successfully.') % filename)
#Signal that uploaded file was a zip file
return True
else:
#Otherwise tell parent to handle file
return False
def upload_document_with_type(request, source):
check_permissions(request.user, [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[0])
else:
document_type = None
if request.method == 'POST':
if source == UPLOAD_SOURCE_LOCAL:
form = DocumentForm(request.POST, request.FILES, document_type=document_type)
if form.is_valid():
try:
expand = form.cleaned_data['expand']
if (not expand) or (expand and not _handle_zip_file(request, request.FILES['file'], document_type)):
instance = form.save()
instance.save()
if document_type:
instance.document_type = document_type
_handle_save_document(request, instance, form)
messages.success(request, _(u'Document uploaded successfully.'))
except Exception, e:
messages.error(request, e)
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,
document_type=document_type)
if form.is_valid():
try:
staging_file = StagingFile.get(form.cleaned_data['staging_file_id'])
expand = form.cleaned_data['expand']
if (not expand) or (expand and not _handle_zip_file(request, staging_file.upload(), document_type)):
document = Document(file=staging_file.upload())
if document_type:
document.document_type = document_type
document.save()
_handle_save_document(request, document, form)
messages.success(request, _(u'Staging file: %s, uploaded successfully.') % staging_file.filename)
if DELETE_STAGING_FILE_AFTER_UPLOAD:
staging_file.delete()
messages.success(request, _(u'Staging file: %s, deleted successfully.') % staging_file.filename)
except Exception, e:
messages.error(request, e)
return HttpResponseRedirect(request.META['HTTP_REFERER'])
else:
if source == UPLOAD_SOURCE_LOCAL:
form = DocumentForm(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,
document_type=document_type)
subtemplates_list = []
if source == UPLOAD_SOURCE_LOCAL:
subtemplates_list.append({
'name': 'generic_form_subtemplate.html',
'context': {
'form': form,
'title': _(u'upload a local document'),
},
})
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_form_subtemplate.html',
'context': {
'form': form,
'title': form_title,
}
},
{
'name': 'generic_list_subtemplate.html',
'context': {
'title': list_title,
'object_list': staging_filelist,
'hide_link': True,
}
},
]
context = {
'source': source,
'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,
}
}]
}
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])
#document = get_object_or_404(Document.objects.select_related(), pk=document_id)
@@ -456,38 +284,14 @@ def document_edit(request, document_id):
}, context_instance=RequestContext(request))
def calculate_converter_arguments(document, *args, **kwargs):
size = kwargs.pop('size', PREVIEW_SIZE)
quality = kwargs.pop('quality', QUALITY_DEFAULT)
page = kwargs.pop('page', 1)
file_format = kwargs.pop('file_format', DEFAULT_FILE_FORMAT)
zoom = kwargs.pop('zoom', DEFAULT_ZOOM_LEVEL)
rotation = kwargs.pop('rotation', DEFAULT_ROTATION)
document_page = DocumentPage.objects.get(document=document, page_number=page)
transformation_string, warnings = document_page.get_transformation_string()
arguments = {
'size': size,
'file_format': file_format,
'quality': quality,
'extra_options': transformation_string,
'page': page - 1,
'zoom': zoom,
'rotation': rotation
}
return arguments, warnings
def get_document_image(request, document_id, size=PREVIEW_SIZE, quality=QUALITY_DEFAULT):
def get_document_image(request, document_id, size=PREVIEW_SIZE):
check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW])
document = get_object_or_404(Document, pk=document_id)
page = int(request.GET.get('page', 1))
page = int(request.GET.get('page', DEFAULT_PAGE_NUMBER))
zoom = int(request.GET.get('zoom', 100))
zoom = int(request.GET.get('zoom', DEFAULT_ZOOM_LEVEL))
if zoom < ZOOM_MIN_LEVEL:
zoom = ZOOM_MIN_LEVEL
@@ -495,37 +299,9 @@ def get_document_image(request, document_id, size=PREVIEW_SIZE, quality=QUALITY_
if zoom > ZOOM_MAX_LEVEL:
zoom = ZOOM_MAX_LEVEL
rotation = int(request.GET.get('rotation', 0)) % 360
rotation = int(request.GET.get('rotation', DEFAULT_ROTATION)) % 360
arguments, warnings = calculate_converter_arguments(document, size=size, file_format=DEFAULT_FILE_FORMAT, quality=quality, page=page, zoom=zoom, rotation=rotation)
if warnings and (request.user.is_staff or request.user.is_superuser):
for warning in warnings:
messages.warning(request, _(u'Page transformation error: %s') % warning)
try:
output_file = convert_document(document, **arguments)
except UnkownConvertError, e:
if request.user.is_staff or request.user.is_superuser:
messages.error(request, e)
if size == THUMBNAIL_SIZE:
output_file = os.path.join(settings.MEDIA_ROOT, u'images', PICTURE_ERROR_SMALL)
else:
output_file = os.path.join(settings.MEDIA_ROOT, u'images', PICTURE_ERROR_MEDIUM)
except UnknownFormat:
if size == THUMBNAIL_SIZE:
output_file = os.path.join(settings.MEDIA_ROOT, u'images', PICTURE_UNKNOWN_SMALL)
else:
output_file = os.path.join(settings.MEDIA_ROOT, u'images', PICTURE_UNKNOWN_MEDIUM)
except Exception, e:
if request.user.is_staff or request.user.is_superuser:
messages.error(request, e)
if size == THUMBNAIL_SIZE:
output_file = os.path.join(settings.MEDIA_ROOT, u'images', PICTURE_ERROR_SMALL)
else:
output_file = os.path.join(settings.MEDIA_ROOT, u'images', PICTURE_ERROR_MEDIUM)
finally:
return sendfile.sendfile(request, output_file)
return sendfile.sendfile(request, document.get_image(size=size, page=page, zoom=zoom, rotation=rotation))
def document_download(request, document_id):
@@ -546,58 +322,6 @@ def document_download(request, document_id):
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)
try:
output_file, errors = StagingFile.get(staging_file_id).preview()
if errors and (request.user.is_staff or request.user.is_superuser):
for error in errors:
messages.warning(request, _(u'Staging file transformation error: %(error)s') % {
'error': error
})
except UnkownConvertError, e:
if request.user.is_staff or request.user.is_superuser:
messages.error(request, e)
output_file = os.path.join(settings.MEDIA_ROOT, u'images', PICTURE_ERROR_MEDIUM)
except UnknownFormat:
output_file = os.path.join(settings.MEDIA_ROOT, u'images', PICTURE_UNKNOWN_MEDIUM)
except Exception, e:
if request.user.is_staff or request.user.is_superuser:
messages.error(request, e)
output_file = os.path.join(settings.MEDIA_ROOT, u'images', PICTURE_ERROR_MEDIUM)
finally:
return sendfile.sendfile(request, output_file)
def staging_file_delete(request, source, staging_file_id):
check_permissions(request.user, [PERMISSION_DOCUMENT_CREATE])
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)))
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', None)))
if request.method == 'POST':
try:
staging_file.delete()
messages.success(request, _(u'Staging file delete successfully.'))
except Exception, e:
messages.error(request, e)
return HttpResponseRedirect(next)
return render_to_response('generic_confirm.html', {
'source': source,
'delete_view': True,
'object': staging_file,
'next': next,
'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])
@@ -689,10 +413,14 @@ def document_find_duplicates(request, document_id):
check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW])
document = get_object_or_404(Document, pk=document_id)
return _find_duplicate_list(request, [document], include_source=True, confirmation=False)
extra_context = {
'title': _(u'duplicates of: %s') % document,
'object': document,
}
return _find_duplicate_list(request, [document], include_source=True, confirmation=False, extra_context=extra_context)
def _find_duplicate_list(request, source_document_list=Document.objects.all(), include_source=False, confirmation=True):
def _find_duplicate_list(request, source_document_list=Document.objects.all(), include_source=False, confirmation=True, extra_context=None):
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', None)))
if confirmation and request.method != 'POST':
@@ -712,10 +440,18 @@ def _find_duplicate_list(request, source_document_list=Document.objects.all(), i
if include_source and results:
duplicated.append(document.pk)
return render_to_response('generic_list.html', {
context = {
'object_list': Document.objects.filter(pk__in=duplicated),
'title': _(u'duplicated documents'),
}, context_instance=RequestContext(request))
'hide_links': True,
'multi_select_as_buttons': True,
}
if extra_context:
context.update(extra_context)
return render_to_response('generic_list.html', context,
context_instance=RequestContext(request))
def document_find_all_duplicates(request):
@@ -802,13 +538,13 @@ def document_page_view(request, document_page_id):
document_page = get_object_or_404(DocumentPage, pk=document_page_id)
zoom = int(request.GET.get('zoom', 100))
rotation = int(request.GET.get('rotation', 0))
zoom = int(request.GET.get('zoom', DEFAULT_ZOOM_LEVEL))
rotation = int(request.GET.get('rotation', DEFAULT_ROTATION))
document_page_form = DocumentPageForm(instance=document_page, zoom=zoom, rotation=rotation)
base_title = _(u'details for: %s') % document_page
if zoom != 100:
if zoom != DEFAULT_ZOOM_LEVEL:
zoom_text = u'(%d%%)' % zoom
else:
zoom_text = u''
@@ -1036,13 +772,14 @@ def document_print(request, document_id):
def document_hard_copy(request, document_id):
#TODO: FIXME
check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW])
document = get_object_or_404(Document, pk=document_id)
RecentDocument.objects.add_document_for_user(request.user, document)
arguments, warnings = calculate_converter_arguments(document, size=PRINT_SIZE, file_format=DEFAULT_FILE_FORMAT, quality=QUALITY_PRINT)
arguments, warnings = calculate_converter_arguments(document, size=PRINT_SIZE, file_format=DEFAULT_FILE_FORMAT)
# Pre-generate
convert_document(document, **arguments)

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)