Initial commit of the new office converter class
This commit is contained in:
@@ -4,8 +4,6 @@ import hashlib
|
||||
|
||||
from common.conf.settings import TEMPORARY_DIRECTORY
|
||||
|
||||
from converter.conf.settings import UNOCONV_PATH
|
||||
from converter.exceptions import OfficeConversionError
|
||||
from converter.literals import DEFAULT_PAGE_NUMBER, \
|
||||
DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION, DEFAULT_FILE_FORMAT
|
||||
|
||||
@@ -16,28 +14,12 @@ from converter.literals import TRANSFORMATION_RESIZE, \
|
||||
from converter.literals import DIMENSION_SEPARATOR
|
||||
from converter.literals import FILE_FORMATS
|
||||
from converter.utils import cleanup
|
||||
from converter.office_converter import OfficeConverter
|
||||
|
||||
|
||||
HASH_FUNCTION = lambda x: hashlib.sha256(x).hexdigest()
|
||||
|
||||
CONVERTER_OFFICE_FILE_EXTENSIONS = [
|
||||
u'ods', u'docx', u'doc'
|
||||
]
|
||||
|
||||
|
||||
def execute_unoconv(input_filepath, arguments=''):
|
||||
"""
|
||||
Executes the program unoconv using subprocess's Popen
|
||||
"""
|
||||
command = []
|
||||
command.append(UNOCONV_PATH)
|
||||
command.extend(unicode(arguments).split())
|
||||
command.append(input_filepath)
|
||||
proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE)
|
||||
return_code = proc.wait()
|
||||
if return_code != 0:
|
||||
raise OfficeConversionError(proc.stderr.readline())
|
||||
|
||||
|
||||
|
||||
def cache_cleanup(input_filepath, *args, **kwargs):
|
||||
try:
|
||||
os.remove(create_image_cache_filename(input_filepath, *args, **kwargs))
|
||||
@@ -53,13 +35,6 @@ def create_image_cache_filename(input_filepath, *args, **kwargs):
|
||||
return None
|
||||
|
||||
|
||||
def convert_office_document(input_filepath):
|
||||
if os.path.exists(UNOCONV_PATH):
|
||||
execute_unoconv(input_filepath, arguments='-f pdf')
|
||||
return input_filepath + u'.pdf'
|
||||
return None
|
||||
|
||||
|
||||
def convert(input_filepath, output_filepath=None, cleanup_files=False, *args, **kwargs):
|
||||
size = kwargs.get('size')
|
||||
file_format = kwargs.get('file_format', DEFAULT_FILE_FORMAT)
|
||||
@@ -70,20 +45,23 @@ def convert(input_filepath, output_filepath=None, cleanup_files=False, *args, **
|
||||
if transformations is None:
|
||||
transformations = []
|
||||
|
||||
unoconv_output = None
|
||||
|
||||
if output_filepath is None:
|
||||
output_filepath = create_image_cache_filename(input_filepath, *args, **kwargs)
|
||||
print 'cache image', output_filepath
|
||||
|
||||
if os.path.exists(output_filepath):
|
||||
return output_filepath
|
||||
|
||||
print 'cleanup_files', cleanup_files
|
||||
|
||||
path, extension = os.path.splitext(input_filepath)
|
||||
if extension[1:].lower() in CONVERTER_OFFICE_FILE_EXTENSIONS:
|
||||
result = convert_office_document(input_filepath)
|
||||
if result:
|
||||
unoconv_output = result
|
||||
input_filepath = result
|
||||
office_converter = OfficeConverter(input_filepath)
|
||||
if office_converter:
|
||||
try:
|
||||
#cleanup_files =False.
|
||||
input_filepath = office_converter.output_filepath
|
||||
except OfficeConverter:
|
||||
print 'office converter exception'
|
||||
raise UnknownFileFormat('office converter exception')
|
||||
|
||||
if size:
|
||||
transformations.append(
|
||||
@@ -114,8 +92,6 @@ def convert(input_filepath, output_filepath=None, cleanup_files=False, *args, **
|
||||
finally:
|
||||
if cleanup_files:
|
||||
cleanup(input_filepath)
|
||||
if unoconv_output:
|
||||
cleanup(unoconv_output)
|
||||
|
||||
return output_filepath
|
||||
|
||||
|
||||
@@ -29,3 +29,7 @@ class UnkownConvertError(ConvertError):
|
||||
|
||||
class OfficeConversionError(ConvertError):
|
||||
pass
|
||||
|
||||
|
||||
class OfficeBackendError(OfficeConversionError):
|
||||
pass
|
||||
|
||||
106
apps/converter/office_converter.py
Normal file
106
apps/converter/office_converter.py
Normal file
@@ -0,0 +1,106 @@
|
||||
import os
|
||||
import subprocess
|
||||
import hashlib
|
||||
|
||||
from mimetype.api import get_mimetype
|
||||
from common.conf.settings import TEMPORARY_DIRECTORY
|
||||
|
||||
from converter.conf.settings import UNOCONV_PATH
|
||||
from converter.exceptions import (OfficeConversionError,
|
||||
OfficeBackendError, UnknownFileFormat)
|
||||
|
||||
HASH_FUNCTION = lambda x: hashlib.sha256(x).hexdigest()
|
||||
|
||||
CACHED_FILE_SUFFIX = u'_office_converter'
|
||||
|
||||
CONVERTER_OFFICE_FILE_MIMETYPES = [
|
||||
'application/msword',
|
||||
'application/mswrite',
|
||||
'application/mspowerpoint',
|
||||
'application/msexcel',
|
||||
'application/vnd.ms-excel',
|
||||
'application/vnd.ms-powerpoint',
|
||||
'text/plain',
|
||||
'application/vnd.oasis.opendocument.presentation',
|
||||
]
|
||||
# 'application/vnd.oasis.opendocument.text': 'ODF_textdocument_32x32.png',
|
||||
# 'application/vnd.oasis.opendocument.spreadsheet': 'ODF_spreadsheet_32x32.png',
|
||||
# 'application/vnd.oasis.opendocument.presentation': 'ODF_presentation_32x32.png',
|
||||
# 'application/vnd.oasis.opendocument.graphics': 'ODF_drawing_32x32.png',
|
||||
# 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'file_extension_xls.png',
|
||||
# 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'file_extension_doc.png',
|
||||
# 'application/vnd.oasis.opendocument.text': 'ODF_textdocument_32x32.png',
|
||||
|
||||
class OfficeConverter(object):
|
||||
def __init__(self, input_filepath):
|
||||
self.backend = OfficeConverterBackendUnoconv(unoconv_path=UNOCONV_PATH)
|
||||
self.input_filepath = input_filepath
|
||||
self.exists = False
|
||||
|
||||
# Make sure file is of a known office format
|
||||
descriptor = open(self.input_filepath)
|
||||
mimetype, encoding = get_mimetype(descriptor, self.input_filepath)
|
||||
|
||||
if mimetype in CONVERTER_OFFICE_FILE_MIMETYPES:
|
||||
# Hash file to cache results of conversion
|
||||
#descriptor = open(self.input_filepath)
|
||||
#file_hash = HASH_FUNCTION(descriptor.read())
|
||||
#descriptor.close()
|
||||
|
||||
#self.output_filepath = os.path.join(TEMPORARY_DIRECTORY, u''.join([file_hash, CACHED_FILE_SUFFIX]))
|
||||
self.output_filepath = os.path.join(TEMPORARY_DIRECTORY, u''.join([self.input_filepath, CACHED_FILE_SUFFIX]))
|
||||
self.exists = os.path.exists(self.output_filepath)
|
||||
print 'self.input_filepath',self.input_filepath
|
||||
print 'self.output_filepath',self.output_filepath
|
||||
print 'self.exists', self.exists
|
||||
if not self.exists:
|
||||
try:
|
||||
self.backend.convert(self.input_filepath, self.output_filepath)
|
||||
except OfficeBackendError, msg:
|
||||
print 'OFFICE EXCEPTION'
|
||||
# convert exception so that atleas the mime type icon is displayed
|
||||
raise UnknownFileFormat(msg)
|
||||
|
||||
|
||||
|
||||
def __unicode__(self):
|
||||
return getattr(self, 'output_filepath', None)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.__unicode__())
|
||||
|
||||
def __nonzero__(self):
|
||||
return self.exists
|
||||
|
||||
__bool__ = __nonzero__
|
||||
|
||||
|
||||
class OfficeConverterBackendUnoconv(object):
|
||||
def __init__(self, unoconv_path=None):
|
||||
self.unoconv_path = unoconv_path if unoconv_path else u'/usr/bin/unoconv'
|
||||
if not os.path.exists(self.unoconv_path):
|
||||
raise OfficeBackendError('cannot find unoconv executable')
|
||||
|
||||
def convert(self, input_filepath, output_filepath):
|
||||
"""
|
||||
Executes the program unoconv using subprocess's Popen
|
||||
"""
|
||||
self.input_filepath = input_filepath
|
||||
self.output_filepath = output_filepath
|
||||
|
||||
command = []
|
||||
command.append(self.unoconv_path)
|
||||
#command.append(u'-v')
|
||||
command.append(u'--pipe')
|
||||
command.append(u'--format="pdf"')
|
||||
command.append(u'--output=%s' % self.output_filepath)
|
||||
command.append(self.input_filepath)
|
||||
print 'convert'
|
||||
try:
|
||||
proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||
return_code = proc.wait()
|
||||
readline = proc.stderr.readline()
|
||||
if return_code != 0:
|
||||
raise OfficeBackendError(proc.stderr.readline())
|
||||
except OSError, msg:
|
||||
raise OfficeBackendError(msg)
|
||||
Reference in New Issue
Block a user