diff --git a/mayan/apps/converter/api.py b/mayan/apps/converter/api.py deleted file mode 100644 index 42ecf485e8..0000000000 --- a/mayan/apps/converter/api.py +++ /dev/null @@ -1,122 +0,0 @@ -from __future__ import unicode_literals - -import hashlib -import logging -import os - -from django.utils.encoding import smart_str - -from common.settings import TEMPORARY_DIRECTORY -from common.utils import fs_cleanup - -from .exceptions import OfficeConversionError, UnknownFileFormat -from .literals import ( - DEFAULT_PAGE_NUMBER, DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION, - DEFAULT_FILE_FORMAT, TRANSFORMATION_CHOICES, TRANSFORMATION_RESIZE, - TRANSFORMATION_ROTATE, TRANSFORMATION_ZOOM, DIMENSION_SEPARATOR -) - -HASH_FUNCTION = lambda x: hashlib.sha256(x).hexdigest() - -logger = logging.getLogger(__name__) - - -def cache_cleanup(input_filepath, *args, **kwargs): - try: - os.remove(create_image_cache_filename(input_filepath, *args, **kwargs)) - except OSError: - pass - - -def create_image_cache_filename(input_filepath, *args, **kwargs): - if input_filepath: - hash_value = HASH_FUNCTION(''.join([HASH_FUNCTION(smart_str(input_filepath)), unicode(args), unicode(kwargs)])) - return os.path.join(TEMPORARY_DIRECTORY, hash_value) - else: - return None - - -def convert(input_filepath, output_filepath=None, cleanup_files=False, mimetype=None, *args, **kwargs): - size = kwargs.get('size') - file_format = kwargs.get('file_format', DEFAULT_FILE_FORMAT) - zoom = kwargs.get('zoom', DEFAULT_ZOOM_LEVEL) - rotation = kwargs.get('rotation', DEFAULT_ROTATION) - page = kwargs.get('page', DEFAULT_PAGE_NUMBER) - transformations = kwargs.get('transformations', []) - - if transformations is None: - transformations = [] - - if output_filepath is None: - output_filepath = create_image_cache_filename(input_filepath, *args, **kwargs) - - if os.path.exists(output_filepath): - return output_filepath - - if office_converter: - try: - office_converter.convert(input_filepath, mimetype=mimetype) - if office_converter.exists: - input_filepath = office_converter.output_filepath - mimetype = 'application/pdf' - else: - # Recycle the already detected mimetype - mimetype = office_converter.mimetype - - except OfficeConversionError: - raise UnknownFileFormat('office converter exception') - - if size: - transformations.append( - { - 'transformation': TRANSFORMATION_RESIZE, - 'arguments': dict(zip(['width', 'height'], size.split(DIMENSION_SEPARATOR))) - } - ) - - if zoom != 100: - transformations.append( - { - 'transformation': TRANSFORMATION_ZOOM, - 'arguments': {'percent': zoom} - } - ) - - if rotation != 0 and rotation != 360: - transformations.append( - { - 'transformation': TRANSFORMATION_ROTATE, - 'arguments': {'degrees': rotation} - } - ) - - try: - backend.convert_file(input_filepath=input_filepath, output_filepath=output_filepath, transformations=transformations, page=page, file_format=file_format, mimetype=mimetype) - finally: - if cleanup_files: - fs_cleanup(input_filepath) - - return output_filepath - - -def get_page_count(input_filepath): - logger.debug('office_converter: %s', office_converter) - if office_converter: - try: - office_converter.convert(input_filepath) - logger.debug('office_converter.exists: %s', office_converter.exists) - if office_converter.exists: - input_filepath = office_converter.output_filepath - - except OfficeConversionError: - raise UnknownFileFormat('office converter exception') - - return backend.get_page_count(input_filepath) - - -def get_available_transformations_choices(): - result = [] - for transformation in backend.get_available_transformations(): - result.append((transformation, TRANSFORMATION_CHOICES[transformation]['label'])) - - return result diff --git a/mayan/apps/converter/office_converter.py b/mayan/apps/converter/office_converter.py deleted file mode 100644 index ceb9288515..0000000000 --- a/mayan/apps/converter/office_converter.py +++ /dev/null @@ -1,149 +0,0 @@ -from __future__ import unicode_literals - -import logging -import os -import subprocess - -from common.settings import TEMPORARY_DIRECTORY -from mimetype.api import get_mimetype - -from .exceptions import OfficeBackendError, UnknownFileFormat -from .settings import LIBREOFFICE_PATH - -CACHED_FILE_SUFFIX = '_office_converter' - -CONVERTER_OFFICE_FILE_MIMETYPES = [ - 'application/msword', - 'application/mswrite', - 'application/mspowerpoint', - 'application/msexcel', - 'application/pgp-keys', - 'application/vnd.ms-excel', - 'application/vnd.ms-excel.addin.macroEnabled.12', - 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', - 'application/vnd.ms-powerpoint', - 'application/vnd.oasis.opendocument.chart', - 'application/vnd.oasis.opendocument.chart-template', - 'application/vnd.oasis.opendocument.formula', - 'application/vnd.oasis.opendocument.formula-template', - 'application/vnd.oasis.opendocument.graphics', - 'application/vnd.oasis.opendocument.graphics-template', - 'application/vnd.oasis.opendocument.image', - 'application/vnd.oasis.opendocument.image-template', - 'application/vnd.oasis.opendocument.presentation', - 'application/vnd.oasis.opendocument.presentation-template', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', - 'application/vnd.openxmlformats-officedocument.presentationml.template', - 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', - 'application/vnd.openxmlformats-officedocument.presentationml.presentation', - 'application/vnd.openxmlformats-officedocument.presentationml.slide', - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', - 'application/vnd.oasis.opendocument.spreadsheet', - 'application/vnd.oasis.opendocument.spreadsheet-template', - 'application/vnd.oasis.opendocument.text', - 'application/vnd.oasis.opendocument.text-master', - 'application/vnd.oasis.opendocument.text-template', - 'application/vnd.oasis.opendocument.text-web', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'application/vnd.ms-office', - 'application/xml', - 'text/x-c', - 'text/x-c++', - 'text/x-pascal', - 'text/x-msdos-batch', - 'text/x-python', - 'text/x-shellscript', - 'text/plain', - 'text/rtf', -] - -logger = logging.getLogger(__name__) - - -class OfficeConverter(object): - def __init__(self): - self.backend_class = OfficeConverterBackendDirect - self.backend = self.backend_class() - self.exists = False - self.mimetype = None - self.encoding = None - - def mimetypes(self): - return CONVERTER_OFFICE_FILE_MIMETYPES - - def convert(self, input_filepath, mimetype=None): - self.exists = False - self.mimetype = None - self.encoding = None - - self.input_filepath = input_filepath - - # Make sure file is of a known office format - if mimetype: - self.mimetype = mimetype - else: - self.mimetype, self.encoding = get_mimetype(open(self.input_filepath), self.input_filepath, mimetype_only=True) - - if self.mimetype in CONVERTER_OFFICE_FILE_MIMETYPES: - # Cache results of conversion - self.output_filepath = os.path.join(TEMPORARY_DIRECTORY, ''.join([self.input_filepath, CACHED_FILE_SUFFIX])) - self.exists = os.path.exists(self.output_filepath) - if not self.exists: - try: - self.backend.convert(self.input_filepath, self.output_filepath) - self.exists = True - except OfficeBackendError as exception: - # convert exception so that at least the mime type icon is displayed - raise UnknownFileFormat(exception) - - -class OfficeConverterBackendDirect(object): - def __init__(self): - self.libreoffice_path = LIBREOFFICE_PATH - if not os.path.exists(self.libreoffice_path): - raise OfficeBackendError('cannot find LibreOffice executable') - logger.debug('self.libreoffice_path: %s', self.libreoffice_path) - - def convert(self, input_filepath, output_filepath): - """ - Executes libreoffice using subprocess's Popen - """ - self.input_filepath = input_filepath - self.output_filepath = output_filepath - - command = [] - command.append(self.libreoffice_path) - - command.append('--headless') - command.append('--convert-to') - command.append('pdf') - command.append(self.input_filepath) - command.append('--outdir') - command.append(TEMPORARY_DIRECTORY) - - logger.debug('command: %s', command) - - try: - os.environ['HOME'] = TEMPORARY_DIRECTORY - proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) - return_code = proc.wait() - logger.debug('return_code: %s', return_code) - - readline = proc.stderr.readline() - logger.debug('stderr: %s', readline) - if return_code != 0: - raise OfficeBackendError(readline) - filename, extension = os.path.splitext(os.path.basename(self.input_filepath)) - logger.debug('filename: %s', filename) - logger.debug('extension: %s', extension) - - converted_output = os.path.join(TEMPORARY_DIRECTORY, os.path.extsep.join([filename, 'pdf'])) - logger.debug('converted_output: %s', converted_output) - - os.rename(converted_output, self.output_filepath) - except OSError as exception: - raise OfficeBackendError(exception) - except Exception as exception: - logger.error('Unhandled exception', exc_info=exception) diff --git a/mayan/apps/navigation/classes.py b/mayan/apps/navigation/classes.py index 9ed29e108e..854d9c22e2 100644 --- a/mayan/apps/navigation/classes.py +++ b/mayan/apps/navigation/classes.py @@ -178,7 +178,7 @@ class Link(object): kwargs = {key: Variable(value) for key, value in self.kwargs.iteritems()} # Use Django's exact {% url %} code to resolve the link - node = URLNode(view_name=view_name, args=args, kwargs={}, asvar=None) + node = URLNode(view_name=view_name, args=args, kwargs=kwargs, asvar=None) # If we were passed an instance of the view context object we are # resolving, inject it into the context. This help resolve links for diff --git a/mayan/apps/sources/managers.py b/mayan/apps/sources/managers.py deleted file mode 100644 index 87f81b5033..0000000000 --- a/mayan/apps/sources/managers.py +++ /dev/null @@ -1,28 +0,0 @@ -from __future__ import unicode_literals - -from ast import literal_eval - -from django.contrib.contenttypes.models import ContentType -from django.db import models - - -class SourceTransformationManager(models.Manager): - def get_for_object(self, obj): - ct = ContentType.objects.get_for_model(obj) - return self.model.objects.filter(content_type=ct).filter(object_id=obj.pk) - - def get_for_object_as_list(self, obj): - warnings = [] - transformations = [] - for transformation in self.get_for_object(obj).values('transformation', 'arguments'): - try: - transformations.append( - { - 'transformation': transformation['transformation'], - 'arguments': literal_eval(transformation['arguments'].strip()) - } - ) - except (ValueError, SyntaxError) as exception: - warnings.append(exception) - - return transformations, warnings