diff --git a/apps/converter/__init__.py b/apps/converter/__init__.py index 331738373a..6ab5029f01 100644 --- a/apps/converter/__init__.py +++ b/apps/converter/__init__.py @@ -2,10 +2,6 @@ from django.utils.translation import ugettext_lazy as _ from navigation.api import register_sidebar_template -TRANFORMATION_CHOICES = { - u'rotate': u'-rotate %(degrees)d' -} - formats_list = {'text': _('file formats'), 'view': 'formats_list', 'famfam': 'pictures'} register_sidebar_template(['formats_list'], 'converter_file_formats_help.html') diff --git a/apps/converter/api.py b/apps/converter/api.py index d7595de8c3..9de0ed737e 100644 --- a/apps/converter/api.py +++ b/apps/converter/api.py @@ -3,62 +3,28 @@ import subprocess from django.utils.importlib import import_module from django.template.defaultfilters import slugify - -from converter.conf.settings import UNPAPER_PATH -from converter.conf.settings import OCR_OPTIONS -from converter.conf.settings import DEFAULT_OPTIONS -from converter.conf.settings import LOW_QUALITY_OPTIONS -from converter.conf.settings import HIGH_QUALITY_OPTIONS -from converter.conf.settings import PRINT_QUALITY_OPTIONS -from converter.conf.settings import GRAPHICS_BACKEND -from converter.conf.settings import UNOCONV_PATH - -from converter.exceptions import UnpaperError, OfficeConversionError +from django.core.exceptions import ImproperlyConfigured from common import TEMPORARY_DIRECTORY from documents.utils import document_save_to_temp_dir -DEFAULT_ZOOM_LEVEL = 100 -DEFAULT_ROTATION = 0 -DEFAULT_PAGE_INDEX_NUMBER = 0 -DEFAULT_FILE_FORMAT = u'jpg' -DEFAULT_OCR_FILE_FORMAT = u'tif' - -QUALITY_DEFAULT = u'quality_default' -QUALITY_LOW = u'quality_low' -QUALITY_HIGH = u'quality_high' -QUALITY_PRINT = u'quality_print' - -QUALITY_SETTINGS = { - QUALITY_DEFAULT: DEFAULT_OPTIONS, - QUALITY_LOW: LOW_QUALITY_OPTIONS, - QUALITY_HIGH: HIGH_QUALITY_OPTIONS, - QUALITY_PRINT: PRINT_QUALITY_OPTIONS -} +from converter.conf.settings import UNPAPER_PATH +from converter.conf.settings import OCR_OPTIONS +from converter.conf.settings import UNOCONV_PATH +from converter.exceptions import UnpaperError, OfficeConversionError +from converter.utils import load_backend +from converter.literals import DEFAULT_PAGE_INDEX_NUMBER, \ + DEFAULT_OCR_FILE_FORMAT, QUALITY_DEFAULT, DEFAULT_ZOOM_LEVEL, \ + DEFAULT_ROTATION, DEFAULT_FILE_FORMAT, QUALITY_PRINT CONVERTER_OFFICE_FILE_EXTENSIONS = [ u'ods', u'docx', u'doc' ] - -def _lazy_load(fn): - _cached = [] - - def _decorated(): - if not _cached: - _cached.append(fn()) - return _cached[0] - return _decorated - - -@_lazy_load -def _get_backend(): - return import_module(GRAPHICS_BACKEND) - try: - backend = _get_backend() -except ImportError: - raise ImportError(u'Missing or incorrect converter backend: %s' % GRAPHICS_BACKEND) + backend = load_backend().ConverterClass() +except ImproperlyConfigured: + raise ImproperlyConfigured(u'Missing or incorrect converter backend: %s' % GRAPHICS_BACKEND) def cleanup(filename): @@ -173,7 +139,7 @@ def convert(input_filepath, *args, **kwargs): if format == u'jpg': extra_options += u' -quality 85' try: - backend.execute_convert(input_filepath=input_arg, arguments=extra_options, output_filepath=u'%s:%s' % (file_format, output_filepath), quality=quality) + backend.convert_file(input_filepath=input_arg, arguments=extra_options, output_filepath=u'%s:%s' % (file_format, output_filepath), quality=quality) finally: if cleanup_files: cleanup(input_filepath) @@ -185,7 +151,7 @@ def convert(input_filepath, *args, **kwargs): def get_page_count(input_filepath): try: - return len(backend.execute_identify(unicode(input_filepath)).splitlines()) + return len(backend.identify_file(unicode(input_filepath)).splitlines()) except: #TODO: send to other page number identifying program return 1 @@ -195,7 +161,7 @@ def get_document_dimensions(document, *args, **kwargs): document_filepath = create_image_cache_filename(document.checksum, *args, **kwargs) if os.path.exists(document_filepath): options = [u'-format', u'%w %h'] - return [int(dimension) for dimension in backend.execute_identify(unicode(document_filepath), options).split()] + return [int(dimension) for dimension in backend.identify_file(unicode(document_filepath), options).split()] else: return [0, 0] @@ -219,13 +185,13 @@ def convert_document_for_ocr(document, page=DEFAULT_PAGE_INDEX_NUMBER, file_form transformation_string, warnings = document_page.get_transformation_string() #Apply default transformations - backend.execute_convert(input_filepath=input_arg, quality=QUALITY_HIGH, arguments=transformation_string, output_filepath=transformation_output_file) + backend.convert_file(input_filepath=input_arg, quality=QUALITY_HIGH, arguments=transformation_string, output_filepath=transformation_output_file) #Do OCR operations - backend.execute_convert(input_filepath=transformation_output_file, arguments=OCR_OPTIONS, output_filepath=unpaper_input_file) + backend.convert_file(input_filepath=transformation_output_file, arguments=OCR_OPTIONS, output_filepath=unpaper_input_file) # Process by unpaper execute_unpaper(input_filepath=unpaper_input_file, output_filepath=unpaper_output_file) # Convert to tif - backend.execute_convert(input_filepath=unpaper_output_file, output_filepath=convert_output_file) + backend.convert_file(input_filepath=unpaper_output_file, output_filepath=convert_output_file) finally: cleanup(transformation_output_file) cleanup(unpaper_input_file) diff --git a/apps/converter/backends/__init__.py b/apps/converter/backends/__init__.py index e69de29bb2..1d81dd8149 100644 --- a/apps/converter/backends/__init__.py +++ b/apps/converter/backends/__init__.py @@ -0,0 +1,43 @@ +class ConverterBase(object): + """ + Base class that all backend classes must inherit + """ + + def identify_file(self, input_filepath, *args, **kwargs): + raise NotImplementedError("Your %s class has not defined a identify_file() method, which is required." % self.__class__.__name__) + + def identify_document(self, document, *args, **kwargs): + raise NotImplementedError("Your %s class has not defined a identify_document() method, which is required." % self.__class__.__name__) + + def convert_file(self, input_filepath, *args, **kwargs): + raise NotImplementedError("Your %s class has not defined a convert_file() method, which is required." % self.__class__.__name__) + + def convert_document(self, document, *args, **kwargs): + raise NotImplementedError("Your %s class has not defined a convert_document() method, which is required." % self.__class__.__name__) + + def get_format_list(self): + raise NotImplementedError("Your %s class has not defined a get_format_list() method, which is required." % self.__class__.__name__) + + def get_available_transformations(self): + raise NotImplementedError("Your %s class has not defined a get_available_transformations() method, which is required." % self.__class__.__name__) + + def get_available_transformations_labels(self): + return ([(name, data['label']) for name, data in self.get_available_transformations().items()]) + + def get_transformation_string(self, transformation_list): + transformations = [] + warnings = [] + transformation_choices = self.get_available_transformations() + for transformation in transformation_list: + try: + if transformation['transformation'] in transformation_choices: + transformations.append( + transformation_choices[transformation['transformation']]['command_line'] % eval( + transformation['arguments'] + ) + ) + except Exception, e: + warnings.append(e) + + return u' '.join(transformations), warnings + diff --git a/apps/converter/backends/graphicsmagick.py b/apps/converter/backends/graphicsmagick.py deleted file mode 100644 index 360a24a58b..0000000000 --- a/apps/converter/backends/graphicsmagick.py +++ /dev/null @@ -1,71 +0,0 @@ -import subprocess -import re - -from converter.conf.settings import GM_PATH -from converter.conf.settings import GM_SETTINGS -from converter.api import QUALITY_DEFAULT, QUALITY_SETTINGS -from converter.exceptions import ConvertError, UnknownFormat, IdentifyError - -CONVERTER_ERROR_STRING_NO_DECODER = u'No decode delegate for this image format' -CONVERTER_ERROR_STARTS_WITH = u'starts with' - - -def execute_identify(input_filepath, arguments=None): - command = [] - command.append(unicode(GM_PATH)) - command.append(u'identify') - if arguments: - command.extend(arguments) - command.append(unicode(input_filepath)) - proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) - return_code = proc.wait() - if return_code != 0: - raise IdentifyError(proc.stderr.readline()) - return proc.stdout.read() - - -def execute_convert(input_filepath, output_filepath, quality=QUALITY_DEFAULT, arguments=None): - command = [] - command.append(unicode(GM_PATH)) - command.append(u'convert') - command.extend(unicode(QUALITY_SETTINGS[quality]).split()) - command.extend(unicode(GM_SETTINGS).split()) - command.append(unicode(input_filepath)) - if arguments: - command.extend(unicode(arguments).split()) - command.append(unicode(output_filepath)) - 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 - 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 - raise UnknownFormat - else: - raise ConvertError(error_line) - - -def get_format_list(): - """ - Call GraphicsMagick to parse all of it's supported file formats, and - return a list of the names and descriptions - """ - format_regex = re.compile(' *([A-Z0-9]+)[*]? +([A-Z0-9]+) +([rw\-+]+) *(.*).*') - formats = [] - command = [] - command.append(unicode(GM_PATH)) - command.append(u'convert') - command.append(u'-list') - command.append(u'formats') - proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) - 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], fields[0][3])) - - return formats diff --git a/apps/converter/backends/graphicsmagick/__init__.py b/apps/converter/backends/graphicsmagick/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/converter/backends/graphicsmagick/base.py b/apps/converter/backends/graphicsmagick/base.py new file mode 100644 index 0000000000..5570650038 --- /dev/null +++ b/apps/converter/backends/graphicsmagick/base.py @@ -0,0 +1,85 @@ +import subprocess +import re + +from django.utils.translation import ugettext_lazy as _ + +from converter.conf.settings import GM_PATH +from converter.conf.settings import GM_SETTINGS +from converter.literals import QUALITY_DEFAULT, QUALITY_SETTINGS +from converter.exceptions import ConvertError, UnknownFormat, IdentifyError +from converter.backends import ConverterBase + +CONVERTER_ERROR_STRING_NO_DECODER = u'No decode delegate for this image format' +CONVERTER_ERROR_STARTS_WITH = u'starts with' + + +class ConverterClass(ConverterBase): + def identify_file(self, input_filepath, arguments=None): + command = [] + command.append(unicode(GM_PATH)) + command.append(u'identify') + if arguments: + command.extend(arguments) + command.append(unicode(input_filepath)) + proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + return_code = proc.wait() + if return_code != 0: + raise IdentifyError(proc.stderr.readline()) + return proc.stdout.read() + + + def convert_file(self, input_filepath, output_filepath, quality=QUALITY_DEFAULT, arguments=None): + command = [] + command.append(unicode(GM_PATH)) + command.append(u'convert') + command.extend(unicode(QUALITY_SETTINGS[quality]).split()) + command.extend(unicode(GM_SETTINGS).split()) + command.append(unicode(input_filepath)) + if arguments: + command.extend(unicode(arguments).split()) + command.append(unicode(output_filepath)) + 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 + 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 + raise UnknownFormat + else: + raise ConvertError(error_line) + + + def get_format_list(self): + """ + Call GraphicsMagick to parse all of it's supported file formats, and + return a list of the names and descriptions + """ + format_regex = re.compile(' *([A-Z0-9]+)[*]? +([A-Z0-9]+) +([rw\-+]+) *(.*).*') + formats = [] + command = [] + command.append(unicode(GM_PATH)) + command.append(u'convert') + command.append(u'-list') + command.append(u'formats') + proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + 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], fields[0][3])) + + return formats + + + def get_available_transformations(self): + return { + 'rotate': { + 'label': _(u'Rotate [degrees]'), + 'arguments': [{'name': 'degrees'}], + 'command_line': u'-rotate %(degrees)d' + } + } diff --git a/apps/converter/backends/imagemagick.py b/apps/converter/backends/imagemagick.py deleted file mode 100644 index 4542ebdeba..0000000000 --- a/apps/converter/backends/imagemagick.py +++ /dev/null @@ -1,68 +0,0 @@ -import subprocess -import re - -from converter.conf.settings import IM_IDENTIFY_PATH -from converter.conf.settings import IM_CONVERT_PATH -from converter.api import QUALITY_DEFAULT, QUALITY_SETTINGS -from converter.exceptions import ConvertError, UnknownFormat, \ - IdentifyError - -CONVERTER_ERROR_STRING_NO_DECODER = u'no decode delegate for this image format' - - -def execute_identify(input_filepath, arguments=None): - command = [] - command.append(unicode(IM_IDENTIFY_PATH)) - if arguments: - command.extend(arguments) - command.append(unicode(input_filepath)) - - proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) - return_code = proc.wait() - if return_code != 0: - raise IdentifyError(proc.stderr.readline()) - return proc.stdout.read() - - -def execute_convert(input_filepath, output_filepath, quality=QUALITY_DEFAULT, arguments=None): - command = [] - command.append(unicode(IM_CONVERT_PATH)) - command.extend(unicode(QUALITY_SETTINGS[quality]).split()) - command.append(unicode(input_filepath)) - if arguments: - command.extend(unicode(arguments).split()) - command.append(unicode(output_filepath)) - 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 - 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 - raise UnknownFormat - else: - raise ConvertError(error_line) - - -def get_format_list(): - """ - Call ImageMagick to parse all of it's supported file formats, and - return a list of the names and descriptions - """ - format_regex = re.compile(' *([A-Z0-9]+)[*]? +([A-Z0-9]+) +([rw\-+]+) *(.*).*') - formats = [] - command = [] - command.append(unicode(IM_CONVERT_PATH)) - command.append(u'-list') - command.append(u'format') - proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) - 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], fields[0][3])) - - return formats diff --git a/apps/converter/backends/imagemagick/__init__.py b/apps/converter/backends/imagemagick/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/converter/backends/imagemagick/base.py b/apps/converter/backends/imagemagick/base.py new file mode 100644 index 0000000000..e2b8c40fdd --- /dev/null +++ b/apps/converter/backends/imagemagick/base.py @@ -0,0 +1,82 @@ +import subprocess +import re + +from django.utils.translation import ugettext_lazy as _ + +from converter.conf.settings import IM_IDENTIFY_PATH +from converter.conf.settings import IM_CONVERT_PATH +from converter.api import QUALITY_DEFAULT, QUALITY_SETTINGS +from converter.exceptions import ConvertError, UnknownFormat, \ + IdentifyError +from converter.backends import ConverterBase + +CONVERTER_ERROR_STRING_NO_DECODER = u'no decode delegate for this image format' + + +class ConverterClass(ConverterBase): + def identify_file(self, input_filepath, arguments=None): + command = [] + command.append(unicode(IM_IDENTIFY_PATH)) + if arguments: + command.extend(arguments) + command.append(unicode(input_filepath)) + + proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + return_code = proc.wait() + if return_code != 0: + raise IdentifyError(proc.stderr.readline()) + return proc.stdout.read() + + + def convert_file(self, input_filepath, output_filepath, quality=QUALITY_DEFAULT, arguments=None): + command = [] + command.append(unicode(IM_CONVERT_PATH)) + command.extend(unicode(QUALITY_SETTINGS[quality]).split()) + command.append(unicode(input_filepath)) + if arguments: + command.extend(unicode(arguments).split()) + command.append(unicode(output_filepath)) + 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 + 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 + raise UnknownFormat + else: + raise ConvertError(error_line) + + + def get_format_list(self): + """ + Call ImageMagick to parse all of it's supported file formats, and + return a list of the names and descriptions + """ + format_regex = re.compile(' *([A-Z0-9]+)[*]? +([A-Z0-9]+) +([rw\-+]+) *(.*).*') + formats = [] + command = [] + command.append(unicode(IM_CONVERT_PATH)) + command.append(u'-list') + command.append(u'format') + proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + 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], fields[0][3])) + + return formats + + + def get_available_transformations(self): + return { + 'rotate': { + 'label': _(u'Rotate [degrees]'), + 'arguments': [{'name': 'degrees'}], + 'command_line': u'-rotate %(degrees)d' + } + } diff --git a/apps/converter/literals.py b/apps/converter/literals.py new file mode 100644 index 0000000000..403400d229 --- /dev/null +++ b/apps/converter/literals.py @@ -0,0 +1,22 @@ +from converter.conf.settings import DEFAULT_OPTIONS +from converter.conf.settings import LOW_QUALITY_OPTIONS +from converter.conf.settings import HIGH_QUALITY_OPTIONS +from converter.conf.settings import PRINT_QUALITY_OPTIONS + +DEFAULT_ZOOM_LEVEL = 100 +DEFAULT_ROTATION = 0 +DEFAULT_PAGE_INDEX_NUMBER = 0 +DEFAULT_FILE_FORMAT = u'jpg' +DEFAULT_OCR_FILE_FORMAT = u'tif' + +QUALITY_DEFAULT = u'quality_default' +QUALITY_LOW = u'quality_low' +QUALITY_HIGH = u'quality_high' +QUALITY_PRINT = u'quality_print' + +QUALITY_SETTINGS = { + QUALITY_DEFAULT: DEFAULT_OPTIONS, + QUALITY_LOW: LOW_QUALITY_OPTIONS, + QUALITY_HIGH: HIGH_QUALITY_OPTIONS, + QUALITY_PRINT: PRINT_QUALITY_OPTIONS +} diff --git a/apps/converter/utils.py b/apps/converter/utils.py index c5a4e7e55b..5fc106a940 100644 --- a/apps/converter/utils.py +++ b/apps/converter/utils.py @@ -1,6 +1,10 @@ +import os + +from django.core.exceptions import ImproperlyConfigured +from django.utils.importlib import import_module + + #http://stackoverflow.com/questions/123198/how-do-i-copy-a-file-in-python - - def copyfile(source, dest, buffer_size=1024 * 1024): """ Copy a file from source to dest. source and dest @@ -21,3 +25,50 @@ def copyfile(source, dest, buffer_size=1024 * 1024): source.close() dest.close() + + +def _lazy_load(fn): + _cached = [] + + def _decorated(): + if not _cached: + _cached.append(fn()) + return _cached[0] + return _decorated + + +@_lazy_load +def load_backend(): + from converter.conf.settings import GRAPHICS_BACKEND as backend_name + + try: + module = import_module('.base', 'converter.backends.%s' % backend_name) + import warnings + warnings.warn( + "Short names for CONVERTER_BACKEND are deprecated; prepend with 'converter.backends.'", + PendingDeprecationWarning + ) + return module + except ImportError, e: + # Look for a fully qualified converter backend name + try: + return import_module('.base', backend_name) + except ImportError, e_user: + # The converter backend wasn't found. Display a helpful error message + # listing all possible (built-in) converter backends. + backend_dir = os.path.join(os.path.dirname(__file__), 'backends') + try: + available_backends = [f for f in os.listdir(backend_dir) + if os.path.isdir(os.path.join(backend_dir, f)) + and not f.startswith('.')] + except EnvironmentError: + available_backends = [] + available_backends.sort() + if backend_name not in available_backends: + error_msg = ("%r isn't an available converter backend. \n" + + "Try using converter.backends.XXX, where XXX is one of:\n %s\n" + + "Error was: %s") % \ + (backend_name, ", ".join(map(repr, available_backends)), e_user) + raise ImproperlyConfigured(error_msg) + else: + raise # If there's some other error, this must be an error in Mayan itself. diff --git a/apps/documents/conf/settings.py b/apps/documents/conf/settings.py index 7a253f52de..4c7749624c 100644 --- a/apps/documents/conf/settings.py +++ b/apps/documents/conf/settings.py @@ -18,10 +18,6 @@ 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', @@ -31,8 +27,6 @@ register_settings( {'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}, # 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'}, diff --git a/apps/documents/models.py b/apps/documents/models.py index 96d988bfdb..e0df918fc1 100644 --- a/apps/documents/models.py +++ b/apps/documents/models.py @@ -12,16 +12,13 @@ from python_magic import magic 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 backend 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.managers import RecentDocumentManager -available_transformations = ([(name, data['label']) for name, data in AVAILABLE_TRANSFORMATIONS.items()]) - def get_filename_from_uuid(instance, filename): """ @@ -263,20 +260,7 @@ class DocumentPage(models.Model): 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 + return backend.get_transformation_string(self.documentpagetransformation_set.values('transformation', 'arguments')) class DocumentPageTransformation(models.Model): @@ -286,7 +270,7 @@ 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=backend.get_available_transformations_labels(), 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}')) def __unicode__(self): diff --git a/apps/documents/urls.py b/apps/documents/urls.py index 4dc99f37de..4a8dcd2d46 100644 --- a/apps/documents/urls.py +++ b/apps/documents/urls.py @@ -1,14 +1,12 @@ from django.conf.urls.defaults import patterns, url -from converter.api import QUALITY_HIGH, QUALITY_PRINT +from converter.literals 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'), diff --git a/apps/sources/models.py b/apps/sources/models.py index 70eaf2d4e4..ffd4211fe6 100644 --- a/apps/sources/models.py +++ b/apps/sources/models.py @@ -4,14 +4,12 @@ from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes import generic from documents.models import DocumentType -from documents.conf.settings import AVAILABLE_TRANSFORMATIONS from documents.managers import RecentDocumentManager from metadata.models import MetadataType +from converter.api import backend from sources.managers import SourceTransformationManager -available_transformations = ([(name, data['label']) for name, data in AVAILABLE_TRANSFORMATIONS.items()]) - SOURCE_UNCOMPRESS_CHOICE_Y = 'y' SOURCE_UNCOMPRESS_CHOICE_N = 'n' SOURCE_UNCOMPRESS_CHOICE_ASK = 'a' @@ -164,7 +162,7 @@ class SourceTransformation(models.Model): object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey('content_type', 'object_id') 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=backend.get_available_transformations_labels(), 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 = SourceTransformationManager() diff --git a/apps/sources/staging.py b/apps/sources/staging.py index c6668455c9..a608f1b30f 100644 --- a/apps/sources/staging.py +++ b/apps/sources/staging.py @@ -8,7 +8,6 @@ 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 DEFAULT_STAGING_DIRECTORY = u'/tmp' @@ -136,13 +135,13 @@ class StagingFile(object): 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) + #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) + #tranformation_string = ' '.join(transformation_list) return tranformation_string, errors