Initial commit of the converter refactor

This commit is contained in:
Roberto Rosario
2015-06-05 03:35:07 -04:00
parent 97f68ea158
commit de6182aea0
11 changed files with 460 additions and 121 deletions
+6 -11
View File
@@ -5,17 +5,12 @@ class ConverterBase(object):
""" """
Base class that all backend classes must inherit Base class that all backend classes must inherit
""" """
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): def convert(self, input_data, ):
raise NotImplementedError('Your %s class has not defined a convert_document() method, which is required.' % self.__class__.__name__) raise NotImplementedError()
def get_format_list(self): def transform(self, input_data, transformations):
raise NotImplementedError('Your %s class has not defined a get_format_list() method, which is required.' % self.__class__.__name__) raise NotImplementedError()
def get_available_transformations(self): def get_page_count(self, input_data):
raise NotImplementedError('Your %s class has not defined a get_available_transformations() method, which is required.' % self.__class__.__name__) raise NotImplementedError()
def get_page_count(self, input_filepath):
raise NotImplementedError('Your %s class has not defined a get_page_count() method, which is required.' % self.__class__.__name__)
@@ -83,12 +83,6 @@ class GraphicsMagick(ConverterBase):
else: else:
raise ConvertError(error_line) raise ConvertError(error_line)
def get_available_transformations(self):
return [
TRANSFORMATION_RESIZE, TRANSFORMATION_ROTATE,
TRANSFORMATION_ZOOM
]
def get_page_count(self, input_filepath): def get_page_count(self, input_filepath):
try: try:
return len(self.identify_file(unicode(input_filepath)).splitlines()) return len(self.identify_file(unicode(input_filepath)).splitlines())
@@ -77,12 +77,6 @@ class ImageMagick(ConverterBase):
else: else:
raise ConvertError(error_line) raise ConvertError(error_line)
def get_available_transformations(self):
return [
TRANSFORMATION_RESIZE, TRANSFORMATION_ROTATE,
TRANSFORMATION_ZOOM
]
def get_page_count(self, input_filepath): def get_page_count(self, input_filepath):
try: try:
return len(self.identify_file(unicode(input_filepath)).splitlines()) return len(self.identify_file(unicode(input_filepath)).splitlines())
+82 -44
View File
@@ -2,6 +2,13 @@ from __future__ import unicode_literals
import io import io
import logging import logging
import os
import tempfile
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
import slate import slate
from PIL import Image from PIL import Image
@@ -30,29 +37,42 @@ logger = logging.getLogger(__name__)
class Python(ConverterBase): class Python(ConverterBase):
def get_page_count(self, input_filepath): def get_page_count(self, file_object, mimetype=None):
page_count = 1 page_count = 1
mimetype, encoding = get_mimetype(open(input_filepath, 'rb'), input_filepath, mimetype_only=True) #file_object, input_filepath = mkstemp()
#file_object.write(input_data)
if not mimetype:
#mimetype, encoding = get_mimetype(file_description=open(input_filepath, 'rb'), filepath=None, mimetype_only=True)
mimetype, encoding = get_mimetype(file_object=file_object, mimetype_only=True)
else:
encoding = None
if mimetype == 'application/pdf': if mimetype == 'application/pdf':
# If file is a PDF open it with slate to determine the page # If file is a PDF open it with slate to determine the page count
# count #with open(input_filepath) as fd:
with open(input_filepath) as fd: try:
try: pages = slate.PDF(file_object)
pages = slate.PDF(fd) except:
except: return 1
return 1 # TODO: Maybe return UnknownFileFormat to display proper unknwon file format message in document description
# TODO: Maybe return UnknownFileFormat to display proper unknwon file format message in document description else:
return len(pages) return len(pages)
finally:
file_object.seek(0)
try: try:
im = Image.open(input_filepath) #im = Image.fromarray(input_data)
image = Image.open(file_object)
except IOError: # cannot identify image file except IOError: # cannot identify image file
raise UnknownFileFormat raise UnknownFileFormat
finally:
file_object.seek(0)
try: try:
while True: while True:
im.seek(im.tell() + 1) image.seek(image.tell() + 1)
page_count += 1 page_count += 1
# do something to im # do something to im
except EOFError: except EOFError:
@@ -60,40 +80,59 @@ class Python(ConverterBase):
return page_count return page_count
def convert_file(self, input_filepath, output_filepath, transformations=None, page=DEFAULT_PAGE_NUMBER, file_format=DEFAULT_FILE_FORMAT, **kwargs): def convert(self, file_object, mimetype=None, output_format=DEFAULT_FILE_FORMAT, page=DEFAULT_PAGE_NUMBER):
tmpfile = None
mimetype = kwargs.get('mimetype', None)
if not mimetype:
mimetype, encoding = get_mimetype(open(input_filepath, 'rb'), input_filepath, mimetype_only=True)
try: #tmpfile = None
if mimetype == 'application/pdf' and pdftoppm: #mimetype = kwargs.get('mimetype', None)
image_buffer = io.BytesIO()
pdftoppm(input_filepath, f=page, l=page, _out=image_buffer) if not mimetype:
image_buffer.seek(0) mimetype, encoding = get_mimetype(file_object=file_object, mimetype_only=True)
im = Image.open(image_buffer)
else: ##try:
im = Image.open(input_filepath) print "MIME!", mimetype
except Exception as exception: if mimetype == 'application/pdf' and pdftoppm:
logger.error('Error converting image; %s', exception) image_buffer = io.BytesIO()
# Python Imaging Library doesn't recognize it as an image
raise ConvertError new_file_object, input_filepath = tempfile.mkstemp()
except IOError: # cannot identify image file os.write(new_file_object, file_object.read())
raise UnknownFileFormat #file_object.seek(0)
finally: #new_file_object.seek(0)
if tmpfile: os.close(new_file_object)
fs_cleanup(tmpfile)
pdftoppm(input_filepath, f=page, l=page, _out=image_buffer)
image_buffer.seek(0)
image = Image.open(image_buffer)
# TODO: remove input_filepath
else:
image = Image.open(file_object)
##except Exception as exception:
## logger.error('Error converting image; %s', exception)
## # Python Imaging Library doesn't recognize it as an image
## raise ConvertError
##except IOError: # cannot identify image file
## raise UnknownFileFormat
#finally:
# if tmpfile:
# fs_cleanup(tmpfile)
current_page = 0 current_page = 0
try: try:
while current_page == page - 1: while current_page == page - 1:
im.seek(im.tell() + 1) image.seek(image.tell() + 1)
current_page += 1 current_page += 1
# do something to im # do something to im
except EOFError: except EOFError:
# end of sequence # end of sequence
pass pass
'''
try: try:
if transformations: if transformations:
aspect = 1.0 * im.size[0] / im.size[1] aspect = 1.0 * im.size[0] / im.size[1]
@@ -112,17 +151,16 @@ class Python(ConverterBase):
except: except:
# Ignore all transformation error # Ignore all transformation error
pass pass
'''
if im.mode not in ('L', 'RGB'): if image.mode not in ('L', 'RGB'):
im = im.convert('RGB') image = image.convert('RGB')
im.save(output_filepath, format=file_format)
def get_available_transformations(self): output = StringIO()
return [ image.save(output, format=output_format)
TRANSFORMATION_RESIZE, TRANSFORMATION_ROTATE,
TRANSFORMATION_ZOOM return output
]
# From: http://united-coders.com/christian-harms/image-resizing-tips-general-and-for-python # From: http://united-coders.com/christian-harms/image-resizing-tips-general-and-for-python
def resize(self, img, box, fit=False, out=None): def resize(self, img, box, fit=False, out=None):
+282
View File
@@ -0,0 +1,282 @@
from __future__ import unicode_literals
import logging
import os
import subprocess
from tempfile import mkstemp
from django.utils.encoding import smart_str
from django.utils.module_loading import import_string
from common.settings import TEMPORARY_DIRECTORY
from common.utils import fs_cleanup
from mimetype.api import get_mimetype
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
)
from .office_converter import OfficeConverter
from .runtime import backend, office_converter
from .settings import GRAPHICS_BACKEND, LIBREOFFICE_PATH
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__)
logger.debug('initializing office backend')
try:
office_converter = OfficeConverter()
except OfficeBackendError as exception:
logger.error('error initializing office backend; %s', exception)
office_converter = None
else:
logger.debug('office_backend initialized')
backend = import_string(GRAPHICS_BACKEND)()
class BaseTransformation(object):
name = 'base_transformation'
arguments = ()
def __init__(self, **kwargs):
for argument_name in self.arguments:
setattr(self, argument_name, kwargs.get(argument_name))
class TransformationResize(BaseTransformation):
name = 'resize'
arguments = ('width', 'height')
class TransformationRotate(BaseTransformation):
name = 'rotate'
arguments = ('degrees',)
class TransformationScale(BaseTransformation):
name = 'scale'
arguments = ('percent',)
class Converter(object):
"""
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
"""
@staticmethod
def soffice(file_object):
"""
Executes libreoffice using subprocess's Popen
"""
new_file_object, input_filepath = tempfile.mkstemp()
new_file_object.write(file_object.read())
file_object.seek(0)
new_file_object.seek(0)
new_file_object.close()
command = []
command.append(LIBREOFFICE_PATH)
command.append('--headless')
command.append('--convert-to')
command.append('pdf')
command.append(input_filepath)
command.append('--outdir')
command.append(TEMPORARY_DIRECTORY)
logger.debug('command: %s', command)
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)
raise Exception(readline)
filename, extension = os.path.splitext(os.path.basename(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)
return open(converted_output)
#os.rename(converted_output, output_filepath)
# TODO: remove temp file
def __init__(self, file_object, mime_type=None):
self.file_object = file_object
self.mime_type = mime_type or get_mimetype(file_object=file_object, mimetype_only=False)[0]
if self.mime_type in CONVERTER_OFFICE_FILE_MIMETYPES:
if os.path.exists(LIBREOFFICE_PATH):
#file_object, filename = mkstemp()
# Cache results of conversion
#output_filepath = os.path.join(TEMPORARY_DIRECTORY, ''.join([self.input_filepath, CACHED_FILE_SUFFIX]))
result = Converter.soffice(file_object)
file_object.close()
self.file_object = result
self.mime_type = 'application/pdf'
#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)
#else:
# result = office_converter.convert(self.file_object, mimetype=mime_type)
# self.file_object.close()
# self.file_object = result
else:
# TODO: NO LIBREOFFICE ERROR
pass
def transform(self, transformations, page=DEFAULT_PAGE_NUMBER):
pass
def convert(self, output_format=DEFAULT_FILE_FORMAT, page=DEFAULT_PAGE_NUMBER):#, *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}
}
)
'''
return backend.convert(file_object=self.file_object, mimetype=self.mime_type, output_format=output_format, page=page)
def get_page_count(self):
return backend.get_page_count(file_object)
'''
def get_available_transformations_choices():
result = []
for transformation in backend.get_available_transformations():
result.append((transformation, TRANSFORMATION_CHOICES[transformation]['label']))
return result
'''
+59 -30
View File
@@ -17,9 +17,7 @@ from django.utils.translation import ugettext_lazy as _
from acls.utils import apply_default_acls from acls.utils import apply_default_acls
from common.settings import TEMPORARY_DIRECTORY from common.settings import TEMPORARY_DIRECTORY
from converter.api import ( from converter.classes import Converter
convert, get_page_count, get_available_transformations_choices
)
from converter.exceptions import UnknownFileFormat from converter.exceptions import UnknownFileFormat
from converter.literals import ( from converter.literals import (
DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION, DEFAULT_PAGE_NUMBER DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION, DEFAULT_PAGE_NUMBER
@@ -127,6 +125,7 @@ class Document(models.Model):
else: else:
event_document_create.commit(target=self) event_document_create.commit(target=self)
"""
def get_cached_image_name(self, page, version): def get_cached_image_name(self, page, version):
document_version = DocumentVersion.objects.get(pk=version) document_version = DocumentVersion.objects.get(pk=version)
document_page = document_version.pages.get(page_number=page) document_page = document_version.pages.get(page_number=page)
@@ -165,19 +164,20 @@ class Document(models.Model):
logger.debug('file_path: %s', file_path) logger.debug('file_path: %s', file_path)
if as_base64: if as_base64:
mimetype = get_mimetype(open(file_path, 'r'), file_path, mimetype_only=True)[0] with open(file_path, 'r') as file_object:
image = open(file_path, 'r') mimetype = get_mimetype(file_object=file_object, mimetype_only=True)[0]
base64_data = base64.b64encode(image.read()) base64_data = base64.b64encode(file_object.read())
image.close() return 'data:%s;base64,%s' % (mimetype, base64_data)
return 'data:%s;base64,%s' % (mimetype, base64_data)
else: else:
return file_path return file_path
"""
def invalidate_cached_image(self, page): def invalidate_cached_image(self, page):
try: pass
os.unlink(self.get_cached_image_name(page, self.latest_version.pk)[0]) #try:
except OSError: # os.unlink(self.get_cached_image_name(page, self.latest_version.pk)[0])
pass #except OSError:
# pass
def add_as_recent_document_for_user(self, user): def add_as_recent_document_for_user(self, user):
RecentDocument.objects.add_document_for_user(user, self) RecentDocument.objects.add_document_for_user(user, self)
@@ -347,33 +347,33 @@ class DocumentVersion(models.Model):
self.save() self.save()
def update_page_count(self, save=True): def update_page_count(self, save=True):
handle, filepath = tempfile.mkstemp() #handle, filepath = tempfile.mkstemp()
# Just need the filepath, close the file description # Just need the filepath, close the file description
os.close(handle) #os.close(handle)
self.save_to_file(filepath) #self.save_to_file(filepath)
try: try:
detected_pages = get_page_count(filepath) with self.open() as file_object:
converter = Converter(file_object=file_object, mimetype=self.mimetype)
detected_pages = converter.get_page_count()
except UnknownFileFormat: except UnknownFileFormat:
# If converter backend doesn't understand the format, # If converter backend doesn't understand the format,
# use 1 as the total page count # use 1 as the total page count
detected_pages = 1 detected_pages = 1
self.description = _('This document\'s file format is not known, the page count has therefore defaulted to 1.') #try:
self.save() # os.remove(filepath)
try: #except OSError:
os.remove(filepath) # pass
except OSError:
pass
current_pages = self.pages.order_by('page_number',) # TODO: put inside a DB transaction
if current_pages.count() > detected_pages: self.pages.all().delete()
for page in current_pages[detected_pages:]:
page.delete()
for page_number in range(detected_pages): for page_number in range(detected_pages):
DocumentPage.objects.get_or_create( DocumentPage.objects.create(
document_version=self, page_number=page_number + 1) document_version=self, page_number=page_number + 1
)
# TODO: is this needed anymore
if save: if save:
self.save() self.save()
@@ -408,7 +408,8 @@ class DocumentVersion(models.Model):
""" """
if self.exists(): if self.exists():
try: try:
self.mimetype, self.encoding = get_mimetype(self.open(), self.document.label) with self.open() as file_object:
self.mimetype, self.encoding = get_mimetype(file_object=file_object)
except: except:
self.mimetype = '' self.mimetype = ''
self.encoding = '' self.encoding = ''
@@ -525,6 +526,33 @@ class DocumentPage(models.Model):
def document(self): def document(self):
return self.document_version.document return self.document_version.document
def get_image(self, *args, **kargs):
#size=DISPLAY_SIZE, page=DEFAULT_PAGE_NUMBER, zoom=DEFAULT_ZOOM_LEVEL, rotation=DEFAULT_ROTATION, as_base64=False, version=None):
#if zoom < ZOOM_MIN_LEVEL:
# zoom = ZOOM_MIN_LEVEL
#if zoom > ZOOM_MAX_LEVEL:
# zoom = ZOOM_MAX_LEVEL
#rotation = rotation % 360
#file_path = self.get_valid_image(size=size, page=page, zoom=zoom, rotation=rotation, version=version)
#logger.debug('file_path: %s', file_path)
converter = Converter(file_object=self.document_version.open())
data = converter.convert(page=self.page_number)
#print "data!!!!", data.getvalue()
##, *args, **kwargs):
return 'data:%s;base64,%s' % ('PNG', base64.b64encode(data.getvalue()))
#if as_base64:
# with open(file_path, 'r') as file_object:
# #mimetype = get_mimetype(file_object=file_object, mimetype_only=True)[0]
# base64_data = base64.b64encode(file_object.read())
# return 'data:%s;base64,%s' % (mimetype, base64_data)
#else:
# return file_path
def argument_validator(value): def argument_validator(value):
""" """
@@ -545,7 +573,8 @@ class DocumentPageTransformation(models.Model):
""" """
document_page = models.ForeignKey(DocumentPage, verbose_name=_('Document page')) document_page = models.ForeignKey(DocumentPage, verbose_name=_('Document page'))
order = models.PositiveIntegerField(default=0, blank=True, null=True, verbose_name=_('Order'), db_index=True) order = models.PositiveIntegerField(default=0, blank=True, null=True, verbose_name=_('Order'), db_index=True)
transformation = models.CharField(choices=get_available_transformations_choices(), max_length=128, verbose_name=_('Transformation')) #transformation = models.CharField(choices=get_available_transformations_choices(), max_length=128, verbose_name=_('Transformation'))
transformation = models.CharField(max_length=128, verbose_name=_('Transformation'))
arguments = models.TextField(blank=True, null=True, verbose_name=_('Arguments'), help_text=_('Use dictionaries to indentify arguments, example: {\'degrees\':90}'), validators=[argument_validator]) arguments = models.TextField(blank=True, null=True, verbose_name=_('Arguments'), help_text=_('Use dictionaries to indentify arguments, example: {\'degrees\':90}'), validators=[argument_validator])
objects = DocumentPageTransformationManager() objects = DocumentPageTransformationManager()
+2 -1
View File
@@ -17,7 +17,8 @@ logger = logging.getLogger(__name__)
@app.task(compression='zlib') @app.task(compression='zlib')
def task_get_document_image(document_id, *args, **kwargs): def task_get_document_image(document_id, *args, **kwargs):
document = Document.objects.get(pk=document_id) document = Document.objects.get(pk=document_id)
return document.get_image(*args, **kwargs) first_page = document.latest_version.pages.first()
return first_page.get_image(*args, **kwargs)
@app.task(ignore_result=True) @app.task(ignore_result=True)
+14 -1
View File
@@ -341,6 +341,9 @@ def document_multiple_document_type_edit(request):
) )
from django.http import HttpResponse
# TODO: Get rid of this view and convert widget to use API and base64 only images # TODO: Get rid of this view and convert widget to use API and base64 only images
def get_document_image(request, document_id, size=PREVIEW_SIZE): def get_document_image(request, document_id, size=PREVIEW_SIZE):
document = get_object_or_404(Document, pk=document_id) document = get_object_or_404(Document, pk=document_id)
@@ -364,7 +367,17 @@ def get_document_image(request, document_id, size=PREVIEW_SIZE):
rotation = int(request.GET.get('rotation', DEFAULT_ROTATION)) % 360 rotation = int(request.GET.get('rotation', DEFAULT_ROTATION)) % 360
task = task_get_document_image.apply_async(kwargs=dict(document_id=document.pk, size=size, page=page, zoom=zoom, rotation=rotation, as_base64=False, version=version), queue='converter') task = task_get_document_image.apply_async(kwargs=dict(document_id=document.pk, size=size, page=page, zoom=zoom, rotation=rotation, as_base64=False, version=version), queue='converter')
return sendfile.sendfile(request, task.get(timeout=DOCUMENT_IMAGE_TASK_TIMEOUT), mimetype=DEFAULT_FILE_FORMAT_MIMETYPE) data = task.get(timeout=DOCUMENT_IMAGE_TASK_TIMEOUT)
response = HttpResponse(data, content_type='data/PNG')
#response['Content-Disposition'] = 'attachment; filename="somefilename.pdf"'
return response
#print 'data!!!!!!!!!!!', task.get(timeout=DOCUMENT_IMAGE_TASK_TIMEOUT)
#re
#return sendfile.sendfile(request, task.get(timeout=DOCUMENT_IMAGE_TASK_TIMEOUT), mimetype=DEFAULT_FILE_FORMAT_MIMETYPE)
def document_download(request, document_id=None, document_id_list=None, document_version_pk=None): def document_download(request, document_id=None, document_id_list=None, document_version_pk=None):
+11 -19
View File
@@ -2,16 +2,10 @@ from __future__ import unicode_literals
import os import os
try: import magic
import magic
USE_PYTHON_MAGIC = True
except:
import mimetypes
mimetypes.init()
USE_PYTHON_MAGIC = False
def get_mimetype(file_description, filepath, mimetype_only=False): def get_mimetype(file_object, mimetype_only=False):
""" """
Determine a file's mimetype by calling the system's libmagic Determine a file's mimetype by calling the system's libmagic
library via python-magic or fallback to use python's mimetypes library via python-magic or fallback to use python's mimetypes
@@ -19,17 +13,15 @@ def get_mimetype(file_description, filepath, mimetype_only=False):
""" """
file_mimetype = None file_mimetype = None
file_mime_encoding = None file_mime_encoding = None
if USE_PYTHON_MAGIC:
mime = magic.Magic(mime=True)
file_mimetype = mime.from_buffer(file_description.read())
if not mimetype_only:
file_description.seek(0)
mime_encoding = magic.Magic(mime_encoding=True)
file_mime_encoding = mime_encoding.from_buffer(file_description.read())
else:
path, filename = os.path.split(filepath)
file_mimetype, file_mime_encoding = mimetypes.guess_type(filename)
file_description.close() mime = magic.Magic(mime=True)
file_mimetype = mime.from_buffer(file_object.read())
file_object.seek(0)
if not mimetype_only:
file_object.seek(0)
mime_encoding = magic.Magic(mime_encoding=True)
file_mime_encoding = mime_encoding.from_buffer(file_object.read())
file_object.seek(0)
return file_mimetype, file_mime_encoding return file_mimetype, file_mime_encoding
+3 -2
View File
@@ -19,7 +19,7 @@ from django.utils.translation import ugettext_lazy as _
from model_utils.managers import InheritanceManager from model_utils.managers import InheritanceManager
from converter.api import get_available_transformations_choices #from converter.api import get_available_transformations_choices
from converter.literals import DIMENSION_SEPARATOR from converter.literals import DIMENSION_SEPARATOR
from djcelery.models import PeriodicTask, IntervalSchedule from djcelery.models import PeriodicTask, IntervalSchedule
from documents.models import Document, DocumentType from documents.models import Document, DocumentType
@@ -376,7 +376,8 @@ class SourceTransformation(models.Model):
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id') content_object = generic.GenericForeignKey('content_type', 'object_id')
order = models.PositiveIntegerField(default=0, blank=True, null=True, verbose_name=_('Order'), db_index=True) order = models.PositiveIntegerField(default=0, blank=True, null=True, verbose_name=_('Order'), db_index=True)
transformation = models.CharField(choices=get_available_transformations_choices(), max_length=128, verbose_name=_('Transformation')) #transformation = models.CharField(choices=get_available_transformations_choices(), max_length=128, verbose_name=_('Transformation'))
transformation = models.CharField(max_length=128, verbose_name=_('Transformation'))
arguments = models.TextField(blank=True, null=True, verbose_name=_('Arguments'), help_text=_('Use dictionaries to indentify arguments, example: {\'degrees\':90}'), validators=[argument_validator]) arguments = models.TextField(blank=True, null=True, verbose_name=_('Arguments'), help_text=_('Use dictionaries to indentify arguments, example: {\'degrees\':90}'), validators=[argument_validator])
objects = models.Manager() objects = models.Manager()
+1 -1
View File
@@ -23,9 +23,9 @@ djangorestframework==2.4.4
pdfminer==20110227 pdfminer==20110227
pycountry==1.10 pycountry==1.10
python-dateutil==2.4.2 python-dateutil==2.4.2
pytz==2015.4
python-gnupg==0.3.7 python-gnupg==0.3.7
python-magic==0.4.6 python-magic==0.4.6
pytz==2015.4
sh==1.11 sh==1.11
slate==0.3 slate==0.3