diff --git a/apps/documents/__init__.py b/apps/documents/__init__.py index 846522bc09..c1f3792bf9 100644 --- a/apps/documents/__init__.py +++ b/apps/documents/__init__.py @@ -1,21 +1,17 @@ from __future__ import absolute_import -import tempfile - from django.utils.translation import ugettext_lazy as _ from acls.api import class_permissions -from app_registry.models import App -from common.utils import validate_path, encapsulate -from diagnostics.api import DiagnosticNamespace +from common.utils import encapsulate +#from diagnostics.api import DiagnosticNamespace from history.permissions import PERMISSION_HISTORY_VIEW from maintenance.api import MaintenanceNamespace from navigation.api import (bind_links, register_top_menu, register_model_list_columns, register_sidebar_template, Link, register_multi_item_links) -from project_setup.api import register_setup -from statistics.api import register_statistics +# Register document type links from .models import (Document, DocumentPage, DocumentPageTransformation, DocumentType, DocumentTypeFilename, DocumentVersion) @@ -24,7 +20,6 @@ from .permissions import (PERMISSION_DOCUMENT_PROPERTIES_EDIT, PERMISSION_DOCUMENT_DOWNLOAD, PERMISSION_DOCUMENT_TRANSFORM, PERMISSION_DOCUMENT_EDIT, PERMISSION_DOCUMENT_VERSION_REVERT, PERMISSION_DOCUMENT_NEW_VERSION) -from .conf import settings as document_settings from .widgets import document_thumbnail from .links import (document_list, document_list_recent, document_create_siblings, document_view_simple, document_view_advanced, @@ -35,7 +30,8 @@ from .links import (document_list, document_list_recent, document_missing_list) from .links import (document_type_list, document_type_setup, document_type_document_list, document_type_edit, document_type_delete, document_type_create, document_type_filename_list, - document_type_filename_create, document_type_filename_edit, document_type_filename_delete) + document_type_filename_create, document_type_filename_edit, document_type_filename_delete, + link_documents_menu) from .links import document_version_list, document_version_revert from .links import (document_page_transformation_list, document_page_transformation_create, document_page_transformation_edit, document_page_transformation_delete, @@ -46,9 +42,7 @@ from .links import (document_page_transformation_list, document_page_transformat document_multiple_clear_transformations, document_multiple_delete, document_multiple_download, document_version_text_compare) from .links import document_clear_image_cache -from .statistics import get_statistics -# Register document type links bind_links([DocumentType], [document_type_document_list, document_type_filename_list, document_type_edit, document_type_delete]) bind_links([DocumentTypeFilename], [document_type_filename_edit, document_type_filename_delete]) @@ -86,8 +80,8 @@ bind_links('document_page_transformation_list', [document_page_transformation_cr bind_links('document_page_transformation_create', [document_page_transformation_create], menu_name='sidebar') bind_links(['document_page_transformation_edit', 'document_page_transformation_delete'], [document_page_transformation_create], menu_name='sidebar') -namespace = DiagnosticNamespace(_(u'documents')) -namespace.create_tool(document_missing_list) +#namespace = DiagnosticNamespace(_(u'documents')) +#namespace.create_tool(document_missing_list) namespace = MaintenanceNamespace(_(u'documents')) namespace.create_tool(document_find_all_duplicates) @@ -104,10 +98,7 @@ register_model_list_columns(Document, [ register_top_menu( 'documents', - link=Link(sprite='page', text=_(u'documents'), view='document_list_recent', - children_url_regex=[r'^documents/[^t]', r'^metadata/[^s]', r'comments', r'tags/document', r'grouping/[^s]', r'history/list/for_object/documents'], - children_view_regex=[r'document_acl', r'smart_link_instance'], - children_views=['document_folder_list', 'folder_add_document', 'document_index_list', 'upload_version', ]), + link=link_documents_menu, position=1 ) @@ -119,11 +110,6 @@ bind_links([Document], [document_view_advanced], menu_name='form_header', positi bind_links([Document], [document_history_view], menu_name='form_header') bind_links([Document], [document_version_list], menu_name='form_header') -if (validate_path(document_settings.CACHE_PATH) == False) or (not document_settings.CACHE_PATH): - setattr(document_settings, 'CACHE_PATH', tempfile.mkdtemp()) - -register_setup(document_type_setup) - class_permissions(Document, [ PERMISSION_DOCUMENT_PROPERTIES_EDIT, PERMISSION_DOCUMENT_EDIT, @@ -136,12 +122,3 @@ class_permissions(Document, [ PERMISSION_HISTORY_VIEW ]) -register_statistics(get_statistics) - -try: - app = App.register('documents', _(u'Documents')) -except App.UnableToRegister: - pass -else: - app.set_dependencies(['app_registry']) - #AppBackup(app, [ModelBackup(), FileBackup(document_settings.STORAGE_BACKEND)]) diff --git a/apps/documents/forms.py b/apps/documents/forms.py index 304663ddb7..1b30783db8 100644 --- a/apps/documents/forms.py +++ b/apps/documents/forms.py @@ -8,7 +8,7 @@ from django.utils.safestring import mark_safe from common.forms import DetailForm from common.literals import PAGE_SIZE_CHOICES, PAGE_ORIENTATION_CHOICES -from common.conf.settings import DEFAULT_PAPER_SIZE, DEFAULT_PAGE_ORIENTATION +from common.settings import DEFAULT_PAPER_SIZE, DEFAULT_PAGE_ORIENTATION from common.widgets import TextAreaDiv from .models import (Document, DocumentType, diff --git a/apps/documents/links.py b/apps/documents/links.py index ede1d65022..8e797beef8 100644 --- a/apps/documents/links.py +++ b/apps/documents/links.py @@ -18,7 +18,6 @@ from .icons import (icon_documents, icon_create_siblings, icon_document_delete, icon_document_properties, icon_document_edit, icon_document_preview, icon_document_download, icon_find_duplicates, icon_print, icon_version_revert, icon_version_compare, icon_versions, icon_document_types) -#from .settings import ZOOM_MAX_LEVEL, ZOOM_MIN_LEVEL # Document page links expressions def is_first_page(context): @@ -30,10 +29,12 @@ def is_last_page(context): def is_min_zoom(context): + from .settings import ZOOM_MIN_LEVEL return context['zoom'] <= ZOOM_MIN_LEVEL def is_max_zoom(context): + from .settings import ZOOM_MAX_LEVEL return context['zoom'] >= ZOOM_MAX_LEVEL diff --git a/apps/documents/managers.py b/apps/documents/managers.py index c69a007254..a95c34475a 100644 --- a/apps/documents/managers.py +++ b/apps/documents/managers.py @@ -1,6 +1,7 @@ from __future__ import absolute_import from ast import literal_eval +from datetime import datetime from django.db import models @@ -24,3 +25,23 @@ class DocumentPageTransformationManager(models.Manager): warnings.append(e) return transformations, warnings + + +class RecentDocumentManager(models.Manager): + def add_document_for_user(self, user, document): + from .settings import RECENT_COUNT + + if user.is_authenticated(): + self.model.objects.filter(user=user, document=document).delete() + new_recent = self.model(user=user, document=document, datetime_accessed=datetime.now()) + new_recent.save() + to_delete = self.model.objects.filter(user=user)[RECENT_COUNT:] + for recent_to_delete in to_delete: + recent_to_delete.delete() + + def get_for_user(self, user): + document_model = models.get_model('documents', 'Document') + if user.is_authenticated(): + return document_model.objects.filter(recentdocument__user=user) + else: + return [] diff --git a/apps/documents/models.py b/apps/documents/models.py index 34ca755520..ca3377c54b 100644 --- a/apps/documents/models.py +++ b/apps/documents/models.py @@ -21,20 +21,24 @@ from django.utils.translation import ugettext from django.contrib.auth.models import User from django.core.exceptions import ValidationError -from converter.api import get_page_count -from converter.api import get_available_transformations_choices -from converter.api import convert -from converter.exceptions import UnknownFileFormat, UnkownConvertError -from mimetype.api import (get_mimetype, get_icon_file_path, - get_error_icon_file_path) +import converter +#from converter import api as converter_api +#from converter.api import get_page_count +#from converter.api import get_available_transformations_choices +#from converter.api import convert +#from converter.exceptions import UnknownFileFormat, UnkownConvertError +#from mimetype.api import (get_mimetype, get_icon_file_path, +# get_error_icon_file_path) from converter.literals import (DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION, DEFAULT_PAGE_NUMBER) -from .conf.settings import RECENT_COUNT -from .conf.settings import (CHECKSUM_FUNCTION, UUID_FUNCTION, - STORAGE_BACKEND, DISPLAY_SIZE, CACHE_PATH, - ZOOM_MAX_LEVEL, ZOOM_MIN_LEVEL) -from .managers import DocumentPageTransformationManager +from mimetype.icons import icon_file_extension_error + +#from .settings import (CHECKSUM_FUNCTION, UUID_FUNCTION, +# STORAGE_BACKEND, DISPLAY_SIZE, CACHE_PATH, +# ZOOM_MAX_LEVEL, ZOOM_MIN_LEVEL) + +from .managers import DocumentPageTransformationManager, RecentDocumentManager from .utils import document_save_to_temp_dir from .literals import (RELEASE_LEVEL_FINAL, RELEASE_LEVEL_CHOICES, VERSION_UPDATE_MAJOR, VERSION_UPDATE_MINOR, VERSION_UPDATE_MICRO) @@ -51,6 +55,8 @@ def get_filename_from_uuid(instance, filename): Store the orignal filename of the uploaded file and replace it with a UUID """ + from .settings import UUID_FUNCTION + instance.filename = filename return UUID_FUNCTION() @@ -82,6 +88,8 @@ class Document(models.Model): @staticmethod def clear_image_cache(): + from .settings import CACHE_PATH + for the_file in os.listdir(CACHE_PATH): file_path = os.path.join(CACHE_PATH, the_file) if os.path.isfile(file_path): @@ -100,6 +108,8 @@ class Document(models.Model): return ('document_view_simple', [self.pk]) def save(self, *args, **kwargs): + from .settings import UUID_FUNCTION + if not self.pk: self.uuid = UUID_FUNCTION() self.date_added = datetime.datetime.now() @@ -107,6 +117,8 @@ class Document(models.Model): self.mark_indexable() def get_cached_image_name(self, page, version): + from .settings import CACHE_PATH + document_version = DocumentVersion.objects.get(pk=version) document_page = document_version.documentpage_set.get(page_number=page) transformations, warnings = document_page.get_transformation_list() @@ -114,6 +126,7 @@ class Document(models.Model): return os.path.join(CACHE_PATH, hash_value), transformations def get_image_cache_name(self, page, version): + from converter.api import convert cache_file_path, transformations = self.get_cached_image_name(page, version) if os.path.exists(cache_file_path): return cache_file_path @@ -122,13 +135,22 @@ class Document(models.Model): document_file = document_save_to_temp_dir(document_version, document_version.checksum) return convert(document_file, output_filepath=cache_file_path, page=page, transformations=transformations, mimetype=self.file_mimetype) - def get_valid_image(self, size=DISPLAY_SIZE, page=DEFAULT_PAGE_NUMBER, zoom=DEFAULT_ZOOM_LEVEL, rotation=DEFAULT_ROTATION, version=None): + def get_valid_image(self, size=None, page=DEFAULT_PAGE_NUMBER, zoom=DEFAULT_ZOOM_LEVEL, rotation=DEFAULT_ROTATION, version=None): + from converter.api import convert + + if not size: + size = DISPLAY_SIZE + if not version: version = self.latest_version.pk image_cache_name = self.get_image_cache_name(page=page, version=version) return convert(image_cache_name, cleanup_files=False, size=size, zoom=zoom, rotation=rotation) - def get_image(self, size=DISPLAY_SIZE, page=DEFAULT_PAGE_NUMBER, zoom=DEFAULT_ZOOM_LEVEL, rotation=DEFAULT_ROTATION, as_base64=False, version=None): + def get_image(self, size=None, page=DEFAULT_PAGE_NUMBER, zoom=DEFAULT_ZOOM_LEVEL, rotation=DEFAULT_ROTATION, as_base64=False, version=None): + from .settings import ZOOM_MAX_LEVEL, ZOOM_MIN_LEVEL + if not size: + size = DISPLAY_SIZE + if zoom < ZOOM_MIN_LEVEL: zoom = ZOOM_MIN_LEVEL @@ -139,12 +161,12 @@ class Document(models.Model): try: file_path = self.get_valid_image(size=size, page=page, zoom=zoom, rotation=rotation, version=version) - except UnknownFileFormat: + except converter.UnknownFileFormat: file_path = get_icon_file_path(self.file_mimetype) - except UnkownConvertError: - file_path = get_error_icon_file_path() + except converter.UnkownConvertError: + file_path = icon_file_extension_error.get_filepath() except: - file_path = get_error_icon_file_path() + file_path = icon_file_extension_error.get_filepath() if as_base64: image = open(file_path, 'r') @@ -340,7 +362,7 @@ class DocumentVersion(models.Model): comment = models.TextField(blank=True, verbose_name=_(u'comment')) # File related fields - file = models.FileField(upload_to=get_filename_from_uuid, storage=STORAGE_BACKEND(), verbose_name=_(u'file')) + file = models.FileField(upload_to=get_filename_from_uuid, verbose_name=_(u'file')) mimetype = models.CharField(max_length=64, null=True, blank=True, editable=False) encoding = models.CharField(max_length=64, null=True, blank=True, editable=False) filename = models.CharField(max_length=255, default=u'', editable=False, db_index=True) @@ -424,6 +446,8 @@ class DocumentVersion(models.Model): Open a document version's file and update the checksum field using the user provided checksum function """ + from .settings import CHECKSUM_FUNCTION + if self.exists(): source = self.open() self.checksum = unicode(CHECKSUM_FUNCTION(source.read())) @@ -432,6 +456,7 @@ class DocumentVersion(models.Model): self.save() def update_page_count(self, save=True): + from coverter.api import get_page_count handle, filepath = tempfile.mkstemp() # Just need the filepath, close the file description os.close(handle) @@ -439,7 +464,7 @@ class DocumentVersion(models.Model): self.save_to_file(filepath) try: detected_pages = get_page_count(filepath) - except UnknownFileFormat: + except converter.UnknownFileFormat: # If converter backend doesn't understand the format, # use 1 as the total page count detected_pages = 1 @@ -660,7 +685,8 @@ 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=get_available_transformations_choices(), max_length=128, verbose_name=_(u'transformation')) + #transformation = models.CharField(choices=get_available_transformations_choices(), max_length=128, verbose_name=_(u'transformation')) + transformation = models.CharField(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: %s') % u'{\'degrees\':90}', validators=[ArgumentsValidator()]) objects = DocumentPageTransformationManager() @@ -673,23 +699,6 @@ class DocumentPageTransformation(models.Model): verbose_name_plural = _(u'document page transformations') -class RecentDocumentManager(models.Manager): - def add_document_for_user(self, user, document): - if user.is_authenticated(): - self.model.objects.filter(user=user, document=document).delete() - new_recent = self.model(user=user, document=document, datetime_accessed=datetime.datetime.now()) - new_recent.save() - to_delete = self.model.objects.filter(user=user)[RECENT_COUNT:] - for recent_to_delete in to_delete: - recent_to_delete.delete() - - def get_for_user(self, user): - if user.is_authenticated(): - return Document.objects.filter(recentdocument__user=user) - else: - return [] - - class RecentDocument(models.Model): """ Keeps a list of the n most recent accessed or created document for diff --git a/apps/documents/statistics.py b/apps/documents/statistics.py index 77ebf94e26..5d09d04d7b 100644 --- a/apps/documents/statistics.py +++ b/apps/documents/statistics.py @@ -5,11 +5,12 @@ from django.db.models import Avg, Count, Min, Max from common.utils import pretty_size, pretty_size_10 -from .conf.settings import STORAGE_BACKEND from .models import Document, DocumentType, DocumentPage, DocumentVersion def get_used_size(path, file_list): + from .settings import STORAGE_BACKEND + total_size = 0 for filename in file_list: try: @@ -21,6 +22,8 @@ def get_used_size(path, file_list): def storage_count(path=u'.'): + from .settings import STORAGE_BACKEND + try: directories, files = STORAGE_BACKEND().listdir(path) except OSError: diff --git a/apps/documents/urls.py b/apps/documents/urls.py index 67708c097c..905c782a6b 100644 --- a/apps/documents/urls.py +++ b/apps/documents/urls.py @@ -2,9 +2,10 @@ from __future__ import absolute_import from django.conf.urls.defaults import patterns, url -from .conf.settings import (PREVIEW_SIZE, PRINT_SIZE, THUMBNAIL_SIZE, +from .settings import (PREVIEW_SIZE, PRINT_SIZE, THUMBNAIL_SIZE, DISPLAY_SIZE, MULTIPAGE_PREVIEW_SIZE) + urlpatterns = patterns('documents.views', url(r'^list/$', 'document_list', (), 'document_list'), url(r'^list/recent/$', 'document_list_recent', (), 'document_list_recent'), diff --git a/apps/documents/utils.py b/apps/documents/utils.py index ca5cb67db3..fb31763c2d 100644 --- a/apps/documents/utils.py +++ b/apps/documents/utils.py @@ -1,6 +1,6 @@ import os -from common.conf.settings import TEMPORARY_DIRECTORY +from common.settings import TEMPORARY_DIRECTORY def document_save_to_temp_dir(document, filename, buffer_size=1024 * 1024): diff --git a/apps/documents/views.py b/apps/documents/views.py index 98bedc5974..63110bf039 100644 --- a/apps/documents/views.py +++ b/apps/documents/views.py @@ -16,14 +16,14 @@ from django.core.exceptions import PermissionDenied from django.conf import settings import sendfile -from common.utils import pretty_size, parse_range, urlquote, \ - return_diff, encapsulate +from common.utils import (pretty_size, parse_range, urlquote, + return_diff, encapsulate) 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.literals import DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION, \ - DEFAULT_PAGE_NUMBER, DEFAULT_FILE_FORMAT_MIMETYPE +from common.literals import (PAGE_SIZE_DIMENSIONS, + PAGE_ORIENTATION_PORTRAIT, PAGE_ORIENTATION_LANDSCAPE) +from common.settings import DEFAULT_PAPER_SIZE +from converter.literals import (DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION, + DEFAULT_PAGE_NUMBER, DEFAULT_FILE_FORMAT_MIMETYPE) from converter.office_converter import OfficeConverter from filetransfers.api import serve_file from navigation.utils import resolve_to_name @@ -31,9 +31,10 @@ from permissions.models import Permission from acls.models import AccessEntry from common.compressed_files import CompressedFile -from .conf.settings import (PREVIEW_SIZE, STORAGE_BACKEND, ZOOM_PERCENT_STEP, +from .settings import (PREVIEW_SIZE, STORAGE_BACKEND, ZOOM_PERCENT_STEP, ZOOM_MAX_LEVEL, ZOOM_MIN_LEVEL, ROTATION_STEP, PRINT_SIZE, RECENT_COUNT) + from .permissions import (PERMISSION_DOCUMENT_CREATE, PERMISSION_DOCUMENT_PROPERTIES_EDIT, PERMISSION_DOCUMENT_VIEW, PERMISSION_DOCUMENT_DELETE, PERMISSION_DOCUMENT_DOWNLOAD, diff --git a/apps/documents/widgets.py b/apps/documents/widgets.py index a7b46294d3..da4ff7dd68 100644 --- a/apps/documents/widgets.py +++ b/apps/documents/widgets.py @@ -8,9 +8,10 @@ from django.utils.translation import ugettext_lazy as _ from django.core.urlresolvers import reverse from django.utils.http import urlencode +from mimetype.icons import icon_file_extension_error + from converter.literals import (DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION, DEFAULT_PAGE_NUMBER) -from mimetype.api import get_error_icon_url def document_thumbnail(document, **kwargs): @@ -73,7 +74,7 @@ def document_html_widget(document, view='document_thumbnail', click_view=None, p } }) .error(function(data) { - $('#document-%(pk)d-%(page)d').html(''); + $('#document-%(pk)d-%(page)d').html('%(error_image)s'); }); }); @@ -82,7 +83,7 @@ def document_html_widget(document, view='document_thumbnail', click_view=None, p 'pk': document.pk, 'page': page if page else 1, 'plain_template': mark_safe(u''.join(plain_template)), - 'error_image': u''.join([settings.STATIC_URL, get_error_icon_url()]), + 'error_image': icon_file_extension_error.display_big(), } )