diff --git a/apps/acls/admin.py b/apps/acls/admin.py index 61c12d9498..b078281a42 100644 --- a/apps/acls/admin.py +++ b/apps/acls/admin.py @@ -5,17 +5,19 @@ from django.contrib import admin from .models import AccessEntry -#class PermissionHolderInline(admin.StackedInline): +# class PermissionHolderInline(admin.StackedInline): # model = PermissionHolder # extra = 1 # classes = ('collapse-open',) # allow_add = True# # + + class AccessEntryAdmin(admin.ModelAdmin): related_lookup_fields = { 'generic': [['holder_type', 'holder_id'], ['content_type', 'object_id']], } - #inlines = [PermissionHolderInline] + # inlines = [PermissionHolderInline] list_display = ('pk', 'holder_object', 'permission', 'content_object') list_display_links = ('pk',) model = AccessEntry diff --git a/apps/acls/classes.py b/apps/acls/classes.py index 89802566ea..533ea7e497 100644 --- a/apps/acls/classes.py +++ b/apps/acls/classes.py @@ -5,9 +5,9 @@ import sys import types from django.contrib.contenttypes.models import ContentType +from django.core.exceptions import ObjectDoesNotExist from django.db.models.base import ModelBase from django.template.defaultfilters import capfirst -from django.core.exceptions import ObjectDoesNotExist from common.models import AnonymousUserSingleton @@ -44,8 +44,8 @@ class EncapsulatedObject(object): def set_source_object_name(cls, new_name): cls.source_object_name = new_name - #@classmethod - #def encapsulate_list(cls, source_object=None, app_label=None, model=None, pk=None): + # @classmethod + # def encapsulate_list(cls, source_object=None, app_label=None, model=None, pk=None): @classmethod def encapsulate(cls, source_object): @@ -83,8 +83,8 @@ class EncapsulatedObject(object): try: content_type = ContentType.objects.get(app_label=app_label, model=model) except ContentType.DoesNotExist: - #cls.add_to_class('DoesNotExist', subclass_exception('DoesNotExist', (ObjectDoesNotExist,), cls.__name__)) - #raise cls.DoesNotExist("%s matching query does not exist." % ContentType._meta.object_name) + # cls.add_to_class('DoesNotExist', subclass_exception('DoesNotExist', (ObjectDoesNotExist,), cls.__name__)) + # raise cls.DoesNotExist("%s matching query does not exist." % ContentType._meta.object_name) raise ObjectDoesNotExist("%s matching query does not exist." % ContentType._meta.object_name) else: source_object_model_class = content_type.model_class() @@ -92,8 +92,8 @@ class EncapsulatedObject(object): try: source_object = content_type.get_object_for_this_type(pk=pk) except source_object_model_class.DoesNotExist: - #cls.add_to_class('DoesNotExist', subclass_exception('DoesNotExist', (ObjectDoesNotExist,), cls.__name__)) - #raise cls.DoesNotExist("%s matching query does not exist." % source_object_model_class._meta.object_name) + # cls.add_to_class('DoesNotExist', subclass_exception('DoesNotExist', (ObjectDoesNotExist,), cls.__name__)) + # raise cls.DoesNotExist("%s matching query does not exist." % source_object_model_class._meta.object_name) raise ObjectDoesNotExist("%s matching query does not exist." % source_object_model_class._meta.object_name) else: source_object = source_object_model_class diff --git a/apps/acls/managers.py b/apps/acls/managers.py index 529643c7ec..6fd54e109e 100644 --- a/apps/acls/managers.py +++ b/apps/acls/managers.py @@ -2,13 +2,13 @@ from __future__ import absolute_import import logging -from django.db import models -from django.utils.translation import ugettext -from django.contrib.contenttypes.models import ContentType from django.contrib.auth.models import User +from django.contrib.contenttypes.models import ContentType from django.core.exceptions import PermissionDenied from django.core.urlresolvers import reverse +from django.db import models from django.db.models import Q +from django.utils.translation import ugettext from common.models import AnonymousUserSingleton from permissions.models import Permission, RoleMember @@ -67,7 +67,7 @@ class AccessEntryManager(models.Manager): obj = get_source_object(obj) actor = get_source_object(actor) - if isinstance(actor, User) and db_only == False: + if isinstance(actor, User) and not db_only: # db_only causes the return of only the stored permissions # and not the perceived permissions for an actor if actor.is_superuser or actor.is_staff: @@ -75,7 +75,7 @@ class AccessEntryManager(models.Manager): actor = AnonymousUserSingleton.objects.passthru_check(actor) try: - content_type=ContentType.objects.get_for_model(obj) + content_type = ContentType.objects.get_for_model(obj) except AttributeError: # Object doesn't have a content type, therefore allow access return True @@ -207,7 +207,7 @@ class AccessEntryManager(models.Manager): logger.debug('obj: %s' % obj) logger.debug('actor: %s' % actor) - if isinstance(actor, User) and db_only == False: + if isinstance(actor, User) and not db_only: if actor.is_superuser or actor.is_staff: return Permission.objects.all() @@ -240,7 +240,7 @@ class AccessEntryManager(models.Manager): qs = object_list.filter(pk__in=[obj.pk for obj in self.get_allowed_class_objects(permission, actor, object_list[0].__class__, related)]) logger.debug('qs: %s' % qs) - if qs.count() == 0 and exception_on_empty == True: + if qs.count() == 0 and exception_on_empty: raise PermissionDenied return qs @@ -248,7 +248,7 @@ class AccessEntryManager(models.Manager): # Fallback to a filtered list object_list = list(set(object_list) & set(self.get_allowed_class_objects(permission, actor, object_list[0].__class__, related))) logger.debug('object_list: %s' % object_list) - if len(object_list) == 0 and exception_on_empty == True: + if len(object_list) == 0 and exception_on_empty: raise PermissionDenied return object_list diff --git a/apps/acls/views.py b/apps/acls/views.py index 856b3edd00..a0a0483c50 100644 --- a/apps/acls/views.py +++ b/apps/acls/views.py @@ -2,30 +2,29 @@ from __future__ import absolute_import import logging -from django.utils.translation import ugettext_lazy as _ +from django.contrib import messages +from django.contrib.contenttypes.models import ContentType +from django.core.exceptions import ObjectDoesNotExist, PermissionDenied +from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect, Http404 from django.shortcuts import render_to_response, get_object_or_404 from django.template import RequestContext -from django.contrib import messages -from django.core.urlresolvers import reverse -from django.contrib.contenttypes.models import ContentType -from django.core.exceptions import ObjectDoesNotExist -from django.utils.simplejson import loads -from django.core.exceptions import PermissionDenied from django.utils.http import urlencode +from django.utils.simplejson import loads +from django.utils.translation import ugettext_lazy as _ -from permissions.models import Permission from common.utils import encapsulate from common.widgets import two_state_template +from permissions.models import Permission -from .permissions import (ACLS_EDIT_ACL, ACLS_VIEW_ACL, - ACLS_CLASS_EDIT_ACL, ACLS_CLASS_VIEW_ACL) -from .models import AccessEntry, DefaultAccessEntry +from .api import get_class_permissions_for from .classes import (AccessHolder, AccessObject, AccessObjectClass, ClassAccessHolder) -from .widgets import object_w_content_type_icon from .forms import HolderSelectionForm, ClassHolderSelectionForm -from .api import get_class_permissions_for +from .models import AccessEntry, DefaultAccessEntry +from .permissions import (ACLS_EDIT_ACL, ACLS_VIEW_ACL, + ACLS_CLASS_EDIT_ACL, ACLS_CLASS_VIEW_ACL) +from .widgets import object_w_content_type_icon logger = logging.getLogger(__name__) @@ -78,7 +77,7 @@ def acl_detail(request, access_object_gid, holder_object_gid): except ObjectDoesNotExist: raise Http404 - #return acl_detail_for(request, holder.source_object, access_object.source_object) + # return acl_detail_for(request, holder.source_object, access_object.source_object) return acl_detail_for(request, holder, access_object) @@ -89,7 +88,7 @@ def acl_detail_for(request, actor, obj): AccessEntry.objects.check_accesses([ACLS_VIEW_ACL], actor, obj) permission_list = get_class_permissions_for(obj.source_object) - #TODO : get all globally assigned permission, new function get_permissions_for_holder (roles aware) + # TODO : get all globally assigned permission, new function get_permissions_for_holder (roles aware) subtemplates_list = [ { 'name': u'generic_list_subtemplate.html', @@ -97,14 +96,14 @@ def acl_detail_for(request, actor, obj): 'title': _(u'permissions available to: %(actor)s for %(obj)s' % { 'actor': actor, 'obj': obj - } + } ), 'object_list': permission_list, 'extra_columns': [ {'name': _(u'namespace'), 'attribute': 'namespace'}, {'name': _(u'label'), 'attribute': 'label'}, { - 'name':_(u'has permission'), + 'name': _(u'has permission'), 'attribute': encapsulate(lambda permission: two_state_template(AccessEntry.objects.has_access(permission, actor, obj, db_only=True))) }, ], @@ -386,7 +385,7 @@ def acl_setup_valid_classes(request): 'title': _(u'classes'), 'extra_columns': [ {'name': _(u'class'), 'attribute': encapsulate(lambda x: object_w_content_type_icon(x.source_object))}, - ], + ], 'hide_object': True, } @@ -408,7 +407,7 @@ def acl_class_acl_list(request, access_object_class_gid): 'extra_columns': [ {'name': _(u'holder'), 'attribute': encapsulate(lambda x: object_w_content_type_icon(x.source_object))}, {'name': _(u'permissions'), 'attribute': encapsulate(lambda x: _permission_titles(DefaultAccessEntry.objects.get_holder_permissions_for(access_object_class.source_object, x.source_object)))}, - ], + ], 'hide_object': True, 'access_object_class': access_object_class, 'object': access_object_class, @@ -427,7 +426,7 @@ def acl_class_acl_detail(request, access_object_class_gid, holder_object_gid): raise Http404 permission_list = get_class_permissions_for(access_object_class.content_type.model_class()) - #TODO : get all globally assigned permission, new function get_permissions_for_holder (roles aware) + # TODO : get all globally assigned permission, new function get_permissions_for_holder (roles aware) subtemplates_list = [ { 'name': u'generic_list_subtemplate.html', @@ -442,7 +441,7 @@ def acl_class_acl_detail(request, access_object_class_gid, holder_object_gid): {'name': _(u'namespace'), 'attribute': 'namespace'}, {'name': _(u'label'), 'attribute': 'label'}, { - 'name':_(u'has permission'), + 'name': _(u'has permission'), 'attribute': encapsulate(lambda x: two_state_template(DefaultAccessEntry.objects.has_access(x, actor.source_object, access_object_class.source_object))) }, ], diff --git a/apps/converter/api.py b/apps/converter/api.py index c09ce336aa..d695d4cb69 100644 --- a/apps/converter/api.py +++ b/apps/converter/api.py @@ -1,23 +1,22 @@ from __future__ import absolute_import -import os -import subprocess -import hashlib import logging +import hashlib +import os from django.utils.encoding import smart_str from common.conf.settings import TEMPORARY_DIRECTORY +from . import backend +from .exceptions import OfficeConversionError, UnknownFileFormat from .literals import (DEFAULT_PAGE_NUMBER, DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION, DEFAULT_FILE_FORMAT) -from . import backend from .literals import (TRANSFORMATION_CHOICES, TRANSFORMATION_RESIZE, TRANSFORMATION_ROTATE, TRANSFORMATION_ZOOM, DIMENSION_SEPARATOR, FILE_FORMATS) -from .utils import cleanup from .runtime import office_converter -from .exceptions import OfficeConversionError, UnknownFileFormat +from .utils import cleanup HASH_FUNCTION = lambda x: hashlib.sha256(x).hexdigest() @@ -116,6 +115,7 @@ def get_page_count(input_filepath): return backend.get_page_count(input_filepath) + ''' def get_document_dimensions(document, *args, **kwargs): document_filepath = create_image_cache_filename(document.checksum, *args, **kwargs) @@ -126,6 +126,7 @@ def get_document_dimensions(document, *args, **kwargs): return [0, 0] ''' + def get_available_transformations_choices(): result = [] for transformation in backend.get_available_transformations(): diff --git a/apps/converter/backends/graphicsmagick/base.py b/apps/converter/backends/graphicsmagick/base.py index 379830d032..a08d382691 100644 --- a/apps/converter/backends/graphicsmagick/base.py +++ b/apps/converter/backends/graphicsmagick/base.py @@ -1,14 +1,14 @@ -import subprocess -import re +from __future__ import absolute_import -from converter.conf.settings import GM_PATH -from converter.conf.settings import GM_SETTINGS -from converter.exceptions import ConvertError, UnknownFileFormat, \ - IdentifyError -from converter.backends import ConverterBase -from converter.literals import TRANSFORMATION_RESIZE, \ - TRANSFORMATION_ROTATE, TRANSFORMATION_ZOOM -from converter.literals import DIMENSION_SEPARATOR, DEFAULT_PAGE_NUMBER, \ +import re +import subprocess + +from ...backends import ConverterBase +from ...conf.settings import GM_PATH, GM_SETTINGS +from ...exceptions import ConvertError, UnknownFileFormat, IdentifyError +from ...literals import (TRANSFORMATION_RESIZE, + TRANSFORMATION_ROTATE, TRANSFORMATION_ZOOM) +from ...literals import DIMENSION_SEPARATOR, DEFAULT_PAGE_NUMBER, \ DEFAULT_FILE_FORMAT CONVERTER_ERROR_STRING_NO_DECODER = u'No decode delegate for this image format' @@ -74,10 +74,10 @@ class ConverterClass(ConverterBase): proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) return_code = proc.wait() if return_code != 0: - #Got an error from convert program + # Got an error from convert program error_line = proc.stderr.readline() if (CONVERTER_ERROR_STRING_NO_DECODER in error_line) or (CONVERTER_ERROR_STARTS_WITH in error_line): - #Try to determine from error message which class of error is it + # Try to determine from error message which class of error is it raise UnknownFileFormat else: raise ConvertError(error_line) @@ -108,7 +108,7 @@ class ConverterClass(ConverterBase): def get_available_transformations(self): return [ - TRANSFORMATION_RESIZE, TRANSFORMATION_ROTATE, \ + TRANSFORMATION_RESIZE, TRANSFORMATION_ROTATE, TRANSFORMATION_ZOOM ] diff --git a/apps/converter/backends/imagemagick/base.py b/apps/converter/backends/imagemagick/base.py index d2a76e3c6c..48ae7b16a1 100644 --- a/apps/converter/backends/imagemagick/base.py +++ b/apps/converter/backends/imagemagick/base.py @@ -1,17 +1,15 @@ -import subprocess -import re +from __future__ import absolute_import + +import re +import subprocess + +from ...backends import ConverterBase +from ...conf.settings import IM_CONVERT_PATH, IM_IDENTIFY_PATH +from ...exceptions import ConvertError, UnknownFileFormat, IdentifyError +from ...literals import (TRANSFORMATION_RESIZE, TRANSFORMATION_ROTATE, + TRANSFORMATION_ZOOM, DIMENSION_SEPARATOR, DEFAULT_PAGE_NUMBER, + DEFAULT_FILE_FORMAT) -from converter.conf.settings import IM_IDENTIFY_PATH -from converter.conf.settings import IM_CONVERT_PATH -from converter.exceptions import ConvertError, UnknownFileFormat, \ - IdentifyError -from converter.backends import ConverterBase -from converter.literals import TRANSFORMATION_RESIZE, \ - TRANSFORMATION_ROTATE, TRANSFORMATION_DENSITY, \ - TRANSFORMATION_ZOOM -from converter.literals import DIMENSION_SEPARATOR, DEFAULT_PAGE_NUMBER, \ - DEFAULT_FILE_FORMAT - CONVERTER_ERROR_STRING_NO_DECODER = u'no decode delegate for this image format' @@ -38,30 +36,30 @@ class ConverterClass(ConverterBase): dimensions = [] dimensions.append(unicode(transformation['arguments']['width'])) if 'height' in transformation['arguments']: - dimensions.append(unicode(transformation['arguments']['height'])) + dimensions.append(unicode(transformation['arguments']['height'])) arguments.append(u'-resize') arguments.append(u'%s' % DIMENSION_SEPARATOR.join(dimensions)) elif transformation['transformation'] == TRANSFORMATION_ZOOM: arguments.append(u'-resize') arguments.append(u'%d%%' % transformation['arguments']['percent']) - + elif transformation['transformation'] == TRANSFORMATION_ROTATE: arguments.append(u'-rotate') arguments.append(u'%s' % transformation['arguments']['degrees']) except: pass - + if file_format.lower() == u'jpeg' or file_format.lower() == u'jpg': arguments.append(u'-quality') arguments.append(u'85') - + # Imagemagick page number is 0 base input_arg = u'%s[%d]' % (input_filepath, page - 1) # Specify the file format next to the output filename output_filepath = u'%s:%s' % (file_format, output_filepath) - + command = [] command.append(unicode(IM_CONVERT_PATH)) command.append(unicode(input_arg)) @@ -71,15 +69,14 @@ class ConverterClass(ConverterBase): proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) return_code = proc.wait() if return_code != 0: - #Got an error from convert program + # Got an error from convert program error_line = proc.stderr.readline() if CONVERTER_ERROR_STRING_NO_DECODER in error_line: - #Try to determine from error message which class of error is it + # Try to determine from error message which class of error is it raise UnknownFileFormat else: raise ConvertError(error_line) - def get_format_list(self): """ Call ImageMagick to parse all of it's supported file formats, and @@ -95,22 +92,20 @@ class ConverterClass(ConverterBase): return_code = proc.wait() if return_code != 0: raise ConvertError(proc.stderr.readline()) - + for line in proc.stdout.readlines(): fields = format_regex.findall(line) if fields: formats.append(fields[0][0]) - - return formats + return formats def get_available_transformations(self): return [ - TRANSFORMATION_RESIZE, TRANSFORMATION_ROTATE, \ + TRANSFORMATION_RESIZE, TRANSFORMATION_ROTATE, TRANSFORMATION_ZOOM ] - def get_page_count(self, input_filepath): try: return len(self.identify_file(unicode(input_filepath)).splitlines()) diff --git a/apps/converter/backends/python/base.py b/apps/converter/backends/python/base.py index 33fda08171..80f9916e77 100644 --- a/apps/converter/backends/python/base.py +++ b/apps/converter/backends/python/base.py @@ -1,5 +1,7 @@ -import tempfile +from __future__ import absolute_import + import os +import tempfile import slate from PIL import Image @@ -12,13 +14,11 @@ except RuntimeError: from mimetype.api import get_mimetype -from converter.exceptions import UnknownFileFormat -from converter.backends import ConverterBase -from converter.literals import TRANSFORMATION_RESIZE, \ - TRANSFORMATION_ROTATE, TRANSFORMATION_ZOOM -from converter.literals import DEFAULT_PAGE_NUMBER, \ - DEFAULT_FILE_FORMAT -from converter.utils import cleanup +from ...exceptions import UnknownFileFormat +from ...backends import ConverterBase +from ...literals import (TRANSFORMATION_RESIZE, TRANSFORMATION_ROTATE, + TRANSFORMATION_ZOOM, DEFAULT_PAGE_NUMBER, DEFAULT_FILE_FORMAT) +from ...utils import cleanup class ConverterClass(ConverterBase): @@ -36,12 +36,12 @@ class ConverterClass(ConverterBase): return 1 # TODO: Maybe return UnknownFileFormat to display proper unknwon file format message in document description return len(pages) - + try: im = Image.open(input_filepath) except IOError: # cannot identify image file raise UnknownFileFormat - + try: while 1: im.seek(im.tell() + 1) @@ -49,7 +49,7 @@ class ConverterClass(ConverterBase): # do something to im except EOFError: pass # end of sequence - + return page_count def convert_file(self, input_filepath, output_filepath, transformations=None, page=DEFAULT_PAGE_NUMBER, file_format=DEFAULT_FILE_FORMAT, **kwargs): @@ -69,7 +69,7 @@ class ConverterClass(ConverterBase): input_file_tmpl = '-f%s' % input_filepath args = [ 'gs', '-q', '-dQUIET', '-dSAFER', '-dBATCH', - '-dNOPAUSE', '-dNOPROMPT', + '-dNOPAUSE', '-dNOPROMPT', first_page_tmpl, last_page_tmpl, '-sDEVICE=jpeg', '-dJPEGQ=95', '-r150', output_file_tmpl, @@ -80,12 +80,12 @@ class ConverterClass(ConverterBase): '-dAlignToPixels=0', '-dGridFitTT=0', '-dTextAlphaBits=4', - '-dGraphicsAlphaBits=4', - ] + '-dGraphicsAlphaBits=4', + ] ghostscript.Ghostscript(*args) page = 1 # Don't execute the following while loop - input_filepath = tmpfile + input_filepath = tmpfile try: im = Image.open(input_filepath) @@ -95,7 +95,7 @@ class ConverterClass(ConverterBase): finally: if tmpfile: cleanup(tmpfile) - + current_page = 0 try: while current_page == page - 1: @@ -105,7 +105,7 @@ class ConverterClass(ConverterBase): except EOFError: # end of sequence pass - + try: if transformations: aspect = 1.0 * im.size[0] / im.size[1] @@ -117,7 +117,7 @@ class ConverterClass(ConverterBase): im = self.resize(im, (width, height)) elif transformation['transformation'] == TRANSFORMATION_ZOOM: decimal_value = float(arguments.get('percent', 100)) / 100 - im = im.transform((int(im.size[0] * decimal_value), int(im.size[1] * decimal_value)), Image.EXTENT, (0, 0, im.size[0], im.size[1])) + im = im.transform((int(im.size[0] * decimal_value), int(im.size[1] * decimal_value)), Image.EXTENT, (0, 0, im.size[0], im.size[1])) elif transformation['transformation'] == TRANSFORMATION_ROTATE: # PIL counter degress counter-clockwise, reverse them im = im.rotate(360 - arguments.get('degrees', 0)) @@ -127,7 +127,7 @@ class ConverterClass(ConverterBase): if im.mode not in ('L', 'RGB'): im = im.convert('RGB') - + im.save(output_filepath, format=file_format) def get_format_list(self): @@ -141,16 +141,16 @@ class ConverterClass(ConverterBase): formats.append('GBR_PIL') else: formats.append(format_name) - + if USE_GHOSTSCRIPT: formats.append('PDF') formats.append('PS') - + return formats def get_available_transformations(self): return [ - TRANSFORMATION_RESIZE, TRANSFORMATION_ROTATE, \ + TRANSFORMATION_RESIZE, TRANSFORMATION_ROTATE, TRANSFORMATION_ZOOM ] @@ -162,14 +162,14 @@ class ConverterClass(ConverterBase): @param fit: boolean - crop the image to fill the box @param out: file-like-object - save the image into the output stream ''' - #preresize image with factor 2, 4, 8 and fast algorithm + # preresize image with factor 2, 4, 8 and fast algorithm factor = 1 while img.size[0] / factor > 2 * box[0] and img.size[1] * 2 / factor > 2 * box[1]: - factor *=2 + factor *= 2 if factor > 1: img.thumbnail((img.size[0] / factor, img.size[1] / factor), Image.NEAREST) - #calculate the cropping box and get the cropped part + # calculate the cropping box and get the cropped part if fit: x1 = y1 = 0 x2, y2 = img.size @@ -183,14 +183,14 @@ class ConverterClass(ConverterBase): x2 = x2 / 2 + box[0] * hRatio / 2 img = img.crop((x1, y1, x2, y2)) - #Resize the image with best quality algorithm ANTI-ALIAS + # Resize the image with best quality algorithm ANTI-ALIAS img.thumbnail(box, Image.ANTIALIAS) if out: - #save it into a file-like object + # save it into a file-like object img.save(out, 'JPEG', quality=75) else: return img - #if isinstance(self.regex, basestring): + # if isinstance(self.regex, basestring): # self.regex = re.compile(regex) diff --git a/apps/converter/conf/settings.py b/apps/converter/conf/settings.py index e9dcad1eaa..41e4d5b69d 100644 --- a/apps/converter/conf/settings.py +++ b/apps/converter/conf/settings.py @@ -1,4 +1,4 @@ -'''Configuration options for the converter app''' +"""Configuration options for the converter app""" from django.utils.translation import ugettext_lazy as _ @@ -14,9 +14,9 @@ register_settings( {'name': u'GM_SETTINGS', 'global_name': u'CONVERTER_GM_SETTINGS', 'default': u''}, {'name': u'GRAPHICS_BACKEND', 'global_name': u'CONVERTER_GRAPHICS_BACKEND', 'default': u'converter.backends.python', 'description': _(u'Graphics conversion backend to use. Options are: converter.backends.imagemagick, converter.backends.graphicsmagick and converter.backends.python.')}, {'name': u'LIBREOFFICE_PATH', 'global_name': u'CONVERTER_LIBREOFFICE_PATH', 'default': u'/usr/bin/libreoffice', 'exists': True, 'description': _(u'Path to the libreoffice program.')}, - - #{'name': u'OCR_OPTIONS', 'global_name': u'CONVERTER_OCR_OPTIONS', 'default': u'-colorspace Gray -depth 8 -resample 200x200'}, - #{'name': u'HIGH_QUALITY_OPTIONS', 'global_name': u'CONVERTER_HIGH_QUALITY_OPTIONS', 'default': u'-density 400'}, - #{'name': u'PRINT_QUALITY_OPTIONS', 'global_name': u'CONVERTER_PRINT_QUALITY_OPTIONS', 'default': u'-density 500'}, + + # {'name': u'OCR_OPTIONS', 'global_name': u'CONVERTER_OCR_OPTIONS', 'default': u'-colorspace Gray -depth 8 -resample 200x200'}, + # {'name': u'HIGH_QUALITY_OPTIONS', 'global_name': u'CONVERTER_HIGH_QUALITY_OPTIONS', 'default': u'-density 400'}, + # {'name': u'PRINT_QUALITY_OPTIONS', 'global_name': u'CONVERTER_PRINT_QUALITY_OPTIONS', 'default': u'-density 500'}, ] ) diff --git a/apps/converter/office_converter.py b/apps/converter/office_converter.py index 3ffab6d26b..2ac1c13a55 100644 --- a/apps/converter/office_converter.py +++ b/apps/converter/office_converter.py @@ -1,16 +1,14 @@ from __future__ import absolute_import +import logging import os import subprocess -import logging -from mimetype.api import get_mimetype from common.conf.settings import TEMPORARY_DIRECTORY -from common.utils import id_generator +from mimetype.api import get_mimetype from .conf.settings import LIBREOFFICE_PATH -from .exceptions import (OfficeConversionError, - OfficeBackendError, UnknownFileFormat) +from .exceptions import OfficeBackendError, UnknownFileFormat CACHED_FILE_SUFFIX = u'_office_converter' @@ -51,7 +49,6 @@ CONVERTER_OFFICE_FILE_MIMETYPES = [ u'text/rtf', ] - logger = logging.getLogger(__name__) @@ -146,4 +143,3 @@ class OfficeConverterBackendDirect(object): raise OfficeBackendError(msg) except Exception, msg: logger.error('Unhandled exception', exc_info=msg) - diff --git a/apps/converter/tests.py b/apps/converter/tests.py deleted file mode 100644 index 3b31148896..0000000000 --- a/apps/converter/tests.py +++ /dev/null @@ -1,22 +0,0 @@ -""" -This file demonstrates two different styles of tests (one doctest and one -unittest). These will both pass when you run "manage.py test". - -Replace these with more appropriate tests for your application. -""" - -from django.test import TestCase - -class SimpleTest(TestCase): - def test_basic_addition(self): - """ - Tests that 1 + 1 always equals 2. - """ - self.failUnlessEqual(1 + 1, 2) - -__test__ = {"doctest": """ -Another way to test that 1 + 1 is equal to 2. - ->>> 1 + 1 == 2 -True -"""} diff --git a/apps/converter/utils.py b/apps/converter/utils.py index 6d99b15ac6..88994ed211 100644 --- a/apps/converter/utils.py +++ b/apps/converter/utils.py @@ -1,6 +1,5 @@ import os -from django.core.exceptions import ImproperlyConfigured from django.utils.importlib import import_module diff --git a/apps/project_tools/api.py b/apps/project_tools/api.py index d8e66ab7d0..684c453066 100644 --- a/apps/project_tools/api.py +++ b/apps/project_tools/api.py @@ -4,9 +4,10 @@ from . import tool_link tool_items = [] + def register_tool(link): tool_items.append(link) - + # Append the link's children_view_regex to the tool main menu children view regex tool_link.setdefault('children_view_regex', []) tool_link['children_view_regex'].extend(link.get('children_view_regex', [])) diff --git a/apps/project_tools/views.py b/apps/project_tools/views.py index 61693a100c..d719864686 100644 --- a/apps/project_tools/views.py +++ b/apps/project_tools/views.py @@ -1,6 +1,6 @@ from __future__ import absolute_import -from django.shortcuts import render_to_response, get_object_or_404 +from django.shortcuts import render_to_response from django.template import RequestContext from django.utils.translation import ugettext_lazy as _ diff --git a/apps/sources/__init__.py b/apps/sources/__init__.py index 359015103b..df5e04d32b 100644 --- a/apps/sources/__init__.py +++ b/apps/sources/__init__.py @@ -45,16 +45,16 @@ register_links(StagingFile, [staging_file_delete]) register_links(SourceTransformation, [setup_source_transformation_edit, setup_source_transformation_delete]) -#register_links(['setup_web_form_list', 'setup_staging_folder_list', 'setup_watch_folder_list', 'setup_source_create'], [setup_web_form_list, setup_staging_folder_list, setup_watch_folder_list], menu_name='form_header') +# register_links(['setup_web_form_list', 'setup_staging_folder_list', 'setup_watch_folder_list', 'setup_source_create'], [setup_web_form_list, setup_staging_folder_list, setup_watch_folder_list], menu_name='form_header') register_links(['setup_web_form_list', 'setup_staging_folder_list', 'setup_watch_folder_list', 'setup_source_create'], [setup_web_form_list, setup_staging_folder_list], menu_name='form_header') -#register_links(WebForm, [setup_web_form_list, setup_staging_folder_list, setup_watch_folder_list], menu_name='form_header') +# register_links(WebForm, [setup_web_form_list, setup_staging_folder_list, setup_watch_folder_list], menu_name='form_header') register_links(WebForm, [setup_web_form_list, setup_staging_folder_list], menu_name='form_header') register_links(WebForm, [setup_source_transformation_list, setup_source_edit, setup_source_delete]) register_links(['setup_web_form_list', 'setup_staging_folder_list', 'setup_watch_folder_list', 'setup_source_edit', 'setup_source_delete', 'setup_source_create'], [setup_sources, setup_source_create], menu_name='sidebar') -#register_links(StagingFolder, [setup_web_form_list, setup_staging_folder_list, setup_watch_folder_list], menu_name='form_header') +# register_links(StagingFolder, [setup_web_form_list, setup_staging_folder_list, setup_watch_folder_list], menu_name='form_header') register_links(StagingFolder, [setup_web_form_list, setup_staging_folder_list], menu_name='form_header') register_links(StagingFolder, [setup_source_transformation_list, setup_source_edit, setup_source_delete]) @@ -69,7 +69,7 @@ register_links(['setup_source_transformation_create', 'setup_source_transformati 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'] register_model_list_columns(StagingFile, [ - {'name':_(u'thumbnail'), 'attribute': + {'name': _(u'thumbnail'), 'attribute': encapsulate(lambda x: staging_file_thumbnail(x)) }, ]) diff --git a/apps/sources/compressed_file.py b/apps/sources/compressed_file.py index be6b4decf3..6e2a545e51 100644 --- a/apps/sources/compressed_file.py +++ b/apps/sources/compressed_file.py @@ -20,5 +20,5 @@ class CompressedFile(object): except zipfile.BadZipfile: raise NotACompressedFile - #def close(self): - # self.file_object.close() + # def close(self): + # self.file_object.close() diff --git a/apps/sources/management/commands/bulk_upload.py b/apps/sources/management/commands/bulk_upload.py index 8fa11f652e..97a415ab34 100644 --- a/apps/sources/management/commands/bulk_upload.py +++ b/apps/sources/management/commands/bulk_upload.py @@ -1,17 +1,17 @@ from __future__ import absolute_import +from optparse import make_option import os import sys -from optparse import make_option -from django.core.management.base import BaseCommand, CommandError, LabelCommand +from django.core.management.base import CommandError, LabelCommand from django.utils.simplejson import loads -from metadata.api import convert_dict_to_dict_list from documents.models import DocumentType +from metadata.api import convert_dict_to_dict_list from ...models import OutOfProcess -from ...compressed_file import CompressedFile, NotACompressedFile +from ...compressed_file import NotACompressedFile class Command(LabelCommand): @@ -76,6 +76,6 @@ class Command(LabelCommand): def _confirm(interactive): if not interactive: return 'yes' - return raw_input('You have requested to bulk upload a number of documents from a compressed file.\n' + return raw_input('You have requested to bulk upload a number of documents from a compressed file.\n' 'Are you sure you want to do this?\n' 'Type \'yes\' to continue, or any other value to cancel: ') diff --git a/apps/sources/models.py b/apps/sources/models.py index 9156b30b71..bfb8f994a0 100644 --- a/apps/sources/models.py +++ b/apps/sources/models.py @@ -12,11 +12,10 @@ from django.db import transaction from converter.api import get_available_transformations_choices from converter.literals import DIMENSION_SEPARATOR -from documents.models import DocumentType, Document +from documents.models import Document from documents.events import HISTORY_DOCUMENT_CREATED from document_indexing.api import update_indexes from history.api import create_history -from metadata.models import MetadataType from metadata.api import save_metadata_list from scheduler.api import register_interval_job, remove_job from acls.utils import apply_default_acls @@ -37,7 +36,6 @@ class BaseModel(models.Model): enabled = models.BooleanField(default=True, verbose_name=_(u'enabled')) whitelist = models.TextField(blank=True, verbose_name=_(u'whitelist'), editable=False) blacklist = models.TextField(blank=True, verbose_name=_(u'blacklist'), editable=False) - #document_type = models.ForeignKey(DocumentType, blank=True, null=True, verbose_name=_(u'document type'), help_text=(u'Optional document type to be applied to documents uploaded from this source.')) @classmethod def class_fullname(cls): @@ -127,7 +125,7 @@ class BaseModel(models.Model): transformations, errors = self.get_transformation_list() new_version.apply_default_transformations(transformations) - #TODO: new HISTORY for version updates + # TODO: new HISTORY for version updates if metadata_dict_list and new_document: # Only do for new documents @@ -174,22 +172,6 @@ class StagingFolder(InteractiveBaseModel): verbose_name = _(u'staging folder') verbose_name_plural = _(u'staging folders') -""" -class SourceMetadata(models.Model): - content_type = models.ForeignKey(ContentType) - object_id = models.PositiveIntegerField() - content_object = generic.GenericForeignKey('content_type', 'object_id') - metadata_type = models.ForeignKey(MetadataType, verbose_name=_(u'metadata type')) - value = models.CharField(max_length=256, blank=True, verbose_name=_(u'value')) - - def __unicode__(self): - return self.source - - class Meta: - verbose_name = _(u'source metadata') - verbose_name_plural = _(u'sources metadata') -""" - class WebForm(InteractiveBaseModel): is_interactive = True @@ -197,7 +179,7 @@ class WebForm(InteractiveBaseModel): default_icon = SOURCE_ICON_DISK uncompress = models.CharField(max_length=1, choices=SOURCE_INTERACTIVE_UNCOMPRESS_CHOICES, verbose_name=_(u'uncompress'), help_text=_(u'Whether to expand or not compressed archives.')) - #Default path + # Default path class Meta(InteractiveBaseModel.Meta): verbose_name = _(u'web form') @@ -276,7 +258,7 @@ class SourceTransformation(models.Model): transformations = SourceTransformationManager() def __unicode__(self): - #return u'"%s" for %s' % (self.get_transformation_display(), unicode(self.content_object)) + # return u'"%s" for %s' % (self.get_transformation_display(), unicode(self.content_object)) return self.get_transformation_display() class Meta: diff --git a/apps/sources/staging.py b/apps/sources/staging.py index b62d78ced1..da06d140b1 100644 --- a/apps/sources/staging.py +++ b/apps/sources/staging.py @@ -1,41 +1,24 @@ from __future__ import absolute_import import errno -import os import hashlib +import os -from django.core.files.base import File from django.core.exceptions import ObjectDoesNotExist -from django.utils.translation import ugettext +from django.core.files.base import File from django.utils.encoding import smart_str +from django.utils.translation import ugettext -from documents.conf.settings import THUMBNAIL_SIZE - -from mimetype.api import (get_icon_file_path, get_error_icon_file_path, - get_mimetype) from converter.api import convert, cache_cleanup from converter.exceptions import UnknownFileFormat, UnkownConvertError +from documents.conf.settings import THUMBNAIL_SIZE +from mimetype.api import (get_icon_file_path, get_error_icon_file_path, + get_mimetype) DEFAULT_STAGING_DIRECTORY = u'/tmp' 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): @@ -51,7 +34,7 @@ def _return_new_class(): def create_staging_file_class(request, directory_path, source=None): cls = _return_new_class() - #cls.set_path(evaluate_user_staging_path(request, source)) + # cls.set_path(evaluate_user_staging_path(request, source)) cls.set_path(directory_path) if source is not None: cls.set_source(source) @@ -143,7 +126,7 @@ class StagingFile(object): def get_image(self, size, transformations): try: return self.get_valid_image(size=size, transformations=transformations) - #return convert(self.filepath, size=size, cleanup_files=False, transformations=transformations) + # return convert(self.filepath, size=size, cleanup_files=False, transformations=transformations) except UnknownFileFormat: mimetype, encoding = get_mimetype(open(self.filepath, 'rb'), self.filepath) return get_icon_file_path(mimetype) diff --git a/apps/sources/utils.py b/apps/sources/utils.py index 79a2c80fc4..326cccee1b 100644 --- a/apps/sources/utils.py +++ b/apps/sources/utils.py @@ -18,13 +18,9 @@ def accept_item(value, whitelist, blacklist, default_accept=True): # note the order for reject, item_list in ([False, whitelist], [True, blacklist]): - #print 'item_list: %s' % item_list - #print 'reject: %s' % reject for okpattern in item_list: - #print 'okpattern: %s' % okpattern if re.findall(okpattern.replace('*', '\S+'), value, re.I): # match! - #print 'MATCH' if reject: return False else: @@ -35,6 +31,5 @@ def accept_item(value, whitelist, blacklist, default_accept=True): def validate_whitelist_blacklist(value, whitelist, blacklist): - #print 'blacklist', blacklist if not accept_item(value, whitelist, blacklist): raise ValidationError(ugettext(u'Whitelist Blacklist validation error.')) diff --git a/apps/sources/views.py b/apps/sources/views.py index 430fbc058d..5581fe5008 100644 --- a/apps/sources/views.py +++ b/apps/sources/views.py @@ -178,7 +178,8 @@ def upload_interactive(request, source_type=None, source_id=None, document_pk=No new_filename = get_form_filename(form) - result = web_form.upload_file(request.FILES['file'], + result = web_form.upload_file( + request.FILES['file'], new_filename, use_file_name=form.cleaned_data.get('use_file_name', False), document_type=document_type, expand=expand, @@ -191,13 +192,13 @@ def upload_interactive(request, source_type=None, source_id=None, document_pk=No messages.success(request, _(u'New document version uploaded successfully.')) return HttpResponseRedirect(reverse('document_version_list', args=[document.pk])) else: - if result['is_compressed'] == None: + if result['is_compressed'] is None: messages.success(request, _(u'File uploaded successfully.')) - if result['is_compressed'] == True: + if result['is_compressed'] is True: messages.success(request, _(u'File uncompressed successfully and uploaded as individual files.')) - if result['is_compressed'] == False: + if result['is_compressed'] is False: messages.warning(request, _(u'File was not a compressed file, uploaded as it was.')) return HttpResponseRedirect(request.get_full_path()) @@ -253,7 +254,8 @@ def upload_interactive(request, source_type=None, source_id=None, document_pk=No new_filename = get_form_filename(form) - result = staging_folder.upload_file(staging_file.upload(), + result = staging_folder.upload_file( + staging_file.upload(), new_filename, use_file_name=form.cleaned_data.get('use_file_name', False), document_type=document_type, expand=expand, @@ -265,13 +267,13 @@ def upload_interactive(request, source_type=None, source_id=None, document_pk=No if document: messages.success(request, _(u'Document version from staging file: %s, uploaded successfully.') % staging_file.filename) else: - if result['is_compressed'] == None: + if result['is_compressed'] is None: messages.success(request, _(u'Staging file: %s, uploaded successfully.') % staging_file.filename) - if result['is_compressed'] == True: + if result['is_compressed'] is True: messages.success(request, _(u'Staging file: %s, uncompressed successfully and uploaded as individual files.') % staging_file.filename) - if result['is_compressed'] == False: + if result['is_compressed'] is False: messages.warning(request, _(u'Staging file: %s, was not compressed, uploaded as a single file.') % staging_file.filename) if staging_folder.delete_after_upload: @@ -621,7 +623,7 @@ def setup_source_transformation_list(request, source_type, source_id): {'name': _(u'order'), 'attribute': 'order'}, {'name': _(u'transformation'), 'attribute': encapsulate(lambda x: x.get_transformation_display())}, {'name': _(u'arguments'), 'attribute': 'arguments'} - ], + ], 'hide_link': True, 'hide_object': True, }