From 9250a6bbdcdf75da20599723d3a3d30297f0d9cd Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Sat, 18 Jun 2011 00:51:32 -0400 Subject: [PATCH] Added view to list supported file formats and reported by the converter backend --- apps/converter/__init__.py | 4 ++ apps/converter/api.py | 10 ++++- apps/converter/backends/graphicsmagick.py | 26 ++++++++++++ apps/converter/backends/imagemagick.py | 25 ++++++++++++ apps/converter/exceptions.py | 26 +++++++----- apps/converter/urls.py | 5 +++ apps/converter/views.py | 50 ++++++++++++++++++++++- apps/main/__init__.py | 5 ++- urls.py | 1 + 9 files changed, 138 insertions(+), 14 deletions(-) create mode 100644 apps/converter/urls.py diff --git a/apps/converter/__init__.py b/apps/converter/__init__.py index 0445dffa0e..963d347167 100644 --- a/apps/converter/__init__.py +++ b/apps/converter/__init__.py @@ -1,3 +1,7 @@ +from django.utils.translation import ugettext_lazy as _ + TRANFORMATION_CHOICES = { u'rotate': u'-rotate %(degrees)d' } + +formats_list = {'text': _('file formats'), 'view': 'formats_list', 'famfam': 'pictures'} diff --git a/apps/converter/api.py b/apps/converter/api.py index e23a8326c4..d7595de8c3 100644 --- a/apps/converter/api.py +++ b/apps/converter/api.py @@ -62,7 +62,9 @@ except ImportError: def cleanup(filename): - ''' tries to remove the given filename. Ignores non-existent files ''' + """ + Tries to remove the given filename. Ignores non-existent files + """ try: os.remove(filename) except OSError: @@ -70,6 +72,9 @@ def cleanup(filename): def execute_unpaper(input_filepath, output_filepath): + """ + Executes the program unpaper using subprocess's Popen + """ command = [] command.append(UNPAPER_PATH) command.append(u'--overwrite') @@ -82,6 +87,9 @@ def execute_unpaper(input_filepath, output_filepath): def execute_unoconv(input_filepath, arguments=''): + """ + Executes the program unoconv using subprocess's Popen + """ command = [] command.append(UNOCONV_PATH) command.extend(unicode(arguments).split()) diff --git a/apps/converter/backends/graphicsmagick.py b/apps/converter/backends/graphicsmagick.py index a1a0bc5797..360a24a58b 100644 --- a/apps/converter/backends/graphicsmagick.py +++ b/apps/converter/backends/graphicsmagick.py @@ -1,4 +1,5 @@ import subprocess +import re from converter.conf.settings import GM_PATH from converter.conf.settings import GM_SETTINGS @@ -43,3 +44,28 @@ def execute_convert(input_filepath, output_filepath, quality=QUALITY_DEFAULT, ar 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/imagemagick.py b/apps/converter/backends/imagemagick.py index b5122cc96a..4542ebdeba 100644 --- a/apps/converter/backends/imagemagick.py +++ b/apps/converter/backends/imagemagick.py @@ -1,4 +1,5 @@ import subprocess +import re from converter.conf.settings import IM_IDENTIFY_PATH from converter.conf.settings import IM_CONVERT_PATH @@ -41,3 +42,27 @@ def execute_convert(input_filepath, output_filepath, quality=QUALITY_DEFAULT, ar 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/exceptions.py b/apps/converter/exceptions.py index 5f1c9c4582..c906fc5c95 100644 --- a/apps/converter/exceptions.py +++ b/apps/converter/exceptions.py @@ -1,31 +1,37 @@ class ConvertError(Exception): - '''Base exception for all coverter app exceptions - ''' + """ + Base exception for all coverter app exceptions + """ pass class UnknownFormat(ConvertError): - '''Raised when the converter backend can't understand or there - isn't an appropiate driver available''' + """ + Raised when the converter backend can't understand or there + isn't an appropiate driver available + """ pass class UnpaperError(ConvertError): - '''Raised by upaper - ''' + """ + Raised by unpaper + """ pass class IdentifyError(ConvertError): - '''Raised by identify - ''' + """ + Raised by identify + """ pass class UnkownConvertError(ConvertError): - '''Raised when an error is found but there is no disernible way to + """ + Raised when an error is found but there is no disernible way to identify the kind of error - ''' + """ pass diff --git a/apps/converter/urls.py b/apps/converter/urls.py new file mode 100644 index 0000000000..5641b27c83 --- /dev/null +++ b/apps/converter/urls.py @@ -0,0 +1,5 @@ +from django.conf.urls.defaults import patterns, url + +urlpatterns = patterns('converter.views', + url(r'^formats/$', 'formats_list', (), 'formats_list'), +) diff --git a/apps/converter/views.py b/apps/converter/views.py index 60f00ef0ef..45e625b000 100644 --- a/apps/converter/views.py +++ b/apps/converter/views.py @@ -1 +1,49 @@ -# Create your views here. +from django.utils.translation import ugettext_lazy as _ +from django.shortcuts import render_to_response +from django.template import RequestContext +from django.utils.importlib import import_module + +from converter.conf.settings import GRAPHICS_BACKEND + + +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) + + +def formats_list(request): + #check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW]) + + context = { + 'title': _(u'suported file formats'), + 'hide_object': True, + 'object_list': backend.get_format_list(), + 'extra_columns': [ + { + 'name': _(u'name'), + 'attribute': lambda x: x[0] + }, + { + 'name': _(u'description'), + 'attribute': lambda x: x[1] + } + ] + } + + return render_to_response('generic_list.html', context, + context_instance=RequestContext(request)) diff --git a/apps/main/__init__.py b/apps/main/__init__.py index 8ae031b1de..3c6f626777 100644 --- a/apps/main/__init__.py +++ b/apps/main/__init__.py @@ -5,6 +5,7 @@ from permissions import role_list, permission_views from user_management import user_list, group_list, user_management_views from navigation.api import register_links from history import history_list +from converter import formats_list from documents import document_type_views from main.conf.settings import SIDE_BAR_SEARCH @@ -37,12 +38,12 @@ __version_info__ = { register_top_menu('home', link={'text': _(u'home'), 'view': 'home', 'famfam': 'house'}, position=0) if not SIDE_BAR_SEARCH: register_top_menu('search', link={'text': _(u'search'), 'view': 'search', 'famfam': 'zoom'}) -register_top_menu('tools', link=tools_menu, children_views=['statistics', 'history_list']) +register_top_menu('tools', link=tools_menu, children_views=['statistics', 'history_list', 'formats_list']) #register_top_menu('setup_menu', link={'text': _(u'setup'), 'view': 'setting_list', 'famfam': 'cog'}, children=setup_views) register_top_menu('setup_menu', link={'text': _(u'setup'), 'view': 'setting_list', 'famfam': 'cog'}, children_path_regex=[r'^settings/', r'^user_management/', r'^permissions', r'^documents/type']) register_top_menu('about', link={'text': _(u'about'), 'view': 'about', 'famfam': 'information'}) -register_links(['tools_menu', 'statistics', 'history_list', 'history_view'], [tools_menu, statistics, history_list, sentry], menu_name='secondary_menu') +register_links(['tools_menu', 'statistics', 'history_list', 'history_view', 'formats_list'], [tools_menu, statistics, history_list, formats_list, sentry], menu_name='secondary_menu') tool_links = [check_settings, role_list, user_list, group_list, document_types, admin_site] register_links(['setting_list'], tool_links, menu_name='secondary_menu') diff --git a/urls.py b/urls.py index 179f385693..f8c245d097 100644 --- a/urls.py +++ b/urls.py @@ -24,6 +24,7 @@ urlpatterns = patterns('', (r'^grouping/', include('grouping.urls')), (r'^document_indexing/', include('document_indexing.urls')), (r'^history/', include('history.urls')), + (r'^converter/', include('converter.urls')), )