From f7cd663cc7e76e5c630cac51de05c62f7b4ed4d8 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Sat, 3 Mar 2012 01:07:06 -0400 Subject: [PATCH 01/65] Call Django's urlencode directly to ensure unicode data preservation --- apps/documents/wizards.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/documents/wizards.py b/apps/documents/wizards.py index d78252dfd7..816a77b608 100644 --- a/apps/documents/wizards.py +++ b/apps/documents/wizards.py @@ -3,9 +3,9 @@ from __future__ import absolute_import from django.utils.translation import ugettext_lazy as _ from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect +from django.utils.http import urlencode from common.wizard import BoundFormWizard -from common.utils import urlquote from metadata.forms import MetadataSelectionForm, MetadataFormSet @@ -79,5 +79,5 @@ class DocumentCreateWizard(BoundFormWizard): if self.document_type: self.query_dict['document_type_id'] = self.document_type.pk - url = urlquote(reverse('upload_interactive'), self.query_dict) + url = '?'.join([reverse('upload_interactive'), urlencode(self.query_dict, doseq=True)]) return HttpResponseRedirect(url) From 365df067ad2926d95bf48d79cc3427246dff3f84 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Sun, 4 Mar 2012 14:34:28 -0400 Subject: [PATCH 02/65] Preserve unicode data in URL query --- apps/navigation/templatetags/navigation_tags.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/navigation/templatetags/navigation_tags.py b/apps/navigation/templatetags/navigation_tags.py index f3b989a511..d4533c09a3 100644 --- a/apps/navigation/templatetags/navigation_tags.py +++ b/apps/navigation/templatetags/navigation_tags.py @@ -3,12 +3,14 @@ from __future__ import absolute_import import copy import re import urlparse +import urllib from django.core.urlresolvers import reverse, NoReverseMatch from django.template import (TemplateSyntaxError, Library, VariableDoesNotExist, Node, Variable) from django.utils.text import unescape_string_literal from django.utils.translation import ugettext as _ +from django.utils.encoding import smart_str, force_unicode, smart_unicode from common.utils import urlquote @@ -101,6 +103,7 @@ def resolve_links(context, links, current_view, current_path, parsed_query_strin else: new_link['url'] = reverse(link['view'], args=args) if link.get('keep_query', False): + print 'parsed_query_string', parsed_query_string new_link['url'] = urlquote(new_link['url'], parsed_query_string) except NoReverseMatch, err: new_link['url'] = '#' @@ -169,7 +172,9 @@ def _get_object_navigation_links(context, menu_name=None, links_dict=object_navi # Don't fudge with the original global dictionary links_dict = links_dict.copy() - query_string = urlparse.urlparse(request.get_full_path()).query or urlparse.urlparse(request.META.get('HTTP_REFERER', u'/')).query + # Preserve unicode data in URL query + previous_path = smart_unicode(urllib.unquote_plus(smart_str(request.get_full_path()) or smart_str(request.META.get('HTTP_REFERER', u'/')))) + query_string = urlparse.urlparse(previous_path).query parsed_query_string = urlparse.parse_qs(query_string) try: From b908f5e2583532dc83e67059f3319c6016131fdd Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Sat, 3 Mar 2012 01:12:56 -0400 Subject: [PATCH 03/65] Fix staging file filename hashing not working with unicode filenames --- apps/sources/staging.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/sources/staging.py b/apps/sources/staging.py index c6a92a2bcb..b62d78ced1 100644 --- a/apps/sources/staging.py +++ b/apps/sources/staging.py @@ -7,11 +7,12 @@ import hashlib from django.core.files.base import File from django.core.exceptions import ObjectDoesNotExist from django.utils.translation import ugettext +from django.utils.encoding import smart_str from documents.conf.settings import THUMBNAIL_SIZE -from mimetype.api import get_icon_file_path, get_error_icon_file_path, \ - get_mimetype +from mimetype.api import (get_icon_file_path, get_error_icon_file_path, + get_mimetype) from converter.api import convert, cache_cleanup from converter.exceptions import UnknownFileFormat, UnkownConvertError @@ -102,7 +103,7 @@ class StagingFile(object): self.source = source self.filepath = filepath self.filename = os.path.basename(filepath) - self._id = HASH_FUNCTION(filepath) + self._id = HASH_FUNCTION(smart_str(filepath)) def __unicode__(self): return self.filename From c69397485ef0bc24d3cfde0072cea551a0f35949 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Tue, 6 Mar 2012 00:33:36 -0400 Subject: [PATCH 04/65] Don't import metadata info on top level __init__.py Not being used anyway, causes problems with Appsembler --- __init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/__init__.py b/__init__.py index a373a640b0..e69de29bb2 100644 --- a/__init__.py +++ b/__init__.py @@ -1,2 +0,0 @@ -from main import (__version__, __author__, __copyright__, __credits__, - __license__, __maintainer__, __email__, __status__) From f82cda218d633d4b0fb7c5c56a06c7fac7e06c2f Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Mon, 19 Mar 2012 09:04:44 -0400 Subject: [PATCH 05/65] Remove Flattr button --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 7e4b8e1203..000f5f57a3 100644 --- a/README.md +++ b/README.md @@ -27,4 +27,3 @@ Donations --------- Please [donate](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=W6LMMZHTNUJ6L) if you are willing to support the further development of this project. -[![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=rosarior&url=http://github.com/rosarior/mayan&title=Mayan EDMS&language=en_GB&tags=github&category=software) From e7d7ae0c88aab6b631baaede6dc192474bcd4888 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Tue, 27 Mar 2012 23:10:26 -0400 Subject: [PATCH 06/65] Simplify auto admin creation code --- apps/common/__init__.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/common/__init__.py b/apps/common/__init__.py index bc663d91d9..77519a42d3 100644 --- a/apps/common/__init__.py +++ b/apps/common/__init__.py @@ -10,6 +10,8 @@ from django.db.models.signals import post_syncdb from navigation.api import register_links, register_top_menu +from .conf.settings import (AUTO_CREATE_ADMIN, AUTO_ADMIN_USERNAME, + AUTO_ADMIN_PASSWORD, TEMPORARY_DIRECTORY) from .conf import settings as common_settings from .utils import validate_path @@ -44,18 +46,16 @@ def create_superuser(sender, **kwargs): Create our own admin super user automatically. """ - if common_settings.AUTO_CREATE_ADMIN: - USERNAME = common_settings.AUTO_ADMIN_USERNAME - PASSWORD = common_settings.AUTO_ADMIN_PASSWORD + if AUTO_CREATE_ADMIN: try: - auth_models.User.objects.get(username=USERNAME) + auth_models.User.objects.get(username=AUTO_ADMIN_USERNAME) except auth_models.User.DoesNotExist: print '*' * 80 - print 'Creating super admin user -- login: %s, password: %s' % (USERNAME, PASSWORD) + print 'Creating super admin user -- login: %s, password: %s' % (AUTO_ADMIN_USERNAME, AUTO_ADMIN_PASSWORD) print '*' * 80 - assert auth_models.User.objects.create_superuser(USERNAME, 'x@x.com', PASSWORD) + assert auth_models.User.objects.create_superuser(AUTO_ADMIN_USERNAME, 'x@x.com', AUTO_ADMIN_PASSWORD) else: - print 'Super admin user already exists. -- login: %s, password: %s' % (USERNAME, PASSWORD) + print 'Super admin user already exists. -- login: %s' % AUTO_ADMIN_USERNAME -if (validate_path(common_settings.TEMPORARY_DIRECTORY) == False) or (not common_settings.TEMPORARY_DIRECTORY): +if (validate_path(TEMPORARY_DIRECTORY) == False) or (not TEMPORARY_DIRECTORY): setattr(common_settings, 'TEMPORARY_DIRECTORY', tempfile.mkdtemp()) From 774b5bc8dcde827e36dc128bcac280d4bd1dea41 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Fri, 6 Apr 2012 01:06:35 -0400 Subject: [PATCH 07/65] Don't install python-gnupg from upstream but from my github fork --- requirements/production.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/production.txt b/requirements/production.txt index 41ab10ed77..eb454ff88a 100644 --- a/requirements/production.txt +++ b/requirements/production.txt @@ -14,6 +14,6 @@ django-compressor==1.1.1 -e git://github.com/rosarior/django-sendfile.git#egg=django-sendfile djangorestframework==0.2.3 South==0.7.3 -python-gnupg==0.2.8 +https://github.com/rosarior/python-gnupg/zipball/0.2.8 python-hkp==0.1.3 requests==0.10.1 From f36d3d1a44445e4fb8b23094d230e228b96d4c04 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Tue, 22 May 2012 12:53:59 -0400 Subject: [PATCH 08/65] Update the required version of South to latest (0.7.5) --- requirements/production.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/production.txt b/requirements/production.txt index eb454ff88a..6666ede069 100644 --- a/requirements/production.txt +++ b/requirements/production.txt @@ -13,7 +13,7 @@ cssmin==0.1.4 django-compressor==1.1.1 -e git://github.com/rosarior/django-sendfile.git#egg=django-sendfile djangorestframework==0.2.3 -South==0.7.3 +South==0.7.5 https://github.com/rosarior/python-gnupg/zipball/0.2.8 python-hkp==0.1.3 requests==0.10.1 From b03f9237ef002dc3493343a933dfae16397c7e73 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Tue, 29 May 2012 02:36:35 -0400 Subject: [PATCH 09/65] Improve document statistics performance, fix None/0 error when calculating statistics on a empty DB --- apps/documents/statistics.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/documents/statistics.py b/apps/documents/statistics.py index 508d699a49..557a0c52dd 100644 --- a/apps/documents/statistics.py +++ b/apps/documents/statistics.py @@ -53,15 +53,15 @@ def get_statistics(): except NotImplementedError: pass + document_stats = DocumentVersion.objects.annotate(page_count=Count('documentpage')).aggregate(Min('page_count'), Max('page_count'), Avg('page_count')) paragraphs.extend( [ _(u'Document pages in database: %d') % DocumentPage.objects.only('pk',).count(), - _(u'Minimum amount of pages per document: %(page_count__min)d') % DocumentVersion.objects.annotate(page_count=Count('documentpage')).aggregate(Min('page_count')), - _(u'Maximum amount of pages per document: %(page_count__max)d') % DocumentVersion.objects.annotate(page_count=Count('documentpage')).aggregate(Max('page_count')), - _(u'Average amount of pages per document: %(page_count__avg)f') % DocumentVersion.objects.annotate(page_count=Count('documentpage')).aggregate(Avg('page_count')), + _(u'Minimum amount of pages per document: %d') % (document_stats['page_count__max'] or 0), + _(u'Maximum amount of pages per document: %d') % (document_stats['page_count__max'] or 0), + _(u'Average amount of pages per document: %f') % (document_stats['page_count__avg'] or 0), ] ) - #[(day_count['date_added'].strftime('%Y-%m-%d'), day_count['id__count']) for day_count in Document.objects.values('date_added').annotate(Count("id"))] return { 'title': _(u'Document statistics'), From 7141f5814e1c75cc28f157250e677727223161ce Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Tue, 29 May 2012 02:37:19 -0400 Subject: [PATCH 10/65] Bump version to v0.12.1 --- apps/main/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/main/__init__.py b/apps/main/__init__.py index 97aa7458f4..09b3b0e52d 100644 --- a/apps/main/__init__.py +++ b/apps/main/__init__.py @@ -21,7 +21,7 @@ __status__ = 'Production' __version_info__ = { 'major': 0, 'minor': 12, - 'micro': 0, + 'micro': 1, 'releaselevel': 'final', 'serial': 0 } From 1f75b76f96ef9630431092f32dda31ebf5642789 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Tue, 29 May 2012 02:40:29 -0400 Subject: [PATCH 11/65] Remove pre-South migration script --- contrib/metadata_conversion.txt | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 contrib/metadata_conversion.txt diff --git a/contrib/metadata_conversion.txt b/contrib/metadata_conversion.txt deleted file mode 100644 index f21d250da9..0000000000 --- a/contrib/metadata_conversion.txt +++ /dev/null @@ -1,7 +0,0 @@ -mysqldump mayan documents_metadatatype -u root -p | replace 'documents_metadatatype' 'metadata_metadatatype' > new_types.mysql -cat new_types.mysql | mysql -u root -p mayan - -mysqldump mayan documents_documentmetadata -u root -p | replace 'documents_documentmetadata' 'metadata_documentmetadata' > new_metadata.mysql -cat new_metadata.mysql | mysql -u root -p mayan - - From 26705d1506ed2fe10276b232b15ec12ae6b5ea8e Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Tue, 29 May 2012 02:46:30 -0400 Subject: [PATCH 12/65] Catch OSError exception when calculating document filesystem stats --- apps/documents/statistics.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/apps/documents/statistics.py b/apps/documents/statistics.py index 557a0c52dd..5c4eb46773 100644 --- a/apps/documents/statistics.py +++ b/apps/documents/statistics.py @@ -21,16 +21,20 @@ def get_used_size(path, file_list): def storage_count(path=u'.'): - directories, files = STORAGE_BACKEND().listdir(path) - total_count = len(files) - total_size = get_used_size(path, files) + try: + directories, files = STORAGE_BACKEND().listdir(path) + except OSError: + return 0, 0 + else: + total_count = len(files) + total_size = get_used_size(path, files) - for directory in directories: - file_count, files_size = storage_count(directory) - total_count += file_count - total_size += files_size + for directory in directories: + file_count, files_size = storage_count(directory) + total_count += file_count + total_size += files_size - return total_count, total_size + return total_count, total_size def get_statistics(): From fbed4678fe9c802cb62fd3ffc60c51c5f51da0b7 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Tue, 29 May 2012 02:49:02 -0400 Subject: [PATCH 13/65] Add libpng-dev and libjpeg-dev to the installation instructions --- docs/intro/installation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/intro/installation.rst b/docs/intro/installation.rst index 3d9056fab7..bfcffe1ad3 100644 --- a/docs/intro/installation.rst +++ b/docs/intro/installation.rst @@ -9,7 +9,7 @@ Local or managed server If using a Debian_ or Ubuntu_ based Linux distribution getting the executable requirements is as easy as:: - $ apt-get install tesseract-ocr unpaper python-virtualenv ghostscript -y + $ apt-get install tesseract-ocr unpaper python-virtualenv ghostscript libjpeg-dev libpng-dev -y To initialize a ``virtualenv`` to deploy the project do:: From a6ee0c91887c9b964ca9bd584495bec29bb9184a Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Tue, 29 May 2012 03:06:54 -0400 Subject: [PATCH 14/65] Add installation test step --- docs/intro/installation.rst | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/intro/installation.rst b/docs/intro/installation.rst index bfcffe1ad3..cb0285e2ab 100644 --- a/docs/intro/installation.rst +++ b/docs/intro/installation.rst @@ -50,7 +50,17 @@ Collect the static files of the project into the ``static`` folder for serving v $ ./manage.py collectstatic -After that deploy it using the webserver of your preference. If your are using Apache_, a sample site file is included under the contrib directory. +To test your installation, create a file called settings_local.py with the following content:: + + DEBUG=True + DEVELOPMENT=True + +Execute Django’s development server using the ``runserver`` command to launch a local instance of Mayan EDMS:: + + $ ./manager.py runserver + +Point your browser to http://127:0.0.1:8000, if everything was installed correctly you should see the login screen. After making sure everything is running correctly, stop the runserver command, delete the settings_local.py and deploy Mayan EDMS using the webserver of your preference. If your are using Apache_, a sample site file is included under the contrib directory. + Webfaction ---------- From ec23b95afec23757975e86f7a1c9d588ecb8d02c Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Tue, 29 May 2012 03:07:12 -0400 Subject: [PATCH 15/65] Add Mailing list link to top --- docs/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/index.rst b/docs/index.rst index 0079a21776..fe94d819c9 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -23,6 +23,7 @@ On the Web * Website: http://www.mayan-edms.com * Source: http://github.com/rosarior/mayan * Video: http://bit.ly/Mayan-Intro +* Mailing list: http://groups.google.com/group/mayan-edms/ Looking for specific information? Try the :doc:`detailed table of contents ` otherwise below are the different part of the documentation. From 2ee3542e054fb64f08092da5fe1f48a81a04af8c Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Tue, 29 May 2012 03:18:08 -0400 Subject: [PATCH 16/65] Bump documentation version --- docs/conf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index ded1ddc7f8..c5b1ad6046 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -52,10 +52,10 @@ copyright = u'2011, Roberto Rosario' # built documents. # # The short X.Y version. -version = '0.12' +version = '0.12.1' # The full version, including alpha/beta/rc tags. -release = '0.12' +release = '0.12.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. From 4331c00b79fc3c7979a5c6c86f9851fb8d80882c Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Tue, 29 May 2012 03:32:33 -0400 Subject: [PATCH 17/65] Update index view name to display again multi document actions in the index instance view --- apps/documents/__init__.py | 2 +- apps/metadata/__init__.py | 2 +- apps/ocr/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/documents/__init__.py b/apps/documents/__init__.py index cae0edd960..e9ebce4ac8 100644 --- a/apps/documents/__init__.py +++ b/apps/documents/__init__.py @@ -132,7 +132,7 @@ register_links(['document_type_filename_create', 'document_type_filename_list', # Register document links register_links(Document, [document_view_simple, document_edit, document_print, document_delete, document_download, document_find_duplicates, document_clear_transformations, document_create_siblings]) -register_multi_item_links(['document_find_duplicates', 'folder_view', 'index_instance_list', 'document_type_document_list', 'search', 'results', 'document_group_view', 'document_list', 'document_list_recent'], [document_multiple_clear_transformations, document_multiple_delete, document_multiple_download]) +register_multi_item_links(['document_find_duplicates', 'folder_view', 'index_instance_node_view', 'document_type_document_list', 'search', 'results', 'document_group_view', 'document_list', 'document_list_recent'], [document_multiple_clear_transformations, document_multiple_delete, document_multiple_download]) # Document Version links register_links(DocumentVersion, [document_version_revert, document_version_download]) diff --git a/apps/metadata/__init__.py b/apps/metadata/__init__.py index 9f7ea6bb6e..29ee9ac45e 100644 --- a/apps/metadata/__init__.py +++ b/apps/metadata/__init__.py @@ -40,7 +40,7 @@ setup_document_type_metadata = {'text': _(u'default metadata'), 'view': 'setup_d register_links(['metadata_add', 'metadata_edit', 'metadata_remove', 'metadata_view'], [metadata_add, metadata_edit, metadata_remove], menu_name='sidebar') register_links(Document, [metadata_view], menu_name='form_header') -register_multi_item_links(['document_find_duplicates', 'folder_view', 'index_instance_list', 'document_type_document_list', 'search', 'results', 'document_group_view', 'document_list', 'document_list_recent'], [metadata_multiple_add, metadata_multiple_edit, metadata_multiple_remove]) +register_multi_item_links(['document_find_duplicates', 'folder_view', 'index_instance_node_view', 'document_type_document_list', 'search', 'results', 'document_group_view', 'document_list', 'document_list_recent'], [metadata_multiple_add, metadata_multiple_edit, metadata_multiple_remove]) register_links(MetadataType, [setup_metadata_type_edit, setup_metadata_type_delete]) register_links([MetadataType, 'setup_metadata_type_list', 'setup_metadata_type_create'], [setup_metadata_type_list, setup_metadata_type_create], menu_name='secondary_menu') diff --git a/apps/ocr/__init__.py b/apps/ocr/__init__.py index 3a3b0ac7c9..e1157f3902 100644 --- a/apps/ocr/__init__.py +++ b/apps/ocr/__init__.py @@ -50,7 +50,7 @@ setup_queue_transformation_edit = {'text': _(u'edit'), 'view': 'setup_queue_tran setup_queue_transformation_delete = {'text': _(u'delete'), 'view': 'setup_queue_transformation_delete', 'args': 'transformation.pk', 'famfam': 'shape_square_delete'} register_links(Document, [submit_document]) -register_multi_item_links(['document_find_duplicates', 'folder_view', 'index_instance_list', 'document_type_document_list', 'search', 'results', 'document_group_view', 'document_list', 'document_list_recent'], [submit_document_multiple]) +register_multi_item_links(['document_find_duplicates', 'folder_view', 'index_instance_node_view', 'document_type_document_list', 'search', 'results', 'document_group_view', 'document_list', 'document_list_recent'], [submit_document_multiple]) register_links(DocumentQueue, [document_queue_disable, document_queue_enable, setup_queue_transformation_list]) register_links(QueueTransformation, [setup_queue_transformation_edit, setup_queue_transformation_delete]) From d235ca406f83464df48293ef8dca184068dbe269 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Tue, 29 May 2012 04:23:18 -0400 Subject: [PATCH 18/65] Add improve office document conversion with new office converter backend --- apps/converter/conf/settings.py | 1 + apps/converter/office_converter.py | 58 +++++++++++++++++++++++++++--- docs/topics/settings.rst | 15 ++++++-- 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/apps/converter/conf/settings.py b/apps/converter/conf/settings.py index 1dbfe4d6bc..f13cc2c76f 100644 --- a/apps/converter/conf/settings.py +++ b/apps/converter/conf/settings.py @@ -15,6 +15,7 @@ register_settings( {'name': u'GRAPHICS_BACKEND', 'global_name': u'CONVERTER_GRAPHICS_BACKEND', 'default': u'converter.backends.python', 'description': _(u'Graphics conversion backend to use. Options are: converter.backends.imagemagick, converter.backends.graphicsmagick and converter.backends.python.')}, {'name': u'UNOCONV_PATH', 'global_name': u'CONVERTER_UNOCONV_PATH', 'default': u'/usr/bin/unoconv', 'exists': True, 'description': _(u'Path to the unoconv program.')}, {'name': u'UNOCONV_USE_PIPE', 'global_name': u'CONVERTER_UNOCONV_USE_PIPE', 'default': True, 'description': _(u'Use alternate method of connection to LibreOffice using a pipe, it is slower but less prone to segmentation faults.')}, + {'name': u'LIBREOFFICE_PATH', 'global_name': u'CONVERTER_LIBREOFFICE_PATH', 'default': u'/usr/bin/libreoffice', 'exists': True, 'description': _(u'Path to the libreoffice program.')}, #{'name': u'OCR_OPTIONS', 'global_name': u'CONVERTER_OCR_OPTIONS', 'default': u'-colorspace Gray -depth 8 -resample 200x200'}, #{'name': u'HIGH_QUALITY_OPTIONS', 'global_name': u'CONVERTER_HIGH_QUALITY_OPTIONS', 'default': u'-density 400'}, diff --git a/apps/converter/office_converter.py b/apps/converter/office_converter.py index 07c7a28f62..40e8ad1dc3 100644 --- a/apps/converter/office_converter.py +++ b/apps/converter/office_converter.py @@ -8,7 +8,7 @@ from mimetype.api import get_mimetype from common.conf.settings import TEMPORARY_DIRECTORY from common.utils import id_generator -from .conf.settings import UNOCONV_PATH, UNOCONV_USE_PIPE +from .conf.settings import UNOCONV_PATH, UNOCONV_USE_PIPE, LIBREOFFICE_PATH from .exceptions import (OfficeConversionError, OfficeBackendError, UnknownFileFormat) @@ -38,7 +38,7 @@ logger = logging.getLogger(__name__) class OfficeConverter(object): def __init__(self): - self.backend_class = OfficeConverterBackendUnoconv + self.backend_class = OfficeConverterBackendDirect self.backend = self.backend_class() self.exists = False self.mimetype = None @@ -86,9 +86,9 @@ class OfficeConverterBackendUnoconv(object): 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 @@ -118,3 +118,53 @@ class OfficeConverterBackendUnoconv(object): raise OfficeBackendError(msg) except Exception, msg: logger.error('Unhandled exception', exc_info=msg) + + +class OfficeConverterBackendDirect(object): + def __init__(self): + self.libreoffice_path = LIBREOFFICE_PATH if LIBREOFFICE_PATH else u'/usr/bin/libreoffice' + 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(u'--headless') + command.append(u'--convert-to') + command.append(u'pdf') + command.append(self.input_filepath) + command.append(u'--outdir') + command.append(TEMPORARY_DIRECTORY) + + logger.debug('command: %s' % command) + + try: + 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, msg: + raise OfficeBackendError(msg) + except Exception, msg: + logger.error('Unhandled exception', exc_info=msg) + diff --git a/docs/topics/settings.rst b/docs/topics/settings.rst index ae395a435e..f40ae0ee69 100644 --- a/docs/topics/settings.rst +++ b/docs/topics/settings.rst @@ -200,7 +200,7 @@ fine tune it's functionality as explained in the `GraphicsMagick documentation`_ Default: ``/usr/bin/unoconv`` -Path to the unoconv program used to call LibreOffice for office document convertion. +Path to the unoconv program used to call LibreOffice for office document conversion. .. setting:: CONVERTER_UNOCONV_USE_PIPE @@ -211,8 +211,19 @@ Path to the unoconv program used to call LibreOffice for office document convert Default: ``True`` Use alternate method of connection to LibreOffice using a pipe, it is slower but less prone to segmentation faults. + + +.. setting:: CONVERTER_LIBREOFFICE_PATH + + +**CONVERTER_LIBREOFFICE_PATH** + +Default: ``/usr/bin/libreoffice`` + +Path to the libreoffice binary used to call LibreOffice for office document conversion. - + + Linking ======= From 29791999c226ddd14a6cddc1cad4556a13cd2e5a Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Tue, 29 May 2012 23:54:07 -0400 Subject: [PATCH 19/65] Allow document mimetypes to be None --- ..._change_document_mimetype_encoding_null.py | 160 ++++++++++++++++++ apps/documents/models.py | 4 +- apps/documents/views.py | 4 +- apps/mimetype/api.py | 4 +- 4 files changed, 166 insertions(+), 6 deletions(-) create mode 100644 apps/documents/migrations/0014_change_document_mimetype_encoding_null.py diff --git a/apps/documents/migrations/0014_change_document_mimetype_encoding_null.py b/apps/documents/migrations/0014_change_document_mimetype_encoding_null.py new file mode 100644 index 0000000000..57288c6aa8 --- /dev/null +++ b/apps/documents/migrations/0014_change_document_mimetype_encoding_null.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + + # Changing field 'DocumentVersion.mimetype' + db.alter_column('documents_documentversion', 'mimetype', self.gf('django.db.models.fields.CharField')(max_length=64, null=True)) + + # Changing field 'DocumentVersion.encoding' + db.alter_column('documents_documentversion', 'encoding', self.gf('django.db.models.fields.CharField')(max_length=64, null=True)) + + def backwards(self, orm): + + # Changing field 'DocumentVersion.mimetype' + db.alter_column('documents_documentversion', 'mimetype', self.gf('django.db.models.fields.CharField')(max_length=64)) + + # Changing field 'DocumentVersion.encoding' + db.alter_column('documents_documentversion', 'encoding', self.gf('django.db.models.fields.CharField')(max_length=64)) + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'comments.comment': { + 'Meta': {'ordering': "('submit_date',)", 'object_name': 'Comment', 'db_table': "'django_comments'"}, + 'comment': ('django.db.models.fields.TextField', [], {'max_length': '3000'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'content_type_set_for_comment'", 'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ip_address': ('django.db.models.fields.IPAddressField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_removed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'object_pk': ('django.db.models.fields.TextField', [], {}), + 'site': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['sites.Site']"}), + 'submit_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'comment_comments'", 'null': 'True', 'to': "orm['auth.User']"}), + 'user_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'user_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), + 'user_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'documents.document': { + 'Meta': {'ordering': "['-date_added']", 'object_name': 'Document'}, + 'date_added': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'document_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['documents.DocumentType']", 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '48', 'blank': 'True'}) + }, + 'documents.documentpage': { + 'Meta': {'ordering': "['page_number']", 'object_name': 'DocumentPage'}, + 'content': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'document_version': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['documents.DocumentVersion']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'page_label': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'page_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'db_index': 'True'}) + }, + 'documents.documentpagetransformation': { + 'Meta': {'ordering': "('order',)", 'object_name': 'DocumentPageTransformation'}, + 'arguments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'document_page': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['documents.DocumentPage']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), + 'transformation': ('django.db.models.fields.CharField', [], {'max_length': '128'}) + }, + 'documents.documenttype': { + 'Meta': {'ordering': "['name']", 'object_name': 'DocumentType'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}) + }, + 'documents.documenttypefilename': { + 'Meta': {'ordering': "['filename']", 'object_name': 'DocumentTypeFilename'}, + 'document_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['documents.DocumentType']"}), + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'filename': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'documents.documentversion': { + 'Meta': {'unique_together': "(('document', 'major', 'minor', 'micro', 'release_level', 'serial'),)", 'object_name': 'DocumentVersion'}, + 'checksum': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['documents.Document']"}), + 'encoding': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), + 'filename': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '255', 'db_index': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'major': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), + 'micro': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'mimetype': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'minor': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'release_level': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), + 'serial': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'timestamp': ('django.db.models.fields.DateTimeField', [], {}) + }, + 'documents.recentdocument': { + 'Meta': {'ordering': "('-datetime_accessed',)", 'object_name': 'RecentDocument'}, + 'datetime_accessed': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['documents.Document']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'sites.site': { + 'Meta': {'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'"}, + 'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'taggit.tag': { + 'Meta': {'object_name': 'Tag'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'}) + }, + 'taggit.taggeditem': { + 'Meta': {'object_name': 'TaggedItem'}, + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'taggit_taggeditem_tagged_items'", 'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}), + 'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'taggit_taggeditem_items'", 'to': "orm['taggit.Tag']"}) + } + } + + complete_apps = ['documents'] \ No newline at end of file diff --git a/apps/documents/models.py b/apps/documents/models.py index e3ad7be96a..c820780c3b 100644 --- a/apps/documents/models.py +++ b/apps/documents/models.py @@ -312,8 +312,8 @@ class DocumentVersion(models.Model): # File related fields file = models.FileField(upload_to=get_filename_from_uuid, storage=STORAGE_BACKEND(), verbose_name=_(u'file')) - mimetype = models.CharField(max_length=64, default='', editable=False) - encoding = models.CharField(max_length=64, default='', editable=False) + mimetype = models.CharField(max_length=64, null=True, blank=True, editable=False) + encoding = models.CharField(max_length=64, null=True, blank=True, editable=False) filename = models.CharField(max_length=255, default=u'', editable=False, db_index=True) checksum = models.TextField(blank=True, null=True, verbose_name=_(u'checksum'), editable=False) diff --git a/apps/documents/views.py b/apps/documents/views.py index e6c10db735..6da52238a9 100644 --- a/apps/documents/views.py +++ b/apps/documents/views.py @@ -130,8 +130,8 @@ def document_view(request, document_id, advanced=False): if advanced: document_properties_form = DocumentPropertiesForm(instance=document, extra_fields=[ {'label': _(u'Filename'), 'field': 'filename'}, - {'label': _(u'File mimetype'), 'field': 'file_mimetype'}, - {'label': _(u'File mime encoding'), 'field': 'file_mime_encoding'}, + {'label': _(u'File mimetype'), 'field': lambda x: x.file_mimetype or _(u'None')}, + {'label': _(u'File mime encoding'), 'field': lambda x: x.file_mime_encoding or _(u'None')}, {'label': _(u'File size'), 'field':lambda x: pretty_size(x.size) if x.size else '-'}, {'label': _(u'Exists in storage'), 'field': 'exists'}, {'label': _(u'File path in storage'), 'field': 'file'}, diff --git a/apps/mimetype/api.py b/apps/mimetype/api.py index cc7e93db32..1580493a7e 100644 --- a/apps/mimetype/api.py +++ b/apps/mimetype/api.py @@ -94,8 +94,8 @@ def get_mimetype(file_description, filepath, mimetype_only=False): library via python-magic or fallback to use python's mimetypes library """ - file_mimetype = u'' - file_mime_encoding = u'' + file_mimetype = None + file_mime_encoding = None if USE_PYTHON_MAGIC: mime = magic.Magic(mime=True) file_mimetype = mime.from_buffer(file_description.read()) From 036ec092347b909be6977cb400979eadbb9b7bfc Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Wed, 30 May 2012 12:56:56 -0400 Subject: [PATCH 20/65] Move the copyfile function to the common app --- apps/common/utils.py | 35 +++++++++++++++++++++++++++++++++++ apps/converter/utils.py | 23 ----------------------- apps/documents/utils.py | 24 ------------------------ 3 files changed, 35 insertions(+), 47 deletions(-) diff --git a/apps/common/utils.py b/apps/common/utils.py index 3905be558c..d21f6b6e72 100644 --- a/apps/common/utils.py +++ b/apps/common/utils.py @@ -392,3 +392,38 @@ def encapsulate(function): def id_generator(size=6, chars=string.ascii_uppercase + string.digits): return ''.join(random.choice(chars) for x in range(size)) + + +def get_descriptor(file_input, read=True): + try: + # Is it a file like object? + file_input.seek(0) + except AttributeError: + # If not, try open it. + if read: + return open(file_input, 'rb') + else: + return open(file_input, 'wb') + else: + return file_input + + +#http://stackoverflow.com/questions/123198/how-do-i-copy-a-file-in-python +def copyfile(source, destination, buffer_size=1024 * 1024): + """ + Copy a file from source to dest. source and dest + can either be strings or any object with a read or + write method, like StringIO for example. + """ + source_descriptor = get_descriptor(source) + destination_descriptor = get_descriptor(destination, read=False) + + while True: + copy_buffer = source_descriptor.read(buffer_size) + if copy_buffer: + destination_descriptor.write(copy_buffer) + else: + break + + source_descriptor.close() + destination_descriptor.close() diff --git a/apps/converter/utils.py b/apps/converter/utils.py index 1544db04ee..d85157ff2b 100644 --- a/apps/converter/utils.py +++ b/apps/converter/utils.py @@ -4,29 +4,6 @@ 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 - can either be strings or any object with a read or - write method, like StringIO for example. - """ - if not hasattr(source, 'read'): - source = open(source, 'rb') - if not hasattr(dest, 'write'): - dest = open(dest, 'wb') - - while 1: - copy_buffer = source.read(buffer_size) - if copy_buffer: - dest.write(copy_buffer) - else: - break - - source.close() - dest.close() - - def _lazy_load(fn): _cached = [] diff --git a/apps/documents/utils.py b/apps/documents/utils.py index 32658d5f43..cae8b87a5f 100644 --- a/apps/documents/utils.py +++ b/apps/documents/utils.py @@ -2,30 +2,6 @@ import os from common.conf.settings import TEMPORARY_DIRECTORY - -#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 - can either be strings or any object with a read or - write method, like StringIO for example. - """ - if not hasattr(source, 'read'): - source = open(source, 'rb') - if not hasattr(dest, 'write'): - dest = open(dest, 'wb') - - while True: - copy_buffer = source.read(buffer_size) - if copy_buffer: - dest.write(copy_buffer) - else: - break - - source.close() - dest.close() - - def document_save_to_temp_dir(document, filename, buffer_size=1024 * 1024): temporary_path = os.path.join(TEMPORARY_DIRECTORY, filename) return document.save_to_file(temporary_path, buffer_size) From babd3ec2f394b08776cbae198fdc1d93fda6dcd7 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Wed, 30 May 2012 12:57:25 -0400 Subject: [PATCH 21/65] Refacto parser system to be class based, add poppler based PDF parser, allow multiple parsers for each mimetype with fallback --- apps/ocr/parsers/__init__.py | 180 ++++++++++++++++++++++++++--------- 1 file changed, 135 insertions(+), 45 deletions(-) diff --git a/apps/ocr/parsers/__init__.py b/apps/ocr/parsers/__init__.py index 6a91d392d4..0eb1d7e9bd 100644 --- a/apps/ocr/parsers/__init__.py +++ b/apps/ocr/parsers/__init__.py @@ -1,5 +1,6 @@ import slate import logging +import tempfile from django.utils.translation import ugettext as _ @@ -7,6 +8,8 @@ from converter import office_converter from converter.office_converter import OfficeConverter from converter.exceptions import OfficeConversionError from documents.utils import document_save_to_temp_dir +from common.utils import copyfile +from common.conf.settings import TEMPORARY_DIRECTORY from ocr.parsers.exceptions import ParserError, ParserUnknownFile @@ -15,48 +18,16 @@ mimetype_registry = {} logger = logging.getLogger(__name__) -def register_parser(function, mimetype=None, mimetypes=None): - if mimetypes: - for mimetype in mimetypes: - mimetype_registry[mimetype] = {'function': function} - else: - mimetype_registry[mimetype] = {'function': function} - - -def pdf_parser(document_page, descriptor=None): - if not descriptor: - descriptor = document_page.document_version.open() - - pdf_pages = slate.PDF(descriptor) - descriptor.close() - - if pdf_pages[document_page.page_number - 1] == '\x0c': - raise ParserError - - document_page.content = pdf_pages[document_page.page_number - 1] - document_page.page_label = _(u'Text extracted from PDF') - document_page.save() - - -def office_parser(document_page): - logger.debug('executing') - try: - office_converter = OfficeConverter() - document_file = document_save_to_temp_dir(document_page.document, document_page.document.checksum) - logger.debug('document_file: %s', document_file) - - office_converter.convert(document_file, mimetype=document_page.document.file_mimetype) - if office_converter.exists: - input_filepath = office_converter.output_filepath - logger.debug('office_converter.output_filepath: %s', input_filepath) - - pdf_parser(document_page, descriptor=open(input_filepath)) - else: - raise ParserError - - except OfficeConversionError, msg: - print msg - raise ParserError +def register_parser(mimetypes, parsers): + for mimetype in mimetypes: + for parser in parsers: + try: + parser_instance = parser() + except ParserError: + # If parser fails initialization is not added to the list for this mimetype + pass + else: + mimetype_registry.setdefault(mimetype, []).append(parser_instance) def parse_document_page(document_page): @@ -65,10 +36,129 @@ def parse_document_page(document_page): logger.debug('mimetype: %s' % document_page.document.file_mimetype) try: - mimetype_registry[document_page.document.file_mimetype]['function'](document_page) + for parser in mimetype_registry[document_page.document.file_mimetype]['function']: + try: + parser.parse(document_page) + except ParserError: + # If parser raises error, try next parser in the list + pass + else: + # If parser was successfull there is no need to try + # others in the list for this mimetype + break; except KeyError: raise ParserUnknownFile -register_parser(mimetype=u'application/pdf', function=pdf_parser) -register_parser(mimetypes=office_converter.CONVERTER_OFFICE_FILE_MIMETYPES, function=office_parser) +class Parser(object): + """ + Parser base class + """ + + def parse(self, document_page): + raise NotImplementedError("Your %s class has not defined a parse() method, which is required." % self.__class__.__name__) + + +class SlateParser(Parser): + """ + Parser for PDF files using the slate library for Python + """ + def parse(document_page, descriptor=None): + if not descriptor: + descriptor = document_page.document_version.open() + + pdf_pages = slate.PDF(descriptor) + descriptor.close() + + if pdf_pages[document_page.page_number - 1] == '\x0c': + raise ParserError + + document_page.content = pdf_pages[document_page.page_number - 1] + document_page.page_label = _(u'Text extracted from PDF') + document_page.save() + + +class OfficeParser(Parser): + """ + Parser for office document formats + """ + def parse(document_page): + logger.debug('executing') + try: + office_converter = OfficeConverter() + document_file = document_save_to_temp_dir(document_page.document, document_page.document.checksum) + logger.debug('document_file: %s', document_file) + + office_converter.convert(document_file, mimetype=document_page.document.file_mimetype) + if office_converter.exists: + input_filepath = office_converter.output_filepath + logger.debug('office_converter.output_filepath: %s', input_filepath) + + # Now that the office document has been converted to PDF + # call the coresponding PDF parser in this new file + parse_document_page(document_page, descriptor=open(input_filepath)) + else: + raise ParserError + + except OfficeConversionError, msg: + logger.error(msg) + raise ParserError + + +class PopplerParser(Parser): + """ + PDF parser using the pdftotext execute from the poppler package + """ + def __init__(self): + self.pdftotext_path = PDFTOTEXT_PATH if PDFTOTEXT_PATH else u'/usr/bin/pdftotext' + if not os.path.exists(self.pdftotext_path): + raise ParserError('cannot find pdftotext executable') + logger.debug('self.pdftotext_path: %s' % self.pdftotext_path) + + def parse(document_page, descriptor=None): + logger.debug('parsing PDF') + pagenum = str(document_page.page_number) + + if descriptor: + destination_descriptor, temp_filepath = tempfile.mkstemp(dir=TEMPORARY_DIRECTORY) + copyfile(descriptor, destination_descriptor) + document_file = temp_filepath + else: + document_file = document_save_to_temp_dir(document_page.document, document_page.document.checksum) + + logger.debug('document_file: %s', document_file) + + logger.debug('parsing PDF page %s' % pagenum) + + command = [] + command.append(self.pdftotext_path) + command.append('-f') + command.append(pagenum) + command.append('-l') + command.append(pagenum) + command.append(document_file) + command.append('-') + + proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + return_code = proc.wait() + if return_code != 0: + logger.error(proc.stderr.readline()) + raise ParserError + + output = proc.stdout.read() + numalpha = len(filter(str.isalpha, output)) + numother = len(filter(notalphaorspace, output)) + + logger.debug("Numalpha = %d Numother = %d" % (numalpha, numother)) + + if numother > numalpha: + logger.debug("parser error... probably scanned pdf.") + raise ParserError + + document_page.content = output + document_page.page_label = _(u'Text extracted from PDF') + document_page.save() + + +register_parser(mimetypes=[u'application/pdf'], parsers=[PopplerParser, SlateParser]) +register_parser(mimetypes=office_converter.CONVERTER_OFFICE_FILE_MIMETYPES, parsers=[OfficeParser]) From bf12814e0ca1d5c0d33bb1b38272c5bff1c109a1 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Wed, 30 May 2012 16:14:53 -0400 Subject: [PATCH 22/65] Log ocr task errors properly --- apps/ocr/tasks.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/ocr/tasks.py b/apps/ocr/tasks.py index 800d0623d2..c1b9c937d4 100644 --- a/apps/ocr/tasks.py +++ b/apps/ocr/tasks.py @@ -66,8 +66,7 @@ def task_process_document_queues(): oldest_queued_document = oldest_queued_document_qs.order_by('datetime_submitted')[0] process_job(task_process_queue_document, oldest_queued_document.pk) except Exception, e: - pass - #print 'DocumentQueueWatcher exception: %s' % e + logger.error('unhandled exception: %s' % e) finally: # Don't process anymore from this queryset, might be stale break From 200e5f394760022c03414cf29fbbcfdc1d2038a1 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Wed, 30 May 2012 16:15:30 -0400 Subject: [PATCH 23/65] Add setting to specify the location of the pdftotext binary --- apps/ocr/conf/settings.py | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/ocr/conf/settings.py b/apps/ocr/conf/settings.py index 31e2c908b8..d9b7dd2fd3 100644 --- a/apps/ocr/conf/settings.py +++ b/apps/ocr/conf/settings.py @@ -15,5 +15,6 @@ register_settings( {'name': u'AUTOMATIC_OCR', 'global_name': u'OCR_AUTOMATIC_OCR', 'default': False, 'description': _(u'Automatically queue newly created documents for OCR.')}, {'name': u'QUEUE_PROCESSING_INTERVAL', 'global_name': u'OCR_QUEUE_PROCESSING_INTERVAL', 'default': 10}, {'name': u'UNPAPER_PATH', 'global_name': u'OCR_UNPAPER_PATH', 'default': u'/usr/bin/unpaper', 'description': _(u'File path to unpaper program.'), 'exists': True}, + {'name': u'PDFTOTEXT_PATH', 'global_name': u'OCR_PDFTOTEXT_PATH', 'default': u'/usr/bin/pdftotext', 'description': _(u'File path to poppler\'s pdftotext program.'), 'exists': True}, ] ) From d1ccca4d2e7e1d57c1da36635c2f0ee6f9fe4147 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Wed, 30 May 2012 16:15:57 -0400 Subject: [PATCH 24/65] Final updates for the PopplerParser --- apps/ocr/parsers/__init__.py | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/apps/ocr/parsers/__init__.py b/apps/ocr/parsers/__init__.py index 0eb1d7e9bd..2cbf9a67a0 100644 --- a/apps/ocr/parsers/__init__.py +++ b/apps/ocr/parsers/__init__.py @@ -1,6 +1,8 @@ +import os import slate import logging import tempfile +import subprocess from django.utils.translation import ugettext as _ @@ -12,6 +14,7 @@ from common.utils import copyfile from common.conf.settings import TEMPORARY_DIRECTORY from ocr.parsers.exceptions import ParserError, ParserUnknownFile +from ocr.conf.settings import PDFTOTEXT_PATH mimetype_registry = {} @@ -30,15 +33,18 @@ def register_parser(mimetypes, parsers): mimetype_registry.setdefault(mimetype, []).append(parser_instance) -def parse_document_page(document_page): +def parse_document_page(document_page, descriptor=None, mimetype=None): logger.debug('executing') logger.debug('document_page: %s' % document_page) logger.debug('mimetype: %s' % document_page.document.file_mimetype) + if not mimetype: + mimetype = document_page.document.file_mimetype + try: - for parser in mimetype_registry[document_page.document.file_mimetype]['function']: + for parser in mimetype_registry[mimetype]: try: - parser.parse(document_page) + parser.parse(document_page, descriptor) except ParserError: # If parser raises error, try next parser in the list pass @@ -55,7 +61,7 @@ class Parser(object): Parser base class """ - def parse(self, document_page): + def parse(self, document_page, descriptor=None): raise NotImplementedError("Your %s class has not defined a parse() method, which is required." % self.__class__.__name__) @@ -63,7 +69,7 @@ class SlateParser(Parser): """ Parser for PDF files using the slate library for Python """ - def parse(document_page, descriptor=None): + def parse(self, document_page, descriptor=None): if not descriptor: descriptor = document_page.document_version.open() @@ -82,7 +88,7 @@ class OfficeParser(Parser): """ Parser for office document formats """ - def parse(document_page): + def parse(self, document_page, descriptor=None): logger.debug('executing') try: office_converter = OfficeConverter() @@ -96,7 +102,7 @@ class OfficeParser(Parser): # Now that the office document has been converted to PDF # call the coresponding PDF parser in this new file - parse_document_page(document_page, descriptor=open(input_filepath)) + parse_document_page(document_page, descriptor=open(input_filepath), mimetype=u'application/pdf') else: raise ParserError @@ -115,13 +121,13 @@ class PopplerParser(Parser): raise ParserError('cannot find pdftotext executable') logger.debug('self.pdftotext_path: %s' % self.pdftotext_path) - def parse(document_page, descriptor=None): + def parse(self, document_page, descriptor=None): logger.debug('parsing PDF') pagenum = str(document_page.page_number) if descriptor: destination_descriptor, temp_filepath = tempfile.mkstemp(dir=TEMPORARY_DIRECTORY) - copyfile(descriptor, destination_descriptor) + copyfile(descriptor, temp_filepath) document_file = temp_filepath else: document_file = document_save_to_temp_dir(document_page.document, document_page.document.checksum) @@ -146,14 +152,6 @@ class PopplerParser(Parser): raise ParserError output = proc.stdout.read() - numalpha = len(filter(str.isalpha, output)) - numother = len(filter(notalphaorspace, output)) - - logger.debug("Numalpha = %d Numother = %d" % (numalpha, numother)) - - if numother > numalpha: - logger.debug("parser error... probably scanned pdf.") - raise ParserError document_page.content = output document_page.page_label = _(u'Text extracted from PDF') From c754a48c92d0efa61566aea631f5cd722549e15a Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Wed, 30 May 2012 16:57:49 -0400 Subject: [PATCH 25/65] Initial v0.12.1 release notes --- docs/releases/0.12.1.rst | 70 ++++++++++++++++++++++++++++++++++++++++ docs/releases/index.rst | 3 +- 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 docs/releases/0.12.1.rst diff --git a/docs/releases/0.12.1.rst b/docs/releases/0.12.1.rst new file mode 100644 index 0000000000..2c16fdba8e --- /dev/null +++ b/docs/releases/0.12.1.rst @@ -0,0 +1,70 @@ +================================ +Mayan EDMS v0.12.1 release notes +================================ + +*May 2012* + +This is the first maintenance release of the 0.12 series. + +Overview +======== + +While bug fixes and minor feature were the focus for this release, some +bigger changes were included becuase of their importance. The parsing of +document saw a complety rewrite being now class based and allows for more +than one parser per mimetype with sequencial fallback. This provides the +best text extraction on deployments where users have control over the +installation and basic extraction when deploying on the cloud or other +environments where users don't have the ability to install OS level +binaries. + + +What's new in Mayan EDMS v0.12.1 +================================ + +Documentation update +~~~~~~~~~~~~~~~~~~~~ + +New configuration options +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Translations +~~~~~~~~~~~~~~~~~~~ + +Usability improvements +~~~~~~~~~~~~~~~~~~~~~~ + +Better office document conversion +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Better PDF text parsing +~~~~~~~~~~~~~~~~~~~~~~~ + + + +Upgrading from a previous version +================================= + +Start off by adding the new requirements:: + + $ pip install -r requirements/production.txt + +Then create the new database structures with:: + + $ ./manage.py syncdb + +Afterwards migrate existing database schema with:: + + $ ./manage.py migrate documents + +The upgrade procedure is now complete. + + +Backward incompatible changes +============================= + +Bugs fixed +========== + +Stuff removed +============= diff --git a/docs/releases/index.rst b/docs/releases/index.rst index 3bbee2aa57..8949542b57 100644 --- a/docs/releases/index.rst +++ b/docs/releases/index.rst @@ -11,11 +11,12 @@ all the backwards-incompatible changes and deprecated features for each 'final' release from the one after your current **Mayan EDMS** version, up to and including the new version. -Latest version (0.12) +Latest version (0.12.1) --------------------- .. toctree:: :maxdepth: 1 + 0.12.1 0.12 Historic changelogs From b9d88d2859cf29e9073c1dc674b50b23866784b9 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Wed, 30 May 2012 18:35:50 -0400 Subject: [PATCH 26/65] Sync Italian translation sources from Transifex --- apps/acls/locale/it/LC_MESSAGES/django.po | 65 +++++----- apps/common/locale/it/LC_MESSAGES/django.po | 7 +- .../converter/locale/it/LC_MESSAGES/django.po | 45 +++---- .../locale/it/LC_MESSAGES/django.po | 31 ++--- .../locale/it/LC_MESSAGES/django.po | 9 +- .../locale/it/LC_MESSAGES/django.po | 121 ++++++++---------- .../locale/it/LC_MESSAGES/django.po | 24 ++-- .../documents/locale/it/LC_MESSAGES/django.po | 61 ++++----- .../locale/it/LC_MESSAGES/django.po | 16 +-- apps/folders/locale/it/LC_MESSAGES/django.po | 7 +- apps/history/locale/it/LC_MESSAGES/django.po | 16 +-- apps/linking/locale/it/LC_MESSAGES/django.po | 41 ++---- apps/metadata/locale/it/LC_MESSAGES/django.po | 51 ++------ .../locale/it/LC_MESSAGES/django.po | 9 +- apps/ocr/locale/it/LC_MESSAGES/django.po | 41 +++--- .../locale/it/LC_MESSAGES/django.po | 32 ++--- .../locale/it/LC_MESSAGES/django.po | 9 +- .../locale/it/LC_MESSAGES/django.po | 9 +- .../locale/it/LC_MESSAGES/django.po | 9 +- apps/sources/locale/it/LC_MESSAGES/django.po | 64 ++++----- apps/tags/locale/it/LC_MESSAGES/django.po | 21 ++- .../web_theme/locale/it/LC_MESSAGES/django.po | 18 +-- 22 files changed, 300 insertions(+), 406 deletions(-) diff --git a/apps/acls/locale/it/LC_MESSAGES/django.po b/apps/acls/locale/it/LC_MESSAGES/django.po index 232cf6fbab..21fcbe7eca 100644 --- a/apps/acls/locale/it/LC_MESSAGES/django.po +++ b/apps/acls/locale/it/LC_MESSAGES/django.po @@ -3,14 +3,15 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# Pierpaolo Baldan , 2012. # Roberto Rosario , 2012. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" "Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" -"PO-Revision-Date: 2012-02-21 00:41+0000\n" -"Last-Translator: Roberto Rosario \n" +"PO-Revision-Date: 2012-03-21 14:55+0000\n" +"Last-Translator: Pierpaolo Baldan \n" "Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -20,7 +21,7 @@ msgstr "" #: __init__.py:14 msgid "ACLs" -msgstr "" +msgstr "ACL" #: __init__.py:15 __init__.py:23 msgid "details" @@ -36,19 +37,19 @@ msgstr "revocare" #: __init__.py:18 __init__.py:24 forms.py:21 msgid "New holder" -msgstr "" +msgstr "Nuovo titolare" #: __init__.py:20 msgid "Default ACLs" -msgstr "" +msgstr "Default ACL" #: __init__.py:21 msgid "List of classes" -msgstr "" +msgstr "Elenco delle classi" #: __init__.py:22 msgid "ACLs for class" -msgstr "" +msgstr "ACL per la classe" #: forms.py:38 msgid "Users" @@ -60,7 +61,7 @@ msgstr "Gruppi" #: forms.py:44 msgid "Roles" -msgstr "" +msgstr "Ruoli" #: forms.py:47 msgid "Special" @@ -68,7 +69,7 @@ msgstr "Speciale" #: managers.py:116 managers.py:128 msgid "Insufficient access." -msgstr "" +msgstr "Accesso insufficiente." #: models.py:27 models.py:69 msgid "permission" @@ -76,19 +77,19 @@ msgstr "autorizzazione" #: models.py:53 msgid "access entry" -msgstr "" +msgstr "voce di accesso" #: models.py:54 msgid "access entries" -msgstr "" +msgstr "voci di accesso" #: models.py:90 msgid "default access entry" -msgstr "" +msgstr "accesso voce predefinita" #: models.py:91 msgid "default access entries" -msgstr "" +msgstr "voci di accesso predefinite " #: models.py:109 msgid "Creator" @@ -100,32 +101,32 @@ msgstr "creatore" #: permissions.py:7 permissions.py:8 msgid "Access control lists" -msgstr "" +msgstr "Liste di controllo accessi" #: permissions.py:10 msgid "Edit ACLs" -msgstr "" +msgstr "Modifica ACL" #: permissions.py:11 msgid "View ACLs" -msgstr "" +msgstr "Visualizza ACL" #: permissions.py:13 msgid "Edit class default ACLs" -msgstr "" +msgstr "Modifica ACL predefiniti di classe" #: permissions.py:14 msgid "View class default ACLs" -msgstr "" +msgstr "Visualizza classi ACL predefinite" #: views.py:47 #, python-format msgid "access control lists for: %s" -msgstr "" +msgstr "lista controllo accessi per: %s" #: views.py:49 views.py:411 msgid "holder" -msgstr "" +msgstr "titolare" #: views.py:50 views.py:412 msgid "permissions" @@ -138,11 +139,11 @@ msgstr "autorizzazioni disponibili per: %(actor)s per %(obj)s " #: views.py:104 views.py:444 msgid "namespace" -msgstr "" +msgstr "namespace" #: views.py:105 views.py:445 msgid "label" -msgstr "" +msgstr "etichetta" #: views.py:107 views.py:447 msgid "has permission" @@ -175,14 +176,14 @@ msgstr "Sei sicuro di voler concedere permessi %(title_suffix)s?" #: views.py:199 views.py:542 #, python-format msgid "Permission \"%(permission)s\" granted to %(actor)s for %(object)s." -msgstr "" +msgstr "Permesso \"%(permission)s\" concesso%(actor)s per %(object)s." #: views.py:205 views.py:548 #, python-format msgid "" "%(actor)s, already had the permission \"%(permission)s\" granted for " "%(object)s." -msgstr "" +msgstr "%(actor)s, ha già i permessi\"%(permission)s\" concessi per%(object)s." #: views.py:281 views.py:610 #, python-format @@ -202,17 +203,17 @@ msgstr "Sei sicuro di voler revocare permessi %(title_suffix)s?" #: views.py:293 views.py:622 #, python-format msgid "Permission \"%(permission)s\" revoked of %(actor)s for %(object)s." -msgstr "" +msgstr "Permessi \"%(permission)s\" revocati al %(actor)s per %(object)s." #: views.py:299 views.py:628 #, python-format msgid "%(actor)s, didn't had the permission \"%(permission)s\" for %(object)s." -msgstr "" +msgstr "%(actor)s, non ha i permessi\"%(permission)s\" per %(object)s." #: views.py:355 #, python-format msgid "add new holder for: %s" -msgstr "" +msgstr "aggiungi nuovo titolare per: %s" #: views.py:356 views.py:488 msgid "Select" @@ -220,23 +221,23 @@ msgstr "Selezionare" #: views.py:388 msgid "classes" -msgstr "" +msgstr "classi" #: views.py:390 msgid "class" -msgstr "" +msgstr "classe" #: views.py:409 #, python-format msgid "default access control lists for class: %s" -msgstr "" +msgstr "lista di default per il controllo accessi per la classe: %s" #: views.py:437 #, python-format msgid "permissions available to: %(actor)s for class %(class)s" -msgstr "" +msgstr "permessi disponibili per: %(actor)s per la classe %(class)s" #: views.py:486 #, python-format msgid "add new holder for class: %s" -msgstr "" +msgstr "aggiungi un nuovo titolare per la calsse: %s" diff --git a/apps/common/locale/it/LC_MESSAGES/django.po b/apps/common/locale/it/LC_MESSAGES/django.po index 365d59fa16..479b0fd546 100644 --- a/apps/common/locale/it/LC_MESSAGES/django.po +++ b/apps/common/locale/it/LC_MESSAGES/django.po @@ -4,14 +4,15 @@ # # Translators: # , 2011. +# Pierpaolo Baldan , 2012. # Roberto Rosario , 2012. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" "Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" -"PO-Revision-Date: 2012-02-21 16:35+0000\n" -"Last-Translator: Roberto Rosario \n" +"PO-Revision-Date: 2012-03-21 13:21+0000\n" +"Last-Translator: Pierpaolo Baldan \n" "Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -99,7 +100,7 @@ msgstr "Orizontale" #: models.py:16 msgid "lock field" -msgstr "" +msgstr "blocca campo" #: models.py:43 msgid "Anonymous user" diff --git a/apps/converter/locale/it/LC_MESSAGES/django.po b/apps/converter/locale/it/LC_MESSAGES/django.po index 3ddbf49310..b5cb89a843 100644 --- a/apps/converter/locale/it/LC_MESSAGES/django.po +++ b/apps/converter/locale/it/LC_MESSAGES/django.po @@ -1,22 +1,21 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # , 2011. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" -"Report-Msgid-Bugs-To: \n" +"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" "PO-Revision-Date: 2011-12-09 14:53+0000\n" "Last-Translator: Pierpaolo Baldan \n" -"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/team/" -"it/)\n" -"Language: it\n" +"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" #: __init__.py:15 @@ -474,8 +473,7 @@ msgstr "Magick Image File Format" #: literals.py:177 msgid "" "Multiple-image Network Graphics (libpng 1.2.42,1.2.44, zlib 1.2.3.3,1.2.3.4)" -msgstr "" -"Multiple-image Network Graphics (libpng 1.2.42,1.2.44, zlib 1.2.3.3,1.2.3.4)" +msgstr "Multiple-image Network Graphics (libpng 1.2.42,1.2.44, zlib 1.2.3.3,1.2.3.4)" #: literals.py:178 msgid "Raw Bi-level bitmap in least-significant-byte first order" @@ -636,24 +634,19 @@ msgstr "Portable Network Graphics (libpng 1.2.42,1.2.44, zlib 1.2.3.3,1.2.3.4)" #: literals.py:227 msgid "" "24-bit RGB PNG, opaque only (libpng 1.2.42,1.2.44, zlib 1.2.3.3,1.2.3.4)" -msgstr "" -"24-bit RGB PNG, opaque only (libpng 1.2.42,1.2.44, zlib 1.2.3.3,1.2.3.4)" +msgstr "24-bit RGB PNG, opaque only (libpng 1.2.42,1.2.44, zlib 1.2.3.3,1.2.3.4)" #: literals.py:228 msgid "" "32-bit RGBA PNG, semitransparency OK (libpng 1.2.42,1.2.44, zlib " "1.2.3.3,1.2.3.4)" -msgstr "" -"32-bit RGBA PNG, semitransparency OK (libpng 1.2.42,1.2.44, zlib " -"1.2.3.3,1.2.3.4)" +msgstr "32-bit RGBA PNG, semitransparency OK (libpng 1.2.42,1.2.44, zlib 1.2.3.3,1.2.3.4)" #: literals.py:229 msgid "" "8-bit indexed PNG, binary transparency only (libpng 1.2.42,1.2.44, zlib " "1.2.3.3,1.2.3.4)" -msgstr "" -"8-bit indexed PNG, binary transparency only (libpng 1.2.42,1.2.44, zlib " -"1.2.3.3,1.2.3.4)" +msgstr "8-bit indexed PNG, binary transparency only (libpng 1.2.42,1.2.44, zlib 1.2.3.3,1.2.3.4)" #: literals.py:230 msgid "Portable anymap" @@ -913,12 +906,10 @@ msgstr "File path per il progarmma " #: conf/settings.py:15 msgid "" -"Graphics conversion backend to use. Options are: converter.backends." -"imagemagick, converter.backends.graphicsmagick and converter.backends.python." -msgstr "" -"Backend da usare per la conversione grafica. Le opzioni sono: converter." -"backends.imagemagick, converter.backends.graphicsmagick e converter.backends." -"python." +"Graphics conversion backend to use. Options are: " +"converter.backends.imagemagick, converter.backends.graphicsmagick and " +"converter.backends.python." +msgstr "Backend da usare per la conversione grafica. Le opzioni sono: converter.backends.imagemagick, converter.backends.graphicsmagick e converter.backends.python." #: conf/settings.py:16 msgid "Path to the unoconv program." @@ -926,11 +917,9 @@ msgstr "Path per il programma unoconv" #: conf/settings.py:17 msgid "" -"Use alternate method of connection to LibreOffice using a pipe, it is slower " -"but less prone to segmentation faults." -msgstr "" -"Utilizzare il metodo alternativo di collegamento a LibreOffice utilizzando " -"questo collegamento, è più lento ma meno soggetto a errori di segmentazione." +"Use alternate method of connection to LibreOffice using a pipe, it is slower" +" but less prone to segmentation faults." +msgstr "Utilizzare il metodo alternativo di collegamento a LibreOffice utilizzando questo collegamento, è più lento ma meno soggetto a errori di segmentazione." #: templates/converter_file_formats_help.html:3 msgid "Help" @@ -941,6 +930,4 @@ msgstr "Aiuto" msgid "" "These are the file formats supported by the currently selected converter " "backend. In this case: '%(backend)s'" -msgstr "" -"Questi sono il formati file supportati dal backend selezionato.In questo " -"caso : '%(backend)s'" +msgstr "Questi sono il formati file supportati dal backend selezionato.In questo caso : '%(backend)s'" diff --git a/apps/django_gpg/locale/it/LC_MESSAGES/django.po b/apps/django_gpg/locale/it/LC_MESSAGES/django.po index f636d037db..e1408d3b5b 100644 --- a/apps/django_gpg/locale/it/LC_MESSAGES/django.po +++ b/apps/django_gpg/locale/it/LC_MESSAGES/django.po @@ -1,22 +1,22 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # , 2011. +# Pierpaolo Baldan , 2012. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" -"Report-Msgid-Bugs-To: \n" +"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" -"PO-Revision-Date: 2012-02-02 18:20+0000\n" -"Last-Translator: Roberto Rosario \n" -"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/team/" -"it/)\n" -"Language: it\n" +"PO-Revision-Date: 2012-03-21 13:33+0000\n" +"Last-Translator: Pierpaolo Baldan \n" +"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" #: __init__.py:14 views.py:67 @@ -77,9 +77,7 @@ msgstr "Errore di firma" #: api.py:60 msgid "Document is signed but no public key is available for verification." -msgstr "" -"Il documento è stato firmato, ma la chiave pubblica non è disponibile per la " -"verifica" +msgstr "Il documento è stato firmato, ma la chiave pubblica non è disponibile per la verifica" #: api.py:64 msgid "Document is signed, and signature is good." @@ -103,7 +101,7 @@ msgstr "Nome, e-mail,key ID , impronte digitali per cercare" #: permissions.py:7 msgid "Key management" -msgstr "" +msgstr "Gestione delle chiavi" #: permissions.py:9 msgid "View keys" @@ -119,7 +117,7 @@ msgstr "Interroga l'autorità per le chiavi" #: permissions.py:12 msgid "Import keys from keyservers" -msgstr "" +msgstr "Importa le chiavi dal server di chiavi" #: views.py:38 #, python-format @@ -129,7 +127,7 @@ msgstr "Chiave: %s, importata con successo." #: views.py:43 #, python-format msgid "Unable to import key id: %(key_id)s; %(error)s" -msgstr "" +msgstr "Impossibile importare chiave id: %(key_id)s ; %(error)s " #: views.py:52 msgid "Import key" @@ -163,10 +161,7 @@ msgid "" "Are you sure you wish to delete key: %s? If you try to delete a public key " "that is part of a public/private pair the private key will be deleted as " "well." -msgstr "" -"Sei sicuro di voler cancellare la chiave: %s? Se provi a cancellare una " -"chiave pubblica che è parte di una coppia publica/privata anche la chiave " -"privata sarà cancellata" +msgstr "Sei sicuro di voler cancellare la chiave: %s? Se provi a cancellare una chiave pubblica che è parte di una coppia publica/privata anche la chiave privata sarà cancellata" #: views.py:129 msgid "Query key server" @@ -218,4 +213,4 @@ msgstr "Lista di server per chiavi che si possono interrogare." #: conf/settings.py:16 msgid "Home directory used to store keys as well as configuration files." -msgstr "" +msgstr "Home directory utilizzata per memorizzare le chiavi così come i file di configurazione." diff --git a/apps/document_comments/locale/it/LC_MESSAGES/django.po b/apps/document_comments/locale/it/LC_MESSAGES/django.po index dfa8084546..76c6c822ac 100644 --- a/apps/document_comments/locale/it/LC_MESSAGES/django.po +++ b/apps/document_comments/locale/it/LC_MESSAGES/django.po @@ -1,22 +1,21 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # , 2011. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" -"Report-Msgid-Bugs-To: \n" +"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" "PO-Revision-Date: 2012-02-02 18:20+0000\n" "Last-Translator: Roberto Rosario \n" -"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/team/" -"it/)\n" -"Language: it\n" +"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" #: __init__.py:19 __init__.py:20 diff --git a/apps/document_indexing/locale/it/LC_MESSAGES/django.po b/apps/document_indexing/locale/it/LC_MESSAGES/django.po index 4559e02b61..0e382aa1f5 100644 --- a/apps/document_indexing/locale/it/LC_MESSAGES/django.po +++ b/apps/document_indexing/locale/it/LC_MESSAGES/django.po @@ -1,22 +1,22 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # , 2011. +# Pierpaolo Baldan , 2012. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" -"Report-Msgid-Bugs-To: \n" +"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" -"PO-Revision-Date: 2012-02-02 18:18+0000\n" -"Last-Translator: Roberto Rosario \n" -"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/team/" -"it/)\n" -"Language: it\n" +"PO-Revision-Date: 2012-03-21 14:44+0000\n" +"Last-Translator: Pierpaolo Baldan \n" +"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" #: __init__.py:31 __init__.py:45 __init__.py:47 models.py:42 views.py:36 @@ -30,23 +30,23 @@ msgstr "lista indici" #: __init__.py:33 views.py:74 msgid "create index" -msgstr "" +msgstr "creare un indice" #: __init__.py:34 __init__.py:39 msgid "edit" -msgstr "" +msgstr "modificare" #: __init__.py:35 __init__.py:40 msgid "delete" -msgstr "" +msgstr "cancellare" #: __init__.py:36 msgid "tree template" -msgstr "" +msgstr "albero di template" #: __init__.py:38 msgid "new child node" -msgstr "" +msgstr "nuovo nodo figlio" #: __init__.py:44 msgid "go up one level" @@ -73,17 +73,13 @@ msgstr "Massimo dei suffissi contati (%s) ." #, python-format msgid "" "Error in document indexing update expression: %(expression)s; %(exception)s" -msgstr "" -"Errore nella creazione dell'indice per l'espressione: %(expression)s; " -"%(exception)s" +msgstr "Errore nella creazione dell'indice per l'espressione: %(expression)s; %(exception)s" #: api.py:96 api.py:111 #, python-format msgid "" "Error updating document index, expression: %(expression)s; %(exception)s" -msgstr "" -"Errore nell'aggiornamento delle'indice documento per l'espressione: " -"%(expression)s; %(exception)s" +msgstr "Errore nell'aggiornamento delle'indice documento per l'espressione: %(expression)s; %(exception)s" #: api.py:150 #, python-format @@ -100,9 +96,7 @@ msgstr "Impossibile creare la directory per gli indici; %s" msgid "" "Unable to create symbolic link, file exists and could not be deleted: " "%(filepath)s; %(exc)s" -msgstr "" -"Impossibile creare un link simbolico, il file già esiste e non può essere " -"cancellato: %(filepath)s; %(exc)s" +msgstr "Impossibile creare un link simbolico, il file già esiste e non può essere cancellato: %(filepath)s; %(exc)s" #: filesystem.py:71 #, python-format @@ -126,27 +120,28 @@ msgstr "Funzioni disponibili: %s" #: models.py:17 views.py:40 msgid "name" -msgstr "" +msgstr "nome" #: models.py:17 msgid "Internal name used to reference this index." -msgstr "" +msgstr "Nome interno utilizzato per fare riferimento a questo indice." #: models.py:18 views.py:41 msgid "title" -msgstr "" +msgstr "titolo" #: models.py:18 msgid "The name that will be visible to users." -msgstr "" +msgstr "Il nome che sarà visibile agli utenti." #: models.py:19 models.py:50 msgid "enabled" msgstr "abilitato" #: models.py:19 -msgid "Causes this index to be visible and updated when document data changes." -msgstr "" +msgid "" +"Causes this index to be visible and updated when document data changes." +msgstr "Fa sì che questo indice possa essere visibile e aggiornato quando i dati del documento cambiano." #: models.py:41 models.py:47 views.py:101 views.py:132 views.py:159 #: views.py:195 views.py:225 views.py:265 @@ -163,7 +158,7 @@ msgstr "Inserisci una espressione python perchè possa essere valutata." #: models.py:50 msgid "Causes this node to be visible and updated when document data changes." -msgstr "" +msgstr "Fa sì che questo nodo possa essere visibili e aggiornato quando i dati del documento cambiano." #: models.py:51 msgid "link documents" @@ -171,17 +166,17 @@ msgstr "link al documento" #: models.py:51 msgid "" -"Check this option to have this node act as a container for documents and not " -"as a parent for further nodes." -msgstr "" +"Check this option to have this node act as a container for documents and not" +" as a parent for further nodes." +msgstr "Selezionare questa opzione per questo specifico nodo quale contenitore per i documenti e non come un genitore per ulteriori nodi." #: models.py:57 models.py:63 msgid "index template node" -msgstr "" +msgstr "indice di nodo modello" #: models.py:58 msgid "indexes template nodes" -msgstr "" +msgstr "indici nodi modello" #: models.py:64 msgid "value" @@ -193,11 +188,11 @@ msgstr "documenti" #: models.py:75 msgid "index instance node" -msgstr "" +msgstr "indice dell'istanza nodo" #: models.py:76 msgid "indexes instance nodes" -msgstr "" +msgstr "indici esempio di nodi" #: models.py:80 msgid "index instance" @@ -221,19 +216,19 @@ msgstr "Indicizzazione" #: permissions.py:9 msgid "Configure document indexes" -msgstr "" +msgstr "Configura gli indici dei documenti" #: permissions.py:10 msgid "Create new document indexes" -msgstr "" +msgstr "Creare nuovi indici documento" #: permissions.py:11 msgid "Edit document indexes" -msgstr "" +msgstr "Modifica gli indici dei documenti" #: permissions.py:12 msgid "Delete document indexes" -msgstr "" +msgstr "Eliminare gli indici dei documenti" #: permissions.py:14 msgid "View document indexes" @@ -249,80 +244,80 @@ msgstr "indici dei documenti" #: views.py:68 msgid "Index created successfully." -msgstr "" +msgstr "Indice creato con successo." #: views.py:92 msgid "Index edited successfully" -msgstr "" +msgstr "Indice modificato con successo" #: views.py:98 #, python-format msgid "edit index: %s" -msgstr "" +msgstr "modifica indice: %s" #: views.py:123 #, python-format msgid "Index: %s deleted successfully." -msgstr "" +msgstr "Indice: %s cancellato con successo." #: views.py:125 #, python-format msgid "Index: %(index)s delete error: %(error)s" -msgstr "" +msgstr "Indice: %(index)s errore di cancellazione: %(error)s" #: views.py:137 #, python-format msgid "Are you sure you with to delete the index: %s?" -msgstr "" +msgstr "Sei sicuro di voler cancella l'indice: %s?" #: views.py:162 #, python-format msgid "tree template nodes for index: %s" -msgstr "" +msgstr "modello nodi della struttura per l'indice: %s" #: views.py:165 msgid "level" -msgstr "" +msgstr "livello" #: views.py:186 msgid "Index template node created successfully." -msgstr "" +msgstr "Modello nodo indice creato con successo." #: views.py:192 msgid "create child node" -msgstr "" +msgstr "creare nodo figlio" #: views.py:213 msgid "Index template node edited successfully" -msgstr "" +msgstr "Template nodo Indice modificato con successo" #: views.py:219 #, python-format msgid "edit index template node: %s" -msgstr "" +msgstr "modifica index template node: %s" #: views.py:226 views.py:266 views.py:334 msgid "node" -msgstr "" +msgstr "nodo" #: views.py:248 #, python-format msgid "Node: %s deleted successfully." -msgstr "" +msgstr "Nodo: %s cancellato con succcesso." #: views.py:250 #, python-format msgid "Node: %(node)s delete error: %(error)s" -msgstr "" +msgstr "Nodo: %(node)s errore di cancellazione: %(error)s" #: views.py:259 #, python-format msgid "Are you sure you with to delete the index template node: %s?" -msgstr "" +msgstr "Sei sicuro di voler cancellare index template node: %s?" #: views.py:283 msgid "nodes" -msgstr "" +msgstr "nodi" #: views.py:316 #, python-format @@ -339,9 +334,7 @@ msgstr "Sei sicuro di voler ricostruire l'indice ?" #: views.py:364 msgid "On large databases this operation may take some time to execute." -msgstr "" -"Per un database di grosse dimensioni l'operazione protrebbe aver bisogno di " -"tempo." +msgstr "Per un database di grosse dimensioni l'operazione protrebbe aver bisogno di tempo." #: views.py:370 msgid "Index rebuild completed successfully." @@ -359,9 +352,9 @@ msgstr "Gli indici contengono: %s" #: conf/settings.py:22 msgid "" -"A dictionary that maps the index name and where on the filesystem that index " -"will be mirrored." -msgstr "" +"A dictionary that maps the index name and where on the filesystem that index" +" will be mirrored." +msgstr "Un dizionario che associa il nome dell'indice e dove sul filesystem verrà copiato." #: templates/indexing_help.html:3 msgid "What are indexes?" @@ -369,6 +362,4 @@ msgstr "Cosa sono gli indici ?" #: templates/indexing_help.html:4 msgid "Indexes group documents into a tree like hierarchical structure." -msgstr "" -"Gli Indici dei documenti rappresentano , nella forma di albero, la struttura " -"gerarchica dei documenti stessi.." +msgstr "Gli Indici dei documenti rappresentano , nella forma di albero, la struttura gerarchica dei documenti stessi.." diff --git a/apps/document_signatures/locale/it/LC_MESSAGES/django.po b/apps/document_signatures/locale/it/LC_MESSAGES/django.po index 2555341d9b..853d1c1b5d 100644 --- a/apps/document_signatures/locale/it/LC_MESSAGES/django.po +++ b/apps/document_signatures/locale/it/LC_MESSAGES/django.po @@ -1,21 +1,21 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: +# Pierpaolo Baldan , 2012. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" -"Report-Msgid-Bugs-To: \n" +"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" -"PO-Revision-Date: 2012-02-02 18:20+0000\n" -"Last-Translator: Roberto Rosario \n" -"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/team/" -"it/)\n" -"Language: it\n" +"PO-Revision-Date: 2012-03-21 14:23+0000\n" +"Last-Translator: Pierpaolo Baldan \n" +"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" #: __init__.py:83 @@ -36,7 +36,7 @@ msgstr "File della firma" #: models.py:20 msgid "document version" -msgstr "" +msgstr "versione del documento" #: models.py:21 msgid "signature file" @@ -44,19 +44,19 @@ msgstr "file della firma" #: models.py:22 msgid "has embedded signature" -msgstr "" +msgstr "ha incorporato la firma" #: models.py:35 msgid "document version signature" -msgstr "" +msgstr "versione della firma del documento" #: models.py:36 msgid "document version signatures" -msgstr "" +msgstr "versione delle firme documento " #: permissions.py:7 msgid "Document signatures" -msgstr "" +msgstr "Firme documento" #: permissions.py:8 msgid "Verify document signatures" diff --git a/apps/documents/locale/it/LC_MESSAGES/django.po b/apps/documents/locale/it/LC_MESSAGES/django.po index e8312c5918..44890d1870 100644 --- a/apps/documents/locale/it/LC_MESSAGES/django.po +++ b/apps/documents/locale/it/LC_MESSAGES/django.po @@ -4,14 +4,15 @@ # # Translators: # , 2011. +# Pierpaolo Baldan , 2012. # Roberto Rosario , 2012. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" "Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" -"PO-Revision-Date: 2012-02-21 00:37+0000\n" -"Last-Translator: Roberto Rosario \n" +"PO-Revision-Date: 2012-03-21 13:44+0000\n" +"Last-Translator: Pierpaolo Baldan \n" "Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -102,13 +103,13 @@ msgstr "Trovare i file di documenti mancanti" #: __init__.py:86 msgid "Clear the document image cache" -msgstr "" +msgstr "Svuota la cache immagine del documento" #: __init__.py:86 msgid "" "Clear the graphics representations used to speed up the documents' display " "and interactive transformations results." -msgstr "" +msgstr "Cancella le rappresentazioni grafiche utilizzate per accellerare la visualizzazione dei documenti e dei risultati interattivi trasformazioni." #: __init__.py:89 msgid "page transformations" @@ -241,7 +242,7 @@ msgstr "Pagine nel documento (%s)" #: forms.py:162 msgid "Use the new version filename as the document filename" -msgstr "" +msgstr "Utilizza il nuovo nome di versione il nome del documento" #: forms.py:178 msgid "Quick document rename" @@ -253,11 +254,11 @@ msgstr "Versione aggiornamento" #: forms.py:190 msgid "Release level" -msgstr "" +msgstr "Livello di versione" #: forms.py:196 msgid "Release level serial" -msgstr "" +msgstr "Livello di versione sequenziale" #: forms.py:204 msgid "Comment" @@ -280,7 +281,7 @@ msgid "" "Download the document in the original format or in a compressed manner. " "This option is selectable only when downloading one document, for multiple " "documents, the bundle will always be downloads as a compressed file." -msgstr "" +msgstr "Scarica il documento nel formato originale o in modo compresso. Questa opzione è selezionabile solo quando il download di un documento, per i documenti multipli, il bundle sarà sempre download come un file compresso." #: literals.py:10 msgid "Document creation" @@ -328,23 +329,23 @@ msgstr "Documento \"%(document)s\" cancellato il %(datetime)s da %(fullname)s." #: literals.py:42 msgid "final" -msgstr "" +msgstr "finale" #: literals.py:43 msgid "alpha" -msgstr "" +msgstr "alfa" #: literals.py:44 msgid "beta" -msgstr "" +msgstr "beta" #: literals.py:45 msgid "release candidate" -msgstr "" +msgstr "Release Candidate" #: literals.py:46 msgid "hotfix" -msgstr "" +msgstr "hotfix" #: models.py:61 msgid "name" @@ -375,37 +376,37 @@ msgstr "documento" #: models.py:287 #, python-format msgid "Major %(major)i.%(minor)i, (new release)" -msgstr "" +msgstr "Magiore %(major)i.%(minor)i, (new release)" #: models.py:288 #, python-format msgid "Minor %(major)i.%(minor)i, (some updates)" -msgstr "" +msgstr "Minore %(major)i.%(minor)i, (some updates)" #: models.py:289 #, python-format msgid "Micro %(major)i.%(minor)i.%(micro)i, (fixes)" -msgstr "" +msgstr "Micro %(major)i.%(minor)i.%(micro)i, (fixes)" #: models.py:301 msgid "mayor" -msgstr "" +msgstr "maggiore" #: models.py:302 msgid "minor" -msgstr "" +msgstr "minore" #: models.py:303 msgid "micro" -msgstr "" +msgstr "micro" #: models.py:304 msgid "release level" -msgstr "" +msgstr "Livello di release" #: models.py:305 msgid "serial" -msgstr "" +msgstr "sequenziale" #: models.py:306 msgid "timestamp" @@ -732,7 +733,7 @@ msgstr "Il documento \"%s\" è ancora in modifica" #: views.py:342 msgid "documents to be downloaded" -msgstr "" +msgstr "documenti da scaricare" #: views.py:352 views.py:1337 msgid "version" @@ -740,11 +741,11 @@ msgstr "versione" #: views.py:409 msgid "Download" -msgstr "" +msgstr "Scarica" #: views.py:411 msgid "Return" -msgstr "" +msgstr "Ritorno" #: views.py:445 #, python-format @@ -980,16 +981,16 @@ msgstr "crea il nome file per i documenti di tipo:%s" #: views.py:1306 msgid "Document image cache cleared successfully" -msgstr "" +msgstr "Cancellata con successo la cache delle immagini dei documenti" #: views.py:1308 #, python-format msgid "Error clearing document image cache; %s" -msgstr "" +msgstr "Errore nella pulizia della cache del documento; %s" #: views.py:1314 msgid "Are you sure you wish to clear the document image cache?" -msgstr "" +msgstr "Sei sicuro di voler cancellare la cache delle immagini del documento?" #: views.py:1331 #, python-format @@ -998,15 +999,15 @@ msgstr "versioni per documento: %s" #: views.py:1341 msgid "time and date" -msgstr "" +msgstr "data e ora" #: views.py:1345 msgid "mimetype" -msgstr "" +msgstr "mimetype" #: views.py:1349 msgid "encoding" -msgstr "" +msgstr "codifica" #: views.py:1380 msgid "Document version reverted successfully" diff --git a/apps/dynamic_search/locale/it/LC_MESSAGES/django.po b/apps/dynamic_search/locale/it/LC_MESSAGES/django.po index 9d354393b5..efb6829e14 100644 --- a/apps/dynamic_search/locale/it/LC_MESSAGES/django.po +++ b/apps/dynamic_search/locale/it/LC_MESSAGES/django.po @@ -1,22 +1,21 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # , 2011. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" -"Report-Msgid-Bugs-To: \n" +"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" "PO-Revision-Date: 2011-12-09 15:32+0000\n" "Last-Translator: Pierpaolo Baldan \n" -"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/team/" -"it/)\n" -"Language: it\n" +"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" #: __init__.py:5 @@ -62,8 +61,7 @@ msgstr "risultati della ricerca" #: views.py:33 #, python-format msgid "results, (showing only %(shown_result_count)s out of %(result_count)s)" -msgstr "" -"risultati, (mostra esclusivamente %(shown_result_count)s di %(result_count)s)" +msgstr "risultati, (mostra esclusivamente %(shown_result_count)s di %(result_count)s)" #: views.py:37 msgid "results" @@ -100,9 +98,7 @@ msgstr "Aiuto" msgid "" "Enter the desired search keywords separated by space. Only the top " "%(search_results_limit)s results will be available." -msgstr "" -"Inserisci le parole da cercare separate da spazzi. Solo i primi " -"%(search_results_limit)s saranno disponibili." +msgstr "Inserisci le parole da cercare separate da spazzi. Solo i primi %(search_results_limit)s saranno disponibili." #: templates/search_results.html:3 msgid "Search results" diff --git a/apps/folders/locale/it/LC_MESSAGES/django.po b/apps/folders/locale/it/LC_MESSAGES/django.po index 882101fe06..86cbc42c74 100644 --- a/apps/folders/locale/it/LC_MESSAGES/django.po +++ b/apps/folders/locale/it/LC_MESSAGES/django.po @@ -4,14 +4,15 @@ # # Translators: # , 2011. +# Pierpaolo Baldan , 2012. # Roberto Rosario , 2012. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" "Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" -"PO-Revision-Date: 2012-02-21 00:25+0000\n" -"Last-Translator: Roberto Rosario \n" +"PO-Revision-Date: 2012-03-21 13:23+0000\n" +"Last-Translator: Pierpaolo Baldan \n" "Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -53,7 +54,7 @@ msgstr "cartelle" #: __init__.py:27 msgid "ACLs" -msgstr "" +msgstr "ACL" #: forms.py:38 msgid "Folder" diff --git a/apps/history/locale/it/LC_MESSAGES/django.po b/apps/history/locale/it/LC_MESSAGES/django.po index 823f6912a8..9f0a07d367 100644 --- a/apps/history/locale/it/LC_MESSAGES/django.po +++ b/apps/history/locale/it/LC_MESSAGES/django.po @@ -1,22 +1,22 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # , 2011. +# Pierpaolo Baldan , 2012. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" -"Report-Msgid-Bugs-To: \n" +"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" -"PO-Revision-Date: 2012-02-02 18:19+0000\n" -"Last-Translator: Roberto Rosario \n" -"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/team/" -"it/)\n" -"Language: it\n" +"PO-Revision-Date: 2012-03-21 13:30+0000\n" +"Last-Translator: Pierpaolo Baldan \n" +"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" #: __init__.py:10 models.py:71 @@ -57,7 +57,7 @@ msgstr "Versioni" #: permissions.py:8 msgid "Access the history of an object" -msgstr "" +msgstr "Accedi alla storia di un oggetto" #: views.py:27 msgid "history events" diff --git a/apps/linking/locale/it/LC_MESSAGES/django.po b/apps/linking/locale/it/LC_MESSAGES/django.po index 5951339586..897b6b241f 100644 --- a/apps/linking/locale/it/LC_MESSAGES/django.po +++ b/apps/linking/locale/it/LC_MESSAGES/django.po @@ -1,22 +1,22 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # , 2011. +# Pierpaolo Baldan , 2012. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" -"Report-Msgid-Bugs-To: \n" +"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" -"PO-Revision-Date: 2012-02-02 18:19+0000\n" -"Last-Translator: Roberto Rosario \n" -"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/team/" -"it/)\n" -"Language: it\n" +"PO-Revision-Date: 2012-03-21 13:18+0000\n" +"Last-Translator: Pierpaolo Baldan \n" +"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" #: __init__.py:17 @@ -53,7 +53,7 @@ msgstr "crea condizioni" #: __init__.py:31 msgid "ACLs" -msgstr "" +msgstr "ACL" #: forms.py:50 msgid "Pages" @@ -148,10 +148,7 @@ msgid "" "This expression will be evaluated against the current selected document. " "The document metadata is available as variables `metadata` and document " "properties under the variable `document`." -msgstr "" -"Questa espressione sarà valutata per il documento corrente selezionato. I " -"metadati del documento sono disponibile come variabili `metadati` e le " -"proprietà dei documenti sotto la variabile `documento`." +msgstr "Questa espressione sarà valutata per il documento corrente selezionato. I metadati del documento sono disponibile come variabili `metadati` e le proprietà dei documenti sotto la variabile `documento`." #: models.py:14 models.py:33 views.py:136 views.py:232 msgid "enabled" @@ -173,9 +170,7 @@ msgstr "dati del documento estero" msgid "" "This represents the metadata of all other documents. Available objects: " "`document.` and `metadata.`." -msgstr "" -"Questo rappresenta i metadati di tutti gli altri documenti. Oggetti " -"disponibili: `document.` e `metadata.`." +msgstr "Questo rappresenta i metadati di tutti gli altri documenti. Oggetti disponibili: `document.` e `metadata.`." #: models.py:31 msgid "expression" @@ -315,16 +310,12 @@ msgstr "Condizioni per il link intelligente: \"%s\" cancellato con successo." #, python-format msgid "" "Error deleting smart link condition: %(smart_link_condition)s; %(error)s." -msgstr "" -"Errore nella cancellazione del link intelligente: %(smart_link_condition)s; " -"%(error)s." +msgstr "Errore nella cancellazione del link intelligente: %(smart_link_condition)s; %(error)s." #: views.py:333 #, python-format msgid "Are you sure you wish to delete smart link condition: \"%s\"?" -msgstr "" -"Sei sicuro di voler cancellare le condizioni per il link intelligente : \"%s" -"\"?" +msgstr "Sei sicuro di voler cancellare le condizioni per il link intelligente : \"%s\"?" #: conf/settings.py:11 msgid "Show smart link that don't return any documents." @@ -341,10 +332,4 @@ msgid "" "source, the results of these queries are a list of documents that relate in " "some manner to the document being displayed and allow users the ability to " "jump to and from linked documents very easily." -msgstr "" -"Collegamenti intelligenti sono un insieme di istruzioni condizionali che " -"vengono utilizzati per interrogare il database utilizzando il documento " -"corrente l'utente sta accedendo come origine dati, i risultati di queste " -"query sono un elenco di documenti che riguardano in qualche modo al " -"documento e consentire la visualizzazione agli utenti la possibilità di " -"saltare da e per i documenti collegati molto facilmente." +msgstr "Collegamenti intelligenti sono un insieme di istruzioni condizionali che vengono utilizzati per interrogare il database utilizzando il documento corrente l'utente sta accedendo come origine dati, i risultati di queste query sono un elenco di documenti che riguardano in qualche modo al documento e consentire la visualizzazione agli utenti la possibilità di saltare da e per i documenti collegati molto facilmente." diff --git a/apps/metadata/locale/it/LC_MESSAGES/django.po b/apps/metadata/locale/it/LC_MESSAGES/django.po index a37122bdee..1ead75e3b6 100644 --- a/apps/metadata/locale/it/LC_MESSAGES/django.po +++ b/apps/metadata/locale/it/LC_MESSAGES/django.po @@ -4,14 +4,15 @@ # # Translators: # , 2011. +# Pierpaolo Baldan , 2012. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" "Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" -"PO-Revision-Date: 2012-02-12 19:24+0000\n" -"Last-Translator: Roberto Rosario \n" -"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/team/it/)\n" +"PO-Revision-Date: 2012-03-21 13:22+0000\n" +"Last-Translator: Pierpaolo Baldan \n" +"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -139,9 +140,7 @@ msgstr "lookup" msgid "" "Enter a string to be evaluated. Example: [user.get_full_name() for user in " "User.objects.all()].%s" -msgstr "" -"Inserisci una stringa per la valutazione. Esempio: [user.get_full_name() " -"per l'utente User.objects.all()].%s" +msgstr "Inserisci una stringa per la valutazione. Esempio: [user.get_full_name() per l'utente User.objects.all()].%s" #: models.py:33 models.py:58 views.py:353 views.py:398 msgid "metadata type" @@ -259,8 +258,7 @@ msgstr "Errore nella cancellazione degli indici di documento;%s" #: views.py:99 #, python-format msgid "Error editing metadata for document %(document)s; %(error)s." -msgstr "" -"Errore nella modifica dei metadata per il documento %(document)s; %(error)s." +msgstr "Errore nella modifica dei metadata per il documento %(document)s; %(error)s." #: views.py:102 #, python-format @@ -291,16 +289,13 @@ msgstr "Modifica metadata per i documenti: %s" msgid "" "Metadata type: %(metadata_type)s successfully added to document " "%(document)s." -msgstr "" -"Tipo metadata: %(metadata_type)s aggiunto con successo al documento " -"%(document)s." +msgstr "Tipo metadata: %(metadata_type)s aggiunto con successo al documento %(document)s." #: views.py:164 #, python-format msgid "" "Metadata type: %(metadata_type)s already present in document %(document)s." -msgstr "" -"Tipo Metadata: %(metadata_type)s già presente per il documento %(document)s." +msgstr "Tipo Metadata: %(metadata_type)s già presente per il documento %(document)s." #: views.py:188 #, python-format @@ -317,17 +312,13 @@ msgstr "Aggiungi tipo metadata ai documents: %s" msgid "" "Successfully remove metadata type: %(metadata_type)s from document: " "%(document)s." -msgstr "" -"Rimuovere con successo tipo di metadati: %(metadata_type)s per il " -"documento: %(document)s." +msgstr "Rimuovere con successo tipo di metadati: %(metadata_type)s per il documento: %(document)s." #: views.py:262 #, python-format msgid "" "Error removing metadata type: %(metadata_type)s from document: %(document)s." -msgstr "" -"Errore durante la rimozione dei metadati di tipo: %(metadata_type)s per il " -"documento: %(document)s." +msgstr "Errore durante la rimozione dei metadati di tipo: %(metadata_type)s per il documento: %(document)s." #: views.py:281 #, python-format @@ -424,7 +415,7 @@ msgstr "Sei sicuro di voler eliminare il set di metadati: %s?" #: views.py:538 views.py:556 msgid "Metadata types" -msgstr "" +msgstr "Tipi di Metadati" #: views.py:594 #, python-format @@ -445,11 +436,7 @@ msgid "" "A metadata set is a group of one or more metadata types. Metadata sets are " "useful when creating new documents; selecing a metadata set automatically " "attaches it's member metadata types to said document." -msgstr "" -"Un insieme di metadati è un gruppo di uno o più tipi di metadati. Set di " -"metadati sono utili durante la creazione di nuovi documenti e, selezionando " -"un set di metadati allega automaticamente è membro tipi di metadati per " -"documentare detto." +msgstr "Un insieme di metadati è un gruppo di uno o più tipi di metadati. Set di metadati sono utili durante la creazione di nuovi documenti e, selezionando un set di metadati allega automaticamente è membro tipi di metadati per documentare detto." #: templates/metadata_type_help.html:3 msgid "What are metadata types?" @@ -466,16 +453,4 @@ msgid "" " will have initially, and the lookup value turns an instance of a metadata " "of this type into a choice list which options are the result of the lookup's" " code execution." -msgstr "" -"Un tipo di metadati definisce le caratteristiche di un valore di qualche " -"tipo che può essere collegato a un documento. Esempi di tipi di metadati: il" -" nome del client, una data o un progetto a cui appartengono diversi " -"documenti. Il nome di un tipo di metadati è l'identificatore interno con il " -"quale possono essere pubblicati da altri moduli come il modulo di " -"indicizzazione, il titolo è il valore che viene mostrato agli utenti, il " -"valore predefinito è il valore di un'istanza di questo tipo di metadati avrà" -" inizialmente, e il valore di ricerca si trasforma un'istanza di metadati di" -" questo tipo in un elenco di opzioni di scelta che sono il risultato della " -"esecuzione di codice la ricerca di." - - +msgstr "Un tipo di metadati definisce le caratteristiche di un valore di qualche tipo che può essere collegato a un documento. Esempi di tipi di metadati: il nome del client, una data o un progetto a cui appartengono diversi documenti. Il nome di un tipo di metadati è l'identificatore interno con il quale possono essere pubblicati da altri moduli come il modulo di indicizzazione, il titolo è il valore che viene mostrato agli utenti, il valore predefinito è il valore di un'istanza di questo tipo di metadati avrà inizialmente, e il valore di ricerca si trasforma un'istanza di metadati di questo tipo in un elenco di opzioni di scelta che sono il risultato della esecuzione di codice la ricerca di." diff --git a/apps/navigation/locale/it/LC_MESSAGES/django.po b/apps/navigation/locale/it/LC_MESSAGES/django.po index 957fcd5f25..bae0bf6670 100644 --- a/apps/navigation/locale/it/LC_MESSAGES/django.po +++ b/apps/navigation/locale/it/LC_MESSAGES/django.po @@ -1,22 +1,21 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # , 2011. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" -"Report-Msgid-Bugs-To: \n" +"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" "PO-Revision-Date: 2011-12-09 18:00+0000\n" "Last-Translator: Pierpaolo Baldan \n" -"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/team/" -"it/)\n" -"Language: it\n" +"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" #: forms.py:14 diff --git a/apps/ocr/locale/it/LC_MESSAGES/django.po b/apps/ocr/locale/it/LC_MESSAGES/django.po index 18fd6b973a..4b53d3edd8 100644 --- a/apps/ocr/locale/it/LC_MESSAGES/django.po +++ b/apps/ocr/locale/it/LC_MESSAGES/django.po @@ -1,22 +1,22 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # , 2011. +# Pierpaolo Baldan , 2012. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" -"Report-Msgid-Bugs-To: \n" +"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" -"PO-Revision-Date: 2012-02-02 18:19+0000\n" -"Last-Translator: Roberto Rosario \n" -"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/team/" -"it/)\n" -"Language: it\n" +"PO-Revision-Date: 2012-03-21 13:29+0000\n" +"Last-Translator: Pierpaolo Baldan \n" +"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" #: __init__.py:32 __init__.py:33 @@ -47,9 +47,7 @@ msgstr "ripulisci il contenuto delle pagine" msgid "" "Runs a language filter to remove common OCR mistakes from document pages " "content." -msgstr "" -"Esegue un filtro per rimuovere i comuni errori di OCR dal contenuto del " -"documento pagine." +msgstr "Esegue un filtro per rimuovere i comuni errori di OCR dal contenuto del documento pagine." #: __init__.py:44 msgid "queue document list" @@ -187,19 +185,19 @@ msgstr "code dei documenti in trasformazione" #: permissions.py:8 msgid "Submit documents for OCR" -msgstr "" +msgstr "Inviare documenti all OCR" #: permissions.py:9 msgid "Delete documents from OCR queue" -msgstr "" +msgstr "Cancella documenti dalla coda OCR" #: permissions.py:10 msgid "Can enable/disable the OCR queue" -msgstr "" +msgstr "Puoi abilitare/disabilitare la coda OCR" #: permissions.py:11 msgid "Can execute the OCR clean up on all document pages" -msgstr "" +msgstr "Posso effettuare la pulizia dell OCR di tutte le pagine dei documenti" #: permissions.py:12 msgid "Can edit an OCR queue properties" @@ -269,8 +267,7 @@ msgstr "Sei sicuro di voler cancellare queste code documento: %s?" #: views.py:148 #, python-format msgid "Document: %(document)s was added to the OCR queue: %(queue)s." -msgstr "" -"Il documento: %(document)s è stato aggiunto alla coda %(queue)s per OCR." +msgstr "Il documento: %(document)s è stato aggiunto alla coda %(queue)s per OCR." #: views.py:151 #, python-format @@ -381,9 +378,7 @@ msgstr "Errore nella cancellazione della coda di trasformazione; %(error)s" #, python-format msgid "" "Are you sure you wish to delete queue transformation \"%(transformation)s\"" -msgstr "" -"Sei sicuro di voler cancellare la coda di trasformazione \"%(transformation)s" -"\"" +msgstr "Sei sicuro di voler cancellare la coda di trasformazione \"%(transformation)s\"" #: views.py:412 msgid "Queue transformation created successfully" @@ -403,15 +398,11 @@ msgstr "Crea una nuova coda di trasformazione:%s" msgid "" "Amount of seconds to delay OCR of documents to allow for the node's storage " "replication overhead." -msgstr "" -"Quantità di secondi di ritardo OCR di documenti per consentire lo stoccaggio " -"nel nodo di replica." +msgstr "Quantità di secondi di ritardo OCR di documenti per consentire lo stoccaggio nel nodo di replica." #: conf/settings.py:14 msgid "Maximum amount of concurrent document OCRs a node can perform." -msgstr "" -"Importo massimo di documenti concorrenti per OCR che un nodo è in grado di " -"eseguire." +msgstr "Importo massimo di documenti concorrenti per OCR che un nodo è in grado di eseguire." #: conf/settings.py:15 msgid "Automatically queue newly created documents for OCR." diff --git a/apps/permissions/locale/it/LC_MESSAGES/django.po b/apps/permissions/locale/it/LC_MESSAGES/django.po index c9c70931c1..030957dca2 100644 --- a/apps/permissions/locale/it/LC_MESSAGES/django.po +++ b/apps/permissions/locale/it/LC_MESSAGES/django.po @@ -1,22 +1,22 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # , 2011. +# Pierpaolo Baldan , 2012. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" -"Report-Msgid-Bugs-To: \n" +"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" -"PO-Revision-Date: 2012-02-02 18:18+0000\n" -"Last-Translator: Roberto Rosario \n" -"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/team/" -"it/)\n" -"Language: it\n" +"PO-Revision-Date: 2012-03-21 13:31+0000\n" +"Last-Translator: Pierpaolo Baldan \n" +"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" #: __init__.py:17 models.py:209 views.py:40 @@ -151,9 +151,7 @@ msgstr "%(requester)s, ha già il permesso \"%(permission)s\" concesso." #, python-format msgid "" "Are you sure you wish to grant the %(permissions_label)s %(title_suffix)s?" -msgstr "" -"Sei sicuro che tu voglia concedere questo permesso %(permissions_label)s " -"%(title_suffix)s?" +msgstr "Sei sicuro che tu voglia concedere questo permesso %(permissions_label)s %(title_suffix)s?" #: views.py:222 #, python-format @@ -169,21 +167,19 @@ msgstr "%(requester)s, non ha i permessi \"%(permission)s\" consentiti." #, python-format msgid "" "Are you sure you wish to revoke the %(permissions_label)s %(title_suffix)s?" -msgstr "" -"Sei sicuro di voler revocare questo permesso %(permissions_label)s " -"%(title_suffix)s?" +msgstr "Sei sicuro di voler revocare questo permesso %(permissions_label)s %(title_suffix)s?" #: views.py:271 views.py:295 msgid "Users" -msgstr "" +msgstr "Utenti" #: views.py:274 views.py:298 msgid "Groups" -msgstr "" +msgstr "Gruppi" #: views.py:277 views.py:301 msgid "Special" -msgstr "" +msgstr "Speciale" #: views.py:330 #, python-format @@ -207,6 +203,4 @@ msgstr "Concessione" msgid "" "A list of existing roles that are automatically assigned to newly created " "users" -msgstr "" -"Un elenco di ruoli esistenti che vengono automaticamente assegnati agli " -"utenti appena creati" +msgstr "Un elenco di ruoli esistenti che vengono automaticamente assegnati agli utenti appena creati" diff --git a/apps/project_setup/locale/it/LC_MESSAGES/django.po b/apps/project_setup/locale/it/LC_MESSAGES/django.po index 647c2314ad..e4cc8b132d 100644 --- a/apps/project_setup/locale/it/LC_MESSAGES/django.po +++ b/apps/project_setup/locale/it/LC_MESSAGES/django.po @@ -1,22 +1,21 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # , 2011. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" -"Report-Msgid-Bugs-To: \n" +"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" "PO-Revision-Date: 2011-12-09 18:08+0000\n" "Last-Translator: Pierpaolo Baldan \n" -"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/team/" -"it/)\n" -"Language: it\n" +"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" #: __init__.py:6 diff --git a/apps/project_tools/locale/it/LC_MESSAGES/django.po b/apps/project_tools/locale/it/LC_MESSAGES/django.po index ca3f7d9be2..4c2ca80d19 100644 --- a/apps/project_tools/locale/it/LC_MESSAGES/django.po +++ b/apps/project_tools/locale/it/LC_MESSAGES/django.po @@ -1,22 +1,21 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # , 2011. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" -"Report-Msgid-Bugs-To: \n" +"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" "PO-Revision-Date: 2011-12-09 18:01+0000\n" "Last-Translator: Pierpaolo Baldan \n" -"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/team/" -"it/)\n" -"Language: it\n" +"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" #: __init__.py:7 views.py:15 diff --git a/apps/smart_settings/locale/it/LC_MESSAGES/django.po b/apps/smart_settings/locale/it/LC_MESSAGES/django.po index ddd908c065..c830f284f7 100644 --- a/apps/smart_settings/locale/it/LC_MESSAGES/django.po +++ b/apps/smart_settings/locale/it/LC_MESSAGES/django.po @@ -1,22 +1,21 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # , 2011. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" -"Report-Msgid-Bugs-To: \n" +"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" "PO-Revision-Date: 2011-12-09 17:38+0000\n" "Last-Translator: Pierpaolo Baldan \n" -"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/team/" -"it/)\n" -"Language: it\n" +"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" #: __init__.py:9 views.py:28 diff --git a/apps/sources/locale/it/LC_MESSAGES/django.po b/apps/sources/locale/it/LC_MESSAGES/django.po index 3905bd9f58..be78eff9df 100644 --- a/apps/sources/locale/it/LC_MESSAGES/django.po +++ b/apps/sources/locale/it/LC_MESSAGES/django.po @@ -4,14 +4,15 @@ # # Translators: # , 2011. +# Pierpaolo Baldan , 2012. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" "Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" -"PO-Revision-Date: 2012-02-12 19:23+0000\n" -"Last-Translator: Roberto Rosario \n" -"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/team/it/)\n" +"PO-Revision-Date: 2012-03-21 14:07+0000\n" +"Last-Translator: Pierpaolo Baldan \n" +"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -64,7 +65,7 @@ msgstr "Sorgente del documento" #: __init__.py:38 msgid "upload new version" -msgstr "" +msgstr "Carica nuova versione" #: __init__.py:68 widgets.py:39 msgid "thumbnail" @@ -84,7 +85,7 @@ msgstr "Mostra file" #: forms.py:50 msgid "File" -msgstr "" +msgstr "File" #: literals.py:8 literals.py:13 msgid "Always" @@ -196,9 +197,7 @@ msgstr "anteprima larghezza" #: models.py:159 msgid "Width value to be passed to the converter backend." -msgstr "" -"valore della larghezza da passare per le operazioni di conversione in " -"backend" +msgstr "valore della larghezza da passare per le operazioni di conversione in backend" #: models.py:160 msgid "preview height" @@ -206,8 +205,7 @@ msgstr "anteprima altezza" #: models.py:160 msgid "Height value to be passed to the converter backend." -msgstr "" -"valore dell'altezza da passare per le operazioni di conversione in backend" +msgstr "valore dell'altezza da passare per le operazioni di conversione in backend" #: models.py:161 models.py:198 models.py:211 msgid "uncompress" @@ -237,9 +235,7 @@ msgstr "intervallo" msgid "" "Inverval in seconds where the watch folder path is checked for new " "documents." -msgstr "" -"Invervallo di pochi secondi in cui viene controllato il percorso cartella di" -" controllo per i nuovi documenti." +msgstr "Invervallo di pochi secondi in cui viene controllato il percorso cartella di controllo per i nuovi documenti." #: models.py:237 msgid "watch folder" @@ -276,7 +272,7 @@ msgstr "trasformazioni dei documenti sorgente" #: models.py:290 models.py:291 msgid "out of process" -msgstr "" +msgstr "fuori del processo" #: permissions.py:7 msgid "Sources setup" @@ -328,41 +324,38 @@ msgstr "Sorgenti caricamento" #: views.py:105 msgid "" "No interactive document sources have been defined or none have been enabled." -msgstr "" -"Nessuna fonte interattiva dei documenti sono state definite o non ne sono " -"state attivate." +msgstr "Nessuna fonte interattiva dei documenti sono state definite o non ne sono state attivate." #: views.py:106 #, python-format msgid "Click %(setup_link)s to add or enable some document sources." -msgstr "" -"Click %(setup_link)s per aggiungere o abilitare una sorgente documenti." +msgstr "Click %(setup_link)s per aggiungere o abilitare una sorgente documenti." #: views.py:163 msgid "New document version uploaded successfully." -msgstr "" +msgstr "Nuova versione del documento caricata con successo." #: views.py:167 msgid "File uploaded successfully." -msgstr "" +msgstr "File caricato con successo." #: views.py:170 msgid "File uncompressed successfully and uploaded as individual files." -msgstr "" +msgstr "File non compresso e caricato con successo come singolo file." #: views.py:173 msgid "File was not a compressed file, uploaded as it was." -msgstr "" +msgstr "Il file non era un file compresso,è stato caricato così com'era." #: views.py:179 views.py:258 #, python-format msgid "Unhandled exception: %s" -msgstr "" +msgstr "Eccezione non gestita: %s" #: views.py:188 #, python-format msgid "upload a new version from source: %s" -msgstr "" +msgstr "caricata una nuova versione da: %s" #: views.py:190 #, python-format @@ -372,7 +365,7 @@ msgstr "carica un documento in locale dalla sorgente: %s" #: views.py:236 #, python-format msgid "Document version from staging file: %s, uploaded successfully." -msgstr "" +msgstr "Versione documento da gestione temporanea file: %s,caricata con successo" #: views.py:239 #, python-format @@ -384,12 +377,12 @@ msgstr "File in allestimento:%s, caricato con successo." msgid "" "Staging file: %s, uncompressed successfully and uploaded as individual " "files." -msgstr "" +msgstr "file temporaneo: %s, non compresso e caricato come file singolo" #: views.py:245 #, python-format msgid "Staging file: %s, was not compressed, uploaded as a single file." -msgstr "" +msgstr "file temporaneo: %s, non è stato compresso, caricato come file singolo." #: views.py:250 #, python-format @@ -399,7 +392,7 @@ msgstr "File in allestimento:%s, cancellato con successo." #: views.py:273 #, python-format msgid "upload a new version from staging source: %s" -msgstr "" +msgstr "caricata una nuova versione da file temporaneo: %s" #: views.py:275 #, python-format @@ -412,11 +405,11 @@ msgstr "path dei file in allestimento" #: views.py:320 msgid "Current document type" -msgstr "" +msgstr "Tipo di documento corrente" #: views.py:321 msgid "None" -msgstr "" +msgstr "Nessuno" #: views.py:328 msgid "Current metadata" @@ -510,16 +503,13 @@ msgstr "Sorgente per la trasformazione cancellata con successo." #: views.py:646 #, python-format msgid "Error deleting source transformation; %(error)s" -msgstr "" -"Erroro nella cancellazione della sorgente per la trasformazione; %(error)s" +msgstr "Erroro nella cancellazione della sorgente per la trasformazione; %(error)s" #: views.py:659 #, python-format msgid "" "Are you sure you wish to delete source transformation \"%(transformation)s\"" -msgstr "" -"Sei sicuro di voler cancellare la sorgente di trasformazione " -"\"%(transformation)s\"" +msgstr "Sei sicuro di voler cancellare la sorgente di trasformazione \"%(transformation)s\"" #: views.py:689 msgid "Source transformation created successfully" @@ -534,5 +524,3 @@ msgstr "Errore nella creazione della sorgente di trasformazione; %s" #, python-format msgid "Create new transformation for source: %s" msgstr "Crea una nuova sorgente per la trasformazione:%s" - - diff --git a/apps/tags/locale/it/LC_MESSAGES/django.po b/apps/tags/locale/it/LC_MESSAGES/django.po index 34e4aceea0..8b4d43b544 100644 --- a/apps/tags/locale/it/LC_MESSAGES/django.po +++ b/apps/tags/locale/it/LC_MESSAGES/django.po @@ -4,15 +4,16 @@ # # Translators: # , 2011. +# Pierpaolo Baldan , 2012. # Roberto Rosario , 2011. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" "Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" -"PO-Revision-Date: 2012-02-12 19:23+0000\n" -"Last-Translator: Roberto Rosario \n" -"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/team/it/)\n" +"PO-Revision-Date: 2012-03-21 13:46+0000\n" +"Last-Translator: Pierpaolo Baldan \n" +"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -53,11 +54,11 @@ msgstr "documenti etichettati" #: __init__.py:30 msgid "ACLs" -msgstr "" +msgstr "ACLs" #: __init__.py:34 msgid "preview" -msgstr "" +msgstr "anteprima" #: __init__.py:38 msgid "tagged items" @@ -137,19 +138,19 @@ msgstr "Crea un nuova etichetta" #: permissions.py:10 msgid "Delete tags" -msgstr "" +msgstr "Eliminare i tag" #: permissions.py:11 msgid "Edit tags" -msgstr "" +msgstr "Modificare i tag" #: permissions.py:12 msgid "View tags" -msgstr "" +msgstr "Visualizzare i tag" #: permissions.py:13 msgid "Attach tags to documents" -msgstr "" +msgstr "Applicare i tag ai documenti" #: permissions.py:14 msgid "Remove tags from documents" @@ -247,5 +248,3 @@ msgstr "Sei sicuro di voler rimuovere le etichette: %s ?" #: templatetags/tags_tags.py:17 msgid "Add tag to document" msgstr "Aggiungi l'etichetta al documento" - - diff --git a/apps/web_theme/locale/it/LC_MESSAGES/django.po b/apps/web_theme/locale/it/LC_MESSAGES/django.po index 26968a531a..07d019a4b5 100644 --- a/apps/web_theme/locale/it/LC_MESSAGES/django.po +++ b/apps/web_theme/locale/it/LC_MESSAGES/django.po @@ -1,22 +1,21 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # , 2011. msgid "" msgstr "" "Project-Id-Version: Mayan EDMS\n" -"Report-Msgid-Bugs-To: \n" +"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n" "POT-Creation-Date: 2012-02-12 15:20-0400\n" "PO-Revision-Date: 2011-12-09 18:07+0000\n" "Last-Translator: Pierpaolo Baldan \n" -"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/team/" -"it/)\n" -"Language: it\n" +"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" #: conf/settings.py:10 @@ -24,10 +23,7 @@ msgid "" "CSS theme to apply, options are: amro, bec, bec-green, blue, default, djime-" "cerulean, drastic-dark, kathleene, olive, orange, red, reidb-greenish and " "warehouse." -msgstr "" -"Tema CSS da applicare, le opzioni sono: ABN AMRO, bec, bec-verde, blu, di " -"default, djime-ceruleo, drastica-scuro, kathleene, oliva, arancio, rosso, " -"reidb-verdastro e magazzino." +msgstr "Tema CSS da applicare, le opzioni sono: ABN AMRO, bec, bec-verde, blu, di default, djime-ceruleo, drastica-scuro, kathleene, oliva, arancio, rosso, reidb-verdastro e magazzino." #: conf/settings.py:12 msgid "Display extra information in the login screen." @@ -66,9 +62,7 @@ msgstr "Reindirizzamento al tuo punto di ingresso al sito in 5 secondi." msgid "" "Or click here if redirection doesn't " "work." -msgstr "" -"Oppure click qui if per essere " -"rimandato al tuo sito nel caso non funzioni." +msgstr "Oppure click qui if per essere rimandato al tuo sito nel caso non funzioni." #: templates/pagination/pagination.html:6 #: templates/pagination/pagination.html:8 From f21a96ae5be23c7d4b46ad135a01012c104ea84f Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Wed, 30 May 2012 18:37:43 -0400 Subject: [PATCH 27/65] Update compiled translation fixes for Italian --- apps/acls/locale/it/LC_MESSAGES/django.mo | Bin 1862 -> 4082 bytes apps/common/locale/it/LC_MESSAGES/django.mo | Bin 5646 -> 5679 bytes .../converter/locale/it/LC_MESSAGES/django.mo | Bin 18971 -> 19014 bytes .../locale/it/LC_MESSAGES/django.mo | Bin 3344 -> 3839 bytes .../locale/it/LC_MESSAGES/django.mo | Bin 1711 -> 1754 bytes .../locale/it/LC_MESSAGES/django.mo | Bin 4055 -> 7450 bytes .../locale/it/LC_MESSAGES/django.mo | Bin 1679 -> 2072 bytes .../documents/locale/it/LC_MESSAGES/django.mo | Bin 19387 -> 21842 bytes .../locale/it/LC_MESSAGES/django.mo | Bin 2079 -> 2122 bytes apps/folders/locale/it/LC_MESSAGES/django.mo | Bin 4562 -> 4580 bytes apps/history/locale/it/LC_MESSAGES/django.mo | Bin 1367 -> 1484 bytes apps/linking/locale/it/LC_MESSAGES/django.mo | Bin 7108 -> 7169 bytes apps/metadata/locale/it/LC_MESSAGES/django.mo | Bin 9789 -> 9834 bytes .../locale/it/LC_MESSAGES/django.mo | Bin 643 -> 686 bytes apps/ocr/locale/it/LC_MESSAGES/django.mo | Bin 8029 -> 8440 bytes .../locale/it/LC_MESSAGES/django.mo | Bin 3232 -> 3360 bytes .../locale/it/LC_MESSAGES/django.mo | Bin 578 -> 621 bytes .../locale/it/LC_MESSAGES/django.mo | Bin 522 -> 565 bytes .../locale/it/LC_MESSAGES/django.mo | Bin 625 -> 668 bytes apps/sources/locale/it/LC_MESSAGES/django.mo | Bin 8517 -> 10013 bytes apps/tags/locale/it/LC_MESSAGES/django.mo | Bin 3510 -> 3793 bytes .../web_theme/locale/it/LC_MESSAGES/django.mo | Bin 1701 -> 1744 bytes 22 files changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/acls/locale/it/LC_MESSAGES/django.mo b/apps/acls/locale/it/LC_MESSAGES/django.mo index 62329ea64c0367181f1201a15da503d613bc0a50..69fc2a374670a94dc12eaf3b48109ddaec195cba 100644 GIT binary patch literal 4082 zcmbuBO^g&p6vs;il=TY`MM1Pc7ItKNz5pcytH81#k;Toj%f+wMcGt|5)O1a{y7z;V zgagLJ7>t^jn8?ZCLAiKQx#7Wh2nsO^PB_k1wRH$;05qm z@CT6At-|Ch@YOny`oCfk$-f4Y{jY-~;9uZga2UeKKW~EM+B4v4@GQ6<{0Q6!ehKad ze+S85MHqqh4MA+pJ_YfKT?FyRzQNCC@H^1y0n+)efe(Qz?@!OW5!{3RAV_kXAnAJn zBza$eB>!uW#^Lm1hAJxF?Q0cqXtYT%2c3_E^?f13rOD zu|fVQqIL@To$Bj|I%!>_Us}t3 z6ULFzTq_%6Fp_-EB-|!hV@BB~$KjlcHy)&aAXc%KuiK4AypcfVTh4?$$j>+&nWSymkEqx_4o3t{r z?1X}%?)VoGWjik7r(;Y&7ut#eJAZ*wsX zsbWealnr$1b!*|)=coSYA8^FF)ZJ_>GW3FYM*{Bzyoe{K#z)1R2>Hmt(c^vNvTdT+ z8?_A;cn6Y(^(LT6GmhJ}QmLWhW-?XuO{)|cD@OUNC_Km$X;kg?EvED%u z%NnniD^;&t^(s|f*;T8Sz4Fd-856y6Ijv~>1@m@z)e5idtnJ#hy^PX#RM^;?zzb+K zUAr0|Q!;7`qYXbGbO5dQwmT!mDL1mO(Si|4$>*>&Lm8Lasda3rogU1SLCcnOCZ?p~QlW43$mqzt?JC7`-!Ps@go`&Z*T#us zISWBrsBjPWnDFE@RtDY2tXP%yWH={q7 z9J&EG$U~$iNLoUOQzExG%`B8yXk)HL_Q1LKPVzu?-UawFy`2j0jN(@LNo45zG~S+w zX8972q2zj-NDu_-)G2Wafg=~m5K9Z_7~mEc(v9)Of8V&feu;gvd?ND+g^eO8>dF`N zx-RJOb_7$@Rj6X+EJ(>(vcpl*ZmTS58?JI$Mi$wKmIyQCBaL^(y#|UMOU$(4NYF;( zfG*D<08HltW>G`3l(7Csaf+4?tJTaO)uO&H^w8_$pWRrBO z6cUY1aB<;wXOLVsJq?ZKEF&5HyMk~_|9P1YFH+sT^l+;)UmA9Xq3;5+(-)0~O2UTX zNyx(mmg^Z=m)>~%$t4lo8P?sIdIgmecILXMiJfQ zRq_kjM?T9i5NCK1&oRJ1*oxUKi6O%sY{yx==Y4^5Jby*mU%JrT*XtcX*09C!fz;z|G-ZCg}1PkYfJqZ%y53A zJLyb5lN{7eUM35qY?P3{hd%#@6qcZ-Dv@0z7jJ|#amCMzD9uR7*OP-)^u*ZcdWyDa z)*G{$5r(4rVy=+6HgC;llB#80)s>oBPIP50uBw$(+f-Goj%&uche5x4ALQM;V8)fg zz5Mv__*gVLIyEuo4#S?COXiWbR9!M@Y}ZUQZJP^a+gvEGnvJcvs<-OD!(1ji6uEla g-`u?2OcM98&>#3?v?~<{-AeI(X!TQ5iLF-u0D)6qpa1{> diff --git a/apps/common/locale/it/LC_MESSAGES/django.mo b/apps/common/locale/it/LC_MESSAGES/django.mo index 6e25f2e7c5d0682b18ae60136ae2316221356ba6..330436c3e8af832ca907e80e9e7a51bf3260ebed 100644 GIT binary patch delta 1329 zcmXxjTSyd99LMqh)_Q5XsA+c5wvB?sR%^8j*;1gGJwzn<76h~FT3f3tIwb_Q1QA46 z5W(z1`A|Vd)S?wZ&_h8a5te}uRu571Qgo-M`u^H&n4Ql#XV3i4fBt9YRPbgn^?I(i z-#D81mGf(vX6E1tFBgu&T(iwsgbmn?OtJo~16j}EbjB}Y4G!TPoWL-?!yqorGb_XG zNSu`I%`~hXnPZ*EX+2yNAcZ^d6zcysxCq~)687YqEkQr7z)d(G+fa!dLOshZoQI>B zgJbApeH*8-fPpETfj?0TsiTQ`sQzqZO)EhqP>vB?kBe~-HUBR9@d2t*Q&@~|QHgv< zJ=kw7V13K?neD^{$lB(j7VJgca0Hoa$1sF_+5aEmS^8tB3bf5MTZl(-4PHWR$po&& zNz@h;%*rGh#*{Ltr%`~-Sb`2J&;jJMGhCFw1=Rejs7j0?Yuf`<;!lv%#<{%kuvNH` zewv%M;Ad1t*0Gq}P(c0F2s5Ano3S3Zq82)i3NVP3_zM5+d0{4iKkHIdg3D2Hs!y3xQ1cF>;vLJ5pT<@6&!Q52g4Zzhl7Y^3e7aDXvXr{e(*J5Au2xTORdOz!KC%e`)%lx6b2f>>J5h=GoFW znN#LzO8>~Ym+MO;qx%AF@mQj@@5Zc=hT5u{P#{!WR})&fn!~rv>2|AHx}1*ggySZ= z>H<6Bv93-hnMeleokXkC5eRqwAE}P~8%Yn(ZpyES5IE`tqE35f(z@c&J@Ht#o3z%L R>pHs=@nm4X8|!dm_7}jJo-qIb delta 1296 zcmXZbPe@cz6vy#1>6n@SOEc|{B%$PJX&Pi!Sfn5>GQ>p@IO=2r>csdgv}l4d#85&B zYg0sEZZgP33Kt@|a3KZ#Sr}Q+9}o$w7DXWS{W0@+?|tsObKkk=oqOl8XTTF$OpU%} z9F<&KxN6pzdGS&-Hytr%hrxwMu>u)lJrR2&-oPmO2e23iF%f669N(Y^Q`VYg;UOeW z$WDeEb{ZLD4ajLN+!P>y$MG`i_m`N7?@$Tt=NYeKZ@IM3{|Ol+<>o8iF`qQ z*b*i&zx|ngjXZKPv9M%r%)BBUvIV<&tnPRL@miImf{?0 z3I3rH^~6(uWl~Hd2`g|T)}jKPK~B5EO$qd)#t)+^F@j2X3^{F*+k(sN1s>q}9)m0K zJ*pBrm_+W3n3qKT6(FCEBUpl(-~uYZb=-wBsI~r%3J{kZHUX7bGAd3cD)Ahw!-J>_ z4x*N97(Ms|^YCLb^;aV{CAI)}P89zq_c#E9&fg44z6;vSYELEThHLeX6 zuQSqr5qI<4gGzJ)M{ydpNke`XTod)8{-+O634Fp5{EUT|!GA{+RiP?Si%O&cwfoPZ zDmj3Bq)j4Kwz-H4s05c$aejsSqii*8yf3=U<+7n!caH1W(2_gLRXOgCc@{G?7yq=n zxS+TwyJ%n8-qQR%9C0vR=Csf5|1^rED{k{$-V9h?q@wT+`N~hy%cYO9A@=loS diff --git a/apps/converter/locale/it/LC_MESSAGES/django.mo b/apps/converter/locale/it/LC_MESSAGES/django.mo index 2b4b16da2ca57d5c96138969620943d05ec31560..fafebbc57ba7624a83c0d165672e8b79280afa39 100644 GIT binary patch delta 1912 zcmXZceQ1?s7{~EzINNc$mAZ30+u6&RbLy7c(_Aw*-JIsjnkxxMO4HyddpXoL**PaN zq$ko!3sTY{>A(^zaD~DC7-Yc=^`90cLP;VjQh)eIiui({*!RbC!{L1Hm-F2Bbzj&0 zoTG=b&L7J9VNs5MG0SXkjakghws>Z3_zu2`XE1`ZpEKKx)i@n@qsI4R34Vio>?~hA zV)rnNm36_o%WyvZO}G@_!$KUdGv5}_xWGUoKExudUmR@k3O+->8)xC$7{`664NhVy zPGB)!bw0u<{lfZSd@;_WzX2;TjSBcky>B*?#;*)016NQBJwyc-c|Pd3ARp^;9zZR4 z4t27d*n~41%yO^;L)eK-*;br}pQAE2f(mfVr=f@@Q765FWjJL?5Ksj&WGk>7GpPB) z_$-d2Qh5WP#>be8c`pR>Q5>Pa8da+6sKB0}O6i9vh!!qDWnu{`vNkuKz^U|iyYYRf zg^r^Fn?OBxA7^2RI_6^xRmy4%;~G?eU6_Y&A_4felZI0LA?m^JaTWfAD#a6LG5L+t zZ^YU7I&xiX0QuOLd==qktib!I%oZ&Re&6csboODC{cRTwonY8ae2X#qr!k6up=x~_ z3o*PrsG)~*>90kdFp0(JqYg5H3S<;@Nq@(M_@8r5Gnr?9Yo(!yZPI=dc7XU<7ZWO7PSQ)t^QIjX0K|Hf}+^9z9rq zhu!>lsEquEYw=%HO>0_%12m%o=s{&{7nb5z=-~uv-P@=VmaioL+Mr=&@cy@>-hw@- z@nP3L={$`($t0>|H&FpR!g8F!#nHyKsEs$G=7(?*et->l3boHat9*BR8Hh6wdNHsH z6=6Fn)o-8{de_Z=;v7X~Y!a*RF6u2PT}?1p=WIchXgz9vBkC^o_%w7`-bdZ${YWf! z1{GoUn&5#j@-J-*Q5kp*X(JUN?ROwa$-7;J*Dq zLmORlKgfM4s9`ng!41v?YQYq0!;f(;9&_WrU^e|fUH>xbq_t0xuQ!?Q%WSLNKG^RK4W<%9$-yD7Ke010;3ZS3 nOn2(w&o!6w-bxJgW)i*KUNY@f9UQIg%I$C?P4TfQUNrVU16}2! delta 1870 zcmXZce@vBC9LMo5gkW5B^AVigUA>(-m{6a{>LJ+FH?+-k&{Zdv;&voacGY`JV6h zJonop3GW?Am?#Q(rxVNui_NmkEEY9uz?ZNQM==e5#wJ|E<=9l>kGEqs{kM?I#`xh8 zyNDrNK+U@}FGGb^B9fRADviOqJGd1fgzK43tReu|ptGAgh+*AG5v#$_eW4%CFl zP&=E%D!hvU%q?dV7(s@t6qjKqDxV6Nd z!y!~Ezr>aJ9VX!|cmG#>pMFNAU#c%qfn7zF(wnBCiDyumSWbZySvG3C0+(Qu8*fF` zd@m}n5!8EAn2OVwjPs~cE@B8XsjmVo!4+7C1mM}rG?eOBQ7<0CdVCjEimT2)Fibz0 zJO?p~92eVwT-MJ|CQe{JPN6dUJL>sRwQs~(gXyeqjWo1_Zg=Bt%%VSx>G%<<*5@z- zXE6;EpEk?GEYuEbQ31b#+DI=dkOQbgdIAga8|N>W%la0o@o!Y(X8LcSGV(EM2j8Ot z{0~+86}5hV#i;Q(>d-Z#0(ld|xDQq1W0;MnP=TLCmEZ^TbQor6gz-<*!og?!&!ZYw z)9*puKZwf6aeM*4M%DCzI)4MHr~s-_8EeF~xCiyWFoOE*&Y?>3cOCiH0!h#M-+vD3 zE7*Y=?{~rHsF_HdiQa1m9KYZ$=W zn5YkZj>b|3=1~*>i_0+O%=+YkoWpmDuc!5OwC#*`^+h8|o7;AE_P2F*RE4|x4qtep K`AjSt%K9IW4ci+4 diff --git a/apps/django_gpg/locale/it/LC_MESSAGES/django.mo b/apps/django_gpg/locale/it/LC_MESSAGES/django.mo index f6df524b0b27f6044cd82b1236c0254aadbc0b9d..72364733cd9c124ba55b7dea477d8ab6918fa383 100644 GIT binary patch delta 1652 zcmZvbU1(fI6vtLP=}Af zH=ro-A-o5E3Lk}MpalL2?t?jGD#Hq7O9hbHRU2yfHk9X2K`H$EVfrtXTwp^gzX;{P zRak+)!fkMzYDBUMl>0R(30{IcqK-p}6GCZ03*HUif>QWxk$}5!DO8I1Kbv6lVZ6}0DMe={{g*_$ zajAICqzH0nHpM7Kiu7XAs>gASkKxiH`Ql6XBreK`$uC{RMQTw+>|R`2ATPTEFXS1- z51Fl;>;Ep-c`gpEZn(tGrE${MEpHn-jkRZG^$FYd+Ian@4Fcg@ z9L>9hR$@{YM|$1`))!Un8C7f8D0TDBdQ}UXagxf(byKhBlQ_)6*<{HkULCe=&B4RN zFf@@_upuG3pKbiT_;O_Gft4cM-?6l7RP}hCsK;HS;Gbk}lO#?GzI$@hrHREfZB|RA z1(zczP@EG4lwiHnm`Xxb(!IqzH6cb5hZ94t@m-J|!EtL5_KG&c0S@#)lTVj>?H zUb?DZbT(<4IEeKD6EsYupK7k{6zkbew{P&saA2Z^7Il|gS}Jr;48B67)t#zdIX}3) z@7RB(O5Al1 ziT8@onu#sMxJP6!e$1kyJzpbo4PRgr4tPZhaT-~YSL41sj_{TMnEfQef zi@7*~9Fdes2D-sT*UOm0d={(lHdf;ThVTovV>vf5l%uHk_t34!KG#9i1jms}&b#YV zNKSGUeVi}X8LVUB4syu@x;%V}MYw>P@mu7QMLMm(XLtS+3z+{#tw1g}Ya*qn->Y?P zMm@OQo$tZ>Ny@#S!5kkfb80Kz@MR8ojrs(OsEK@XUB=_gJ(MkoCvY21VFTVpwv;!h zZ}9_i$r7C={tekeRxnx1Ad9qhg9hxtZrq6%P@n7}YDJ!*fv-^S|ACrdF*oUfe$+%O zQST3833i}XBeOaJrS!*ATjYMS4YKlfHj#l|((!NE8$LbQ=l%0cuIN6PkejL&^zl`lHmO z^~v;5t>jjsjL^e1ac#{RWHV~Dw2@!>0kRJ<;5Gc$>X_+!(+UI#eKIYhwx$f}-tUgJ zf<^N+-UUx}xJ$wVR?LZ>j#>!`50Auc#~8FmrP~@c!d)plXC*b0`z|$;ci?a+*cLK& z?CuP;HMP<5kC+K3*lU}y#E|L4?M~xZ{FG%oaZH$YG;Zv(GYc(tW}zh#kByl_)>x{_ z*Hh+L=5TA&X$`PZEOOS2Se-`HNlo}p&VTj!v+Dmzt>1K0GmZW;QS+Q78OU({QNb=x Is;=<;Uk2rmu>b%7 diff --git a/apps/document_comments/locale/it/LC_MESSAGES/django.mo b/apps/document_comments/locale/it/LC_MESSAGES/django.mo index abb91fe5a93a612bed63d2e4ae1bf11a2b597667..ba9668087fd948c2e95be20178652bd30b7011cc 100644 GIT binary patch delta 240 zcmZ3_dy99%mik+a3=AI33=Ap^3=GPw3=GCV+5<}00BKbqe*=(~2h!JoGzXCW2Bd|7 z^nV~N2&9GC7#OU8v?`DWsY?LTAo&I$4U(S%q(S@36pw8NlAf~zJ7XUNk(asUUGh}eo=mLVo_#(k$!GsWn!LwW^r+8YVqV+ k=KH)kiFxUziRr2OnI-y~lZ#lQxqP4^RtlR>u{>o20Bou+Z~y=R delta 198 zcmcb`yPkK#miqOK3=AI33=Ap^3=BV57#NI!v@9!x4g}JwKz=KbmIuEg)S0qDFrpZf~?~9eBCg$pAmgsA8`6TA0mnNpCS}A0fOrF3Jz4-^rBSruhvLDs} diff --git a/apps/document_indexing/locale/it/LC_MESSAGES/django.mo b/apps/document_indexing/locale/it/LC_MESSAGES/django.mo index 666b1225ac56d27679d3a84376cb4d47d843b9c3..d8f677d171e67c26708a8dc9f1eabcdca0c3de08 100644 GIT binary patch literal 7450 zcmbW5UyNNv9mj`1R;-{5Qs&w`hOFM~4wzu+`@$y=0q2Y48q1TA<6_&9h7d)o`pm$%y&x11mX;9>Q5xfZe7x+$a z%iF^EN)Qri97M(HW>EN>0WSpa1ZDllKvba$P}YAEJQsWn6uW%|J(EDt}M?j(bC@B0q8OPs< z;~#)B|3@Hy>SuBMTM$*K--Fx1zsC1l5c-9)&}-HK5lMxR3FZpv-#-6u&rRr-Ss!~4& z#lM~h#SdNr#qa(Oq6+mIDDiL}M8xmLK^fl!%KQgF4IT$kwR!}Uc~5{s|J$I*{}WK; z{sk!ezW|EA{{s}h{sYRq3vpsZP?v)8ei9VAhvN97p!in-il4545>KCs?;nlh$K&{0 z5x)nbV)cDc_W2bk{QVAWfPahcFGksCF&3SOoN~!J%gTpe2 z*Y%+Ik?8(x?i;v8zv7c}iEq~zsm=SuIq}7<;25{}8&Ldj?R5bIvDqE*at@>-8H>}C#zlBvMV|@U8_yn(kD7Lw>nGxwD(?>E@^4Q3cuJEw`?}M^s`$wv87$Z6&v>w z!>crF*=fDwOcuxK%f=;UF|m57O1%aO`JiS@RajAgE20MA7MYe^;bgX`qUyES+p8qi zt*lvfZCYyH8Qtudv~7#AAv(gO2>t(%>DcD+z)jW@I|-eRSr%o$p{Hz`r8b3T^DHfm zOKq-~vb@h2U*I{-;-sF*gTd!?AiF`f<~Gt&bLwmR~08hq>Ez288B( zTm_A^h>T_v_Lr(8Sshd1n?-!wYwf4_r4E~BhW`^1!;|Xu^(-smd#?_3hoVNGii6>q zugj0<%v)!)&@o2qJxBZldh=Tg6LH3-EZaDb$ZO|W)$6NQf)I~4y3DQBi92p}$JyNE z&5moDM4X^%miTOx9n-KQevN#9Ckbuw?GJaNqzdRb8wxnAb|#Q!u#&jr#oH*%ZK#lec9!4`VHY!emO^uLfQN<$EZm;IsFe|(qV8S!yw%kU0|^^}P8Sgz2w-@blbZxPB; zfA$cqNJLCE$k~dl*)3FHT6|U4IxUpwMWvW=jTOXal>8K`&X|!0Rk|{<%IBPV-{DbU zZk?f}@K|*u&pu8#HRf84dk8!V)3ly9t0vX62j-7$J!*SdUN+{7wre%^SM8#)kWK4O zS@x#K$J?&#REuMz_whU{OzyILoV;MtaaR4PYD`Qu zCa3h|p6RKH#>DQ42_`mIn$(lKr+4qZZh~v;ou()o3%N-P`YEXvM@X+d zlO>tnZ;}>V-`uO;j4k>%x3;_VPQv5|Se~{k)3%KTYr4~Vt~7~b%}A8z#EBDQr4V;Z zc4aKJ<#;b>rx@=A!5X&JEyj~bX55wIqg&_a=4S`Gn;e_iN^2sK)mT{VA#rI}Ae0!F z?v;isFKoH*?uCPm8wc}bPx5_ZHf?4t?_oDCy0Xviv}SN5sdAGv4rY0m-Y@O>VX<#& zuMUs-zM=)Pq$j@;P`Zdf=it%ir52SoVDSKH_7)|dY=K^1Dd|}Y0 z-NtQGWYiBs> zR#SY#t4tR?+jL9lU-ai$r_6G}?y zT;_c9Idwap@Ap{e`8qc}@g@vMHqg7G3TUCaM)o$z zqRq2ibkDxoFKPDi)BX`)IE$SC#}yTg7B1W`CjDGKL*K{|5}OYe>H2I^MVI$>_i^jb zB2svy=<)BL#AWp>tP|#`THU!-wX3Mwb%v^#ua{E)eF`>270nTaONIl%`$U`?ULaxU z7f3%fa7(A^EDHnmqwvQ6CpUCGLla_hQbyVtqBTXyZsr4S$3PGZA`IWOwT3!1jEi-dfwJ<% z*A`nsI@)BJ_7h%$2;R%q`j(QWR7p1x>qIoImq5s?y2kiCFmM$)`q2EVkamT!TEn8) by6#90mr5?ZYRJf;wg%q3gdB$Gn$-UQq#}u= delta 1255 zcmZA0OH30%7{KvCtH?uIYHfK`sXT<*K%r=Y1s~C9h>9`b!3dX?u4QBC;&zMZL1K&- zucHw;X=02A6A#3Qi800l9yAdXA2$gH51ME^8BWIkN2>?FboRHMPG-LOW;&bv)G+3rR!+efcvo( zH{cjHDmAUn7k{{cHT>`aTk!`DV{pAvyU@WHJ}CMgWt_~u8QQQK_hJxFpe&R|A5Nf* zyMkqS3xlk$?()J%&GYc$3uJAzh*kIz%kc~HQ9pUe0xP%)y{sbRn^49_QRe9>_V?o> zs(KuE(Epp&Wus9h?PYy+fR}xE8HeyW8tAW3DvmDhzb!*HMmc0jGEKvck(wOfXwLrcriy6(!SIBzZN50eptr@f}JjSBl@) zux2g=Iwt6l1+OFbM%_g@%ljyoXdY#vMWm9e$027a zeG+u9CM3txK#R~MDA2!NlL>1 zhui~6Sdy2JYRcu?CSM4tW-CqpTok>KZ8OUGNl2NbB66{|(sZb_Q_q!#bfBzHpDlZ% z$IAEU{S^cHX+@K6tUNt;ukvDvK3FxV7pfATjFoeBv$sWG@CL(H_FN=okLJhCteaDg zc_wdVQV}bgGN(-K@$J!Lz5_=R?VX88S5LC5C)P=nA2V`p`$@;h<}!wBJITnPea3WL z8*_$Z*^xe{(9z)(Iy%yJ_L7k?FX`{Tp`dFT<8jN4N0}&_&Kqen8L?bFP(7?4SI6{D ze@wsh*XpZ*KD`|HrTxKS9S&X7OQB|cs>ac})<5T|eNv*o)lKR<_1%@SAwzPuMlJ0P nH|mk_);RkzGXJ(_E5{nObFP!Oa-&uxow17J)ufTJ9aH@QMw+uL diff --git a/apps/document_signatures/locale/it/LC_MESSAGES/django.mo b/apps/document_signatures/locale/it/LC_MESSAGES/django.mo index fe8816f982b3e80f3efeb72fe4fea47a2c0b308e..fa6bcfe2579a34afdc1e18e5289e15638581d8cf 100644 GIT binary patch literal 2072 zcmaKsJ&YSg6vqd0d^tc!_zWOr4k>UaSg-8_>Ey$ZrvzV`A z{*8Ga^T$W6`r_!W2>yaQ4kzk?)y7v$hyAjPrv1Y_sG zb0Eom0Fr+nf^UFgdHw}R`rm;k!JojF!Jk38_fL@g`UiXrJb_>-zNbJc3Dw|5T4U0n zSZI(9sJKCTl%sMWbaxl6$v4VlIjHVrA7yd_X>@*5E@+TX2$8*jNq$o9!hOgmLAzy<>?_u24~9@Rs~=(IglX=z^20Ra#1r^NphFG z)iT#vF11zCR8dxkhArw^v$LkUn$Lhniu z8E>3*`PACH>-&+i)8e2RWQngcBecr2pOCJvj47mP?0-D=cC-{0X1%_!C{m}@?s%<^ z*Y5E4yWLL9Yh7%$An09}hl;MhPws-(Y4i5QZs)?=EsVxBVXQaSA~mtFRKtBGbuO|v z<5xr+!t3|)a;JIVb}mJUP%%0AKGf5w5Rvr8QY2kIup(B_*;vLio6VY*jH`*f)l8-J zkxa^t@$*Gso(vP?$4fK5vi@dcI2i7(a@TIQ8ar8P(Inp3y-<3%ejW>zZu4L&w2`)V zW4z~Wt>oy=iPYY18f2kLqb}b%P_}Zn%dyyx3oT-AFVhKHBhB5?^g7#o@!8u*`FfAH zHydnE=|pf7h_JANizq^2(AR4|d%(GR0LoNS@Wg4i)|}f&lM{E!)_IQe2> oW6_;c!E4LPNk(m5&mlvn=2}Vn>$eCkB;FyrFFT_vymZ53vESFs6!1-7t_1|IopEln&pp z6D!Mu!u=@g#_$JDqa3`1Qg{>Dq6#QCa)R_%Y8px*4N1r!mAz_F9t3Mkn`B%^Mo768 z=~Rl!=V>Il992O|A!$OQisTZMvXh~4dm8$*|HCczJ$z&@BQp!hp+wRdok%4Ug9#$G zsPq2Ns?oXpuJ%2Xa+bZVjPX6pYvX#(Zxc)mn_yx%>*Wf1H&d`3(Um4YqxVK!e`J7z va@hl&&7>UHx5v?S`x;%onJW*KHRsbDl-AC+YxcBqb7{})dxmQExnlMUL^@Vv diff --git a/apps/documents/locale/it/LC_MESSAGES/django.mo b/apps/documents/locale/it/LC_MESSAGES/django.mo index d9194843bd7f149100b08408f2fb46ca784e4c19..2c1c8afe64c3614df906b264163303ad1449475a 100644 GIT binary patch delta 7393 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 aT-f!r19ICICb}w{@$S5&oolyf_x}K&fGOnw delta 5018 zcmYk;33N?&0>|v=nd2}@hvha^G}?Hk#X+lb8s~03o#cj;0TOr<#&5Lk$D_L z#cb3UPGf8Q8TBy5Gv8_`2YX>2hT>Ax)ULppcmnlsC3CUtjA59Ex=#UWrYGVce9=!q zJ-L9oVFJS+j_px1vjEkxH&8dMMoo2C8~6K7a2Mw-uoHfQT7sW2_zcmS&f`!^n2J0W zrT{b0KZSy(?p0*j%oYs8qo}Dqg&O$<)c0wR+W$)^=%HGPYG5O(;ceD;Q6o8q+Q%1B9sM5Ffx1kS*1Q?ABTWwK`r*hH zHxp6MP8BlAW(DfHx3P`({}BrHsJMk1>3!6N|Fza{?{=^QMo`}cHNt$&SBM&5De?+1tCN_2-S{mkf*nCk*>TibevVqRzoR-Bne2|R zC90zds2NB`J!Dz7eweKvi`PBIOvY3`@0!A_;VkTdAEhw=B@{yWv@e!f_hT04)tH89 z{Gw=lI1OLM3HSiHml@4_TQ0-F7(jl4drTe7V6SN)T~X(gtTX%+G<9=OGw{51IqG3r zhtaqL+v7nj#BZ=3W@Ng%As=Ho_hA%Pq8eI^dZDeves~JIU}Ptr6ZH3`z>hi2uRiz? z+hPxfUmvGo16+W-+{{{gz7LsI^D$~F|AoCVGuxf9D%6^9M~(ahYKgu@4d@Z_e(;;< z&hE%MA)PZ5Q9WFblkq(E#1!7M{jm(yk%M>}uVEuR#xPk8a~Zj}sl`n+quo&r_s6E_ z!zb{0jM4sIO+hb|&DIZ4Q+XXVWp}VCcIxUr1H(`a_)*WoLDbqe@8&ufSsk+wHA8z) zGk61a-@B;Y71Eu0+BY#2G}Vcy9(Tb6?1MwG#MU3eUvhpD>67Woycgj-)b-a;pWi_y z!AxV?`1@tHqB?LAb^oiVf!#uXEeh>=@s|oyaUo8}hWIy(!H1~tMX|umF&4E{X*dC= z;#fR^YM@D;`%JV(cCIPHVfYei25zD{d@qmr*BdJ=-~B5Vi7cntk6P0^*aAa&GBtwM z*bH+p4o71$SWb^BTG}IS!Q4dW% zY7L)7jeHgAdpl7L?6v1dQ4iG_)b&?TBmD-|@gJ}?MlkQ~G1)rCPeD_$7&X#YP$LYW zw#gS5k6&B8YynMa8`Q`OQ5~Funz41L4(z}uaj&gEi@M(}49B~ucKr`1sONPG+;@F5 z)YBf1deL-8b!;ta#CuQ;9L7*QZO=coeu;_H{{bjGtHNA|r@gC~>A5quW9q86Kz(~$pU~vDp z4;I)?s3{zR>giO}jpv|VwaZWqY`_HEi(1nws0OR8p@ZD1jz)F3IVNEy>i&~Z9h!&1 zzyFI=pkg^{>er&yXt%B3haS#1l2JsBX}h%|MdUJBP2MIoN0lv<;RsviwGliz@muX2 zA^s)7Dn@Iq;ROnl$rmI*W{?lb=R~uhsr`VwO!|>?Z)#3(JQ-ro%CGCig#pG8cglr}$M6YNa z$;7Ym?;veRCh1RVj`p_jH2TQLH6LIi(O_e7Ft`^Sm$DbE$bb!*OtG;L*$}8UvAZlOvf0ax9Klz z`@uh>IaC}cr$}egmGmO7k=f)OGK{PsHOB@Dyjjg0Td~#pu2rleC6ArYq&%Hu2kV04 zcmH!aLq*GACI3EI-@}vS_hb;6N8TiB$ulIJOd(6jVRD5WB!wiGgpnkYMJ|v$vVgow zdXUp)Z-Ugzh8`<^oAQ9`;iEOBDsYNF2*C~Eh**U3t{98odd{dS;v z@-tq?NjcyYrgn8MHLmAuOHGI^_06q}d(Jn#*vu}j^iB0u`kd<2qt4Z|4o*b+^uVI@ zzMg>@9W&D7($czQc1}v;h#br{9YddJ zg+HUIO+}D8yxCkFy$J0Ng#aaeXmom@S1bKu$PlNqDP~u(#n$AJ`JU$%=iDn V1V;SZIX`lM6F;iV*);0C{{i>!PXGV_ diff --git a/apps/dynamic_search/locale/it/LC_MESSAGES/django.mo b/apps/dynamic_search/locale/it/LC_MESSAGES/django.mo index 3de067b8dc0eee803dc4acaba633e9614bd425b2..51351035ec16432db053308121c3f3f6df054497 100644 GIT binary patch delta 272 zcmXZWv1-Cl6b9hmV47M?4N~c(xQQ0LxO7ONV7uxhPENPQ#tSAX$;}`R-3qmf#mO$d zLwyU^bm-zs^a=a}nZ9#=_z!329Gvyd-N@=?i5AnqJZ+t!n+l~xd($^3 O7lS-;oBOT#Zkzx{PcJ$E delta 230 zcmWm8yAHts6vpwd(z?Z^K`@DxrJI4tC?T;MszZqZODz_IL2QyffVHzegv4y{04Ads z;NRpVzms!vE)V-^U!I4^kXokHm2|hHHGYxMJS`1zfdh;%slTy?A8gUy z1Ei%9mT-z?bTOIRX4F%g0;G{2RmEgsGd>%SRJb=^^}zSm&MI&^ W`LVZI?!2YnZ?A&TwPx|%I;Q?z9Ut=m diff --git a/apps/folders/locale/it/LC_MESSAGES/django.mo b/apps/folders/locale/it/LC_MESSAGES/django.mo index a1af93bc035fc42622a9433fbd4ef1215f435aa9..a2bb375e3eb621cb3628fbd535bc81364c976c62 100644 GIT binary patch delta 1164 zcmXxjJ4{ni9LMoLP#zW)ijVq0xlmDRX(@Ej6b7^os3jo=6XQgEBoLbx+s-yoVq8ch zYFJ!IjDzu&bXNxl6I?)JbkIp<&{3QW_4~Wr{?l_m_nv!t?*0GIxvQb?q4Kv5-vcA! zv`*T?IwANS!)Jc`Tc;9qRUAP4n#;Q>5@Rh-6Mvc)WbH&FNQ zVjIu5=bUV#;}tU2-lJaRBQm%BKz{a{!xmh}AXbrNEl6h@cB01jd)EonJSl9&N!0vP zxErT2!1JxliAuGARK*^lCVqk+SdJH{3f*EBt;%C`bRWaGjOTIP^X%5mC0IgbzJjXg z8jhi|O~Pp`4|6id$zgnh%4`kwz$%iY^=#kV8xeH49>ZfegZkeRYTP^Q#}(|x4ICf= zhw`Z86O=>q=TQH<-A?^gif452EPIP8;VNpazMv-lg%rX5cy6FJYYT&PzZaEh%)35? zs_3}q6z=4@=-t1A+Di+nzXm>~Lof0g^#Y$fzaj~^)c`jul`^6W;vh{ED;Vl#7egv- zQJP*#p=DLZT{Kllp@izS{;01$@zlRJvFh@%?K|C89%v&R`-r zl!(L$e>zhvMJEfHTrry|N({F-_GpT5DpozNC3EP-|1)pchf;!T5$0Btnr&XFi`OnLBWF;6^iIVd^<_?;K73z{r+~>A+w*^+0D#6&&+;HzD?FXMuH1Q z$x{2NcUsKGv2zU1=rSLlgZ#g0pb9cNSt8=YBtq;5pPE>!|mZaR{53z*Wq$@NUwgR39b{ z8h;Y?zbYyNOUP9AI86SPx@UAKB`;9}zej?%FTSg&!};5P-pk91v>)|;9(Cx(d?#=N z_a*=NHPjiZ`Og{?>UkTkLrZYDITinehl zb%2_ps%W7Bx8+@QCUpMXqW#z2>Ql?OJ)CG?rD_M2Z8UwAI_)tk*>6S_(8|($T(g{=5l#Hj&*jYrhkyLY+&EA^L?Xfc_286S; zv0B8!e?bJXywXYtHWpfln##t)_y>sJ-<>{q`^ijZ-g~?EseUju_&Q&E9uSM;7PoLv$%!2w>#b+1P}Q`1)kt3 ze2N<81y18@RG}fN@OxCj52%KpQTM;$M~3`?hV_ucI{$^oX*|R!{Ea8@4^9RH9>>Oo zW^wdp$p3;R)Wv1g#L+)*p$cr`9Nx!^xQn{~40Z1%s?ICaz;9544pH~tVTJyq(3|Lx zqDt}-qpzX0ns7Eas|7Jn>ITjy8q6}Ia#OZmubrg71;d6t`Xn{CtSdhh>Eqcz$oA64(p yWVW01Z4!s650}fs>K2v8JCP}`)fz^lZ>Pp)nKc?bwT5M%$&)1ZJ}-A_M}GnE18=SX delta 593 zcmXZZze~eF6u|M+M62l!Ypc~kpw6i!U1_vDk zH@6N7{sRgQ4sH&LD2TIzxa#*Mee~{gx!k>bxju%T_4Zp_J5`7g+BofwHbJWg=!kdJ z@B<_Gg*yIV5dW|bgFXJbD9XA74qzGwF^jTqp*vqe_P3Q)22ozDV-hV4<338FLzDu} zP!e9C9C(FNKnFV%af`CfqKjc2L%4_ic!0A01ZDp@MmS%&WWZ19(8{QwDCvuKIk+bYZ%cz?z_d#7tHcewYUu)(w`m)imb`8rcrD{!gO51RcwXFN9 Geg6YNbweQl diff --git a/apps/linking/locale/it/LC_MESSAGES/django.mo b/apps/linking/locale/it/LC_MESSAGES/django.mo index 0fd371e57b18e2ed0da85b0c2f2aeae814ff799e..ca7ddf5b921b6d414fa4e4069c8eb828d89071b7 100644 GIT binary patch delta 1768 zcmYk+OH5RE6vy!+MdcyoS+FhAK^{U8?u@`Vj#LY%XabQ$gC>gUrA}ZHV93m1)3BJ5 zxUlXJo751~)QuZrjKoKDW700P)fnQ!N3;tPWp7Nhb<^)}=1$^2ocY}Qzcc^GIseO_ z+h;?mf68)yG1>v5nmCzb=Hg;5A2k0uGhGI-5reoBhta_c7{dGb8Ro1vtHh01h7Nv? zJy?#%u>_}(Ia4;vMJFA9<7Qlwm-%8nuH`<2jBUHnk9$2&d0s{>$so5LY%{)HD(uaEA!ji0(QlNTAtp)qj(xCHe^eKzqN~}siz*W=&?xJ>j4>=C@0JVTesEMDWcJ>-o z(|6u|A%p07HELl^sD$GHE+T(+jgMA*h+5DGWRq6NDpjgFBpDV)rF;-o^CPGoA482loH1oFF7(4$ z)XsiI{_Hv*%FHtA^?HFC@ITZ*9Qt&osEq9EzC+d~$AhJ#8MNMypn$C$zsO)Ydf`nQ(p;D*}4)dq~ z^>Y5KfzVEs);)w;fY5 zjl`$i*m%s>Zoh2W+!)7vD8g1Ns??H z5lSAQc(D1C#RI0Ki1GwQJP?gMpveQx`*ZGD`E|bMb$-8d&-wlPo_j1ZRF`}|J?)%P zT8R0?p7CZ5UP$9a2~ILA#1O8;7OcP?jNkyy#P2u@Crmb*j(Ip2%P<$4F@UYO5j(KP zENOSRSVY4&)DN?#m`%h2!%nU`r` zxu}7J@fJ%SLFLL99^QhX90rAM4(nge#dR7M;u};F{Xy+%fK1X1N-%`GQ0+%>C-z}A z4*U0mj7lrffLijss1=Q&*CEzZzm5&~HJA0*Md^%GlDSw+{W5A`&wT$NW3nRl;Sw{7 zVg>cLjCMI@%;vXPk0&vm^)JLeR1yv%kJ$&*ihlI{mgHh74Zl%Iw2;ix42qCdvnEt7 zY)9Qch|93szkk(lzm1ydL)2D1MQz1vzy1?BY?PCJH%2V#uP8rMRuKMwmRHxOwt>)W)nSNG(RQyScr63d_eTkO=TwL6 zg!g?e@!PbVQ9`rQUXK;+zlv5xMXRK*NZV9J)DS9b2~9|oQ%VJit65eYwxv> zO0M;UiuPGaQcLK&@2{D(CB64rcEhG{S!Fm_6^T}@D5<1mY<9X5W!vLUXIF=laO2V7 zR(D@4o^Y|tiMPAKRq<3qc|6rn-sX08I~}p^-txeiu3Gc+V&<@d#0uXLbym^7){22F)JA4OodI_$a=B89ag0i_P{Gnmx>Qrr2y1 z{(-A8SYoyw8}Tu8QT?65EvCHOwBz)z4r`;HG~<|4OHsYNOEmCdisYjAKHR0EW#KT;9g|XHjdhwIn;n} zp)z&?nUkGHW#%)i!mm*SE}#~6!@qyazkd%oGFHBf{nvw)jINGrQ3E%i4r4opFoqiN zMbv~+s1>}9n!r1#6`w=(cft1u)K*bT+{@USdZ`G5MIPSEas*TaSU0I zXCG71gBj${e&a)_{||L0@_4rx(~2;H4ZgeaS+3teW#&5S@Rl%JJy(rN`ATGMw$(R| zB*Ttp^?1#w=n!4cRNe1i>qzrMl3l)W z@>dk?CyNwHqpWAvR=dxsNf3`PTo0Q?8RbIvbyxA6e=J`Z^-* zZBAQ9S9^P7E2Svv&ZQz_Nq2f~%1zBAyPV-fJUQ#mOwBmG?$o3^?R3xHZ)qOSwxmN< lqroY6`q0bnq4<2Vs;9VYEHRsKCKJw3Zp6g=7pvY5{12c5)w}=z delta 2117 zcmXxlTWr&17{~EvqjYS8!6*#o94m-(W9!znY-1Nn} zAR*BZV=*ztn*qw5#&k<`_;a;jdF;%Td~CKr1bMbsas~Y9_w)}_Tqhb5U=8^I8kU8D>l1}_H3!yMx4h@ z_!qWf)pD~o96*hC1}n`xo1(IYj#<4W@B5p2GlM!ZDmh zEnq{L**&-&yYX4n_ogt0pXT28%*s}pu?dS{2)j@N96_!4b<{#WL&mmS$an2e*Y>Z< z?{p37d+pedBe)GO;=_0yb#e{m`GpOkkNNEc6`l4=s1=?>eeeR-;Z+>K-!Y84*tR}@ z0+-?|SdFKUKReHhPGknx;T-D7e?Sh^{&DXY@gYw~Uqz(^!&rn}$YQMzbtU^y6F!eR zsTYv7*d*#i-oOfc7d7F>=)*bp{#Wk(1teAMH`o71fcw|LK31WLOHoM}z$y%*CXAsL zG>qE8bEpNRkj>a>)I#2Iet^27Y1BflU=Y7Ro$xK>_N;g<=dTGW*`|(i6Y2|ft{uYp z0<$QRtyaSJbd;NMGxp%GIEJ%qZJ0Ne1Ldr~7Ne-E9K}|A4cqY()Rq10QBhWxv2E=< z1U0}6Drs+^zPE@v>R(VNTFL6=He~a5zK7*R@ zJ=gys7SjF_movY8O+`CcaQ=uv+KZ@xO1WqaRF69Ph_e@UQiIN<>wgP%CFh-4^wItt z8PevEL$%x3p#fKsQQA=uwU8~SFSNLJ8y3)3pOUPL7|HbbYrF@j-6?yh>>&0N54lcF zqf20bTsgpNH=#^W(Q;It$dgND{$b>{uP&`_JE0%Bo-mIRTL_&WC3DSRU97a$L!l>A zP!#aO>Zcsaz4GirrIDWG!$dow+fZpDl>2we5S2$<<0;%r3=*BLuh*%w+U@E>zZaFI z`bY32m7PRAp?n=BRJIbjmA=eOQBAy`nv#wOQLa4b>_Gj@qJ)y~e&Qg}Opu4UpHu{& zCRBD2D+p!&W5g0dr6t?CthqRwDu3D69|^TYf-N1Lk*y73N=Yo9N{99(;}fZ)@pK~D z85~TEjVIFyOvRH&62b0dzN0Cb?`S%ln3#+o9iPlZD~5dO@%XXq*@~Xh?83&gzW)Kt CuFKs3 diff --git a/apps/navigation/locale/it/LC_MESSAGES/django.mo b/apps/navigation/locale/it/LC_MESSAGES/django.mo index bdb151f775a9c4983122370c95c27ef48b741077..be999a7a8d9d55a0b540edd07ea27b443d526393 100644 GIT binary patch delta 115 zcmZo>UB^1XM)ooz1H*g<1_lWrE@on2kO9&?K$--7^As-pdwZZ Ilckt40r{&VLjV8( delta 73 zcmZ3-+RQq^Ms@`w1H*g<1_lWr_F!UQkO9((K$-AyVEjpcW2q1@rKDZ zYD~Nk)J7A72@fWkcn>uJO)$n6AS#LBg$IFDjKL715@O`R%lEfCrJn46KWEOKIp@s( zoY`~h{_4!1ubA?tq3j~&5!WKdgk|c7YSaxDvYn<5HBb}Q zU_0sw2k=gO5?PCR3pL<-I0cWRj?XutC&TvBsCmwW?dN8bf9>r>8rW8I88zXbsD(vY zwkD`SEvO!~z!ua5t5Ns0qsG~Qx^Ek5q9N3H8Pqs=)RrE^GbP5nUqSu{Y1mJG@4@r9 z7OScl9Q#8L;3lq5piX}kkK2lyaV0*7_v4os!xCoES!u@mZ~*J^FltLrA!{&K^Hj9* zC>vUf<+uoA*oZq&6TN^s6UVR_FQNvlVqes+9Z8x=V+)R8FOH!W@Hc9K-M1GH`^(73 zua&T!crT`pI~7yT{aQ-6578Ap%NRt5?z?rJE2Y4 ztR{+NW8w@tay;LmgTYdlX||eM z+gesHZK9NIv~zyL_N<-GC2il!wpo3ylg-#((zCkkWP+uy$xO5~4i;KQ4^{M+C++lb zU=KSn*N@eYPO03*NX3>mYwXd=pChThz;i8o&`r9&oeeV3{BYip$bTGrQT+e_ delta 2057 zcmXxlU1(HC7{>88n-AS+Ys{uGjp=r)@nfUeO=7-`CT^^nMx(Wxq+;6$8@q&5&9>VJ z8Z7ILMQsFSYoSmOkxH$i)CDiR@FF0^i$Ythw55vP3Bh77iejPqf6h(@-~G)@&Y3f3 z=AGly?z>%?d*wx^jk1HNA#VH3GB{bx59R1AvjiT)W}L=$49zxMg*#FGC$JZ%T>o6Z zS(J7R8}MV)b!RbzcW{Ls^@PeYIu@6j&BrasGi(SKV-mx7%$Y-Ow7c%_{yAo~wChpV z#W8?~T>B(;(!P!{e2VLE^<1+Sz3M?K3+T9l75F1+LVuxVUi6Y#1Y2+^eu%H(7ubat zP!oTMn!qzG#M+n5_-D)ciD4Ty;Q`cj7qL!D{Tr3#X!G(D2;)06yHFE5iHvFAp_cF( za*Iu42|mMeEGRScV+B@X5VaC5uD=&`eLu2G_8w+5&~7TPVjA^klNiMBk+JO-YQR6R z2p^-;<6q~0uD^g~&;&|Qe=kFAWhJs(7DPQSjG9>ceAZtN=%Yh3`T#YqH6TlW!a3$mz*p2sD486$WbS79NutHU;I#NiAT4fG}I z!W+n>?GY+jo?|aIRhezXL#T;NVGRB3TQzQWCUFJr!`O|Na6SHwE!fD#i*N)7F>{=X zmhL`kB9BqoTfH#fAH*2#2x@>7>J7d{P55Wjl0HWk&pP>t?8G>-Sau1uMN_EjesS%2 zBpO?tu^<&*(w3kfJ5lGp2Q}axr! zIiXpy3pN{d-6F~JZ6y^wpcTmz+k_;qmmu%rOwm57Y#_AsGexU4Q+SqF_;z_GMU8r* zjaWwb2$hw2EZbaCqd9n|!1Z~P2+`P1Xhl?%<(j<;x#yh{C8SCZp`>HQy{(F&-dL-u zqLZK%Qdvv%5qe=I=o`v`0V*AYGE>Q=MAKes|FzUQ3FM{q6DqC54zHH~(b0{%_EO|~ z(Nt({I^PjV=Q|=Jsj-Q~-sD8~XrRAxJek-R9UYH` oOZyUIBl{C0$&S$Ic=lo7{oMA72fpl?1!K8r)&Ir0p5PC@7b$VV&Hw-a diff --git a/apps/permissions/locale/it/LC_MESSAGES/django.mo b/apps/permissions/locale/it/LC_MESSAGES/django.mo index 1662db40f5abafd11c4dff433f290e9061330bce..629ce70c6d3f258ceb682308bb54687bc2027a87 100644 GIT binary patch delta 1178 zcmXxjPe>F|9Ki9n{##pDEwlXBpD`={JL!tmT2X2g6&R>NCDdqxF756NGqaFk?4=GC z(P4=oDug_ShxXJZ>JVfE5)lMNK@>p{L{Wzh(f7B`KK8xOn>TOX`^|6O&ezS?r$1B` z-Bgqg>IUj;K&gIwUqC~7UZ_+tE}@3YIEX)R2z!f^8patsf=hT5t9dAlXMGbG;`$=; zQ&(u#D3w;%=#(&U7wd2V`|vUD!rxeiT}+aBQJN||fI%EZrl@h04JNP>6Ua|pq9G=A z8D-uaR^W}?by}%=bY!6gT#FA-9(aPQ@EO+NGRg*Dk;v6glt7AjSOTm;hEx;E^KJgP zj*^LfT#biO0y&AV)1>>1KM-NJ&D_|Hdu4*}Ega|i4W7atq8P>NC;@$v13U;uxkS)mQ11;!~7~FR&J0`QzXG@n0x!@)u>pAQ$pnt#2c8OSPe- zxDSb09Yk4o7$txcC>ctG`TjD&VPGT9qAYkD*WrENNB;OS%0h2ZQuq-ikT1S}P(Dep zeC2*UlHlBDZNX-0BbBq83uF`ft9mXZh;39Ua`0snSxAa}dr4!yu!q`8mBX4Z)qY2U z$(J@da!%wh@`Y79Rk9*4D5aGe+E25cDsR(7mGns_G^!N&OG+lB$l2(~^;Xiig??>z zuJCi9_>g0z?9BP%hv5<1oQxT9HRhU5wxOgq&^+yVc2w7=V%~IWqHEGh=#J$YPRw%j zgfU|z^_c6XOgA$e92ksr_H=9Ak!Ym5eFr6U%y7NVQO8KSal^BmsCGPNI<{fOEp5Pv zpEHu$9y>qMHIW<1ybF$$$BpDv%9t|sn5Va9hDuMf(#l9w%ibyNDInsMZD(GF7AyRS PO*Q73NiTb$tR?UtYY>db delta 1055 zcmXxjPe_w-9LMqR+|=o$KcnY6~p_?OOSyq&nRv?u@X&{d@#y}lBt{^+CLonz% z1nrVVbO@tp5JXU2I@H0ULq|_~34-WQ5FL7d+Osdu_xF09-?rcH`+T2g%hBb|;#zBH z!H5{Si@X*vJBllH48&s4tR9!p!TWd`-{A;`LT00Q2Gh8NXK@`{Fu{-IFg9ZvwcaI$ zt!71=;G~m@89a<7OyL`h;BRceAVVuQqZaDI&De(=mSSK}JAwSfMsO3R{p%~($n_*{ z!z_l_-)?cz#Kdjfj(1TTJVYwAr>KqJq6+$g9Ja=w4LAJxZ>T%{gVGq@)pqmU@_>S)as-VZX6JKBluHqrwKy@_A zm)OG2BemH$?m!ods(79gEnGr{;^nxh#g4N;xCn`>z;89v1xu4XXD0)dcZr!AA#vy5d zMM-r-p%=Xt`nScjphE4_OVM6=6E diff --git a/apps/project_setup/locale/it/LC_MESSAGES/django.mo b/apps/project_setup/locale/it/LC_MESSAGES/django.mo index 8147693df5e4ff91a7f402a265ed39a34a486ae8..552b7388f30ef4b3718af08707858fa065a5ad3f 100644 GIT binary patch delta 107 zcmX@a@|IkOtC$6FuYAGfGMdtn~HMGfOf`lk}4FbM=ez zixZ17^NaLz6Dt$*^fQZ#OH+#{uDHRQlbDxYnwXxdpIM@>Ie8jmG?x!l#7bfEJH`+I DeXJsv delta 65 zcmaFMa)@PuiRcPO28Ln=1_n+bmSJLGkOtCf6FuW6p1&bhlA4&SpIM@>$>o!nmtLBf So@%9#Su%MGWAtPhra%A)%Mq~v diff --git a/apps/project_tools/locale/it/LC_MESSAGES/django.mo b/apps/project_tools/locale/it/LC_MESSAGES/django.mo index de891e390b5e4d2d884f55524f79053492e0caa4..9febddf27933713c31e4b8e1e623ec55a2a39c5e 100644 GIT binary patch delta 99 zcmeBT*~&6Ohxalg14B3i0|O@zYfrQcR?jFYDX`MlPtPpLC{5B!&d=2^$}dhV%FHj) w&rPgM%+t>-E-pFi!RK!YQ@+C$K0OzwHmgs9vKEW8x O7|M3sa6V^C6k{qMo;!*@&f>Yq!Q2o diff --git a/apps/sources/locale/it/LC_MESSAGES/django.mo b/apps/sources/locale/it/LC_MESSAGES/django.mo index 73223cfe1a3f1f6d1d71f271a90538668ea00c4a..0224510929ec3e165182b20adb02f9603f3186d6 100644 GIT binary patch delta 3773 zcmbW&ZH!b`9mnxATgo%L+udcmTefhhtSs#Alx1mwh4S1jj|&t;lvcQ%xw{=ZbMG(@ z+d?RlN*W(hY2>Dcv?Zbj0|rfWUSQN{T2PZ>W78U|^$|6-FMI*U7}J{S_jm7|?Lz1q zPx#O0?0q=*od5aX%TLyw8mj!EX~J`cHcE65KflG8Q+Q+&KeVe;jG2hnum}H*o3V4M zF?VAgC*x^ciRW+@zKwTc-85sm(Be$ogpIf#xvygKbZ+OsAzX%E!U^~a>cU^(D*O}P zigTt%19hVATY)oh7q*~-n$Rff!4+)Bv)GF-qb7b8=kt7Hxx0-68&Lx~s0kdxHFy-Y zq90>F{uY&yhWhC5R@}zln~_uIBx<7Hz-~N`Tk+SZaXTA~QF0ez2hTT)>CDCLs0SUy zJMfFR5YM6pdIJ~We^C!wKzdk&S&Fl918STU_TbYvAHR#5;9IDSblny$Y$sOcao_|U z-FPAPH>ga!hwHGp$rvVY_TUn9k?l3lqaJ()d+`!>;y-XPwlznY*n+x$CvwUhK+4Dz zo5{aAPjWyh{Vej&9Op*^e+}p0OQ_UcK^AY`My2pysG@owDG$>^0q8m#+li`$g{Up* zM@?io>i&%_Dj~XzCt#}L>+dPl_GvDS%6TOHU;1$&UucIb*1+}1Ss0Y3m zpHDET&NremYf%|oR-vOkU60zU9BNCRL+#=BQ7QWyYOmi#O>`2o)5>O|9ymL;3*ShP ze$+%KQrX&y8MqVI;N5rv*GM4!&TKo|v@sGF^>sj`_IEbp1CsD=v3@)wEIY~#a&ugf? zc^~^QX^mNp2T;dPqf+`BuEO@Y#@vH@aS0wrcEMc4<@kG~{><%nMc4PBYUnXktv!Ji z71?PzDw0=m8=8+qTQP)6;qKTxDg)2Nei@b0)2IxbLv6`VWB(qXZ=#|#ky)tw7ojpZ zFpvD}_1epUTQG~NfjsK<7)4d_Q>eG#bEpAcKo#Q|)cqGw#do>1y$8oQ7N3n#%oJjP!HaKB+rylnLLTSspc|j z;#W|6{!i3Ilz%;MN+s?zV}b(@5)DMHDGORbk#GoJig3jRTu5jiHxSyk3B*3)F+zo> zX2aiTk-Ou*9<0KCh^Xw~=KF83O-IK#Y{N-5P{i3s2;R;H#Sv#j-YnKru3^g z)sz{vG;u$%hS*PJ_5SN~IKDj`|Dk$#B<`=kM~St>RzlUSrng3g+P)yl-qu*ZK? zcwgM#gu_H1p|@u*k<$CGmLVDmy{BsHBEsKrzvz98_!Oc2oJjb@5V4xb6LX0{qKiu5@Z-{rC1MGoS4mA3sx}f~wj*EZ@MERoQu{QqE9^zzhELL0 zL8@3)z{`k(go<`0p`xv|0Xo(5likFOw4W;HT(4wHhw^SPdFrv&+JRBGP|WzA9WMAe zTMR1oUDYp4-Iv&u$+~8cA6xcPelA~di$ynWi{(^`-f%gaJ!Bm(ZOi$r@1!~76m7;! zXGSyWvXiyL+*wS90|d|3xAli3J6a4A|L++FN9wzSqxDU_wW)nDvFqpL*kZ;TAsd=*aHc-n~{{PgE@Kxbtb}L`Tc)FfW>JPs%A|Qcg*G?A6Mp`eN(riHd3Q`#+2Z_Uu(o~Qq#<^@?D^Ff+8gRtYqqxJ=JGxp z;`(7?!ijyzs#$1wi;9fZ2Ipq=4SwhtAFLvNFa4hJ3%Y)+;LTazYPp}6_AnLdhI1Hk zi=|AddbHy^bxp%%zrb#@$hctrYI4r+5|!E}mOaOMH)O;K%W^CgH@zfU&h;5E>%&oR Z7|*chrGlT$QZY`US{{vy2iT3~i delta 2421 zcmYk-TTC2P9LMpqTaZF=xpxJjETvGOEU-Yauz)RIKnk?wQcJPIqJT986t-3|anndr zwLXwej4{1v)IhB-Hv3?W39(pXV(^j}@zU6vniQKzOyi49)bDS1G@kI^&zWK7oHPIP zpWTxkpEQLorN+EsXd^^6(Y?x;7xCrW_@KSF+8A}uVkw@(R{RCau_E3Wx@G|DaX;RP zvzUVmScF$F8RHY8*Jq*In2^b*vxR^7F$ROE3!lMQd9~kmz*W>l zzhWk)tue-nUerSSa3dbYJ1~rH<~NIU^n^cS72d#h%uS3=G>Tftv)G1*F%G{#Wo!xa z@FwcXGgw^~`mhAsa1$QFVtfnvGoSO3$o%FaoppE}HBg)@n(AWIig%-)>^a3i;O!>p7u4+=yC81?t8c)Pfq3 z1yn7Zz(}#8?mvgR|0C3bzC=CHWz;;&Ddb-ltk@U)g(@-^kFV4f zqV~*(+KN78o6Ym61+IJ81XHzx4d zeoRIcTN`e}gV>7iV*@&QcM5PTD#gR71&yJuJA|XSfXYw>?;>9*rV)Fw36-f6$oE6Y z%+e|3#0AvrbOSxOn&p;ZG2VrHum)#PTlOicn3nASUqdg)S-gWvZ43JFY5VvLHgfy} zZpKU|tJeF!gHA0crcp&SkGk+{)Ly5uOznLxmSQt%FN4^QbEpjdfsAc#*}B<3J!zF~ z11eL^$k1jd7BIgVRR=Bmf)7v&SwIc&Ei$ILimLX%Q7KJhV>PiGRjfIvVk<)3SB|Qg zTGV~pQMJ@>JA)y{GUw^&i{%Pxg|VKfE@U^18}reJ8n_2FQ9o)chHVcb$3C6za}i=ga-E6`q80dLf;Pqgi@{aI|)_1n$lPj=|w+!?EX%C zgt(7T5vsKiZIPZaciXD|BE_XF+(W28_PbigJi7rChq!g=l5PAbV z#2!LVtj3!g`E^xaSy4vRl(`1xj}+fFr6Frk)DJWObhiiu`I?ID8KInwk)Q$-9$56y0D zBvdE6h$5nwP(A&>)o{QY8u@Ae_dHu)XCCB8#iXVxSIZ-E3B9L}5-OHhB98d4g_q+W zb66v5rox`Yy$&ncb<+CY)fO&E`q*LlQ`TC?QXUVdrxrNFE$QtJ>(7j()=ICh(&MYG ztE}2oK}%>0Oa{H(6M?bG1A*Z9M4hK|d~j$YIF6HniT&fA`iba?vWe)4vXSwzslb7u zDJ#w06%!l^jE2YD9;fwA=5+X}tgjr__3Uq~-*bAyo$Fjq>kUtZm6>-Y{A1p`&hYUK K7ai8MLjONXVeobU diff --git a/apps/tags/locale/it/LC_MESSAGES/django.mo b/apps/tags/locale/it/LC_MESSAGES/django.mo index 053f74c2735b0f6487db39e36f237bd057e3a893..32ff33bacb7c70d3c718c253d8060d3e6c6e6324 100644 GIT binary patch delta 1510 zcmYk*OKeP09LMo9eNIP<)~nRxQe`{_HRClw6-_)tJZkIeTy>M_%w*;k>1IeQ5DCdm z7c7XRHnpG{U3kP^L*lWrAR%GJLL!7ne1FqhoZSEYoOAA-bI$#rGb2qe<`myHRP-Cl zI$}2QI%LdFyj0GOa<{@5E;Gb!3Xb4%e2Ovr9<*C3$Jz(5k^VEtBXbqG%=N$loJ4yN zd0sRRs7#>a2`<1=5C zn=yeMn8ZFTuA*|Eiu{N=12fnU4V*wNXah30*@820N6>#1HDNcd##5*T4&qvThzx1I zqB8Rv>#&^FYrOhe_TQp1lMYRoM5Ve7^@E*g;XYi5Ib4kWLHjXkLGN)6{zQFgBeQ6n zBsSo7)Y&?M`k+44mY=O7|I?`S2M=ze_Wm9!<)cUz%^TFA`4F_rc&LddpeAZYeNilE zuR)F5h8pj1(9Q&&L;dbrk%|t_0P2*EUSSw^fNRFq~FEkZ@vQPGLk#A^usg~!Vx zD#1Uvv<2GtsYF@u!gSPD6_pO9lzB_18%lem#pp~dA+$iHpX{1Ap;YUuRCHccl=ktW zl(!H%1FghTB1Y(ol}&Ah%1UE4kJY#yS8tD#@d|!fWi;ZX9nUE}^P`n5;gsu@8pFFQ+e1~Iu5-%r z{PR^et8;nhB(33Sby;XzJhr;kYK})z~ zZMD-WJ7aCkjrXiLR_gJ+@WF7}&UE+M-HtyRzFMy39;^8_yFHgnyIpqPv0N?1vfaN+ zcKyysVp2!i?Qt`IU+^zP5|j64Q||Hqel`3kaxv7<=@xqJwAmN K$M);%Zv6qhk++fn delta 1230 zcmYk*OK1~89LMpANt!mXwWh7rJ~XzmwYG_|4Prw@YsHK8pjCR&Lo7k6HIZ#V2tp7a zrP7NmB2_#HJ$Mv~4=P0w4~o4g>cN8-1@S1>gAdT}FB!pMXFof$$;^NLGyAIbesl3d z*muoPwozNCa~@-cu*b`dvcqRg9rj}n9>5qDZ2OLFzeO(N^&7)wDy=oRigrEfeH7cU z3pL0pSR ztXcFiznS8pofk96W$tnd;sacbPmwXr8?3?i_Wc*+GRxeW@fRwn@)uW?3E0USmC zYR0e;PuczpSnQ?a3J=?H5xLAVH?8;&R-->u9-s~*w3|^A3?OrwLDcW}+xG`CO54Fs zyl&f%Q2~6yR{R|z|5{NK%hx~ysKc=j75O-7@6KQYUbOu;P@{;-HT1JkHOb`#l&(ifnwMMZ(C=)L`D3=1q} zNC&cqsyVu;TD1b)LRBCQ+JBWWHC}ouN2~*>L)BsXg!WkJ{8u*du+=t{HDW6j1zbzj zC#~#lrYcMS7j1Jrb$1sxr7l8M(Y~pWF|&rcP7R6TXs<`)jFWp&xr@Q2D zpa0?C<#G1}Zq0uVcs%Zt%8I@HsouWs1SL3}p3KJ%JL&A?L^_{yQjtTs;~6KP!^yNW zo{J1P<&L;h?uehrWee$vOu_B08u8^b>C^7zs#!N0{N^S@eeT&%-~6M{w8tH-UUFkK GbAJJ%33xLA diff --git a/apps/web_theme/locale/it/LC_MESSAGES/django.mo b/apps/web_theme/locale/it/LC_MESSAGES/django.mo index 989093a22a4ee86fed1b4e7c63de7c1820e4dd0a..12ad99730e83e5b05449adb90162b3bd8ce6046e 100644 GIT binary patch delta 190 zcmZ3=dx3XCOX_7t28KUO3=A6>7#J?FFfb?q=|)xt1|VWs0wlPA^eP}-0Hn7<`D$zo z4E8|2A&?dW(uF`8h!{G61UHcG2hx&2dNz=j0@7PIzVu*H&nPJ=u+rC0&n(F(P0~xw z&($x=FHS7V%rDZyOeiAOX>7#NnaFfb?q=`dCX1|VXn1QJ|8x*kXu0O>9$|2L4f z2lCn27#PHWv>T8HB8FHX!40HSfV3o#E&$R}K)P$=OAn^W5zIHlN>USZ^)pNKHMx8e Y^U_Nb(^IV!GD{}gvP5rQ%A(B#0FU+>MgRZ+ From 7bc61e0cff769715c485cf8579de2fa77e8f587c Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Wed, 30 May 2012 18:53:08 -0400 Subject: [PATCH 28/65] Documentation update --- docs/credits/contributors.rst | 4 ++++ docs/intro/installation.rst | 2 +- docs/releases/0.12.1.rst | 29 ++++++++++++++++++++++++----- docs/topics/settings.rst | 10 ++++++++++ 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/docs/credits/contributors.rst b/docs/credits/contributors.rst index 7d015e8d78..a6e2079d59 100644 --- a/docs/credits/contributors.rst +++ b/docs/credits/contributors.rst @@ -31,12 +31,14 @@ Bug reports * IHLeanne (https://github.com/IHLeanne) * valterwill (https://github.com/valterwill) * David Herring (https://github.com/abadger1406) +* Alexandru Kiss (usurel@gmail.com) Patches ------- * Meurig Freeman (https://github.com/meurig) * Сергей Глита [Sergey Glita] (s.v.glita@gmail.com) +* Brian E (brian@realize.org) Suggestions @@ -45,6 +47,7 @@ Suggestions * Сергей Глита [Sergey Glita] (s.v.glita@gmail.com) * Barry Rowlingson (http://geospaced.blogspot.com) * Gour (https://github.com/gour) +* Alexandru Kiss (usurel@gmail.com) Translations @@ -72,6 +75,7 @@ Remote access for debugging * Сергей Глита [Sergey Glita] (s.v.glita@gmail.com) * David Herring (https://github.com/abadger1406) * Michael Terretta (terretta@gmail.com) +* Alexandru Kiss (usurel@gmail.com) Monetary donations diff --git a/docs/intro/installation.rst b/docs/intro/installation.rst index cb0285e2ab..008554b147 100644 --- a/docs/intro/installation.rst +++ b/docs/intro/installation.rst @@ -9,7 +9,7 @@ Local or managed server If using a Debian_ or Ubuntu_ based Linux distribution getting the executable requirements is as easy as:: - $ apt-get install tesseract-ocr unpaper python-virtualenv ghostscript libjpeg-dev libpng-dev -y + $ apt-get install tesseract-ocr unpaper python-virtualenv ghostscript libjpeg-dev libpng-dev poppler-utils -y To initialize a ``virtualenv`` to deploy the project do:: diff --git a/docs/releases/0.12.1.rst b/docs/releases/0.12.1.rst index 2c16fdba8e..f0500bfa4c 100644 --- a/docs/releases/0.12.1.rst +++ b/docs/releases/0.12.1.rst @@ -24,22 +24,38 @@ What's new in Mayan EDMS v0.12.1 Documentation update ~~~~~~~~~~~~~~~~~~~~ +The installation instructions were updated to include the installation of +the libpng-dev and libjpeg-dev libraries. An additional step to help +users test their new installation of *Mayan EDMS* was also added. -New configuration options -~~~~~~~~~~~~~~~~~~~~~~~~~ - Translations -~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~ +The Italian translation has been synchronized with the source files at +Transifex and finished to %100 completion. Usability improvements ~~~~~~~~~~~~~~~~~~~~~~ +The index instance view now feature the same multi document action +buttons (Submit to OCR, delete, download, etc) as the mail and recent +document views. Better office document conversion ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A new method of converting office document has been implemented, this +new method doesn't require the use of the command line utility ``UNOCONV``. +If this new method proves to work better than previous solutions the use +of ``UNOCONV`` may be deprecated in the future. The conversion method +adds just one new configuration option: :setting:`CONVERTER_LIBREOFFICE_PATH` +which defaults to '/usr/bin/libreoffice'. Better PDF text parsing ~~~~~~~~~~~~~~~~~~~~~~~ - +Brian E submitted a patch to use the Poppler package pdftotext utility to +extract text from PDF files. This is now the default method Mayan EDMS +will execute to try to extract text from a PDF and failing that will +fallback to the previous method. This change add a new configuration +option: :setting:`OCR_PDFTOTEXT_PATH` to specify the location of the ``pdftotext`` +executable, it defaults to '/usr/bin/pdftotext' Upgrading from a previous version @@ -62,9 +78,12 @@ The upgrade procedure is now complete. Backward incompatible changes ============================= +* None Bugs fixed ========== +* Issue #25 "Office document conversion error" Stuff removed ============= +* None diff --git a/docs/topics/settings.rst b/docs/topics/settings.rst index f40ae0ee69..36b6b84ea9 100644 --- a/docs/topics/settings.rst +++ b/docs/topics/settings.rst @@ -373,7 +373,17 @@ Default: ``/usr/bin/unpaper`` File path to the ``unpaper`` executable, used to clean up images before doing OCR. + +.. setting:: OCR_PDFTOTEXT_PATH + +**OCR_PDFTOTEXT_PATH** + +Default: ``/usr/bin/pdftotext`` + +File path to ``poppler's`` ``pdftotext`` program used to extract text +from PDF files. + Metadata ======== From 0cf8fe2decee5fa185be02d321a6ce4b7f0be05d Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Wed, 30 May 2012 18:53:28 -0400 Subject: [PATCH 29/65] Update PDFTOTEXT_PATH config option description --- apps/ocr/conf/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/ocr/conf/settings.py b/apps/ocr/conf/settings.py index d9b7dd2fd3..a4e9768ba0 100644 --- a/apps/ocr/conf/settings.py +++ b/apps/ocr/conf/settings.py @@ -15,6 +15,6 @@ register_settings( {'name': u'AUTOMATIC_OCR', 'global_name': u'OCR_AUTOMATIC_OCR', 'default': False, 'description': _(u'Automatically queue newly created documents for OCR.')}, {'name': u'QUEUE_PROCESSING_INTERVAL', 'global_name': u'OCR_QUEUE_PROCESSING_INTERVAL', 'default': 10}, {'name': u'UNPAPER_PATH', 'global_name': u'OCR_UNPAPER_PATH', 'default': u'/usr/bin/unpaper', 'description': _(u'File path to unpaper program.'), 'exists': True}, - {'name': u'PDFTOTEXT_PATH', 'global_name': u'OCR_PDFTOTEXT_PATH', 'default': u'/usr/bin/pdftotext', 'description': _(u'File path to poppler\'s pdftotext program.'), 'exists': True}, + {'name': u'PDFTOTEXT_PATH', 'global_name': u'OCR_PDFTOTEXT_PATH', 'default': u'/usr/bin/pdftotext', 'description': _(u'File path to poppler\'s pdftotext program used to extract text from PDF files.'), 'exists': True}, ] ) From 166a952f8ee1793cad157d3a78f0abc10374ad61 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Wed, 30 May 2012 18:54:07 -0400 Subject: [PATCH 30/65] Release note update --- docs/releases/0.12.1.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/releases/0.12.1.rst b/docs/releases/0.12.1.rst index f0500bfa4c..0dac6687a7 100644 --- a/docs/releases/0.12.1.rst +++ b/docs/releases/0.12.1.rst @@ -25,8 +25,9 @@ What's new in Mayan EDMS v0.12.1 Documentation update ~~~~~~~~~~~~~~~~~~~~ The installation instructions were updated to include the installation of -the libpng-dev and libjpeg-dev libraries. An additional step to help -users test their new installation of *Mayan EDMS* was also added. +the libpng-dev and libjpeg-dev libraries as well as the installation of +the poppler-utils package. An additional step to help users test their +new installation of *Mayan EDMS* was also added. Translations ~~~~~~~~~~~~ From 86d23f2656ece6e0c597fb54af3bbfe63bfd707a Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Wed, 30 May 2012 19:26:50 -0400 Subject: [PATCH 31/65] The OCR and parsing queue is now active as soon as it is created --- apps/ocr/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/ocr/models.py b/apps/ocr/models.py index 3717f0ffe9..cc504136ac 100644 --- a/apps/ocr/models.py +++ b/apps/ocr/models.py @@ -27,7 +27,7 @@ class DocumentQueue(models.Model): label = models.CharField(max_length=64, verbose_name=_(u'label')) state = models.CharField(max_length=4, choices=DOCUMENTQUEUE_STATE_CHOICES, - default=DOCUMENTQUEUE_STATE_STOPPED, + default=DOCUMENTQUEUE_STATE_ACTIVE, verbose_name=_(u'state')) objects = DocumentQueueManager() From f2f99bf0ad57a5f98f70c11324aeb2ee326657d2 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Wed, 30 May 2012 19:27:23 -0400 Subject: [PATCH 32/65] Change default value of OCR_AUTOMATIC_OCR to True --- apps/ocr/conf/settings.py | 2 +- docs/topics/settings.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/ocr/conf/settings.py b/apps/ocr/conf/settings.py index a4e9768ba0..b7cce9421e 100644 --- a/apps/ocr/conf/settings.py +++ b/apps/ocr/conf/settings.py @@ -12,7 +12,7 @@ register_settings( {'name': u'TESSERACT_LANGUAGE', 'global_name': u'OCR_TESSERACT_LANGUAGE', 'default': u'eng'}, {'name': u'REPLICATION_DELAY', 'global_name': u'OCR_REPLICATION_DELAY', 'default': 0, 'description': _(u'Amount of seconds to delay OCR of documents to allow for the node\'s storage replication overhead.')}, {'name': u'NODE_CONCURRENT_EXECUTION', 'global_name': u'OCR_NODE_CONCURRENT_EXECUTION', 'default': 1, 'description': _(u'Maximum amount of concurrent document OCRs a node can perform.')}, - {'name': u'AUTOMATIC_OCR', 'global_name': u'OCR_AUTOMATIC_OCR', 'default': False, 'description': _(u'Automatically queue newly created documents for OCR.')}, + {'name': u'AUTOMATIC_OCR', 'global_name': u'OCR_AUTOMATIC_OCR', 'default': True, 'description': _(u'Automatically queue newly created documents for OCR.')}, {'name': u'QUEUE_PROCESSING_INTERVAL', 'global_name': u'OCR_QUEUE_PROCESSING_INTERVAL', 'default': 10}, {'name': u'UNPAPER_PATH', 'global_name': u'OCR_UNPAPER_PATH', 'default': u'/usr/bin/unpaper', 'description': _(u'File path to unpaper program.'), 'exists': True}, {'name': u'PDFTOTEXT_PATH', 'global_name': u'OCR_PDFTOTEXT_PATH', 'default': u'/usr/bin/pdftotext', 'description': _(u'File path to poppler\'s pdftotext program used to extract text from PDF files.'), 'exists': True}, diff --git a/docs/topics/settings.rst b/docs/topics/settings.rst index 36b6b84ea9..ed9f888596 100644 --- a/docs/topics/settings.rst +++ b/docs/topics/settings.rst @@ -352,7 +352,7 @@ Maximum amount of concurrent document OCRs a node can perform. **OCR_AUTOMATIC_OCR** -Default: ``False`` +Default: ``True`` Automatically queue newly created documents or newly uploaded versions of existing documents for OCR. From eed1f6aa7b8ec89e34fcba438efbdc097dcaa753 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Wed, 30 May 2012 19:35:17 -0400 Subject: [PATCH 33/65] Add missing import --- apps/ocr/models.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/ocr/models.py b/apps/ocr/models.py index cc504136ac..895ad38999 100644 --- a/apps/ocr/models.py +++ b/apps/ocr/models.py @@ -17,7 +17,8 @@ from sources.managers import SourceTransformationManager from .literals import (DOCUMENTQUEUE_STATE_STOPPED, DOCUMENTQUEUE_STATE_CHOICES, QUEUEDOCUMENT_STATE_PENDING, - QUEUEDOCUMENT_STATE_CHOICES, QUEUEDOCUMENT_STATE_PROCESSING) + QUEUEDOCUMENT_STATE_CHOICES, QUEUEDOCUMENT_STATE_PROCESSING, + DOCUMENTQUEUE_STATE_ACTIVE) from .managers import DocumentQueueManager from .exceptions import ReQueueError From c6dc854b94ad8838544dba7c713f78846aa1d2ba Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Thu, 31 May 2012 01:41:25 -0400 Subject: [PATCH 34/65] Set the HOME environment to allow libreoffice to run when launched from apache --- apps/converter/office_converter.py | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/converter/office_converter.py b/apps/converter/office_converter.py index 40e8ad1dc3..bdf9e36419 100644 --- a/apps/converter/office_converter.py +++ b/apps/converter/office_converter.py @@ -147,6 +147,7 @@ class OfficeConverterBackendDirect(object): 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) From c7ea5271e43d890c27a039b66febefb9fa6a3d2c Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Thu, 31 May 2012 01:42:01 -0400 Subject: [PATCH 35/65] Add logging to converter.api --- apps/converter/api.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/converter/api.py b/apps/converter/api.py index fb6bfaa8ec..c09ce336aa 100644 --- a/apps/converter/api.py +++ b/apps/converter/api.py @@ -3,6 +3,7 @@ from __future__ import absolute_import import os import subprocess import hashlib +import logging from django.utils.encoding import smart_str @@ -20,6 +21,8 @@ from .exceptions import OfficeConversionError, UnknownFileFormat HASH_FUNCTION = lambda x: hashlib.sha256(x).hexdigest() +logger = logging.getLogger(__name__) + def cache_cleanup(input_filepath, *args, **kwargs): try: @@ -100,9 +103,11 @@ def convert(input_filepath, output_filepath=None, cleanup_files=False, mimetype= 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 From ddfe650390dd6ee3635855906a97c6f2351f3f9d Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Thu, 31 May 2012 08:46:09 -0400 Subject: [PATCH 36/65] Release notes remark about OCR default change --- docs/releases/0.12.1.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/releases/0.12.1.rst b/docs/releases/0.12.1.rst index 0dac6687a7..ac1a2194cf 100644 --- a/docs/releases/0.12.1.rst +++ b/docs/releases/0.12.1.rst @@ -58,6 +58,11 @@ fallback to the previous method. This change add a new configuration option: :setting:`OCR_PDFTOTEXT_PATH` to specify the location of the ``pdftotext`` executable, it defaults to '/usr/bin/pdftotext' +Changed defaults +~~~~~~~~~~~~~~~~ +OCR_AUTOMATIC_OCR = True +OCR queue started by default + Upgrading from a previous version ================================= From ac500e48a4a4ed938140a0274a7651f230ab564a Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Thu, 31 May 2012 20:38:25 -0400 Subject: [PATCH 37/65] Initial commit of the fabric file for automatic installation --- fabfile.py | 32 +++++++++++++++++++++ fabfiles/__init__.py | 0 fabfiles/conf.py | 14 +++++++++ fabfiles/databases/__init__.py | 0 fabfiles/databases/mysql.py | 20 +++++++++++++ fabfiles/literals.py | 15 ++++++++++ fabfiles/platforms/__init__.py | 0 fabfiles/platforms/ubuntu.py | 50 +++++++++++++++++++++++++++++++++ fabfiles/templates.py | 20 +++++++++++++ fabfiles/templates/apache_site | 20 +++++++++++++ fabfiles/webservers/__init__.py | 0 fabfiles/webservers/apache.py | 45 +++++++++++++++++++++++++++++ 12 files changed, 216 insertions(+) create mode 100644 fabfile.py create mode 100644 fabfiles/__init__.py create mode 100644 fabfiles/conf.py create mode 100644 fabfiles/databases/__init__.py create mode 100644 fabfiles/databases/mysql.py create mode 100644 fabfiles/literals.py create mode 100644 fabfiles/platforms/__init__.py create mode 100644 fabfiles/platforms/ubuntu.py create mode 100644 fabfiles/templates.py create mode 100644 fabfiles/templates/apache_site create mode 100644 fabfiles/webservers/__init__.py create mode 100644 fabfiles/webservers/apache.py diff --git a/fabfile.py b/fabfile.py new file mode 100644 index 0000000000..66afdccc18 --- /dev/null +++ b/fabfile.py @@ -0,0 +1,32 @@ +import os + +from fabric.api import run, sudo, cd, env, task + +from fabfiles.databases import mysql +from fabfiles.webservers import apache +from fabfiles.platforms import ubuntu +from fabfiles.conf import setup_paths + + +@task(default=True) +def install(**kwargs): + setup_paths(**kwargs) + + ubuntu.install_dependencies() + ubuntu.install_mayan() + mysql.install_database_manager() + mysql.create_database() + ubuntu.fix_permissions() + apache.install() + apache.install_site() + apache.restart() + + +@task +def uninstall(**kwargs): + setup_paths(**kwargs) + + ubuntu.uninstall() + apache.remove_site() + + diff --git a/fabfiles/__init__.py b/fabfiles/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/fabfiles/conf.py b/fabfiles/conf.py new file mode 100644 index 0000000000..0aaeec2885 --- /dev/null +++ b/fabfiles/conf.py @@ -0,0 +1,14 @@ +import os + +from fabric.api import run, sudo, cd, env, task + +from literals import DEFAULT_INSTALL_PATH, DEFAULT_VIRTUALENV_NAME, DEFAULT_REPOSITORY_NAME, DEFAULT_OS + + +def setup_paths(**kwargs): + env['os'] = kwargs.pop('os', DEFAULT_OS) + env['install_path'] = kwargs.pop('path', DEFAULT_INSTALL_PATH[env.os]) + env['virtualenv_name'] = kwargs.pop('virtualenv_name', DEFAULT_VIRTUALENV_NAME[env.os]) + env['repository_name'] = kwargs.pop('repository_name', DEFAULT_REPOSITORY_NAME[env.os]) + env['virtualenv_path'] = os.path.join(env.install_path, env.virtualenv_name) + env['repository_path'] = os.path.join(env.virtualenv_path, env.repository_name) diff --git a/fabfiles/databases/__init__.py b/fabfiles/databases/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/fabfiles/databases/mysql.py b/fabfiles/databases/mysql.py new file mode 100644 index 0000000000..7e25b4a226 --- /dev/null +++ b/fabfiles/databases/mysql.py @@ -0,0 +1,20 @@ +from fabric.api import run, sudo, cd, env, task + + +@task +def install_database_manager(): + print('Installing MySQL') + + sudo('apt-get install -y mysql-server libmysqlclient-dev') + + with cd(env.virtualenv_path): + sudo('source bin/activate; pip install MySQL-python') + + +@task +def create_database(*args, **kwargs): + print('Setting up Mayan EDMS\'s MySQL database') + + #TODO: create DB and mayan user + #TODO: custom settings_local + diff --git a/fabfiles/literals.py b/fabfiles/literals.py new file mode 100644 index 0000000000..f04ef0f492 --- /dev/null +++ b/fabfiles/literals.py @@ -0,0 +1,15 @@ +OS_UBUNTU = 'ubuntu' + +DEFAULT_INSTALL_PATH = { + OS_UBUNTU: '/usr/share' +} + +DEFAULT_VIRTUALENV_NAME = { + OS_UBUNTU: 'mayan' +} + +DEFAULT_REPOSITORY_NAME = { + OS_UBUNTU: 'mayan' +} + +DEFAULT_OS = OS_UBUNTU diff --git a/fabfiles/platforms/__init__.py b/fabfiles/platforms/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/fabfiles/platforms/ubuntu.py b/fabfiles/platforms/ubuntu.py new file mode 100644 index 0000000000..429cd872ff --- /dev/null +++ b/fabfiles/platforms/ubuntu.py @@ -0,0 +1,50 @@ +from fabric.api import run, sudo, cd, env, task + +from ..conf import setup_paths + +@task +def install_dependencies(): + print('Installing dependencies') + + sudo('apt-get install -y git-core gcc tesseract-ocr unpaper python-virtualenv ghostscript libjpeg-dev libpng-dev poppler-utils') + + +@task +def uninstall(**kwargs): + drop_database=kwargs.pop('drop_database', False) + setup_paths(**kwargs) + print('Uninstalling Mayan EDMS from: %s' % env.virtualenv_path) + + sudo('rm %s -Rf' % env.virtualenv_path) + + if drop_database: + #TODO: drop database + pass + +@task +def fix_permissions(**kwargs): + setup_paths(**kwargs) + + sudo('chmod 777 %s -R' % env.virtualenv_path) + sudo('chgrp www-data %s -R' % env.virtualenv_path) + + +@task +def install_mayan(): + print('Installing Mayan EDMS from git repository') + + with cd(env.install_path): + sudo('virtualenv --no-site-packages %s' % env.virtualenv_name) + + with cd(env.virtualenv_path): + sudo('git clone http://www.github.com/rosarior/mayan %s' % env.repository_name) + sudo('source bin/activate; pip install -r %s/requirements/production.txt' % env.repository_name) + + +@task +def syncdb(**kwargs): + setup_paths(**kwargs) + + with cd(env.virtualenv_path): + sudo('source bin/activate; %(repository_name)s/manage.py syncdb --noinput; %(repository_name)s/manage.py migrate' % (env)) + diff --git a/fabfiles/templates.py b/fabfiles/templates.py new file mode 100644 index 0000000000..510cf10279 --- /dev/null +++ b/fabfiles/templates.py @@ -0,0 +1,20 @@ +import os + +TEMPLATE_DIR = 'fabfiles/templates' + + +class Template(object): + def open(self, filename): + self.descriptor = open(os.path.join(TEMPLATE_DIR, filename), 'r') + + def load(self, filename, context=None): + self.open() + self.content = self.descriptor.read() % (context if context else {}) + + def save_as(self, filename): + output_descriptor = open(filename, 'w') + output_descriptor.write(self.content) + output_descriptor.close() + + def close(self): + self.descriptor.close() diff --git a/fabfiles/templates/apache_site b/fabfiles/templates/apache_site new file mode 100644 index 0000000000..a89641cfcd --- /dev/null +++ b/fabfiles/templates/apache_site @@ -0,0 +1,20 @@ + + # Uncomment if libapache2-mod-xsendfile is installed + # XSendFile On + # XSendFileAllowAbove On + + WSGIScriptAlias / %(repository_path)/wsgi/dispatch.wsgi + + + Order deny,allow + Allow from all + + ErrorLog /var/log/apache2/mayan_error.log + LogLevel warn + CustomLog /var/log/apache2/mayan_access.log combined + + Alias /mayan-static "%(repository_path)/static/" + + SetHandler None + + diff --git a/fabfiles/webservers/__init__.py b/fabfiles/webservers/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/fabfiles/webservers/apache.py b/fabfiles/webservers/apache.py new file mode 100644 index 0000000000..bbdb5bc996 --- /dev/null +++ b/fabfiles/webservers/apache.py @@ -0,0 +1,45 @@ +import os + +from fabric.api import run, sudo, cd, env, task + +from ..templates import Template +from ..conf import setup_paths + + +@task +def install(): + print('Installing apache and mod-wsgi') + + sudo('apt-get install -y apache2 libapache2-mod-wsgi') + # Get rid of Apache's default site + sudo('a2dissite default') + reload_webserver() + + +@task +def install_site(**kwargs): + print('Adding Mayan EDMS\'s virtualhost file to apache') + + setup_paths(**kwargs) + #TODO: mod site with paths + sudo('cp %s /etc/apache2/sites-available/' % os.path.join(env.repository_path, 'contrib/apache/mayan')) + sudo('a2ensite mayan') + + +@task +def remove_site(): + sudo('a2dissite mayan') + + +@task +def restart(): + print('Restarting the web server') + + sudo('/etc/init.d/apache2 restart') + + +@task +def reload(): + print('Reloading the web server') + + sudo('/etc/init.d/apache2 reload') From 9f0d7966bce300ac0ab9588f92dc60fca8b32ea5 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Fri, 1 Jun 2012 01:55:09 -0400 Subject: [PATCH 38/65] Update fabfile to user global environment configuration, abstracted tasks for platform, webserver and database manager --- fabfile.py | 32 ---------- fabfile/__init__.py | 35 +++++++++++ fabfile/conf.py | 31 ++++++++++ fabfile/databases/__init__.py | 25 ++++++++ fabfile/databases/mysql.py | 18 ++++++ fabfile/literals.py | 50 +++++++++++++++ fabfile/platforms/__init__.py | 64 +++++++++++++++++++ fabfile/platforms/ubuntu.py | 68 +++++++++++++++++++++ {fabfiles => fabfile}/templates/apache_site | 0 fabfile/webservers/__init__.py | 49 +++++++++++++++ fabfile/webservers/apache.py | 34 +++++++++++ fabfiles/__init__.py | 0 fabfiles/conf.py | 14 ----- fabfiles/databases/__init__.py | 0 fabfiles/databases/mysql.py | 20 ------ fabfiles/literals.py | 15 ----- fabfiles/platforms/__init__.py | 0 fabfiles/platforms/ubuntu.py | 50 --------------- fabfiles/templates.py | 20 ------ fabfiles/webservers/__init__.py | 0 fabfiles/webservers/apache.py | 45 -------------- 21 files changed, 374 insertions(+), 196 deletions(-) delete mode 100644 fabfile.py create mode 100644 fabfile/__init__.py create mode 100644 fabfile/conf.py create mode 100644 fabfile/databases/__init__.py create mode 100644 fabfile/databases/mysql.py create mode 100644 fabfile/literals.py create mode 100644 fabfile/platforms/__init__.py create mode 100644 fabfile/platforms/ubuntu.py rename {fabfiles => fabfile}/templates/apache_site (100%) create mode 100644 fabfile/webservers/__init__.py create mode 100644 fabfile/webservers/apache.py delete mode 100644 fabfiles/__init__.py delete mode 100644 fabfiles/conf.py delete mode 100644 fabfiles/databases/__init__.py delete mode 100644 fabfiles/databases/mysql.py delete mode 100644 fabfiles/literals.py delete mode 100644 fabfiles/platforms/__init__.py delete mode 100644 fabfiles/platforms/ubuntu.py delete mode 100644 fabfiles/templates.py delete mode 100644 fabfiles/webservers/__init__.py delete mode 100644 fabfiles/webservers/apache.py diff --git a/fabfile.py b/fabfile.py deleted file mode 100644 index 66afdccc18..0000000000 --- a/fabfile.py +++ /dev/null @@ -1,32 +0,0 @@ -import os - -from fabric.api import run, sudo, cd, env, task - -from fabfiles.databases import mysql -from fabfiles.webservers import apache -from fabfiles.platforms import ubuntu -from fabfiles.conf import setup_paths - - -@task(default=True) -def install(**kwargs): - setup_paths(**kwargs) - - ubuntu.install_dependencies() - ubuntu.install_mayan() - mysql.install_database_manager() - mysql.create_database() - ubuntu.fix_permissions() - apache.install() - apache.install_site() - apache.restart() - - -@task -def uninstall(**kwargs): - setup_paths(**kwargs) - - ubuntu.uninstall() - apache.remove_site() - - diff --git a/fabfile/__init__.py b/fabfile/__init__.py new file mode 100644 index 0000000000..b15d7515a6 --- /dev/null +++ b/fabfile/__init__.py @@ -0,0 +1,35 @@ +import sys +import os + +from fabric.api import run, sudo, cd, env, task +from fabric.main import load_settings + +import databases +import webservers +import platforms +from conf import setup_environment + +setup_environment() + + +@task(default=True) +def install(): + platforms.install_dependencies() + platforms.install_mayan() + platform.install_database_manager() + databases.create_database() + platforms.fix_permissions() + platforms.install_webserver() + webservers.install_site() + webservers.restart() + + +@task +def uninstall(): + platforms.uninstall() + webservers.remove_site() + + if env.drop_database: + databases.drop() + + diff --git a/fabfile/conf.py b/fabfile/conf.py new file mode 100644 index 0000000000..d257cb1f52 --- /dev/null +++ b/fabfile/conf.py @@ -0,0 +1,31 @@ +import os + +from fabric.api import env + +from literals import (DEFAULT_INSTALL_PATH, DEFAULT_VIRTUALENV_NAME, + DEFAULT_REPOSITORY_NAME, DEFAULT_OS, OS_CHOICES, + DEFAULT_DATABASE_MANAGER, DB_CHOICES, DEFAULT_DATABASE_NAME, + DEFAULT_WEBSERVER, WEB_CHOICES) + + +def setup_environment(): + env['os'] = getattr(env, 'os', DEFAULT_OS) + env['os_name'] = OS_CHOICES[env.os] + + env['install_path'] = getattr(env, 'install_path', DEFAULT_INSTALL_PATH[env.os]) + env['virtualenv_name'] = getattr(env, 'virtualenv_name', DEFAULT_VIRTUALENV_NAME[env.os]) + env['repository_name'] = getattr(env, 'repository_name', DEFAULT_REPOSITORY_NAME[env.os]) + env['virtualenv_path'] = os.path.join(env.install_path, env.virtualenv_name) + env['repository_path'] = os.path.join(env.virtualenv_path, env.repository_name) + + env['database_manager'] = getattr(env, 'database_manager', DEFAULT_DATABASE_MANAGER) + env['database_manager_name'] = DB_CHOICES[env.database_manager] + + if not getattr(env, 'database_manager_admin_password', None): + print('Must set the database_manager_admin_password entry in the fabric settings file (~/.fabricrc by default)') + exit(1) + + env['database_name'] = getattr(env, 'database_name', DEFAULT_DATABASE_NAME) + + env['webserver'] = getattr(env, 'webserver', DEFAULT_WEBSERVER) + env['webserver_name'] = WEB_CHOICES[env.webserver] diff --git a/fabfile/databases/__init__.py b/fabfile/databases/__init__.py new file mode 100644 index 0000000000..17eeff711d --- /dev/null +++ b/fabfile/databases/__init__.py @@ -0,0 +1,25 @@ +from fabric.api import run, sudo, cd, env, task + +from ..literals import DB_MYSQL +import mysql + + +@task +def create_database(): + """ + Create the Mayan EDMS database + """ + + if env.database_manager == DB_MYSQL: + mysql.create_database() + + +@task +def drop_database(): + """ + Drop Mayan EDMS's database + """ + + if env.database_manager == DB_MYSQL: + mysql.drop_database() + diff --git a/fabfile/databases/mysql.py b/fabfile/databases/mysql.py new file mode 100644 index 0000000000..3f321d77f1 --- /dev/null +++ b/fabfile/databases/mysql.py @@ -0,0 +1,18 @@ +from fabric.api import run, sudo, cd, env, task + + +def create_database(): + """ + Create the MySQL Mayan EDMS database + """ + run('echo "create database %(database_name)s;" | mysql -u root --password=%(database_manager_admin_password)s' % env) + #TODO: create DB and mayan user + #TODO: custom settings_local + + +def drop_database(): + """ + Drop MySQL's Mayan EDMS's database + """ + run('echo "drop database %(database_name)s;" | mysql -u root --password=%(database_manager_admin_password)s' % env) + diff --git a/fabfile/literals.py b/fabfile/literals.py new file mode 100644 index 0000000000..ed8060a0db --- /dev/null +++ b/fabfile/literals.py @@ -0,0 +1,50 @@ +OS_UBUNTU = 'ubuntu' +OS_REDHAT = 'redhat' +OS_CENTOS = 'centos' +OS_FEDORA = 'fedora' +OS_WINDOWS = 'windows' +OS_FREEBSD = 'freebds', + +OS_CHOICES = { + OS_UBUNTU: 'Ubuntu', + OS_REDHAT: 'RedHat', + OS_CENTOS: 'CentOS', + OS_FEDORA: 'Fedora', + OS_WINDOWS: 'MS Windows', + OS_FREEBSD: 'FreeBSD', +} + +DEFAULT_INSTALL_PATH = { + OS_UBUNTU: '/usr/share' +} + +DEFAULT_VIRTUALENV_NAME = { + OS_UBUNTU: 'mayan' +} + +DEFAULT_REPOSITORY_NAME = { + OS_UBUNTU: 'mayan' +} + +DB_MYSQL = 'mysql' +DB_PGSQL = 'pgsql' +DB_SQLITE = 'sqlite' + +DB_CHOICES = { + DB_MYSQL: 'MySQL', + DB_PGSQL: 'PostgreSQL', + DB_SQLITE: 'SQLite' +} + +WEB_APACHE = 'apache' +WEB_NGINX = 'nginx' + +WEB_CHOICES = { + WEB_APACHE: 'Apache', + WEB_NGINX: 'Nginx', +} + +DEFAULT_OS = OS_UBUNTU +DEFAULT_DATABASE_MANAGER = DB_MYSQL +DEFAULT_DATABASE_NAME = 'mayan' +DEFAULT_WEBSERVER = WEB_APACHE diff --git a/fabfile/platforms/__init__.py b/fabfile/platforms/__init__.py new file mode 100644 index 0000000000..f974fffc14 --- /dev/null +++ b/fabfile/platforms/__init__.py @@ -0,0 +1,64 @@ +from fabric.api import run, sudo, cd, env, task + +from ..literals import OS_UBUNTU +import ubuntu + + +@task +def install_dependencies(): + """ + Install OS dependencies + """ + + print('Installing dependencies for %s' % env.os_name) + + if env.os == OS_UBUNTU: + ubuntu.install_dependencies() + + +@task +def install_mayan(): + """ + Install Mayan EDMS + """ + + print('Installing Mayan EDMS from git repository') + + if env.os == OS_UBUNTU: + ubuntu.install_mayan() + + +@task +def install_database_manager(): + """ + Install the selected database manager + """ + + print('Installing database manager: %s' % env.database_manager_name) + + if env.os == OS_UBUNTU: + ubuntu.install_database_manager() + + +@task +def fix_permissions(): + """ + Fix installation files' permissions + """ + + print('Fixing installation files\' permissions') + + if env.os == OS_UBUNTU: + ubuntu.fix_permissions() + + +@task +def install_webserver(): + """ + Installing the OS packages for the webserver + """ + + print('Installing webserver: %s' % env.webserver_name) + + if env.os == OS_UBUNTU: + ubuntu.install_webserver() diff --git a/fabfile/platforms/ubuntu.py b/fabfile/platforms/ubuntu.py new file mode 100644 index 0000000000..bf3bc2db6d --- /dev/null +++ b/fabfile/platforms/ubuntu.py @@ -0,0 +1,68 @@ +from fabric.api import run, sudo, cd, env, task + +from ..literals import DB_MYSQL, WEB_APACHE + + +def install_dependencies(): + """ + Install Ubuntu dependencies + """ + sudo('apt-get install -y git-core gcc tesseract-ocr unpaper python-virtualenv ghostscript libjpeg-dev libpng-dev poppler-utils') + + +def uninstall(): + """ + Uninstall Mayan EDMS from an Ubuntu system + """ + sudo('rm %s -Rf' % env.virtualenv_path) + + +def fix_permissions(): + """ + Fix installation files' permissions on an Ubuntu system + """ + sudo('chmod 777 %s -R' % env.virtualenv_path) + sudo('chgrp www-data %s -R' % env.virtualenv_path) + + +def install_mayan(): + """ + Install Mayan EDMS on an Ubuntu system + """ + with cd(env.install_path): + sudo('virtualenv --no-site-packages %s' % env.virtualenv_name) + + with cd(env.virtualenv_path): + sudo('git clone http://www.github.com/rosarior/mayan %s' % env.repository_name) + sudo('source bin/activate; pip install -r %s/requirements/production.txt' % env.repository_name) + + +def syncdb(): + with cd(env.virtualenv_path): + sudo('source bin/activate; %(repository_name)s/manage.py syncdb --noinput; %(repository_name)s/manage.py migrate' % (env)) + + +def install_database_manager(): + """ + Install the database manager on an Ubuntu system + """ + + if env.database_manager == DB_MYSQL: + sudo('apt-get install -y mysql-server libmysqlclient-dev') + + with cd(env.virtualenv_path): + sudo('source bin/activate; pip install MySQL-python') + + +@task +def install_webserver(): + """ + Installing the Ubuntu packages for the webserver + """ + + if env.webserver == WEB_APACHE: + sudo('apt-get install -y apache2 libapache2-mod-wsgi') + + with settings(warn_only=True): + # Get rid of Apache's default site + sudo('a2dissite default') diff --git a/fabfiles/templates/apache_site b/fabfile/templates/apache_site similarity index 100% rename from fabfiles/templates/apache_site rename to fabfile/templates/apache_site diff --git a/fabfile/webservers/__init__.py b/fabfile/webservers/__init__.py new file mode 100644 index 0000000000..1f6d60e495 --- /dev/null +++ b/fabfile/webservers/__init__.py @@ -0,0 +1,49 @@ +from fabric.api import run, sudo, cd, env, task + +from ..literals import WEB_APACHE +import apache + + +@task +def install_site(): + """ + Install Mayan EDMS site in the webserver configuration files + """ + + print('Adding Mayan EDMS\'s site files to: %s' % os.webserver_name) + + if os.webserver == WEB_APACHE: + apache.install_site() + + +@task +def remove_site(): + """ + Install Mayan EDMS's site file from the webserver's configuration + """ + print('Removing Mayan EDMS\s site file from %s configuration' % os.webserver_name) + + if os.webserver == WEB_APACHE: + apache.remove_site() + + +@task +def restart(): + """ + Restart the webserver + """ + print('Restarting the web server: %s' % os.webserver_name) + + if os.webserver == WEB_APACHE: + apache.restart() + + +@task +def reload(): + """ + Reload webserver configuration files + """ + print('Reloading the web server configuration files') + + if os.webserver == WEB_APACHE: + apache.reload() diff --git a/fabfile/webservers/apache.py b/fabfile/webservers/apache.py new file mode 100644 index 0000000000..03f0e3acff --- /dev/null +++ b/fabfile/webservers/apache.py @@ -0,0 +1,34 @@ +import os + +from fabric.api import run, sudo, cd, env, task + + +def install_site(): + """ + Install Mayan EDMS's site file in Apache configuration + """ + + #TODO: mod site with paths + sudo('cp %s /etc/apache2/sites-available/' % os.path.join(env.repository_path, 'contrib/apache/mayan')) + sudo('a2ensite mayan') + + +def remove_site(): + """ + Install Mayan EDMS's site file from Apache's configuration + """ + sudo('a2dissite mayan') + + +def restart(): + """ + Restart Apache + """ + sudo('/etc/init.d/apache2 restart') + + +def reload(): + """ + Reload Apache configuration files + """ + sudo('/etc/init.d/apache2 reload') diff --git a/fabfiles/__init__.py b/fabfiles/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/fabfiles/conf.py b/fabfiles/conf.py deleted file mode 100644 index 0aaeec2885..0000000000 --- a/fabfiles/conf.py +++ /dev/null @@ -1,14 +0,0 @@ -import os - -from fabric.api import run, sudo, cd, env, task - -from literals import DEFAULT_INSTALL_PATH, DEFAULT_VIRTUALENV_NAME, DEFAULT_REPOSITORY_NAME, DEFAULT_OS - - -def setup_paths(**kwargs): - env['os'] = kwargs.pop('os', DEFAULT_OS) - env['install_path'] = kwargs.pop('path', DEFAULT_INSTALL_PATH[env.os]) - env['virtualenv_name'] = kwargs.pop('virtualenv_name', DEFAULT_VIRTUALENV_NAME[env.os]) - env['repository_name'] = kwargs.pop('repository_name', DEFAULT_REPOSITORY_NAME[env.os]) - env['virtualenv_path'] = os.path.join(env.install_path, env.virtualenv_name) - env['repository_path'] = os.path.join(env.virtualenv_path, env.repository_name) diff --git a/fabfiles/databases/__init__.py b/fabfiles/databases/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/fabfiles/databases/mysql.py b/fabfiles/databases/mysql.py deleted file mode 100644 index 7e25b4a226..0000000000 --- a/fabfiles/databases/mysql.py +++ /dev/null @@ -1,20 +0,0 @@ -from fabric.api import run, sudo, cd, env, task - - -@task -def install_database_manager(): - print('Installing MySQL') - - sudo('apt-get install -y mysql-server libmysqlclient-dev') - - with cd(env.virtualenv_path): - sudo('source bin/activate; pip install MySQL-python') - - -@task -def create_database(*args, **kwargs): - print('Setting up Mayan EDMS\'s MySQL database') - - #TODO: create DB and mayan user - #TODO: custom settings_local - diff --git a/fabfiles/literals.py b/fabfiles/literals.py deleted file mode 100644 index f04ef0f492..0000000000 --- a/fabfiles/literals.py +++ /dev/null @@ -1,15 +0,0 @@ -OS_UBUNTU = 'ubuntu' - -DEFAULT_INSTALL_PATH = { - OS_UBUNTU: '/usr/share' -} - -DEFAULT_VIRTUALENV_NAME = { - OS_UBUNTU: 'mayan' -} - -DEFAULT_REPOSITORY_NAME = { - OS_UBUNTU: 'mayan' -} - -DEFAULT_OS = OS_UBUNTU diff --git a/fabfiles/platforms/__init__.py b/fabfiles/platforms/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/fabfiles/platforms/ubuntu.py b/fabfiles/platforms/ubuntu.py deleted file mode 100644 index 429cd872ff..0000000000 --- a/fabfiles/platforms/ubuntu.py +++ /dev/null @@ -1,50 +0,0 @@ -from fabric.api import run, sudo, cd, env, task - -from ..conf import setup_paths - -@task -def install_dependencies(): - print('Installing dependencies') - - sudo('apt-get install -y git-core gcc tesseract-ocr unpaper python-virtualenv ghostscript libjpeg-dev libpng-dev poppler-utils') - - -@task -def uninstall(**kwargs): - drop_database=kwargs.pop('drop_database', False) - setup_paths(**kwargs) - print('Uninstalling Mayan EDMS from: %s' % env.virtualenv_path) - - sudo('rm %s -Rf' % env.virtualenv_path) - - if drop_database: - #TODO: drop database - pass - -@task -def fix_permissions(**kwargs): - setup_paths(**kwargs) - - sudo('chmod 777 %s -R' % env.virtualenv_path) - sudo('chgrp www-data %s -R' % env.virtualenv_path) - - -@task -def install_mayan(): - print('Installing Mayan EDMS from git repository') - - with cd(env.install_path): - sudo('virtualenv --no-site-packages %s' % env.virtualenv_name) - - with cd(env.virtualenv_path): - sudo('git clone http://www.github.com/rosarior/mayan %s' % env.repository_name) - sudo('source bin/activate; pip install -r %s/requirements/production.txt' % env.repository_name) - - -@task -def syncdb(**kwargs): - setup_paths(**kwargs) - - with cd(env.virtualenv_path): - sudo('source bin/activate; %(repository_name)s/manage.py syncdb --noinput; %(repository_name)s/manage.py migrate' % (env)) - diff --git a/fabfiles/templates.py b/fabfiles/templates.py deleted file mode 100644 index 510cf10279..0000000000 --- a/fabfiles/templates.py +++ /dev/null @@ -1,20 +0,0 @@ -import os - -TEMPLATE_DIR = 'fabfiles/templates' - - -class Template(object): - def open(self, filename): - self.descriptor = open(os.path.join(TEMPLATE_DIR, filename), 'r') - - def load(self, filename, context=None): - self.open() - self.content = self.descriptor.read() % (context if context else {}) - - def save_as(self, filename): - output_descriptor = open(filename, 'w') - output_descriptor.write(self.content) - output_descriptor.close() - - def close(self): - self.descriptor.close() diff --git a/fabfiles/webservers/__init__.py b/fabfiles/webservers/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/fabfiles/webservers/apache.py b/fabfiles/webservers/apache.py deleted file mode 100644 index bbdb5bc996..0000000000 --- a/fabfiles/webservers/apache.py +++ /dev/null @@ -1,45 +0,0 @@ -import os - -from fabric.api import run, sudo, cd, env, task - -from ..templates import Template -from ..conf import setup_paths - - -@task -def install(): - print('Installing apache and mod-wsgi') - - sudo('apt-get install -y apache2 libapache2-mod-wsgi') - # Get rid of Apache's default site - sudo('a2dissite default') - reload_webserver() - - -@task -def install_site(**kwargs): - print('Adding Mayan EDMS\'s virtualhost file to apache') - - setup_paths(**kwargs) - #TODO: mod site with paths - sudo('cp %s /etc/apache2/sites-available/' % os.path.join(env.repository_path, 'contrib/apache/mayan')) - sudo('a2ensite mayan') - - -@task -def remove_site(): - sudo('a2dissite mayan') - - -@task -def restart(): - print('Restarting the web server') - - sudo('/etc/init.d/apache2 restart') - - -@task -def reload(): - print('Reloading the web server') - - sudo('/etc/init.d/apache2 reload') From 66e3e4d7b501db6d185a980c0d740acfee8ea69b Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Fri, 1 Jun 2012 02:42:21 -0400 Subject: [PATCH 39/65] Add Django tasks, update setting_local and apache site template render, fix os vs. env error --- fabfile/__init__.py | 35 +++++++++++++++++----------------- fabfile/conf.py | 12 +++++++++++- fabfile/databases/__init__.py | 2 +- fabfile/databases/mysql.py | 6 +++--- fabfile/django/__init__.py | 14 ++++++++++++++ fabfile/literals.py | 13 ++++++++++++- fabfile/platforms/ubuntu.py | 5 ----- fabfile/webservers/__init__.py | 14 +++++++------- fabfile/webservers/apache.py | 6 +++--- 9 files changed, 68 insertions(+), 39 deletions(-) create mode 100644 fabfile/django/__init__.py diff --git a/fabfile/__init__.py b/fabfile/__init__.py index b15d7515a6..671e93868d 100644 --- a/fabfile/__init__.py +++ b/fabfile/__init__.py @@ -1,12 +1,9 @@ -import sys -import os +from fabric.api import task -from fabric.api import run, sudo, cd, env, task -from fabric.main import load_settings - -import databases -import webservers -import platforms +import databases as database +import webservers as webserver +import platforms as platform +import django from conf import setup_environment setup_environment() @@ -14,22 +11,24 @@ setup_environment() @task(default=True) def install(): - platforms.install_dependencies() - platforms.install_mayan() + platform.install_dependencies() + platform.install_mayan() platform.install_database_manager() - databases.create_database() - platforms.fix_permissions() - platforms.install_webserver() - webservers.install_site() - webservers.restart() + database.create_database() + django.database_config() + django.syncdb() + platform.fix_permissions() + platform.install_webserver() + webserver.install_site() + webserver.restart() @task def uninstall(): - platforms.uninstall() - webservers.remove_site() + platform.uninstall() + webserver.remove_site() if env.drop_database: - databases.drop() + database.drop() diff --git a/fabfile/conf.py b/fabfile/conf.py index d257cb1f52..add8176fe8 100644 --- a/fabfile/conf.py +++ b/fabfile/conf.py @@ -5,7 +5,12 @@ from fabric.api import env from literals import (DEFAULT_INSTALL_PATH, DEFAULT_VIRTUALENV_NAME, DEFAULT_REPOSITORY_NAME, DEFAULT_OS, OS_CHOICES, DEFAULT_DATABASE_MANAGER, DB_CHOICES, DEFAULT_DATABASE_NAME, - DEFAULT_WEBSERVER, WEB_CHOICES) + DEFAULT_WEBSERVER, WEB_CHOICES, DEFAULT_DATABASE_USERNAME, + DJANGO_DB_DRIVERS, DEFAULT_DATABASE_HOST) + + +def password_generator(): + return 'password' def setup_environment(): @@ -20,6 +25,9 @@ def setup_environment(): env['database_manager'] = getattr(env, 'database_manager', DEFAULT_DATABASE_MANAGER) env['database_manager_name'] = DB_CHOICES[env.database_manager] + env['database_username'] = getattr(env, 'database_username', DEFAULT_DATABASE_USERNAME) + env['database_password'] = getattr(env, 'database_password', password_generator()) + env['database_host'] = getattr(env, 'database_host', DEFAULT_DATABASE_HOST) if not getattr(env, 'database_manager_admin_password', None): print('Must set the database_manager_admin_password entry in the fabric settings file (~/.fabricrc by default)') @@ -29,3 +37,5 @@ def setup_environment(): env['webserver'] = getattr(env, 'webserver', DEFAULT_WEBSERVER) env['webserver_name'] = WEB_CHOICES[env.webserver] + + env['django_database_driver'] = DJANGO_DB_DRIVERS[env.database_manager] diff --git a/fabfile/databases/__init__.py b/fabfile/databases/__init__.py index 17eeff711d..8af29c0ea8 100644 --- a/fabfile/databases/__init__.py +++ b/fabfile/databases/__init__.py @@ -1,4 +1,4 @@ -from fabric.api import run, sudo, cd, env, task +from fabric.api import env, task from ..literals import DB_MYSQL import mysql diff --git a/fabfile/databases/mysql.py b/fabfile/databases/mysql.py index 3f321d77f1..3338666da5 100644 --- a/fabfile/databases/mysql.py +++ b/fabfile/databases/mysql.py @@ -5,9 +5,9 @@ def create_database(): """ Create the MySQL Mayan EDMS database """ - run('echo "create database %(database_name)s;" | mysql -u root --password=%(database_manager_admin_password)s' % env) - #TODO: create DB and mayan user - #TODO: custom settings_local + run('echo "CREATE DATABASE %(database_name)s;" | mysql -u root --password=%(database_manager_admin_password)s' % env) + run('echo "CREATE USER \'%(database_username)s\'@\'localhost\' IDENTIFIED BY \'%(database_password)s\';" | mysql -u root --password=%(database_manager_admin_password)s' % env) + run('echo "GRANT ALL PRIVILEGES ON %(database_name)s.* TO \'%(database_username)s\'@\'localhost\' WITH GRANT OPTION; | mysql -u root --password=%(database_manager_admin_password)s' % env) def drop_database(): diff --git a/fabfile/django/__init__.py b/fabfile/django/__init__.py new file mode 100644 index 0000000000..4cda853034 --- /dev/null +++ b/fabfile/django/__init__.py @@ -0,0 +1,14 @@ +import os + +from fabric.api import env, task, cd, sudo +from fabric.contrib.files import upload_template + + +@task +def syncdb(): + with cd(env.virtualenv_path): + sudo('source bin/activate; %(repository_name)s/manage.py syncdb --noinput; %(repository_name)s/manage.py migrate' % (env)) + +@task +def database_config(): + upload_template(filename=os.path.join('fabfile', 'templates', 'settings_local.py'), destination=env.repository_path, context=env, use_sudo=True) diff --git a/fabfile/literals.py b/fabfile/literals.py index ed8060a0db..cc33060091 100644 --- a/fabfile/literals.py +++ b/fabfile/literals.py @@ -29,11 +29,20 @@ DEFAULT_REPOSITORY_NAME = { DB_MYSQL = 'mysql' DB_PGSQL = 'pgsql' DB_SQLITE = 'sqlite' +DB_ORACLE = 'oracle' DB_CHOICES = { DB_MYSQL: 'MySQL', DB_PGSQL: 'PostgreSQL', - DB_SQLITE: 'SQLite' + DB_SQLITE: 'SQLite', + DB_ORACLE: 'ORACLE' +} + +DJANGO_DB_DRIVERS = { + DB_MYSQL: 'mysql', + DB_PGSQL: 'postgresql_psycopg2', + DB_SQLITE: 'sqlite3', + DB_ORACLE: 'oracle', } WEB_APACHE = 'apache' @@ -48,3 +57,5 @@ DEFAULT_OS = OS_UBUNTU DEFAULT_DATABASE_MANAGER = DB_MYSQL DEFAULT_DATABASE_NAME = 'mayan' DEFAULT_WEBSERVER = WEB_APACHE +DEFAULT_DATABASE_USERNAME = 'mayan' +DEFAULT_DATABASE_HOST = '127.0.0.1' diff --git a/fabfile/platforms/ubuntu.py b/fabfile/platforms/ubuntu.py index bf3bc2db6d..a86601fbed 100644 --- a/fabfile/platforms/ubuntu.py +++ b/fabfile/platforms/ubuntu.py @@ -37,11 +37,6 @@ def install_mayan(): sudo('source bin/activate; pip install -r %s/requirements/production.txt' % env.repository_name) -def syncdb(): - with cd(env.virtualenv_path): - sudo('source bin/activate; %(repository_name)s/manage.py syncdb --noinput; %(repository_name)s/manage.py migrate' % (env)) - - def install_database_manager(): """ Install the database manager on an Ubuntu system diff --git a/fabfile/webservers/__init__.py b/fabfile/webservers/__init__.py index 1f6d60e495..41a8fc8580 100644 --- a/fabfile/webservers/__init__.py +++ b/fabfile/webservers/__init__.py @@ -10,9 +10,9 @@ def install_site(): Install Mayan EDMS site in the webserver configuration files """ - print('Adding Mayan EDMS\'s site files to: %s' % os.webserver_name) + print('Adding Mayan EDMS\'s site files to: %s' % env.webserver_name) - if os.webserver == WEB_APACHE: + if env.webserver == WEB_APACHE: apache.install_site() @@ -21,9 +21,9 @@ def remove_site(): """ Install Mayan EDMS's site file from the webserver's configuration """ - print('Removing Mayan EDMS\s site file from %s configuration' % os.webserver_name) + print('Removing Mayan EDMS\s site file from %s configuration' % env.webserver_name) - if os.webserver == WEB_APACHE: + if env.webserver == WEB_APACHE: apache.remove_site() @@ -32,9 +32,9 @@ def restart(): """ Restart the webserver """ - print('Restarting the web server: %s' % os.webserver_name) + print('Restarting the web server: %s' % env.webserver_name) - if os.webserver == WEB_APACHE: + if env.webserver == WEB_APACHE: apache.restart() @@ -45,5 +45,5 @@ def reload(): """ print('Reloading the web server configuration files') - if os.webserver == WEB_APACHE: + if env.webserver == WEB_APACHE: apache.reload() diff --git a/fabfile/webservers/apache.py b/fabfile/webservers/apache.py index 03f0e3acff..d760a8b94c 100644 --- a/fabfile/webservers/apache.py +++ b/fabfile/webservers/apache.py @@ -1,15 +1,15 @@ import os from fabric.api import run, sudo, cd, env, task +from fabric.contrib.files import upload_template def install_site(): """ Install Mayan EDMS's site file in Apache configuration """ - - #TODO: mod site with paths - sudo('cp %s /etc/apache2/sites-available/' % os.path.join(env.repository_path, 'contrib/apache/mayan')) + # TODO: configurable site name + upload_template(filename=os.path.join('fabfile', 'templates', 'apache_site'), destination='/etc/apache2/sites-available/mayan', context=env, use_sudo=True) sudo('a2ensite mayan') From 60a7cee93b3c4d7b520ea59518a1ac3494964ad4 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Fri, 1 Jun 2012 03:20:26 -0400 Subject: [PATCH 40/65] Add colorization and logo --- fabfile/__init__.py | 18 ++++++++++++++++++ fabfile/databases/__init__.py | 4 ++++ fabfile/platforms/__init__.py | 12 ++++++------ fabfile/webservers/__init__.py | 9 +++++---- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/fabfile/__init__.py b/fabfile/__init__.py index 671e93868d..b0e11f2eb0 100644 --- a/fabfile/__init__.py +++ b/fabfile/__init__.py @@ -1,4 +1,5 @@ from fabric.api import task +from fabric.colors import white import databases as database import webservers as webserver @@ -9,6 +10,22 @@ from conf import setup_environment setup_environment() +print(white('\n\n ######## ', bold=True)) +print(white(' ######## ', bold=True)) +print(white(' ### ### ', bold=True)) +print(white(' ##### ##### ', bold=True)) +print(white(' ############## ', bold=True)) +print(white(' ####### ####### ', bold=True)) +print(white(' ################## ', bold=True)) +print(white(' ######### ######### ', bold=True)) +print(white(' ###################### ', bold=True)) +print(white(' ########### ########### ', bold=True)) +print(white(' ########################## ', bold=True)) +print(white('############# #############', bold=True)) + +print(white('\nMayan EDMS Fabric installation file\n\n', bold=True)) + + @task(default=True) def install(): platform.install_dependencies() @@ -17,6 +34,7 @@ def install(): database.create_database() django.database_config() django.syncdb() + django.collectstatic() platform.fix_permissions() platform.install_webserver() webserver.install_site() diff --git a/fabfile/databases/__init__.py b/fabfile/databases/__init__.py index 8af29c0ea8..32975466b1 100644 --- a/fabfile/databases/__init__.py +++ b/fabfile/databases/__init__.py @@ -1,4 +1,6 @@ from fabric.api import env, task +from fabric.colors import green + from ..literals import DB_MYSQL import mysql @@ -9,6 +11,7 @@ def create_database(): """ Create the Mayan EDMS database """ + print(green('Creating Mayan EDMS database', bold=True)) if env.database_manager == DB_MYSQL: mysql.create_database() @@ -19,6 +22,7 @@ def drop_database(): """ Drop Mayan EDMS's database """ + print(green('Droping Mayan EDMS database', bold=True)) if env.database_manager == DB_MYSQL: mysql.drop_database() diff --git a/fabfile/platforms/__init__.py b/fabfile/platforms/__init__.py index f974fffc14..3d9dfc41c6 100644 --- a/fabfile/platforms/__init__.py +++ b/fabfile/platforms/__init__.py @@ -1,4 +1,5 @@ from fabric.api import run, sudo, cd, env, task +from fabric.colors import green from ..literals import OS_UBUNTU import ubuntu @@ -9,8 +10,7 @@ def install_dependencies(): """ Install OS dependencies """ - - print('Installing dependencies for %s' % env.os_name) + print(green('Installing dependencies for %s' % env.os_name, bold=True)) if env.os == OS_UBUNTU: ubuntu.install_dependencies() @@ -22,7 +22,7 @@ def install_mayan(): Install Mayan EDMS """ - print('Installing Mayan EDMS from git repository') + print(green('Installing Mayan EDMS from git repository', bold=True)) if env.os == OS_UBUNTU: ubuntu.install_mayan() @@ -34,7 +34,7 @@ def install_database_manager(): Install the selected database manager """ - print('Installing database manager: %s' % env.database_manager_name) + print(green('Installing database manager: %s' % env.database_manager_name, bold=True)) if env.os == OS_UBUNTU: ubuntu.install_database_manager() @@ -46,7 +46,7 @@ def fix_permissions(): Fix installation files' permissions """ - print('Fixing installation files\' permissions') + print(green('Fixing installation files\' permissions', bold=True)) if env.os == OS_UBUNTU: ubuntu.fix_permissions() @@ -58,7 +58,7 @@ def install_webserver(): Installing the OS packages for the webserver """ - print('Installing webserver: %s' % env.webserver_name) + print(green('Installing webserver: %s' % env.webserver_name, bold=True)) if env.os == OS_UBUNTU: ubuntu.install_webserver() diff --git a/fabfile/webservers/__init__.py b/fabfile/webservers/__init__.py index 41a8fc8580..b4c46991c1 100644 --- a/fabfile/webservers/__init__.py +++ b/fabfile/webservers/__init__.py @@ -1,4 +1,5 @@ from fabric.api import run, sudo, cd, env, task +from fabric.colors import green from ..literals import WEB_APACHE import apache @@ -10,7 +11,7 @@ def install_site(): Install Mayan EDMS site in the webserver configuration files """ - print('Adding Mayan EDMS\'s site files to: %s' % env.webserver_name) + print(green('Adding Mayan EDMS\'s site files to: %s' % env.webserver_name, bold=True)) if env.webserver == WEB_APACHE: apache.install_site() @@ -21,7 +22,7 @@ def remove_site(): """ Install Mayan EDMS's site file from the webserver's configuration """ - print('Removing Mayan EDMS\s site file from %s configuration' % env.webserver_name) + print(green('Removing Mayan EDMS\s site file from %s configuration' % env.webserver_name, bold=True)) if env.webserver == WEB_APACHE: apache.remove_site() @@ -32,7 +33,7 @@ def restart(): """ Restart the webserver """ - print('Restarting the web server: %s' % env.webserver_name) + print(green('Restarting the web server: %s' % env.webserver_name, bold=True)) if env.webserver == WEB_APACHE: apache.restart() @@ -43,7 +44,7 @@ def reload(): """ Reload webserver configuration files """ - print('Reloading the web server configuration files') + print(green('Reloading the web server configuration files', bold=True)) if env.webserver == WEB_APACHE: apache.reload() From b2522d815896df1a449014a2886f8b719e2a2f71 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Fri, 1 Jun 2012 03:21:10 -0400 Subject: [PATCH 41/65] Add random password generator --- fabfile/conf.py | 10 +++++++--- fabfile/literals.py | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/fabfile/conf.py b/fabfile/conf.py index add8176fe8..c9d28b4770 100644 --- a/fabfile/conf.py +++ b/fabfile/conf.py @@ -1,4 +1,6 @@ import os +import string +import random from fabric.api import env @@ -6,13 +8,15 @@ from literals import (DEFAULT_INSTALL_PATH, DEFAULT_VIRTUALENV_NAME, DEFAULT_REPOSITORY_NAME, DEFAULT_OS, OS_CHOICES, DEFAULT_DATABASE_MANAGER, DB_CHOICES, DEFAULT_DATABASE_NAME, DEFAULT_WEBSERVER, WEB_CHOICES, DEFAULT_DATABASE_USERNAME, - DJANGO_DB_DRIVERS, DEFAULT_DATABASE_HOST) + DJANGO_DB_DRIVERS, DEFAULT_DATABASE_HOST, DEFAULT_PASSWORD_LENGTH) def password_generator(): - return 'password' - + # http://snipplr.com/view/63223/python-password-generator/ + chars = string.ascii_letters + string.digits + return ''.join(random.choice(chars) for x in range(DEFAULT_PASSWORD_LENGTH)) + def setup_environment(): env['os'] = getattr(env, 'os', DEFAULT_OS) env['os_name'] = OS_CHOICES[env.os] diff --git a/fabfile/literals.py b/fabfile/literals.py index cc33060091..aad7b3dfae 100644 --- a/fabfile/literals.py +++ b/fabfile/literals.py @@ -59,3 +59,4 @@ DEFAULT_DATABASE_NAME = 'mayan' DEFAULT_WEBSERVER = WEB_APACHE DEFAULT_DATABASE_USERNAME = 'mayan' DEFAULT_DATABASE_HOST = '127.0.0.1' +DEFAULT_PASSWORD_LENGTH = 10 From 2b1af0c4c40b31b12ce8dd7b96db2bfb1b297ac9 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Fri, 1 Jun 2012 03:21:34 -0400 Subject: [PATCH 42/65] Add database_host to database creation task --- fabfile/databases/mysql.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fabfile/databases/mysql.py b/fabfile/databases/mysql.py index 3338666da5..0a3b11b76b 100644 --- a/fabfile/databases/mysql.py +++ b/fabfile/databases/mysql.py @@ -6,8 +6,8 @@ def create_database(): Create the MySQL Mayan EDMS database """ run('echo "CREATE DATABASE %(database_name)s;" | mysql -u root --password=%(database_manager_admin_password)s' % env) - run('echo "CREATE USER \'%(database_username)s\'@\'localhost\' IDENTIFIED BY \'%(database_password)s\';" | mysql -u root --password=%(database_manager_admin_password)s' % env) - run('echo "GRANT ALL PRIVILEGES ON %(database_name)s.* TO \'%(database_username)s\'@\'localhost\' WITH GRANT OPTION; | mysql -u root --password=%(database_manager_admin_password)s' % env) + run('echo "CREATE USER \'%(database_username)s\'@\'%(database_host)s\' IDENTIFIED BY \'%(database_password)s\';" | mysql -u root --password=%(database_manager_admin_password)s' % env) + run('echo "GRANT ALL PRIVILEGES ON %(database_name)s.* TO \'%(database_username)s\'@\'%(database_host)s\' WITH GRANT OPTION;" | mysql -u root --password=%(database_manager_admin_password)s' % env) def drop_database(): From 81492db807a94e13a4580e87427163e3bd21cfae Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Fri, 1 Jun 2012 03:21:56 -0400 Subject: [PATCH 43/65] Add django.collectstatic task --- fabfile/django/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fabfile/django/__init__.py b/fabfile/django/__init__.py index 4cda853034..294d17075f 100644 --- a/fabfile/django/__init__.py +++ b/fabfile/django/__init__.py @@ -12,3 +12,9 @@ def syncdb(): @task def database_config(): upload_template(filename=os.path.join('fabfile', 'templates', 'settings_local.py'), destination=env.repository_path, context=env, use_sudo=True) + + +@task +def collectstatic(): + with cd(env.virtualenv_path): + sudo('source bin/activate; %(repository_name)s/manage.py collectstatic --noinput' % (env)) From cd4d8b6f3353a6529d59c9b45a309bae9aa77e3d Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Fri, 1 Jun 2012 03:22:14 -0400 Subject: [PATCH 44/65] Add missing import --- fabfile/platforms/ubuntu.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabfile/platforms/ubuntu.py b/fabfile/platforms/ubuntu.py index a86601fbed..25613a62ce 100644 --- a/fabfile/platforms/ubuntu.py +++ b/fabfile/platforms/ubuntu.py @@ -1,4 +1,4 @@ -from fabric.api import run, sudo, cd, env, task +from fabric.api import run, sudo, cd, env, task, settings from ..literals import DB_MYSQL, WEB_APACHE From f8226e662e8712296999d2ac19ca264ad69c99f9 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Fri, 1 Jun 2012 03:22:28 -0400 Subject: [PATCH 45/65] Small fix to apache site template --- fabfile/templates/apache_site | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fabfile/templates/apache_site b/fabfile/templates/apache_site index a89641cfcd..68b7916810 100644 --- a/fabfile/templates/apache_site +++ b/fabfile/templates/apache_site @@ -3,9 +3,9 @@ # XSendFile On # XSendFileAllowAbove On - WSGIScriptAlias / %(repository_path)/wsgi/dispatch.wsgi + WSGIScriptAlias / %(repository_path)s/wsgi/dispatch.wsgi - + Order deny,allow Allow from all @@ -13,7 +13,7 @@ LogLevel warn CustomLog /var/log/apache2/mayan_access.log combined - Alias /mayan-static "%(repository_path)/static/" + Alias /mayan-static "%(repository_path)s/static/" SetHandler None From 2e0b2f65357b35e787a672183008ee161633c103 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Fri, 1 Jun 2012 03:39:06 -0400 Subject: [PATCH 46/65] Finish uninstall task --- fabfile/__init__.py | 7 ++++--- fabfile/conf.py | 1 + fabfile/databases/mysql.py | 5 +++-- fabfile/platforms/__init__.py | 12 ++++++++++++ fabfile/platforms/ubuntu.py | 4 ++-- fabfile/webservers/__init__.py | 2 +- 6 files changed, 23 insertions(+), 8 deletions(-) diff --git a/fabfile/__init__.py b/fabfile/__init__.py index b0e11f2eb0..c770c891b0 100644 --- a/fabfile/__init__.py +++ b/fabfile/__init__.py @@ -1,4 +1,4 @@ -from fabric.api import task +from fabric.api import task, env from fabric.colors import white import databases as database @@ -43,10 +43,11 @@ def install(): @task def uninstall(): - platform.uninstall() + platform.delete_mayan() webserver.remove_site() + webserver.restart() if env.drop_database: - database.drop() + database.drop_database() diff --git a/fabfile/conf.py b/fabfile/conf.py index c9d28b4770..b0ec550ac7 100644 --- a/fabfile/conf.py +++ b/fabfile/conf.py @@ -32,6 +32,7 @@ def setup_environment(): env['database_username'] = getattr(env, 'database_username', DEFAULT_DATABASE_USERNAME) env['database_password'] = getattr(env, 'database_password', password_generator()) env['database_host'] = getattr(env, 'database_host', DEFAULT_DATABASE_HOST) + env['drop_database'] = getattr(env, 'drop_database', False) if not getattr(env, 'database_manager_admin_password', None): print('Must set the database_manager_admin_password entry in the fabric settings file (~/.fabricrc by default)') diff --git a/fabfile/databases/mysql.py b/fabfile/databases/mysql.py index 0a3b11b76b..eeed8f3412 100644 --- a/fabfile/databases/mysql.py +++ b/fabfile/databases/mysql.py @@ -1,4 +1,4 @@ -from fabric.api import run, sudo, cd, env, task +from fabric.api import run, env, task, settings def create_database(): @@ -14,5 +14,6 @@ def drop_database(): """ Drop MySQL's Mayan EDMS's database """ - run('echo "drop database %(database_name)s;" | mysql -u root --password=%(database_manager_admin_password)s' % env) + with settings(warn_only=True): + run('echo "drop database %(database_name)s;" | mysql -u root --password=%(database_manager_admin_password)s' % env) diff --git a/fabfile/platforms/__init__.py b/fabfile/platforms/__init__.py index 3d9dfc41c6..99a428ba55 100644 --- a/fabfile/platforms/__init__.py +++ b/fabfile/platforms/__init__.py @@ -62,3 +62,15 @@ def install_webserver(): if env.os == OS_UBUNTU: ubuntu.install_webserver() + + +@task +def delete_mayan(): + """ + Delete Mayan EDMS from the OS + """ + + print(green('Deleting Mayan EDMS files', bold=True)) + + if env.os == OS_UBUNTU: + ubuntu.delete_mayan() diff --git a/fabfile/platforms/ubuntu.py b/fabfile/platforms/ubuntu.py index 25613a62ce..8b28e719d0 100644 --- a/fabfile/platforms/ubuntu.py +++ b/fabfile/platforms/ubuntu.py @@ -10,9 +10,9 @@ def install_dependencies(): sudo('apt-get install -y git-core gcc tesseract-ocr unpaper python-virtualenv ghostscript libjpeg-dev libpng-dev poppler-utils') -def uninstall(): +def delete_mayan(): """ - Uninstall Mayan EDMS from an Ubuntu system + Delete Mayan EDMS files from an Ubuntu system """ sudo('rm %s -Rf' % env.virtualenv_path) diff --git a/fabfile/webservers/__init__.py b/fabfile/webservers/__init__.py index b4c46991c1..ceaeeebf1e 100644 --- a/fabfile/webservers/__init__.py +++ b/fabfile/webservers/__init__.py @@ -22,7 +22,7 @@ def remove_site(): """ Install Mayan EDMS's site file from the webserver's configuration """ - print(green('Removing Mayan EDMS\s site file from %s configuration' % env.webserver_name, bold=True)) + print(green('Removing Mayan EDMS\'s site file from %s configuration' % env.webserver_name, bold=True)) if env.webserver == WEB_APACHE: apache.remove_site() From bfc588fa3e863a74a47ef20616e0d046d7f4a0b5 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Fri, 1 Jun 2012 03:54:49 -0400 Subject: [PATCH 47/65] Add compressed fabfile script, and latest fabfile --- contrib/fabfile.tar.gz | Bin 0 -> 3898 bytes misc/make_fabfile_tar.sh | 3 +++ 2 files changed, 3 insertions(+) create mode 100644 contrib/fabfile.tar.gz create mode 100755 misc/make_fabfile_tar.sh diff --git a/contrib/fabfile.tar.gz b/contrib/fabfile.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..61c08cd5623547dcf5eb7b601a84da1f030cbd97 GIT binary patch literal 3898 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 Date: Fri, 1 Jun 2012 04:17:40 -0400 Subject: [PATCH 48/65] Add database.drop_username task --- fabfile/__init__.py | 1 + fabfile/databases/__init__.py | 10 ++++++++++ fabfile/databases/mysql.py | 10 +++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/fabfile/__init__.py b/fabfile/__init__.py index c770c891b0..1b3365fa7d 100644 --- a/fabfile/__init__.py +++ b/fabfile/__init__.py @@ -49,5 +49,6 @@ def uninstall(): if env.drop_database: database.drop_database() + database.drop_username() diff --git a/fabfile/databases/__init__.py b/fabfile/databases/__init__.py index 32975466b1..ad48ada637 100644 --- a/fabfile/databases/__init__.py +++ b/fabfile/databases/__init__.py @@ -27,3 +27,13 @@ def drop_database(): if env.database_manager == DB_MYSQL: mysql.drop_database() + +@task +def drop_username(): + """ + Drop Mayan EDMS's username + """ + print(green('Droping Mayan EDMS username', bold=True)) + + if env.database_manager == DB_MYSQL: + mysql.drop_username() diff --git a/fabfile/databases/mysql.py b/fabfile/databases/mysql.py index eeed8f3412..43d947bcb4 100644 --- a/fabfile/databases/mysql.py +++ b/fabfile/databases/mysql.py @@ -15,5 +15,13 @@ def drop_database(): Drop MySQL's Mayan EDMS's database """ with settings(warn_only=True): - run('echo "drop database %(database_name)s;" | mysql -u root --password=%(database_manager_admin_password)s' % env) + run('echo "DROP DATABASE %(database_name)s;" | mysql -u root --password=%(database_manager_admin_password)s' % env) + + +def drop_username(): + """ + Drop MySQL's Mayan EDMS's username + """ + with settings(warn_only=True): + run('echo "DROP USER \'%(database_username)s\'@\'%(database_host)s\';" | mysql -u root --password=%(database_manager_admin_password)s' % env) From 0d76a4b6c622ebae07002c183951a36f9ac8d164 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Fri, 1 Jun 2012 04:18:05 -0400 Subject: [PATCH 49/65] Update compressed fabfile --- contrib/fabfile.tar.gz | Bin 3898 -> 3947 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/contrib/fabfile.tar.gz b/contrib/fabfile.tar.gz index 61c08cd5623547dcf5eb7b601a84da1f030cbd97..98c9a70f7aeec4650d67908a49df6896cf2735f0 100644 GIT binary patch literal 3947 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 F008Po<|_aI literal 3898 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 Date: Fri, 1 Jun 2012 05:02:47 -0400 Subject: [PATCH 50/65] Remove extra decorator --- fabfile/platforms/ubuntu.py | 1 - 1 file changed, 1 deletion(-) diff --git a/fabfile/platforms/ubuntu.py b/fabfile/platforms/ubuntu.py index 8b28e719d0..f9b0c0d5bf 100644 --- a/fabfile/platforms/ubuntu.py +++ b/fabfile/platforms/ubuntu.py @@ -49,7 +49,6 @@ def install_database_manager(): sudo('source bin/activate; pip install MySQL-python') -@task def install_webserver(): """ Installing the Ubuntu packages for the webserver From f9e028e13474ffd410abe07ff03a2cdafedbea14 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Fri, 1 Jun 2012 05:03:09 -0400 Subject: [PATCH 51/65] Update compressed fabfile --- contrib/fabfile.tar.gz | Bin 3947 -> 3953 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/contrib/fabfile.tar.gz b/contrib/fabfile.tar.gz index 98c9a70f7aeec4650d67908a49df6896cf2735f0..0be3548aa84a2a3921f35a9c46b18fbf46340b1d 100644 GIT binary patch delta 3593 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 PAO-#lMM8s^0C)fZlbs9A delta 3587 zcmV+e4*c=)9_twCyBVW3(--!Lo_(IK0*G=E%(QJqat^0nPi z2CoDn{`1}U3(N$b9{)GnolX}2?*roXzx$a$O8j4IwCaBSS39)+JJnh>i~silYvO-! zGetHD*bx8E3C1S)4n|QfFTjBjb>X9XA7`I_nScEAT*UFqN9XrNPIj2Fn1K7TgM$P1 z_n4uPdyA124*63HnUqIQOrgBO_zZKN#1#pcmg*TQ^#+}F0Wwi z)JAN4@T}`>{Leqj!0~)6ODCiw6TVYMsmy`Y&eN`kuVt*7VIA4{YLYQ02acL?V^!mf;;AGJ6p^v|W zxr29{+bqVD-Qx)={W56=6i{RtWk(D{G8+05d< zeZZ#p&sphK5ovnyDa!$CRs*j3A7|Z*?(tb)tOuyJs@>wyEHk|D9`=a?j*~-4N(MYE z&h*vee0`TS&SY1{{=P+MI_ixM1CndtWHS7Tb40N`6;6>y zmQ%J>_qP12Wx!bJ^$i#X6@NiW$3%s95LN)CP((Tm;D*UGIZ`Uv)w~{5uTTo7q~58< zf@)D=2LM0ToLf1Mto z2o&)1-{^0-`~-Q-G<0fF)`f+HEJ^kTx0h7+2?5@w+^8HS^F{%P@qgcM;IF#>-)?oP zbpF@uG+WvHe;*L9e`$2vQ66djzY3H6aQ$~`jcoqE7kK~KAnrGemMMl^@Ha{ zFHOx_(lfL)Mj=6efJvN7ezAc z)#P+A(THKY-G!k#sDFaqnvk`d8izM^CEv8Yl#d<4^qJ4ZlpnH66s7tklfBIni|Rqj+$Sy*%5$us9T!xUeJ zbVdz?=lBjU5M7MtTVl}8tmOs)s-|Jbp%TEsEw2p|44UKGF@Li#suDl(hz^o$#Bmkw z1mB-q8h4Nf9^xRd#00x%s;Mu)97D^*UWo|AU^=$sP7Z6*X6Lf_B#RdY!J3X!(dI>DCKRg`_`;exHGuzkY zYgPLV26m_XE`QGxgHzx-G43!az;r1PG3wk?#cK&xSkiPyWodTole{^-_Ie$xk!PbVj&~q3ZUeWYC-Bq~b zQ78Q5F>SD&z}IvfYeh7SAULk5nrqyF`#aRjIugJ(Oo)d&#J;-Rv{) zK#c#iMSs7<-ERshzyj||JnJE{Xj7Oi)+;|n45F)MO0I_mYaNohl`%~ z$oKju-OKaoY%rWmyXWV#i|+KSh(zk=!FYPvJ?{@c&*-$E$X9X%cHF-hO$O7^_!kc= z5Ti*EjV80>v(ezVKZ$UOsm$zCci27ckBjtbfPYUKqhgXn0Ww$qhde0x0dOj!z}p%DvVvbRfz)=JYKhD)zJ)Nwg9(7FXaDC zB!BD1+;I6;3c>D*m@pOMu8X&VvUY138qPCm1$1K(^gy@d06WL|b!GF;4Y1WZ=KbS$ z^m!Q}>5F1H$~RDSj=^=fB+r~1O_ZBJK_+L;hw%jM;tO?amh&xGB4os3FlK1pA3CoRAtnCB|(j!hbL4SIbqPVUTZPwklNhoBYEV5bH?r%9#pk#H| z3ykE-Wk#ckNYzD86(<-XMv~AAy@8>yUT|RMVC?vkbo1z2f(-ux(+2INOHONtl_dQ{ z*WM)Crzs{5B}roGD##|048LYPljX^0_mkv>@I`b2o&txj-$xt|0q4*G|&I1QsxMvq3cKFEsqtH;9@;~Fx-4C z_)ai%TDw@+CU|=Y1P15%;=%%4G49g}2{Hn$B!BlMbiV7Gly~wXAMY(uAGoH|ymq*g zK?FqnFXFdXc>k$hYq!MuPrFXn34d#?S~Gk9X)gd#)8)s@;q($Zv9h{eneIx-LE^aI zJL^tqBEkBt>axV+{%|^?I|Ygc<0gbYsKAh>FP7-RhmH1iQ$JwP0Tc7LNufZ!?u z;)HAHBRn+$^J#*vJVgUGt}W#QW#Jc~{>bH$BEv+*D=UXo9Eg^&BJ)MUzC>1j;!5U< zgmY|eYF z>#@6PMUl+%f#eH_9_9pxaDO~QK*A52pO4^~0)qeG#fZ97x$A87kgu)Sa!@e}W5rbazs16@bcI12zq;8>`ohQs7gA6jrAcG7t$RL9ZGRPo<3^G^?{{_;l J=@0;T0012cCRP9d From a0193ca78be502703ec2add5c8c0a21ed5717c5a Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Sat, 2 Jun 2012 01:41:23 -0400 Subject: [PATCH 52/65] Add Fedora support to the fabfile (Tested on Fedora 17) --- fabfile/__init__.py | 1 + fabfile/literals.py | 9 +++-- fabfile/platforms/__init__.py | 33 +++++++++++++---- fabfile/platforms/fedora.py | 62 ++++++++++++++++++++++++++++++++ fabfile/platforms/linux.py | 20 +++++++++++ fabfile/platforms/ubuntu.py | 42 ++++++++-------------- fabfile/templates/apache_site | 4 +-- fabfile/templates/selinux.config | 10 ++++++ fabfile/webservers/apache.py | 27 ++++++++++---- 9 files changed, 163 insertions(+), 45 deletions(-) create mode 100644 fabfile/platforms/fedora.py create mode 100644 fabfile/platforms/linux.py create mode 100644 fabfile/templates/selinux.config diff --git a/fabfile/__init__.py b/fabfile/__init__.py index 1b3365fa7d..3bb092a3bd 100644 --- a/fabfile/__init__.py +++ b/fabfile/__init__.py @@ -39,6 +39,7 @@ def install(): platform.install_webserver() webserver.install_site() webserver.restart() + platform.post_install() @task diff --git a/fabfile/literals.py b/fabfile/literals.py index aad7b3dfae..7d93f9fd82 100644 --- a/fabfile/literals.py +++ b/fabfile/literals.py @@ -15,15 +15,18 @@ OS_CHOICES = { } DEFAULT_INSTALL_PATH = { - OS_UBUNTU: '/usr/share' + OS_UBUNTU: '/usr/share', + OS_FEDORA: '/usr/share' } DEFAULT_VIRTUALENV_NAME = { - OS_UBUNTU: 'mayan' + OS_UBUNTU: 'mayan', + OS_FEDORA: 'mayan' } DEFAULT_REPOSITORY_NAME = { - OS_UBUNTU: 'mayan' + OS_UBUNTU: 'mayan', + OS_FEDORA: 'mayan' } DB_MYSQL = 'mysql' diff --git a/fabfile/platforms/__init__.py b/fabfile/platforms/__init__.py index 99a428ba55..af81d0f128 100644 --- a/fabfile/platforms/__init__.py +++ b/fabfile/platforms/__init__.py @@ -1,8 +1,8 @@ from fabric.api import run, sudo, cd, env, task from fabric.colors import green -from ..literals import OS_UBUNTU -import ubuntu +from ..literals import OS_UBUNTU, OS_FEDORA +import linux, ubuntu, fedora @task @@ -14,6 +14,8 @@ def install_dependencies(): if env.os == OS_UBUNTU: ubuntu.install_dependencies() + elif env.os == OS_FEDORA: + fedora.install_dependencies() @task @@ -24,9 +26,9 @@ def install_mayan(): print(green('Installing Mayan EDMS from git repository', bold=True)) - if env.os == OS_UBUNTU: - ubuntu.install_mayan() - + if env.os in [OS_UBUNTU, OS_FEDORA]: + linux.install_mayan() + @task def install_database_manager(): @@ -38,6 +40,8 @@ def install_database_manager(): if env.os == OS_UBUNTU: ubuntu.install_database_manager() + elif env.os == OS_FEDORA: + fedora.install_database_manager() @task @@ -49,7 +53,9 @@ def fix_permissions(): print(green('Fixing installation files\' permissions', bold=True)) if env.os == OS_UBUNTU: - ubuntu.fix_permissions() + ubuntu.fix_permissions() + elif env.os == OS_FEDORA: + fedora.fix_permissions() @task @@ -62,6 +68,8 @@ def install_webserver(): if env.os == OS_UBUNTU: ubuntu.install_webserver() + elif env.os == OS_FEDORA: + fedora.install_webserver() @task @@ -72,5 +80,16 @@ def delete_mayan(): print(green('Deleting Mayan EDMS files', bold=True)) + if env.os in [OS_UBUNTU, OS_FEDORA]: + linux.delete_mayan() + + +@task +def post_install(): + """ + Perform post install operations + """ if env.os == OS_UBUNTU: - ubuntu.delete_mayan() + ubuntu.post_install() + elif env.os == OS_FEDORA: + fedora.post_install() diff --git a/fabfile/platforms/fedora.py b/fabfile/platforms/fedora.py new file mode 100644 index 0000000000..4bc8bdd3fb --- /dev/null +++ b/fabfile/platforms/fedora.py @@ -0,0 +1,62 @@ +import os + +from fabric.api import run, sudo, cd, env, task, settings +from fabric.operations import put, reboot + +from ..literals import DB_MYSQL, WEB_APACHE + + +def install_dependencies(): + """ + Install Fedora dependencies + """ + sudo('yum install -y git gcc tesseract unpaper python-virtualenv ghostscript libjpeg-turbo-devel libpng-devel poppler-utils') + + +def install_database_manager(): + """ + Install the database manager on a Fedora system + """ + + if env.database_manager == DB_MYSQL: + sudo('yum install -y mysql-server mysql-devel') + sudo('systemctl enable mysqld.service') + sudo('systemctl start mysqld.service') + sudo('mysql_secure_installation') + + with cd(env.virtualenv_path): + sudo('source bin/activate; pip install MySQL-python') + + +def install_webserver(): + """ + Installing the Fedora packages for the webserver + """ + + if env.webserver == WEB_APACHE: + sudo('yum install -y httpd mod_wsgi') + sudo('systemctl enable httpd.service') + sudo('systemctl start httpd.service') + + with settings(warn_only=True): + # Get rid of Apache's default site + sudo('rm /etc/httpd/conf.d/welcome.conf') + + # Disable SELinux as it blocks mod_wsgi's file access + # TODO: implement a proper solution is implemented + put(local_path=os.path.join('fabfile', 'templates', 'selinux.config'), remote_path='/etc/selinux/config', use_sudo=True) + + +def fix_permissions(): + """ + Fix installation files' permissions on a Fedora system + """ + sudo('chmod 770 %s -R' % env.virtualenv_path) + sudo('chgrp apache %s -R' % env.virtualenv_path) + + +def post_install(): + """ + Post install operations on a Fedora system + """ + reboot() diff --git a/fabfile/platforms/linux.py b/fabfile/platforms/linux.py new file mode 100644 index 0000000000..572dd34bcb --- /dev/null +++ b/fabfile/platforms/linux.py @@ -0,0 +1,20 @@ +from fabric.api import run, sudo, cd, env, task, settings + + +def delete_mayan(): + """ + Delete Mayan EDMS files from an Ubuntu system + """ + sudo('rm %s -Rf' % env.virtualenv_path) + + +def install_mayan(): + """ + Install Mayan EDMS on an Ubuntu system + """ + with cd(env.install_path): + sudo('virtualenv --no-site-packages %s' % env.virtualenv_name) + + with cd(env.virtualenv_path): + sudo('git clone http://www.github.com/rosarior/mayan %s' % env.repository_name) + sudo('source bin/activate; pip install -r %s/requirements/production.txt' % env.repository_name) diff --git a/fabfile/platforms/ubuntu.py b/fabfile/platforms/ubuntu.py index f9b0c0d5bf..c99f4e1a50 100644 --- a/fabfile/platforms/ubuntu.py +++ b/fabfile/platforms/ubuntu.py @@ -10,33 +10,6 @@ def install_dependencies(): sudo('apt-get install -y git-core gcc tesseract-ocr unpaper python-virtualenv ghostscript libjpeg-dev libpng-dev poppler-utils') -def delete_mayan(): - """ - Delete Mayan EDMS files from an Ubuntu system - """ - sudo('rm %s -Rf' % env.virtualenv_path) - - -def fix_permissions(): - """ - Fix installation files' permissions on an Ubuntu system - """ - sudo('chmod 777 %s -R' % env.virtualenv_path) - sudo('chgrp www-data %s -R' % env.virtualenv_path) - - -def install_mayan(): - """ - Install Mayan EDMS on an Ubuntu system - """ - with cd(env.install_path): - sudo('virtualenv --no-site-packages %s' % env.virtualenv_name) - - with cd(env.virtualenv_path): - sudo('git clone http://www.github.com/rosarior/mayan %s' % env.repository_name) - sudo('source bin/activate; pip install -r %s/requirements/production.txt' % env.repository_name) - - def install_database_manager(): """ Install the database manager on an Ubuntu system @@ -60,3 +33,18 @@ def install_webserver(): with settings(warn_only=True): # Get rid of Apache's default site sudo('a2dissite default') + + +def fix_permissions(): + """ + Fix installation files' permissions on an Ubuntu system + """ + sudo('chmod 770 %s -R' % env.virtualenv_path) + sudo('chgrp www-data %s -R' % env.virtualenv_path) + + +def post_install(): + """ + Post install operations on an Ubuntu system + """ + pass diff --git a/fabfile/templates/apache_site b/fabfile/templates/apache_site index 68b7916810..6df729225e 100644 --- a/fabfile/templates/apache_site +++ b/fabfile/templates/apache_site @@ -9,9 +9,9 @@ Order deny,allow Allow from all - ErrorLog /var/log/apache2/mayan_error.log + #ErrorLog /var/log/apache2/mayan_error.log LogLevel warn - CustomLog /var/log/apache2/mayan_access.log combined + #CustomLog /var/log/apache2/mayan_access.log combined Alias /mayan-static "%(repository_path)s/static/" diff --git a/fabfile/templates/selinux.config b/fabfile/templates/selinux.config new file mode 100644 index 0000000000..2f8cc2e2c4 --- /dev/null +++ b/fabfile/templates/selinux.config @@ -0,0 +1,10 @@ +# This file controls the state of SELinux on the system. +# SELINUX= can take one of these three values: +# enforcing - SELinux security policy is enforced. +# permissive - SELinux prints warnings instead of enforcing. +# disabled - No SELinux policy is loaded. +SELINUX=disabled +# SELINUXTYPE= can take one of these two values: +# targeted - Only targeted network daemons are protected. +# strict - Full SELinux protection. +SELINUXTYPE=targeted diff --git a/fabfile/webservers/apache.py b/fabfile/webservers/apache.py index d760a8b94c..80840acb69 100644 --- a/fabfile/webservers/apache.py +++ b/fabfile/webservers/apache.py @@ -1,34 +1,49 @@ import os -from fabric.api import run, sudo, cd, env, task +from fabric.api import run, sudo, cd, env, task, settings from fabric.contrib.files import upload_template +from ..literals import OS_UBUNTU, OS_FEDORA + def install_site(): """ Install Mayan EDMS's site file in Apache configuration """ # TODO: configurable site name - upload_template(filename=os.path.join('fabfile', 'templates', 'apache_site'), destination='/etc/apache2/sites-available/mayan', context=env, use_sudo=True) - sudo('a2ensite mayan') + if env.os == OS_UBUNTU: + upload_template(filename=os.path.join('fabfile', 'templates', 'apache_site'), destination='/etc/apache2/sites-available/mayan', context=env, use_sudo=True) + sudo('a2ensite mayan') + elif env.os == OS_FEDORA: + upload_template(filename=os.path.join('fabfile', 'templates', 'apache_site'), destination='/etc/httpd/conf.d/mayan.conf', context=env, use_sudo=True) def remove_site(): """ Install Mayan EDMS's site file from Apache's configuration """ - sudo('a2dissite mayan') + if env.os == OS_UBUNTU: + sudo('a2dissite mayan') + elif env.os == OS_FEDORA: + with settings(warn_only=True): + sudo('rm /etc/httpd/conf.d/mayan.conf') def restart(): """ Restart Apache """ - sudo('/etc/init.d/apache2 restart') + if env.os == OS_UBUNTU: + sudo('/etc/init.d/apache2 restart') + elif env.os == OS_FEDORA: + sudo('systemctl restart httpd.service') def reload(): """ Reload Apache configuration files """ - sudo('/etc/init.d/apache2 reload') + if env.os == OS_UBUNTU: + sudo('/etc/init.d/apache2 reload') + elif env.os == OS_FEDORA: + sudo('systemctl reload httpd.service') From 50032767cb0e867251fe7cdbde2625b52faf2106 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Sat, 2 Jun 2012 01:42:20 -0400 Subject: [PATCH 53/65] Update compressed fabfile --- contrib/fabfile.tar.gz | Bin 3953 -> 4722 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/contrib/fabfile.tar.gz b/contrib/fabfile.tar.gz index 0be3548aa84a2a3921f35a9c46b18fbf46340b1d..9817ad2a75f846553d0590fbf4b234e700517bd9 100644 GIT binary patch literal 4722 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 z zdkkt~q@K;7mNIto5un&h7%>am!Hi(xBU3V3yS!gp&!*)VcHybUp8NazDqYCWYVO(4 z{a}u$|KFd^){_QF`Onp$gU0_I#qB?xqvPEF>mcw0^8YDnK8q3LFYRP=7yZv z9CFAZha7UqA%`4t$RURua>yZv9CFAZha7UqA%`4t$RURu{{O=N0UJ6uSpc8_0OP${ ATL1t6 literal 3953 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 LMM8s^0C)fZWbMnL From cf88bf759ed341aa8ef91550e1e093ac491e4770 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Sat, 2 Jun 2012 01:55:01 -0400 Subject: [PATCH 54/65] Display the supported configurations --- contrib/fabfile.tar.gz | Bin 4722 -> 4820 bytes fabfile/__init__.py | 5 +++-- fabfile/conf.py | 7 +++++++ fabfile/literals.py | 18 +++++++++--------- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/contrib/fabfile.tar.gz b/contrib/fabfile.tar.gz index 9817ad2a75f846553d0590fbf4b234e700517bd9..4f573e5cdd69fde97ce929a634fc93e7cac87237 100644 GIT binary patch literal 4820 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 z zdkkt~q@K;7mNIto5un&h7%>am!Hi(xBU3V3yS!gp&!*)VcHybUp8NazDqYCWYVO(4 z{a}u$|KFd^){_QF`Onp$gU0_I#qB?xqvPEF>mcw0^8YDnK8q3LFYRP=7yZv z9CFAZha7UqA%`4t$RURua>yZv9CFAZha7UqA%`4t$RURu{{O=N0UJ6uSpc8_0OP${ ATL1t6 diff --git a/fabfile/__init__.py b/fabfile/__init__.py index 3bb092a3bd..d4f48fe803 100644 --- a/fabfile/__init__.py +++ b/fabfile/__init__.py @@ -5,11 +5,10 @@ import databases as database import webservers as webserver import platforms as platform import django -from conf import setup_environment +from conf import setup_environment, print_supported_configs setup_environment() - print(white('\n\n ######## ', bold=True)) print(white(' ######## ', bold=True)) print(white(' ### ### ', bold=True)) @@ -25,6 +24,8 @@ print(white('############# #############', bold=True)) print(white('\nMayan EDMS Fabric installation file\n\n', bold=True)) +print_supported_configs() + @task(default=True) def install(): diff --git a/fabfile/conf.py b/fabfile/conf.py index b0ec550ac7..9574948f9f 100644 --- a/fabfile/conf.py +++ b/fabfile/conf.py @@ -44,3 +44,10 @@ def setup_environment(): env['webserver_name'] = WEB_CHOICES[env.webserver] env['django_database_driver'] = DJANGO_DB_DRIVERS[env.database_manager] + + +def print_supported_configs(): + print('Supported operating systems (os=): %s' % dict(OS_CHOICES).keys()) + print('Supported database managers (database_manager=): %s' % dict(DB_CHOICES).keys()) + print('Supported webservers (webserver=): %s' % dict(WEB_CHOICES).keys()) + print('\n') diff --git a/fabfile/literals.py b/fabfile/literals.py index 7d93f9fd82..23f5c44c4d 100644 --- a/fabfile/literals.py +++ b/fabfile/literals.py @@ -3,15 +3,15 @@ OS_REDHAT = 'redhat' OS_CENTOS = 'centos' OS_FEDORA = 'fedora' OS_WINDOWS = 'windows' -OS_FREEBSD = 'freebds', +OS_FREEBSD = 'freebds' OS_CHOICES = { OS_UBUNTU: 'Ubuntu', - OS_REDHAT: 'RedHat', - OS_CENTOS: 'CentOS', OS_FEDORA: 'Fedora', - OS_WINDOWS: 'MS Windows', - OS_FREEBSD: 'FreeBSD', + #OS_REDHAT: 'RedHat', + #OS_CENTOS: 'CentOS', + #OS_WINDOWS: 'MS Windows', + #OS_FREEBSD: 'FreeBSD', } DEFAULT_INSTALL_PATH = { @@ -36,9 +36,9 @@ DB_ORACLE = 'oracle' DB_CHOICES = { DB_MYSQL: 'MySQL', - DB_PGSQL: 'PostgreSQL', - DB_SQLITE: 'SQLite', - DB_ORACLE: 'ORACLE' + #DB_PGSQL: 'PostgreSQL', + #DB_SQLITE: 'SQLite', + #DB_ORACLE: 'ORACLE' } DJANGO_DB_DRIVERS = { @@ -53,7 +53,7 @@ WEB_NGINX = 'nginx' WEB_CHOICES = { WEB_APACHE: 'Apache', - WEB_NGINX: 'Nginx', + #WEB_NGINX: 'Nginx', } DEFAULT_OS = OS_UBUNTU From 4b4dc9d96f0e08e7ff2df81979af1bd59f407809 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Sun, 3 Jun 2012 02:46:41 -0400 Subject: [PATCH 55/65] Add support for Debian, merge Debian/Ubuntu platforms --- fabfile/literals.py | 11 +++++--- fabfile/platforms/__init__.py | 27 ++++++++++--------- fabfile/platforms/debian.py | 50 +++++++++++++++++++++++++++++++++++ fabfile/platforms/linux.py | 8 +++--- fabfile/platforms/ubuntu.py | 45 ------------------------------- fabfile/webservers/apache.py | 13 ++++----- 6 files changed, 84 insertions(+), 70 deletions(-) create mode 100644 fabfile/platforms/debian.py diff --git a/fabfile/literals.py b/fabfile/literals.py index 23f5c44c4d..b1fb4f9c91 100644 --- a/fabfile/literals.py +++ b/fabfile/literals.py @@ -4,10 +4,12 @@ OS_CENTOS = 'centos' OS_FEDORA = 'fedora' OS_WINDOWS = 'windows' OS_FREEBSD = 'freebds' +OS_DEBIAN = 'debian' OS_CHOICES = { OS_UBUNTU: 'Ubuntu', OS_FEDORA: 'Fedora', + OS_DEBIAN: 'Debian', #OS_REDHAT: 'RedHat', #OS_CENTOS: 'CentOS', #OS_WINDOWS: 'MS Windows', @@ -16,17 +18,20 @@ OS_CHOICES = { DEFAULT_INSTALL_PATH = { OS_UBUNTU: '/usr/share', - OS_FEDORA: '/usr/share' + OS_FEDORA: '/usr/share', + OS_DEBIAN: '/usr/share', } DEFAULT_VIRTUALENV_NAME = { OS_UBUNTU: 'mayan', - OS_FEDORA: 'mayan' + OS_FEDORA: 'mayan', + OS_DEBIAN: 'mayan', } DEFAULT_REPOSITORY_NAME = { OS_UBUNTU: 'mayan', - OS_FEDORA: 'mayan' + OS_FEDORA: 'mayan', + OS_DEBIAN: 'mayan', } DB_MYSQL = 'mysql' diff --git a/fabfile/platforms/__init__.py b/fabfile/platforms/__init__.py index af81d0f128..6ccdf8971d 100644 --- a/fabfile/platforms/__init__.py +++ b/fabfile/platforms/__init__.py @@ -1,8 +1,8 @@ from fabric.api import run, sudo, cd, env, task from fabric.colors import green -from ..literals import OS_UBUNTU, OS_FEDORA -import linux, ubuntu, fedora +from ..literals import OS_UBUNTU, OS_FEDORA, OS_DEBIAN +import linux, ubuntu, fedora, debian @task @@ -10,10 +10,11 @@ def install_dependencies(): """ Install OS dependencies """ + print(green('Installing dependencies for %s' % env.os_name, bold=True)) - if env.os == OS_UBUNTU: - ubuntu.install_dependencies() + if env.os in [OS_UBUNTU, OS_DEBIAN]: + debian.install_dependencies() elif env.os == OS_FEDORA: fedora.install_dependencies() @@ -26,7 +27,7 @@ def install_mayan(): print(green('Installing Mayan EDMS from git repository', bold=True)) - if env.os in [OS_UBUNTU, OS_FEDORA]: + if env.os in [OS_UBUNTU, OS_FEDORA, OS_DEBIAN]: linux.install_mayan() @@ -38,8 +39,8 @@ def install_database_manager(): print(green('Installing database manager: %s' % env.database_manager_name, bold=True)) - if env.os == OS_UBUNTU: - ubuntu.install_database_manager() + if env.os in [OS_UBUNTU, OS_DEBIAN]: + debian.install_database_manager() elif env.os == OS_FEDORA: fedora.install_database_manager() @@ -52,8 +53,8 @@ def fix_permissions(): print(green('Fixing installation files\' permissions', bold=True)) - if env.os == OS_UBUNTU: - ubuntu.fix_permissions() + if env.os in [OS_UBUNTU, OS_DEBIAN]: + debian.fix_permissions() elif env.os == OS_FEDORA: fedora.fix_permissions() @@ -66,8 +67,8 @@ def install_webserver(): print(green('Installing webserver: %s' % env.webserver_name, bold=True)) - if env.os == OS_UBUNTU: - ubuntu.install_webserver() + if env.os in [OS_UBUNTU, OS_DEBIAN]: + debian.install_webserver() elif env.os == OS_FEDORA: fedora.install_webserver() @@ -80,7 +81,7 @@ def delete_mayan(): print(green('Deleting Mayan EDMS files', bold=True)) - if env.os in [OS_UBUNTU, OS_FEDORA]: + if env.os in [OS_UBUNTU, OS_FEDORA, OS_DEBIAN]: linux.delete_mayan() @@ -93,3 +94,5 @@ def post_install(): ubuntu.post_install() elif env.os == OS_FEDORA: fedora.post_install() + elif env.os == OS_DEBIAN: + debian.post_install() diff --git a/fabfile/platforms/debian.py b/fabfile/platforms/debian.py new file mode 100644 index 0000000000..0d103730b3 --- /dev/null +++ b/fabfile/platforms/debian.py @@ -0,0 +1,50 @@ +from fabric.api import run, sudo, cd, env, task, settings + +from ..literals import DB_MYSQL, WEB_APACHE + + +def install_dependencies(): + """ + Install Debian dependencies + """ + sudo('apt-get install -y git-core gcc tesseract-ocr unpaper python-virtualenv ghostscript libjpeg-dev libpng-dev poppler-utils') + + +def install_database_manager(): + """ + Install the database manager on an Ubuntu system + """ + + if env.database_manager == DB_MYSQL: + sudo('apt-get install -y mysql-server libmysqlclient-dev') + + with cd(env.virtualenv_path): + sudo('source bin/activate; pip install MySQL-python') + + +def install_webserver(): + """ + Installing the Debian packages for the webserver + """ + + if env.webserver == WEB_APACHE: + sudo('apt-get install -y apache2 libapache2-mod-wsgi') + + with settings(warn_only=True): + # Get rid of Apache's default site + sudo('a2dissite default') + + +def fix_permissions(): + """ + Fix installation files' permissions on a Debian system + """ + sudo('chmod 770 %s -R' % env.virtualenv_path) + sudo('chgrp www-data %s -R' % env.virtualenv_path) + + +def post_install(): + """ + Post install operations on a Debian system + """ + pass diff --git a/fabfile/platforms/linux.py b/fabfile/platforms/linux.py index 572dd34bcb..a47e314300 100644 --- a/fabfile/platforms/linux.py +++ b/fabfile/platforms/linux.py @@ -5,7 +5,7 @@ def delete_mayan(): """ Delete Mayan EDMS files from an Ubuntu system """ - sudo('rm %s -Rf' % env.virtualenv_path) + sudo('rm %(virtualenv_path)s -Rf' % env) def install_mayan(): @@ -13,8 +13,8 @@ def install_mayan(): Install Mayan EDMS on an Ubuntu system """ with cd(env.install_path): - sudo('virtualenv --no-site-packages %s' % env.virtualenv_name) + sudo('virtualenv --no-site-packages %(virtualenv_name)s' % env) with cd(env.virtualenv_path): - sudo('git clone http://www.github.com/rosarior/mayan %s' % env.repository_name) - sudo('source bin/activate; pip install -r %s/requirements/production.txt' % env.repository_name) + sudo('git clone http://www.github.com/rosarior/mayan %(repository_name)s' % env) + sudo('source bin/activate; pip install -r %(repository_name)s/requirements/production.txt' % env) diff --git a/fabfile/platforms/ubuntu.py b/fabfile/platforms/ubuntu.py index c99f4e1a50..501785f545 100644 --- a/fabfile/platforms/ubuntu.py +++ b/fabfile/platforms/ubuntu.py @@ -1,48 +1,3 @@ -from fabric.api import run, sudo, cd, env, task, settings - -from ..literals import DB_MYSQL, WEB_APACHE - - -def install_dependencies(): - """ - Install Ubuntu dependencies - """ - sudo('apt-get install -y git-core gcc tesseract-ocr unpaper python-virtualenv ghostscript libjpeg-dev libpng-dev poppler-utils') - - -def install_database_manager(): - """ - Install the database manager on an Ubuntu system - """ - - if env.database_manager == DB_MYSQL: - sudo('apt-get install -y mysql-server libmysqlclient-dev') - - with cd(env.virtualenv_path): - sudo('source bin/activate; pip install MySQL-python') - - -def install_webserver(): - """ - Installing the Ubuntu packages for the webserver - """ - - if env.webserver == WEB_APACHE: - sudo('apt-get install -y apache2 libapache2-mod-wsgi') - - with settings(warn_only=True): - # Get rid of Apache's default site - sudo('a2dissite default') - - -def fix_permissions(): - """ - Fix installation files' permissions on an Ubuntu system - """ - sudo('chmod 770 %s -R' % env.virtualenv_path) - sudo('chgrp www-data %s -R' % env.virtualenv_path) - - def post_install(): """ Post install operations on an Ubuntu system diff --git a/fabfile/webservers/apache.py b/fabfile/webservers/apache.py index 80840acb69..7b33b5fa83 100644 --- a/fabfile/webservers/apache.py +++ b/fabfile/webservers/apache.py @@ -3,7 +3,7 @@ import os from fabric.api import run, sudo, cd, env, task, settings from fabric.contrib.files import upload_template -from ..literals import OS_UBUNTU, OS_FEDORA +from ..literals import OS_UBUNTU, OS_FEDORA, OS_DEBIAN def install_site(): @@ -11,7 +11,7 @@ def install_site(): Install Mayan EDMS's site file in Apache configuration """ # TODO: configurable site name - if env.os == OS_UBUNTU: + if env.os in [OS_UBUNTU, OS_DEBIAN]: upload_template(filename=os.path.join('fabfile', 'templates', 'apache_site'), destination='/etc/apache2/sites-available/mayan', context=env, use_sudo=True) sudo('a2ensite mayan') elif env.os == OS_FEDORA: @@ -22,8 +22,9 @@ def remove_site(): """ Install Mayan EDMS's site file from Apache's configuration """ - if env.os == OS_UBUNTU: - sudo('a2dissite mayan') + if env.os in [OS_UBUNTU, OS_DEBIAN]: + with settings(warn_only=True): + sudo('a2dissite mayan') elif env.os == OS_FEDORA: with settings(warn_only=True): sudo('rm /etc/httpd/conf.d/mayan.conf') @@ -33,7 +34,7 @@ def restart(): """ Restart Apache """ - if env.os == OS_UBUNTU: + if env.os in [OS_UBUNTU, OS_DEBIAN]: sudo('/etc/init.d/apache2 restart') elif env.os == OS_FEDORA: sudo('systemctl restart httpd.service') @@ -43,7 +44,7 @@ def reload(): """ Reload Apache configuration files """ - if env.os == OS_UBUNTU: + if env.os in [OS_UBUNTU, OS_DEBIAN]: sudo('/etc/init.d/apache2 reload') elif env.os == OS_FEDORA: sudo('systemctl reload httpd.service') From a4bc5dbd63baef30089b48b974d35a7a8ea893f4 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Sun, 3 Jun 2012 03:02:52 -0400 Subject: [PATCH 56/65] Display database password --- fabfile/databases/mysql.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fabfile/databases/mysql.py b/fabfile/databases/mysql.py index 43d947bcb4..7a41f9f5f0 100644 --- a/fabfile/databases/mysql.py +++ b/fabfile/databases/mysql.py @@ -1,4 +1,5 @@ from fabric.api import run, env, task, settings +from fabric.colors import green def create_database(): @@ -9,6 +10,8 @@ def create_database(): run('echo "CREATE USER \'%(database_username)s\'@\'%(database_host)s\' IDENTIFIED BY \'%(database_password)s\';" | mysql -u root --password=%(database_manager_admin_password)s' % env) run('echo "GRANT ALL PRIVILEGES ON %(database_name)s.* TO \'%(database_username)s\'@\'%(database_host)s\' WITH GRANT OPTION;" | mysql -u root --password=%(database_manager_admin_password)s' % env) + print(green('Password used for Mayan EDMS database account: %s' % env.database_password, bold=True)) + def drop_database(): """ From f47d202b4eb70f2f1005ab74bcd83b3e8a87b80d Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Sun, 3 Jun 2012 03:03:28 -0400 Subject: [PATCH 57/65] Add per host settings, Add host group support via server_config.json or server_config.yaml files (requires pyyaml) http://fueledbylemons.com/blog/2011/04/09/server-configs-and-fabric/ --- fabfile/__init__.py | 19 +++-- fabfile/conf.py | 15 +++- fabfile/databases/__init__.py | 5 +- fabfile/django/__init__.py | 14 ++++ fabfile/platforms/__init__.py | 14 ++-- fabfile/server_config.py | 141 +++++++++++++++++++++++++++++++++ fabfile/webservers/__init__.py | 7 +- 7 files changed, 196 insertions(+), 19 deletions(-) create mode 100644 fabfile/server_config.py diff --git a/fabfile/__init__.py b/fabfile/__init__.py index d4f48fe803..40f2c894ff 100644 --- a/fabfile/__init__.py +++ b/fabfile/__init__.py @@ -1,13 +1,14 @@ +import sys + from fabric.api import task, env from fabric.colors import white import databases as database -import webservers as webserver import platforms as platform +import webservers as webserver import django -from conf import setup_environment, print_supported_configs - -setup_environment() +from conf import print_supported_configs +from server_config import servers print(white('\n\n ######## ', bold=True)) print(white(' ######## ', bold=True)) @@ -27,8 +28,11 @@ print(white('\nMayan EDMS Fabric installation file\n\n', bold=True)) print_supported_configs() -@task(default=True) +@task def install(): + """ + Perform a complete install of Mayan EDMS on a host + """ platform.install_dependencies() platform.install_mayan() platform.install_database_manager() @@ -45,6 +49,9 @@ def install(): @task def uninstall(): + """ + Perform a complete removal of Mayan EDMS from a host + """ platform.delete_mayan() webserver.remove_site() webserver.restart() @@ -52,5 +59,3 @@ def uninstall(): if env.drop_database: database.drop_database() database.drop_username() - - diff --git a/fabfile/conf.py b/fabfile/conf.py index 9574948f9f..16e380234d 100644 --- a/fabfile/conf.py +++ b/fabfile/conf.py @@ -3,12 +3,14 @@ import string import random from fabric.api import env +from fabric.colors import green from literals import (DEFAULT_INSTALL_PATH, DEFAULT_VIRTUALENV_NAME, DEFAULT_REPOSITORY_NAME, DEFAULT_OS, OS_CHOICES, DEFAULT_DATABASE_MANAGER, DB_CHOICES, DEFAULT_DATABASE_NAME, DEFAULT_WEBSERVER, WEB_CHOICES, DEFAULT_DATABASE_USERNAME, DJANGO_DB_DRIVERS, DEFAULT_DATABASE_HOST, DEFAULT_PASSWORD_LENGTH) +from server_config import reduce_env def password_generator(): @@ -16,7 +18,8 @@ def password_generator(): chars = string.ascii_letters + string.digits return ''.join(random.choice(chars) for x in range(DEFAULT_PASSWORD_LENGTH)) - + +@reduce_env def setup_environment(): env['os'] = getattr(env, 'os', DEFAULT_OS) env['os_name'] = OS_CHOICES[env.os] @@ -47,7 +50,11 @@ def setup_environment(): def print_supported_configs(): - print('Supported operating systems (os=): %s' % dict(OS_CHOICES).keys()) - print('Supported database managers (database_manager=): %s' % dict(DB_CHOICES).keys()) - print('Supported webservers (webserver=): %s' % dict(WEB_CHOICES).keys()) + print('Supported operating systems (os=): %s, default=\'%s\'' % (dict(OS_CHOICES).keys(), green(DEFAULT_OS))) + print('Supported database managers (database_manager=): %s, default=\'%s\'' % (dict(DB_CHOICES).keys(), green(DEFAULT_DATABASE_MANAGER))) + print('Supported webservers (webserver=): %s, default=\'%s\'' % (dict(WEB_CHOICES).keys(), green(DEFAULT_WEBSERVER))) print('\n') + + + + diff --git a/fabfile/databases/__init__.py b/fabfile/databases/__init__.py index ad48ada637..8afccd8032 100644 --- a/fabfile/databases/__init__.py +++ b/fabfile/databases/__init__.py @@ -1,7 +1,7 @@ from fabric.api import env, task from fabric.colors import green - +from ..conf import setup_environment from ..literals import DB_MYSQL import mysql @@ -11,6 +11,7 @@ def create_database(): """ Create the Mayan EDMS database """ + setup_environment() print(green('Creating Mayan EDMS database', bold=True)) if env.database_manager == DB_MYSQL: @@ -22,6 +23,7 @@ def drop_database(): """ Drop Mayan EDMS's database """ + setup_environment() print(green('Droping Mayan EDMS database', bold=True)) if env.database_manager == DB_MYSQL: @@ -33,6 +35,7 @@ def drop_username(): """ Drop Mayan EDMS's username """ + setup_environment() print(green('Droping Mayan EDMS username', bold=True)) if env.database_manager == DB_MYSQL: diff --git a/fabfile/django/__init__.py b/fabfile/django/__init__.py index 294d17075f..9ce0309435 100644 --- a/fabfile/django/__init__.py +++ b/fabfile/django/__init__.py @@ -3,18 +3,32 @@ import os from fabric.api import env, task, cd, sudo from fabric.contrib.files import upload_template +from ..conf import setup_environment + @task def syncdb(): + """ + Perform Django's syncdb command + """ + setup_environment() with cd(env.virtualenv_path): sudo('source bin/activate; %(repository_name)s/manage.py syncdb --noinput; %(repository_name)s/manage.py migrate' % (env)) @task def database_config(): + """ + Create a settings_local.py file tailored to the database manager selected + """ + setup_environment() upload_template(filename=os.path.join('fabfile', 'templates', 'settings_local.py'), destination=env.repository_path, context=env, use_sudo=True) @task def collectstatic(): + """ + Perform Django's collectstatic command + """ + setup_environment() with cd(env.virtualenv_path): sudo('source bin/activate; %(repository_name)s/manage.py collectstatic --noinput' % (env)) diff --git a/fabfile/platforms/__init__.py b/fabfile/platforms/__init__.py index 6ccdf8971d..5a8ec61da4 100644 --- a/fabfile/platforms/__init__.py +++ b/fabfile/platforms/__init__.py @@ -2,6 +2,7 @@ from fabric.api import run, sudo, cd, env, task from fabric.colors import green from ..literals import OS_UBUNTU, OS_FEDORA, OS_DEBIAN +from ..conf import setup_environment import linux, ubuntu, fedora, debian @@ -10,7 +11,7 @@ def install_dependencies(): """ Install OS dependencies """ - + setup_environment() print(green('Installing dependencies for %s' % env.os_name, bold=True)) if env.os in [OS_UBUNTU, OS_DEBIAN]: @@ -24,7 +25,7 @@ def install_mayan(): """ Install Mayan EDMS """ - + setup_environment() print(green('Installing Mayan EDMS from git repository', bold=True)) if env.os in [OS_UBUNTU, OS_FEDORA, OS_DEBIAN]: @@ -36,7 +37,7 @@ def install_database_manager(): """ Install the selected database manager """ - + setup_environment() print(green('Installing database manager: %s' % env.database_manager_name, bold=True)) if env.os in [OS_UBUNTU, OS_DEBIAN]: @@ -50,7 +51,7 @@ def fix_permissions(): """ Fix installation files' permissions """ - + setup_environment() print(green('Fixing installation files\' permissions', bold=True)) if env.os in [OS_UBUNTU, OS_DEBIAN]: @@ -64,7 +65,7 @@ def install_webserver(): """ Installing the OS packages for the webserver """ - + setup_environment() print(green('Installing webserver: %s' % env.webserver_name, bold=True)) if env.os in [OS_UBUNTU, OS_DEBIAN]: @@ -78,7 +79,7 @@ def delete_mayan(): """ Delete Mayan EDMS from the OS """ - + setup_environment() print(green('Deleting Mayan EDMS files', bold=True)) if env.os in [OS_UBUNTU, OS_FEDORA, OS_DEBIAN]: @@ -90,6 +91,7 @@ def post_install(): """ Perform post install operations """ + setup_environment() if env.os == OS_UBUNTU: ubuntu.post_install() elif env.os == OS_FEDORA: diff --git a/fabfile/server_config.py b/fabfile/server_config.py new file mode 100644 index 0000000000..29228e4a74 --- /dev/null +++ b/fabfile/server_config.py @@ -0,0 +1,141 @@ +"""Fabric server config management fabfile. +If you need additional configuration, setup ~/.fabricrc file: + + user = your_remote_server_username + +To get specific command help type: + fab -d command_name + +""" +# From http://fueledbylemons.com/blog/2011/04/09/server-configs-and-fabric/ + + +import os + +from fabric.api import env, task +from fabric.utils import puts +from fabric import colors +import fabric.network +import fabric.state + + +YAML_AVAILABLE = True +try: + import yaml +except ImportError: + YAML_AVAILABLE = False + + +JSON_AVAILABLE = True +try: + import simplejson as json +except ImportError: + try: + import json + except ImportError: + JSON_AVAILABLE = False + +################################ +# ENVIRONMENTS # +################################ + +def _load_config(**kwargs): + """Find and parse server config file. + + If `config` keyword argument wasn't set look for default + 'server_config.yaml' or 'server_config.json' file. + + """ + config, ext = os.path.splitext(kwargs.get('config', + 'server_config.yaml' if os.path.exists('server_config.yaml') else 'server_config.json')) + + if not os.path.exists(config + ext): + print colors.red('Error. "%s" file not found.' % (config + ext)) + return {} + if YAML_AVAILABLE and ext == '.yaml': + loader = yaml + elif JSON_AVAILABLE and ext =='.json': + loader = json + else: + print colors.red('Parser package not available') + return {} + # Open file and deserialize settings. + with open(config + ext) as config_file: + return loader.load(config_file) + +@task +def servers(*args, **kwargs): + """Set destination servers or server groups by comma delimited list of names""" + # Load config + servers = _load_config(**kwargs) + # If no arguments were recieved, print a message with a list of available configs. + if not args: + print 'No server name given. Available configs:' + for key in servers: + print colors.green('\t%s' % key) + + # Create `group` - a dictionary, containing copies of configs for selected servers. Server hosts + # are used as dictionary keys, which allows us to connect current command destination host with + # the correct config. This is important, because somewhere along the way fabric messes up the + # hosts order, so simple list index incrementation won't suffice. + env.group = {} + # For each given server name + for name in args: + # Recursive function call to retrieve all server records. If `name` is a group(e.g. `all`) + # - get it's members, iterate through them and create `group` + # record. Else, get fields from `name` server record. + # If requested server is not in the settings dictionary output error message and list all + # available servers. + _build_group(name, servers) + + + # Copy server hosts from `env.group` keys - this gives us a complete list of unique hosts to + # operate on. No host is added twice, so we can safely add overlaping groups. Each added host is + # guaranteed to have a config record in `env.group`. + env.hosts = env.group.keys() + +def _build_group(name, servers): + """Recursively walk through servers dictionary and search for all server records.""" + # We're going to reference server a lot, so we'd better store it. + server = servers.get(name, None) + # If `name` exists in servers dictionary we + if server: + # check whether it's a group by looking for `members` + if isinstance(server, list): + if fabric.state.output['debug']: + puts("%s is a group, getting members" % name) + for item in server: + # and call this function for each of them. + _build_group(item, servers) + # When, finally, we dig through to the standalone server records, we retrieve + # configs and store them in `env.group` + else: + if fabric.state.output['debug']: + puts("%s is a server, filling up env.group" % name) + env.group[server['host']] = server + else: + print colors.red('Error. "%s" config not found. Run `fab servers` to list all available configs' % name) + +def reduce_env(task): + """ + Copies server config settings from `env.group` dictionary to env variable. + + This way, tasks have easier access to server-specific variables: + `env.owner` instead of `env.group[env.host]['owner']` + + """ + def task_with_setup(*args, **kwargs): + # If `s:server` was run before the current command - then we should copy values to + # `env`. Otherwise, hosts were passed through command line with `fab -H host1,host2 + # command` and we skip. + if env.get("group", None): + for key,val in env.group[env.host].items(): + setattr(env, key, val) + if fabric.state.output['debug']: + puts("[env] %s : %s" % (key, val)) + + task(*args, **kwargs) + # Don't keep host connections open, disconnect from each host after each task. + # Function will be available in fabric 1.0 release. + # fabric.network.disconnect_all() + return task_with_setup diff --git a/fabfile/webservers/__init__.py b/fabfile/webservers/__init__.py index ceaeeebf1e..d6084a6fbe 100644 --- a/fabfile/webservers/__init__.py +++ b/fabfile/webservers/__init__.py @@ -1,7 +1,9 @@ from fabric.api import run, sudo, cd, env, task from fabric.colors import green +from ..conf import setup_environment from ..literals import WEB_APACHE + import apache @@ -10,7 +12,7 @@ def install_site(): """ Install Mayan EDMS site in the webserver configuration files """ - + setup_environment() print(green('Adding Mayan EDMS\'s site files to: %s' % env.webserver_name, bold=True)) if env.webserver == WEB_APACHE: @@ -22,6 +24,7 @@ def remove_site(): """ Install Mayan EDMS's site file from the webserver's configuration """ + setup_environment() print(green('Removing Mayan EDMS\'s site file from %s configuration' % env.webserver_name, bold=True)) if env.webserver == WEB_APACHE: @@ -33,6 +36,7 @@ def restart(): """ Restart the webserver """ + setup_environment() print(green('Restarting the web server: %s' % env.webserver_name, bold=True)) if env.webserver == WEB_APACHE: @@ -44,6 +48,7 @@ def reload(): """ Reload webserver configuration files """ + setup_environment() print(green('Reloading the web server configuration files', bold=True)) if env.webserver == WEB_APACHE: From d5b27bb22935c53fbf866430644ab5c48da4a365 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Sun, 3 Jun 2012 04:20:45 -0400 Subject: [PATCH 58/65] Fix mayan github repository url --- fabfile/platforms/linux.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabfile/platforms/linux.py b/fabfile/platforms/linux.py index a47e314300..c95b5114bb 100644 --- a/fabfile/platforms/linux.py +++ b/fabfile/platforms/linux.py @@ -16,5 +16,5 @@ def install_mayan(): sudo('virtualenv --no-site-packages %(virtualenv_name)s' % env) with cd(env.virtualenv_path): - sudo('git clone http://www.github.com/rosarior/mayan %(repository_name)s' % env) + sudo('git clone git://github.com/rosarior/mayan.git %(repository_name)s' % env) sudo('source bin/activate; pip install -r %(repository_name)s/requirements/production.txt' % env) From c4e3c1a65e35b954dbc22a0cb8e216468f1483e8 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Sun, 3 Jun 2012 04:21:10 -0400 Subject: [PATCH 59/65] Add python-dev to the list of Ubuntu/Debian dependencies (required by Pillow) --- fabfile/platforms/debian.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabfile/platforms/debian.py b/fabfile/platforms/debian.py index 0d103730b3..64df1bc608 100644 --- a/fabfile/platforms/debian.py +++ b/fabfile/platforms/debian.py @@ -7,7 +7,7 @@ def install_dependencies(): """ Install Debian dependencies """ - sudo('apt-get install -y git-core gcc tesseract-ocr unpaper python-virtualenv ghostscript libjpeg-dev libpng-dev poppler-utils') + sudo('apt-get install -y git-core gcc tesseract-ocr unpaper python-virtualenv ghostscript libjpeg-dev libpng-dev poppler-utils python-dev') def install_database_manager(): From 57f2fe3d4ac16d6f754b791901a1beac4367e399 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Sun, 3 Jun 2012 04:40:27 -0400 Subject: [PATCH 60/65] Autodetect version of Python being executed --- wsgi/dispatch.wsgi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wsgi/dispatch.wsgi b/wsgi/dispatch.wsgi index 68cd5368ac..3736618102 100644 --- a/wsgi/dispatch.wsgi +++ b/wsgi/dispatch.wsgi @@ -1,11 +1,11 @@ import os import sys import site +import platform sys.stdout = sys.stderr -#TODO fix properly -ve_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'lib/python2.7/site-packages')) # Change python 2.6 to the python version you are using +ve_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'lib/python%s/site-packages' % platform.python_version()[:3])) # Add the virtual Python environment site-packages directory to the path site.addsitedir(ve_path) From b88fd35b8a72bd21bc203ae6fb9c0776fc3d0222 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Sun, 3 Jun 2012 04:47:48 -0400 Subject: [PATCH 61/65] Update compressed fabric file --- contrib/fabfile.tar.gz | Bin 4820 -> 7044 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/contrib/fabfile.tar.gz b/contrib/fabfile.tar.gz index 4f573e5cdd69fde97ce929a634fc93e7cac87237..14cd5c4c2e9edbbc54dabbddeb40e278735968fb 100644 GIT binary patch literal 7044 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 ukV6hRCQkV6hR Date: Sun, 3 Jun 2012 21:08:22 -0400 Subject: [PATCH 62/65] Detect blank pages with the PopplerParser, raise ParserError to fallback to OCR if all parsers fail --- apps/ocr/parsers/__init__.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/ocr/parsers/__init__.py b/apps/ocr/parsers/__init__.py index 2cbf9a67a0..c9be3f7eed 100644 --- a/apps/ocr/parsers/__init__.py +++ b/apps/ocr/parsers/__init__.py @@ -51,7 +51,9 @@ def parse_document_page(document_page, descriptor=None, mimetype=None): else: # If parser was successfull there is no need to try # others in the list for this mimetype - break; + return + + raise ParserError('Parser list exhausted') except KeyError: raise ParserUnknownFile @@ -70,6 +72,8 @@ class SlateParser(Parser): Parser for PDF files using the slate library for Python """ def parse(self, document_page, descriptor=None): + logger.debug('Starting SlateParser') + if not descriptor: descriptor = document_page.document_version.open() @@ -122,7 +126,7 @@ class PopplerParser(Parser): logger.debug('self.pdftotext_path: %s' % self.pdftotext_path) def parse(self, document_page, descriptor=None): - logger.debug('parsing PDF') + logger.debug('parsing PDF with PopplerParser') pagenum = str(document_page.page_number) if descriptor: @@ -151,7 +155,10 @@ class PopplerParser(Parser): logger.error(proc.stderr.readline()) raise ParserError - output = proc.stdout.read() + output = proc.stdout.read() + if output == '\x0c': + logger.debug('Parser didn\'t any output') + raise ParserError('No output') document_page.content = output document_page.page_label = _(u'Text extracted from PDF') From 05ec39e6f037a82d89a876afcc23b1224228cf35 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Sun, 3 Jun 2012 22:36:13 -0400 Subject: [PATCH 63/65] Add Fedora,fabfile,appsembler install steps --- docs/intro/installation.rst | 193 ++++++++++++++++++++++++++++++++---- 1 file changed, 176 insertions(+), 17 deletions(-) diff --git a/docs/intro/installation.rst b/docs/intro/installation.rst index 008554b147..e1f3029419 100644 --- a/docs/intro/installation.rst +++ b/docs/intro/installation.rst @@ -2,14 +2,90 @@ Installation ============ -Local or managed server ------------------------ +Automatic install using included fabfile +---------------------------------------- +A Fabric_ file is included to help users not very familiar with Ubuntu_, +Python_ and Django_ install **Mayan EDMS**, or for system administrators +looking to automate the install whether in a local or remote system. + +To bootstrap **Mayan EDMS** via the fabfile without having to clone the +entire repository, run the following command, replacing the part that +reads: with your current MySQL root password +or the MySQL root password you plan to assign to it, during the MySQL +installation when executing the fabfile. + +* Debian or Ubuntu:: + + $ cd /tmp && sudo apt-get install -y fabric wget tar gzip && wget https://raw.github.com/rosarior/mayan/contrib/fabfile.tar.gz -O - | tar -xvzf - && echo "database_manager_admin_password=" > ~/.fabricrc && fab -H localhost install + +* Fedora:: + + $ cd /tmp && sudo yum install -y fabric wget tar gzip && wget https://raw.github.com/rosarior/mayan/contrib/fabfile.tar.gz -O - | tar -xvzf - && echo "database_manager_admin_password=" > ~/.fabricrc && fab -H localhost install + + +The ``fabfile`` also supports deploying to more than one server whether +the they same configuration or not, via a ``server_config.json`` file. +The fabfile also supports YAML server configuration +files but requires installing ``pyyaml`` via ``pip``, ``python-yaml`` +via ``apt`` (Debian_, Ubuntu_) or ``PyYAML`` via ``yum`` (Fedora_) + +A sample ``server_config.yaml`` would be as follows:: + + debian_server: + host: 192.168.1.1 + database_manager_admin_password: my_debian_mysql_pa$$word + drop_database: True + os: debian + ubuntu_server: + host: 192.168.1.2 + database_manager_admin_password: my_ubuntu_mysql_pa$$word + drop_database: True + os: ubuntu + database_username: mayan_release_12 + database_name: mayan_release_12 + all_servers: [debian_server, ubuntu_server] + +To install **Mayan EDMS** to these servers the ``fabfile`` should be called in the following manner:: + + $ fab servers:debian_server install + +or:: + + $ fab servers:ubuntu_server,debian_server install + +or:: + + $ fab servers:all_servers install + + +Configuration options for the ``fabfile``: + +* ``host`` Hostname or address of the host to which to install **Mayan EDMS**. Required setting. +* ``os`` Operating system of the target host. Options: ubuntu, debian, fedora. default: ubuntu +* ``install_path`` Installation path. Default: /usr/share +* ``virtualenv_name`` Name of the directory that will house the virtualenv under the ``install_path``. Default: mayan +* ``repository_name`` Name of the directory where the repository will be clone under the ``virtualenv_name`` directory. Default: mayan +* ``database_manager`` Database manager to use. Options: mysql. Default: mysql +* ``database_username`` Username that will be created and used to access the database. Default: mayan +* ``database_password`` Password of the database user account. Default: random autogenerated password +* ``database_host`` Address of the database manager host. Default: 127.0.0.1 +* ``drop_database`` Weather or not to drop the database when uninstalling **Mayan EDMS** via the fabfile. Default: False +* ``database_manager_admin_password`` Administrator password of the database manager, only used to create the **Mayan EDMS** database and user. Required setting. +* ``database_name`` Name of the **Mayan EDMS** database. Default: mayan +* ``webserver`` Web server that will be install and configure to server **Mayan EDMS**. Options: apache. Default: apache + + +Only the options: ``host``, ``os`` and ``database_manager_admin_password`` should be required for most installations. + + +Local or managed Ubuntu or Debian server +---------------------------------------- **Mayan EDMS** should be deployed_ like any other Django_ project and preferably using virtualenv_. If using a Debian_ or Ubuntu_ based Linux distribution getting the executable requirements is as easy as:: - $ apt-get install tesseract-ocr unpaper python-virtualenv ghostscript libjpeg-dev libpng-dev poppler-utils -y + $ sudo apt-get install python-dev gcc tesseract-ocr unpaper python-virtualenv ghostscript libjpeg-dev libpng-dev poppler-utils -y To initialize a ``virtualenv`` to deploy the project do:: @@ -34,22 +110,18 @@ To install the python dependencies ``easy_install`` can be used, however for eas Create the database that will hold the data. Install any corresponding python database drivers. Update the settings.py file with you database settings. If using the ``MySQL`` database manager, use the following commands:: - $ apt-get install python-dev libmysqlclient-dev gcc -y + $ sudo apt-get install libmysqlclient-dev -y $ pip install MySQL-python -If using PostgreSQL, enter the following:: +If using ``PostgreSQL``, enter the following:: - $ apt-get install python-dev libpq-dev gcc-y - $ pip install pip install psycopg2 + $ sudo apt-get install libpq-dev -y + $ pip install psycopg2 Populate the database with the project's schema doing:: $ ./manage.py syncdb --migrate -Collect the static files of the project into the ``static`` folder for serving via a webserver:: - - $ ./manage.py collectstatic - To test your installation, create a file called settings_local.py with the following content:: DEBUG=True @@ -59,7 +131,96 @@ Execute Django’s development server using the ``runserver`` command to launch $ ./manager.py runserver -Point your browser to http://127:0.0.1:8000, if everything was installed correctly you should see the login screen. After making sure everything is running correctly, stop the runserver command, delete the settings_local.py and deploy Mayan EDMS using the webserver of your preference. If your are using Apache_, a sample site file is included under the contrib directory. +Point your browser to http://127:0.0.1:8000, if everything was installed +correctly you should see the login screen. After making sure everything +is running correctly, stop the runserver command and delete the settings_local.py. +Deploy **Mayan EDMS** using the webserver of your preference. If your are +using Apache_, a sample site file is included under the contrib directory. + +Before finally deploying to your favorite webserver don't forget to collect the +static files of the project into the ``static`` folder for serving via a webserver:: + + $ ./manage.py collectstatic + + + +Local or managed Fedora server +------------------------------ + +**Mayan EDMS** should be deployed_ like any other Django_ project and preferably using virtualenv_. + +If using a Fedora_ based Linux distribution getting the executable requirements is as easy as:: + + $ sudo yum install -y git gcc tesseract unpaper python-virtualenv ghostscript libjpeg-turbo-devel libpng-devel poppler-util python-devel + +To initialize a ``virtualenv`` to deploy the project do:: + + $ virtualenv --no-site-packages mayan + +Download_ and decompress the latest version of **Mayan EDMS**:: + + $ cd mayan + $ tar -xvzf mayan.tar.gz + +Or clone the latest development version straight from github:: + + $ cd mayan + $ git clone git://github.com/rosarior/mayan.git + +To install the python dependencies ``easy_install`` can be used, however for easier retrieval a production dependencies file is included, to use it execute:: + + $ cd mayan + $ source ../bin/activate + $ pip install -r requirements/production.txt + +Create the database that will hold the data. Install any corresponding python database drivers. Update the settings.py file with you database settings. +If using the ``MySQL`` database manager, use the following commands:: + + $ sudo yum install -y mysql-devel + $ pip install MySQL-python + +If using ``PostgreSQL``, enter the following:: + + $ sudo yum install -y postgresql-devel + $ pip install psycopg2 + +Populate the database with the project's schema doing:: + + $ ./manage.py syncdb --migrate + +To test your installation, create a file called settings_local.py with the following content:: + + DEBUG=True + DEVELOPMENT=True + +Execute Django’s development server using the ``runserver`` command to launch a local instance of Mayan EDMS:: + + $ ./manager.py runserver + +Point your browser to http://127:0.0.1:8000, if everything was installed +correctly you should see the login screen. After making sure everything +is running correctly, stop the runserver command and delete the settings_local.py. +Deploy **Mayan EDMS** using the webserver of your preference. If your are +using Apache_, a sample site file is included under the contrib directory. + +Before finally deploying to your favorite webserver don't forget to collect the +static files of the project into the ``static`` folder for serving via a webserver:: + + $ ./manage.py collectstatic + + +Cloud install +------------- +SaaS provied Appsembler_ has started providing a "1-click install" cloud +offering of **Mayan EDMS**. Go to their website and click on apps to start +your trial period of **Mayan EDMS** on the cloud. + + +DjangoZoom +---------- +For instructions on how to deploy **Mayan EDMS** on DjangoZoom, watch the screencast: + +"Deploying Mayan EDMS on DjangoZoom.net" available on Youtube_ Webfaction @@ -171,11 +332,6 @@ To install **Mayan EDMS** on Webfaction_, follow these steps: apache2/bin/restart -DjangoZoom ----------- -For instructions on how to deploy **Mayan EDMS** on DjangoZoom, watch the screencast: - -"Deploying Mayan EDMS on DjangoZoom.net" available on Youtube_ .. _`vendor lock-in`: https://secure.wikimedia.org/wikipedia/en/wiki/Vendor_lock-in @@ -196,3 +352,6 @@ For instructions on how to deploy **Mayan EDMS** on DjangoZoom, watch the screen .. _deployed: https://docs.djangoproject.com/en/1.3/howto/deployment/ .. _virtualenv: http://www.virtualenv.org/en/latest/index.html .. _`Reducing mod_wsgi Memory Consumption`: http://docs.webfaction.com/software/mod-wsgi.html#mod-wsgi-reducing-memory-consumption +.. _Fedora: http://fedoraproject.org/ +.. _Fabric: http://docs.fabfile.org/ +.. _Appsembler: http://appsembler.com/ From 91c4477f27b4d6366a5c503be71efe0d12120751 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Sun, 3 Jun 2012 22:36:40 -0400 Subject: [PATCH 64/65] Update version 0.12.1 release notes --- docs/releases/0.12.1.rst | 51 ++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/docs/releases/0.12.1.rst b/docs/releases/0.12.1.rst index ac1a2194cf..75379ea8d7 100644 --- a/docs/releases/0.12.1.rst +++ b/docs/releases/0.12.1.rst @@ -10,8 +10,8 @@ Overview ======== While bug fixes and minor feature were the focus for this release, some -bigger changes were included becuase of their importance. The parsing of -document saw a complety rewrite being now class based and allows for more +bigger changes were included because of their importance. The parsing of +documents saw a complete rewrite being now class based and allows for more than one parser per mimetype with sequencial fallback. This provides the best text extraction on deployments where users have control over the installation and basic extraction when deploying on the cloud or other @@ -22,12 +22,23 @@ binaries. What's new in Mayan EDMS v0.12.1 ================================ +Fabric file (fabfile) +~~~~~~~~~~~~~~~~~~~~~ +A Fabric file is included to help users not very familiar with Ubuntu, +Python and Django install **Mayan EDMS**, or for system administrators +looking to automate the install whether in local or remote systems. +At the moment the fabfile will install **Mayan EDMS** in the same configurations +listed in this documentation, that is: (Ubuntu/Debian/Fedora) + virtualenv + Apache + MySQL. +Feel free to submit your configuration settings and files for different databases, +webserver or Linux distribution. More configurations will be added to +the fabfile as more are tested. + Documentation update ~~~~~~~~~~~~~~~~~~~~ The installation instructions were updated to include the installation of the libpng-dev and libjpeg-dev libraries as well as the installation of the poppler-utils package. An additional step to help users test their -new installation of *Mayan EDMS* was also added. +new installation of **Mayan EDMS** was also added. Translations ~~~~~~~~~~~~ @@ -42,7 +53,7 @@ document views. Better office document conversion ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A new method of converting office document has been implemented, this +A new method of converting office documents has been implemented, this new method doesn't require the use of the command line utility ``UNOCONV``. If this new method proves to work better than previous solutions the use of ``UNOCONV`` may be deprecated in the future. The conversion method @@ -51,34 +62,44 @@ which defaults to '/usr/bin/libreoffice'. Better PDF text parsing ~~~~~~~~~~~~~~~~~~~~~~~ -Brian E submitted a patch to use the Poppler package pdftotext utility to +Brian E. submitted a patch to use the Poppler package pdftotext utility to extract text from PDF files. This is now the default method Mayan EDMS will execute to try to extract text from a PDF and failing that will fallback to the previous method. This change add a new configuration option: :setting:`OCR_PDFTOTEXT_PATH` to specify the location of the ``pdftotext`` -executable, it defaults to '/usr/bin/pdftotext' +executable, it defaults to '/usr/bin/pdftotext'. Be sure to install the +``poppler-utils`` os package to take advantage of this new parser. Changed defaults ~~~~~~~~~~~~~~~~ -OCR_AUTOMATIC_OCR = True -OCR queue started by default - +The OCR queue is now active by default when first created during the +``syncdb`` phase and the :setting:`OCR_AUTOMATIC_OCR` option now defaults +to ``True``. These two changes are made to reduce the steps required for +new users to start enjoying the benefits of automatic text extraction from +uploaded documents without having to read the documentation and have a more +functional default install. Upgrading from a previous version ================================= Start off by adding the new requirements:: - $ pip install -r requirements/production.txt + $ pip install -r requirements/production.txt -Then create the new database structures with:: - - $ ./manage.py syncdb - -Afterwards migrate existing database schema with:: +Migrate existing database schema with:: $ ./manage.py migrate documents +Install the ``poppler-utils`` package: + +* Ubuntu, Debian:: + + $ apt-get install -y poppler-utils + +* Fedora:: + + $ yum install -y poppler-utils + The upgrade procedure is now complete. From 001f7f1695eefa2f8960a84bdb9187b5950e6074 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Sun, 3 Jun 2012 22:37:02 -0400 Subject: [PATCH 65/65] Remove cyrillic characters from doc utils makepdf error is resolved --- docs/credits/contributors.rst | 12 ++++++------ docs/releases/0.10.rst | 2 +- docs/releases/0.9.1.rst | 4 ++-- docs/releases/0.9.rst | 4 ++-- docs/releases/index.rst | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/credits/contributors.rst b/docs/credits/contributors.rst index a6e2079d59..1b34f42e0f 100644 --- a/docs/credits/contributors.rst +++ b/docs/credits/contributors.rst @@ -15,7 +15,7 @@ Bug fixes --------- * Aziz M. Bookwala (https://github.com/azizmb) * IHLeanne (https://github.com/IHLeanne) -* Сергей Глита [Sergey Glita] (s.v.glita@gmail.com) +* Sergey Glita (s.v.glita@gmail.com) * Meurig Freeman (https://github.com/meurig) * David Herring (https://github.com/abadger1406) @@ -27,7 +27,7 @@ Bug reports * Joost Cassee (joost@cassee.net, https://github.com/jcassee) * Brian Huxley * dAnjou (https://github.com/dAnjou) -* Сергей Глита [Sergey Glita] (s.v.glita@gmail.com) +* Sergey Glita (s.v.glita@gmail.com) * IHLeanne (https://github.com/IHLeanne) * valterwill (https://github.com/valterwill) * David Herring (https://github.com/abadger1406) @@ -37,14 +37,14 @@ Bug reports Patches ------- * Meurig Freeman (https://github.com/meurig) -* Сергей Глита [Sergey Glita] (s.v.glita@gmail.com) +* Sergey Glita (s.v.glita@gmail.com) * Brian E (brian@realize.org) Suggestions ----------- * Cezar Jenkins (https://twitter.com/#!/emperorcezar) -* Сергей Глита [Sergey Glita] (s.v.glita@gmail.com) +* Sergey Glita (s.v.glita@gmail.com) * Barry Rowlingson (http://geospaced.blogspot.com) * Gour (https://github.com/gour) * Alexandru Kiss (usurel@gmail.com) @@ -59,7 +59,7 @@ Translations * Russian - - Сергей Глита [Sergey Glita] (s.v.glita@gmail.com) + - Sergey Glita (s.v.glita@gmail.com) * Italian @@ -72,7 +72,7 @@ Translations Remote access for debugging --------------------------- -* Сергей Глита [Sergey Glita] (s.v.glita@gmail.com) +* Sergey Glita (s.v.glita@gmail.com) * David Herring (https://github.com/abadger1406) * Michael Terretta (terretta@gmail.com) * Alexandru Kiss (usurel@gmail.com) diff --git a/docs/releases/0.10.rst b/docs/releases/0.10.rst index cbe2f65ff5..9fa5065a30 100644 --- a/docs/releases/0.10.rst +++ b/docs/releases/0.10.rst @@ -39,7 +39,7 @@ Version 0.10 * Document image serving response now specifies a MIME type for increased browser compatibility. * Small change in the scheduler that increases stability. -* Russian translation updates (Сергей Глита [Sergey Glita]) +* Russian translation updates Sergey Glita * Improved and generalized the OCR queue locking mechanism, this should eliminate any posibility of race conditions between Mayan EDMS OCR nodes. * Added support for signals to the OCR queue, this results in instant OCR diff --git a/docs/releases/0.9.1.rst b/docs/releases/0.9.1.rst index 2dc29b1a65..62c45bdf11 100644 --- a/docs/releases/0.9.1.rst +++ b/docs/releases/0.9.1.rst @@ -1,7 +1,7 @@ Version 0.9.1 ------------- * Added handling percent encoded unicode query strings in search URL, - thanks to (Сергей Глита [Sergei Glita]) for reporting. + thanks to Sergei Glita for reporting. * Added a FAQ explaing how to fix MySQL collation related error when - doing searches also thanks to (Сергей Глита [Sergei Glita]) for + doing searches also thanks to Sergei Glita for reporting this one. diff --git a/docs/releases/0.9.rst b/docs/releases/0.9.rst index c3709ffe2f..be8714217b 100644 --- a/docs/releases/0.9.rst +++ b/docs/releases/0.9.rst @@ -16,11 +16,11 @@ Version 0.9 * Changed to Semantic Versioning (http://semver.org/), with recommendations 7, 8 and 9 causing the most effect in the versioning number. -* Added Russian locale post OCR cleanup backend (Сергей Глита [Sergei Glita]) +* Added Russian locale post OCR cleanup backend Sergei Glita * Reduced severity of the messages displayed when no OCR cleanup backend is found for a language * Complete Portuguese translation (Emerson Soares and Renata Oliveira) -* Complete Russian translation (Сергей Глита [Sergei Glita]) +* Complete Russian translation Sergei Glita) * Added animate.css to use CSS to animate flash messages with better fallback on non JS browsers * The admin and sentry links are no longer hard-coded (Meurig Freeman) diff --git a/docs/releases/index.rst b/docs/releases/index.rst index 8949542b57..328b8f08cf 100644 --- a/docs/releases/index.rst +++ b/docs/releases/index.rst @@ -9,10 +9,10 @@ changes made in that version. For those upgrading to a new version of **Mayan EDMS**, you will need to check all the backwards-incompatible changes and deprecated features for each 'final' release from the one after your current **Mayan EDMS** version, -up to and including the new version. +up to and including the latest version. Latest version (0.12.1) ---------------------- +----------------------- .. toctree:: :maxdepth: 1