Merge branch 'hotfix/v0.12.1' into development
Conflicts: apps/converter/conf/settings.py apps/documents/__init__.py apps/main/__init__.py apps/metadata/__init__.py apps/navigation/templatetags/navigation_tags.py apps/ocr/__init__.py apps/ocr/conf/settings.py docs/intro/installation.rst docs/releases/index.rst requirements/production.txt
This commit is contained in:
Binary file not shown.
@@ -3,14 +3,15 @@
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Pierpaolo Baldan <pierpaolo.baldan@gmail.com>, 2012.
|
||||
# Roberto Rosario <roberto.rosario.gonzalez@gmail.com>, 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 <roberto.rosario.gonzalez@gmail.com>\n"
|
||||
"PO-Revision-Date: 2012-03-21 14:55+0000\n"
|
||||
"Last-Translator: Pierpaolo Baldan <pierpaolo.baldan@gmail.com>\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"
|
||||
|
||||
Binary file not shown.
@@ -4,14 +4,15 @@
|
||||
#
|
||||
# Translators:
|
||||
# <pierpaolo.baldan@gmail.com>, 2011.
|
||||
# Pierpaolo Baldan <pierpaolo.baldan@gmail.com>, 2012.
|
||||
# Roberto Rosario <roberto.rosario.gonzalez@gmail.com>, 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 <roberto.rosario.gonzalez@gmail.com>\n"
|
||||
"PO-Revision-Date: 2012-03-21 13:21+0000\n"
|
||||
"Last-Translator: Pierpaolo Baldan <pierpaolo.baldan@gmail.com>\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"
|
||||
|
||||
@@ -396,3 +396,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()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -15,15 +15,6 @@ Setting(
|
||||
exists=True,
|
||||
)
|
||||
|
||||
Setting(
|
||||
namespace=namespace,
|
||||
name='IM_CONVERT_PATH',
|
||||
global_name='CONVERTER_IM_CONVERT_PATH',
|
||||
default=u'/usr/bin/convert',
|
||||
description=_(u'File path to imagemagick\'s convert program.'),
|
||||
exists=True,
|
||||
)
|
||||
|
||||
Setting(
|
||||
namespace=namespace,
|
||||
name='IM_IDENTIFY_PATH',
|
||||
@@ -75,6 +66,16 @@ Setting(
|
||||
description=_(u'Use alternate method of connection to LibreOffice using a pipe, it is slower but less prone to segmentation faults.'),
|
||||
)
|
||||
|
||||
Setting(
|
||||
namespace=namespace,
|
||||
name='LIBREOFFICE_PATH',
|
||||
global_name='CONVERTER_LIBREOFFICE_PATH',
|
||||
default=u'/usr/bin/libreoffice',
|
||||
description=_(u'Path to the libreoffice program.'),
|
||||
exists=True
|
||||
)
|
||||
|
||||
|
||||
#{'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'},
|
||||
#{'name': u'PRINT_QUALITY_OPTIONS', 'global_name': u'CONVERTER_PRINT_QUALITY_OPTIONS', 'default': u'-density 500'},
|
||||
|
||||
Binary file not shown.
@@ -7,16 +7,15 @@
|
||||
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 <pierpaolo.baldan@gmail.com>\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."
|
||||
@@ -928,9 +919,7 @@ msgstr "Path per il programma unoconv"
|
||||
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."
|
||||
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'"
|
||||
|
||||
@@ -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,54 @@ 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:
|
||||
os.environ['HOME'] = TEMPORARY_DIRECTORY
|
||||
proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||
return_code = proc.wait()
|
||||
logger.debug('return_code: %s' % return_code)
|
||||
|
||||
readline = proc.stderr.readline()
|
||||
logger.debug('stderr: %s' % readline)
|
||||
if return_code != 0:
|
||||
raise OfficeBackendError(readline)
|
||||
filename, extension = os.path.splitext(os.path.basename(self.input_filepath))
|
||||
logger.debug('filename: %s' % filename)
|
||||
logger.debug('extension: %s' % extension)
|
||||
|
||||
converted_output = os.path.join(TEMPORARY_DIRECTORY, os.path.extsep.join([filename, 'pdf']))
|
||||
logger.debug('converted_output: %s' % converted_output)
|
||||
|
||||
os.rename(converted_output, self.output_filepath)
|
||||
except OSError, msg:
|
||||
raise OfficeBackendError(msg)
|
||||
except Exception, msg:
|
||||
logger.error('Unhandled exception', exc_info=msg)
|
||||
|
||||
|
||||
@@ -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 = []
|
||||
|
||||
|
||||
Binary file not shown.
@@ -4,19 +4,19 @@
|
||||
#
|
||||
# Translators:
|
||||
# <pierpaolo.baldan@gmail.com>, 2011.
|
||||
# Pierpaolo Baldan <pierpaolo.baldan@gmail.com>, 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 <roberto.rosario.gonzalez@gmail.com>\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 <pierpaolo.baldan@gmail.com>\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."
|
||||
|
||||
Binary file not shown.
@@ -7,16 +7,15 @@
|
||||
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 <roberto.rosario.gonzalez@gmail.com>\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
|
||||
|
||||
Binary file not shown.
@@ -4,19 +4,19 @@
|
||||
#
|
||||
# Translators:
|
||||
# <pierpaolo.baldan@gmail.com>, 2011.
|
||||
# Pierpaolo Baldan <pierpaolo.baldan@gmail.com>, 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 <roberto.rosario.gonzalez@gmail.com>\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 <pierpaolo.baldan@gmail.com>\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"
|
||||
@@ -173,15 +168,15 @@ msgstr "link al documento"
|
||||
msgid ""
|
||||
"Check this option to have this node act as a container for documents and not"
|
||||
" as a parent for further nodes."
|
||||
msgstr ""
|
||||
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."
|
||||
@@ -361,7 +354,7 @@ msgstr "Gli indici contengono: %s"
|
||||
msgid ""
|
||||
"A dictionary that maps the index name and where on the filesystem that index"
|
||||
" will be mirrored."
|
||||
msgstr ""
|
||||
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.."
|
||||
|
||||
Binary file not shown.
@@ -3,19 +3,19 @@
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Pierpaolo Baldan <pierpaolo.baldan@gmail.com>, 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 <roberto.rosario.gonzalez@gmail.com>\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 <pierpaolo.baldan@gmail.com>\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"
|
||||
|
||||
Binary file not shown.
@@ -4,14 +4,15 @@
|
||||
#
|
||||
# Translators:
|
||||
# <pierpaolo.baldan@gmail.com>, 2011.
|
||||
# Pierpaolo Baldan <pierpaolo.baldan@gmail.com>, 2012.
|
||||
# Roberto Rosario <roberto.rosario.gonzalez@gmail.com>, 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 <roberto.rosario.gonzalez@gmail.com>\n"
|
||||
"PO-Revision-Date: 2012-03-21 13:44+0000\n"
|
||||
"Last-Translator: Pierpaolo Baldan <pierpaolo.baldan@gmail.com>\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"
|
||||
|
||||
@@ -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']
|
||||
@@ -331,8 +331,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)
|
||||
|
||||
|
||||
@@ -21,7 +21,11 @@ def get_used_size(path, file_list):
|
||||
|
||||
|
||||
def storage_count(path=u'.'):
|
||||
try:
|
||||
directories, files = STORAGE_BACKEND().listdir(path)
|
||||
except OSError:
|
||||
return 0, 0
|
||||
else:
|
||||
total_count = len(files)
|
||||
total_size = get_used_size(path, files)
|
||||
|
||||
@@ -53,15 +57,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'),
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -129,8 +129,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'},
|
||||
|
||||
Binary file not shown.
@@ -7,16 +7,15 @@
|
||||
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 <pierpaolo.baldan@gmail.com>\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"
|
||||
|
||||
Binary file not shown.
@@ -4,14 +4,15 @@
|
||||
#
|
||||
# Translators:
|
||||
# <pierpaolo.baldan@gmail.com>, 2011.
|
||||
# Pierpaolo Baldan <pierpaolo.baldan@gmail.com>, 2012.
|
||||
# Roberto Rosario <roberto.rosario.gonzalez@gmail.com>, 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 <roberto.rosario.gonzalez@gmail.com>\n"
|
||||
"PO-Revision-Date: 2012-03-21 13:23+0000\n"
|
||||
"Last-Translator: Pierpaolo Baldan <pierpaolo.baldan@gmail.com>\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"
|
||||
|
||||
Binary file not shown.
@@ -4,19 +4,19 @@
|
||||
#
|
||||
# Translators:
|
||||
# <pierpaolo.baldan@gmail.com>, 2011.
|
||||
# Pierpaolo Baldan <pierpaolo.baldan@gmail.com>, 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 <roberto.rosario.gonzalez@gmail.com>\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 <pierpaolo.baldan@gmail.com>\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"
|
||||
|
||||
Binary file not shown.
@@ -4,19 +4,19 @@
|
||||
#
|
||||
# Translators:
|
||||
# <pierpaolo.baldan@gmail.com>, 2011.
|
||||
# Pierpaolo Baldan <pierpaolo.baldan@gmail.com>, 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 <roberto.rosario.gonzalez@gmail.com>\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 <pierpaolo.baldan@gmail.com>\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.<attribute>` and `metadata.<metadata_type_name>`."
|
||||
msgstr ""
|
||||
"Questo rappresenta i metadati di tutti gli altri documenti. Oggetti "
|
||||
"disponibili: `document.<attribute>` e `metadata.<metadata_type_name>`."
|
||||
msgstr "Questo rappresenta i metadati di tutti gli altri documenti. Oggetti disponibili: `document.<attribute>` e `metadata.<metadata_type_name>`."
|
||||
|
||||
#: 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."
|
||||
|
||||
Binary file not shown.
@@ -4,14 +4,15 @@
|
||||
#
|
||||
# Translators:
|
||||
# <pierpaolo.baldan@gmail.com>, 2011.
|
||||
# Pierpaolo Baldan <pierpaolo.baldan@gmail.com>, 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 <roberto.rosario.gonzalez@gmail.com>\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 <pierpaolo.baldan@gmail.com>\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."
|
||||
|
||||
@@ -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())
|
||||
|
||||
Binary file not shown.
@@ -7,16 +7,15 @@
|
||||
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 <pierpaolo.baldan@gmail.com>\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
|
||||
|
||||
@@ -3,11 +3,14 @@ from __future__ import absolute_import
|
||||
import copy
|
||||
import re
|
||||
import logging
|
||||
#import urlparse
|
||||
#import urllib
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.template import (TemplateSyntaxError, Library,
|
||||
Node, Variable, VariableDoesNotExist)
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.encoding import smart_str, force_unicode, smart_unicode
|
||||
|
||||
from ..api import (link_binding, multi_object_navigation,
|
||||
sidebar_templates, get_context_navigation_links)
|
||||
@@ -30,6 +33,184 @@ def get_top_menu_links(parser, token):
|
||||
return TopMenuNavigationNode()
|
||||
|
||||
|
||||
'''
|
||||
def resolve_arguments(context, src_args):
|
||||
args = []
|
||||
kwargs = {}
|
||||
if type(src_args) == type([]):
|
||||
for i in src_args:
|
||||
val = resolve_template_variable(context, i)
|
||||
if val:
|
||||
args.append(val)
|
||||
elif type(src_args) == type({}):
|
||||
for key, value in src_args.items():
|
||||
val = resolve_template_variable(context, value)
|
||||
if val:
|
||||
kwargs[key] = val
|
||||
else:
|
||||
val = resolve_template_variable(context, src_args)
|
||||
if val:
|
||||
args.append(val)
|
||||
|
||||
return args, kwargs
|
||||
|
||||
|
||||
def resolve_links(context, links, current_view, current_path, parsed_query_string=None):
|
||||
"""
|
||||
Express a list of links from definition to final values
|
||||
"""
|
||||
context_links = []
|
||||
for link in links:
|
||||
# Check to see if link has conditional display
|
||||
if 'condition' in link:
|
||||
condition_result = link['condition'](context)
|
||||
else:
|
||||
condition_result = True
|
||||
|
||||
if condition_result:
|
||||
new_link = copy.copy(link)
|
||||
try:
|
||||
args, kwargs = resolve_arguments(context, link.get('args', {}))
|
||||
except VariableDoesNotExist:
|
||||
args = []
|
||||
kwargs = {}
|
||||
|
||||
if 'view' in link:
|
||||
if not link.get('dont_mark_active', False):
|
||||
new_link['active'] = link['view'] == current_view
|
||||
|
||||
try:
|
||||
if kwargs:
|
||||
new_link['url'] = reverse(link['view'], kwargs=kwargs)
|
||||
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'] = '#'
|
||||
new_link['error'] = err
|
||||
elif 'url' in link:
|
||||
if not link.get('dont_mark_active', False):
|
||||
new_link['active'] = link['url'] == current_path
|
||||
|
||||
if kwargs:
|
||||
new_link['url'] = link['url'] % kwargs
|
||||
else:
|
||||
new_link['url'] = link['url'] % args
|
||||
if link.get('keep_query', False):
|
||||
new_link['url'] = urlquote(new_link['url'], parsed_query_string)
|
||||
else:
|
||||
new_link['active'] = False
|
||||
|
||||
if 'conditional_highlight' in link:
|
||||
new_link['active'] = link['conditional_highlight'](context)
|
||||
|
||||
if 'conditional_disable' in link:
|
||||
new_link['disabled'] = link['conditional_disable'](context)
|
||||
else:
|
||||
new_link['disabled'] = False
|
||||
|
||||
if current_view in link.get('children_views', []):
|
||||
new_link['active'] = True
|
||||
|
||||
for child_url_regex in link.get('children_url_regex', []):
|
||||
if re.compile(child_url_regex).match(current_path.lstrip('/')):
|
||||
new_link['active'] = True
|
||||
|
||||
for children_view_regex in link.get('children_view_regex', []):
|
||||
if re.compile(children_view_regex).match(current_view):
|
||||
new_link['active'] = True
|
||||
|
||||
for cls in link.get('children_classes', []):
|
||||
obj, object_name = get_navigation_object(context)
|
||||
if type(obj) == cls or obj == cls:
|
||||
new_link['active'] = True
|
||||
|
||||
context_links.append(new_link)
|
||||
return context_links
|
||||
|
||||
|
||||
def get_navigation_object(context):
|
||||
try:
|
||||
object_name = Variable('navigation_object_name').resolve(context)
|
||||
except VariableDoesNotExist:
|
||||
object_name = 'object'
|
||||
|
||||
try:
|
||||
obj = Variable(object_name).resolve(context)
|
||||
except VariableDoesNotExist:
|
||||
obj = None
|
||||
|
||||
return obj, object_name
|
||||
|
||||
|
||||
def _get_object_navigation_links(context, menu_name=None, links_dict=object_navigation):
|
||||
request = Variable('request').resolve(context)
|
||||
current_path = request.META['PATH_INFO']
|
||||
current_view = resolve_to_name(current_path)
|
||||
context_links = []
|
||||
|
||||
# Don't fudge with the original global dictionary
|
||||
links_dict = links_dict.copy()
|
||||
|
||||
# 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:
|
||||
"""
|
||||
Override the navigation links dictionary with the provided
|
||||
link list
|
||||
"""
|
||||
navigation_object_links = Variable('overrided_object_links').resolve(context)
|
||||
if navigation_object_links:
|
||||
return [link for link in resolve_links(context, navigation_object_links, current_view, current_path, parsed_query_string)]
|
||||
except VariableDoesNotExist:
|
||||
pass
|
||||
|
||||
try:
|
||||
"""
|
||||
Check for and inject a temporary navigation dictionary
|
||||
"""
|
||||
temp_navigation_links = Variable('temporary_navigation_links').resolve(context)
|
||||
if temp_navigation_links:
|
||||
links_dict.update(temp_navigation_links)
|
||||
except VariableDoesNotExist:
|
||||
pass
|
||||
|
||||
try:
|
||||
links = links_dict[menu_name][current_view]['links']
|
||||
for link in resolve_links(context, links, current_view, current_path, parsed_query_string):
|
||||
context_links.append(link)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
obj, object_name = get_navigation_object(context)
|
||||
|
||||
try:
|
||||
links = links_dict[menu_name][type(obj)]['links']
|
||||
for link in resolve_links(context, links, current_view, current_path, parsed_query_string):
|
||||
context_links.append(link)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
return context_links
|
||||
|
||||
|
||||
def resolve_template_variable(context, name):
|
||||
try:
|
||||
return unescape_string_literal(name)
|
||||
except ValueError:
|
||||
#return Variable(name).resolve(context)
|
||||
#TODO: Research if should return always as a str
|
||||
return str(Variable(name).resolve(context))
|
||||
except TypeError:
|
||||
return name
|
||||
|
||||
|
||||
'''
|
||||
class GetNavigationLinks(Node):
|
||||
def __init__(self, menu_name=None, links_dict=link_binding, var_name='object_navigation_links'):
|
||||
self.menu_name = menu_name
|
||||
|
||||
@@ -50,7 +50,6 @@ setup_queue_transformation_edit = Link(text=_(u'edit'),view='setup_queue_transfo
|
||||
setup_queue_transformation_delete = Link(text=_(u'delete'),view='setup_queue_transformation_delete',args='transformation.pk',sprite='shape_square_delete')
|
||||
|
||||
bind_links([Document], [submit_document])
|
||||
|
||||
bind_links([DocumentQueue], [document_queue_disable, document_queue_enable, setup_queue_transformation_list])
|
||||
bind_links([QueueTransformation], [setup_queue_transformation_edit, setup_queue_transformation_delete])
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
<<<<<<< HEAD
|
||||
from smart_settings.api import Setting, SettingNamespace
|
||||
|
||||
namespace = SettingNamespace('ocr', _(u'OCR'), module='ocr.conf.settings')
|
||||
@@ -61,3 +62,12 @@ Setting(
|
||||
description=_(u'File path to unpaper program.'),
|
||||
exists=True
|
||||
)
|
||||
|
||||
Setting(
|
||||
namespace=namespace,
|
||||
name='PDFTOTEXT_PATH',
|
||||
global_name='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
|
||||
)
|
||||
|
||||
Binary file not shown.
@@ -4,19 +4,19 @@
|
||||
#
|
||||
# Translators:
|
||||
# <pierpaolo.baldan@gmail.com>, 2011.
|
||||
# Pierpaolo Baldan <pierpaolo.baldan@gmail.com>, 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 <roberto.rosario.gonzalez@gmail.com>\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 <pierpaolo.baldan@gmail.com>\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."
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -27,7 +28,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()
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import os
|
||||
import slate
|
||||
import logging
|
||||
import tempfile
|
||||
import subprocess
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
@@ -7,23 +10,70 @@ 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
|
||||
from ocr.conf.settings import PDFTOTEXT_PATH
|
||||
|
||||
|
||||
mimetype_registry = {}
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def register_parser(function, mimetype=None, mimetypes=None):
|
||||
if mimetypes:
|
||||
def register_parser(mimetypes, parsers):
|
||||
for mimetype in mimetypes:
|
||||
mimetype_registry[mimetype] = {'function': function}
|
||||
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[mimetype] = {'function': function}
|
||||
mimetype_registry.setdefault(mimetype, []).append(parser_instance)
|
||||
|
||||
|
||||
def pdf_parser(document_page, descriptor=None):
|
||||
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[mimetype]:
|
||||
try:
|
||||
parser.parse(document_page, descriptor)
|
||||
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
|
||||
return
|
||||
|
||||
raise ParserError('Parser list exhausted')
|
||||
except KeyError:
|
||||
raise ParserUnknownFile
|
||||
|
||||
|
||||
class Parser(object):
|
||||
"""
|
||||
Parser base class
|
||||
"""
|
||||
|
||||
def parse(self, document_page, descriptor=None):
|
||||
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(self, document_page, descriptor=None):
|
||||
logger.debug('Starting SlateParser')
|
||||
|
||||
if not descriptor:
|
||||
descriptor = document_page.document_version.open()
|
||||
|
||||
@@ -38,7 +88,11 @@ def pdf_parser(document_page, descriptor=None):
|
||||
document_page.save()
|
||||
|
||||
|
||||
def office_parser(document_page):
|
||||
class OfficeParser(Parser):
|
||||
"""
|
||||
Parser for office document formats
|
||||
"""
|
||||
def parse(self, document_page, descriptor=None):
|
||||
logger.debug('executing')
|
||||
try:
|
||||
office_converter = OfficeConverter()
|
||||
@@ -50,25 +104,66 @@ def office_parser(document_page):
|
||||
input_filepath = office_converter.output_filepath
|
||||
logger.debug('office_converter.output_filepath: %s', input_filepath)
|
||||
|
||||
pdf_parser(document_page, descriptor=open(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), mimetype=u'application/pdf')
|
||||
else:
|
||||
raise ParserError
|
||||
|
||||
except OfficeConversionError, msg:
|
||||
print msg
|
||||
logger.error(msg)
|
||||
raise ParserError
|
||||
|
||||
|
||||
def parse_document_page(document_page):
|
||||
logger.debug('executing')
|
||||
logger.debug('document_page: %s' % document_page)
|
||||
logger.debug('mimetype: %s' % document_page.document.file_mimetype)
|
||||
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)
|
||||
|
||||
try:
|
||||
mimetype_registry[document_page.document.file_mimetype]['function'](document_page)
|
||||
except KeyError:
|
||||
raise ParserUnknownFile
|
||||
def parse(self, document_page, descriptor=None):
|
||||
logger.debug('parsing PDF with PopplerParser')
|
||||
pagenum = str(document_page.page_number)
|
||||
|
||||
if descriptor:
|
||||
destination_descriptor, temp_filepath = tempfile.mkstemp(dir=TEMPORARY_DIRECTORY)
|
||||
copyfile(descriptor, temp_filepath)
|
||||
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()
|
||||
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')
|
||||
document_page.save()
|
||||
|
||||
|
||||
register_parser(mimetype=u'application/pdf', function=pdf_parser)
|
||||
register_parser(mimetypes=office_converter.CONVERTER_OFFICE_FILE_MIMETYPES, function=office_parser)
|
||||
register_parser(mimetypes=[u'application/pdf'], parsers=[PopplerParser, SlateParser])
|
||||
register_parser(mimetypes=office_converter.CONVERTER_OFFICE_FILE_MIMETYPES, parsers=[OfficeParser])
|
||||
|
||||
@@ -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
|
||||
|
||||
Binary file not shown.
@@ -4,19 +4,19 @@
|
||||
#
|
||||
# Translators:
|
||||
# <pierpaolo.baldan@gmail.com>, 2011.
|
||||
# Pierpaolo Baldan <pierpaolo.baldan@gmail.com>, 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 <roberto.rosario.gonzalez@gmail.com>\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 <pierpaolo.baldan@gmail.com>\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"
|
||||
|
||||
Binary file not shown.
@@ -7,16 +7,15 @@
|
||||
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 <pierpaolo.baldan@gmail.com>\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
|
||||
|
||||
Binary file not shown.
@@ -7,16 +7,15 @@
|
||||
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 <pierpaolo.baldan@gmail.com>\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
|
||||
|
||||
Binary file not shown.
@@ -7,16 +7,15 @@
|
||||
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 <pierpaolo.baldan@gmail.com>\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
|
||||
|
||||
Binary file not shown.
@@ -4,14 +4,15 @@
|
||||
#
|
||||
# Translators:
|
||||
# <pierpaolo.baldan@gmail.com>, 2011.
|
||||
# Pierpaolo Baldan <pierpaolo.baldan@gmail.com>, 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 <roberto.rosario.gonzalez@gmail.com>\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 <pierpaolo.baldan@gmail.com>\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"
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
@@ -4,15 +4,16 @@
|
||||
#
|
||||
# Translators:
|
||||
# <pierpaolo.baldan@gmail.com>, 2011.
|
||||
# Pierpaolo Baldan <pierpaolo.baldan@gmail.com>, 2012.
|
||||
# Roberto Rosario <roberto.rosario.gonzalez@gmail.com>, 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 <roberto.rosario.gonzalez@gmail.com>\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 <pierpaolo.baldan@gmail.com>\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"
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
@@ -7,16 +7,15 @@
|
||||
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 <pierpaolo.baldan@gmail.com>\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 <a href=\"%(LOGIN_REDIRECT_URL)s\">here</a> if redirection doesn't "
|
||||
"work."
|
||||
msgstr ""
|
||||
"Oppure click <a href=\"%(LOGIN_REDIRECT_URL)s\">qui</a> if per essere "
|
||||
"rimandato al tuo sito nel caso non funzioni."
|
||||
msgstr "Oppure click <a href=\"%(LOGIN_REDIRECT_URL)s\">qui</a> if per essere rimandato al tuo sito nel caso non funzioni."
|
||||
|
||||
#: templates/pagination/pagination.html:6
|
||||
#: templates/pagination/pagination.html:8
|
||||
|
||||
BIN
contrib/fabfile.tar.gz
Normal file
BIN
contrib/fabfile.tar.gz
Normal file
Binary file not shown.
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,24 +27,27 @@ 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)
|
||||
* Alexandru Kiss (usurel@gmail.com)
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
Translations
|
||||
@@ -56,7 +59,7 @@ Translations
|
||||
|
||||
* Russian
|
||||
|
||||
- Сергей Глита [Sergey Glita] (s.v.glita@gmail.com)
|
||||
- Sergey Glita (s.v.glita@gmail.com)
|
||||
|
||||
* Italian
|
||||
|
||||
@@ -69,9 +72,10 @@ 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)
|
||||
|
||||
|
||||
Monetary donations
|
||||
|
||||
@@ -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 <contents>` otherwise below are the different part of the documentation.
|
||||
|
||||
|
||||
@@ -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: <Your MySQL root password> 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=<Your MySQL root 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=<Your MySQL root 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 -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,19 +110,35 @@ 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::
|
||||
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
|
||||
|
||||
@@ -59,6 +151,85 @@ Execute Django's runserver command to launch a local instance of **Mayan EDMS**
|
||||
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.
|
||||
|
||||
|
||||
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
|
||||
----------
|
||||
|
||||
@@ -168,11 +339,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
|
||||
@@ -193,3 +359,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/
|
||||
|
||||
@@ -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
|
||||
|
||||
116
docs/releases/0.12.1.rst
Normal file
116
docs/releases/0.12.1.rst
Normal file
@@ -0,0 +1,116 @@
|
||||
================================
|
||||
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 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
|
||||
environments where users don't have the ability to install OS level
|
||||
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.
|
||||
|
||||
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 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
|
||||
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'. Be sure to install the
|
||||
``poppler-utils`` os package to take advantage of this new parser.
|
||||
|
||||
Changed defaults
|
||||
~~~~~~~~~~~~~~~~
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Backward incompatible changes
|
||||
=============================
|
||||
* None
|
||||
|
||||
Bugs fixed
|
||||
==========
|
||||
* Issue #25 "Office document conversion error"
|
||||
|
||||
Stuff removed
|
||||
=============
|
||||
* None
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -9,7 +9,7 @@ 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.13)
|
||||
---------------------
|
||||
@@ -17,6 +17,7 @@ Latest version (0.13)
|
||||
:maxdepth: 1
|
||||
|
||||
0.13
|
||||
0.12.1
|
||||
0.12
|
||||
|
||||
Historic changelogs
|
||||
|
||||
@@ -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
|
||||
@@ -213,6 +213,17 @@ 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
|
||||
=======
|
||||
|
||||
@@ -341,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.
|
||||
@@ -364,6 +375,16 @@ 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
|
||||
========
|
||||
|
||||
|
||||
61
fabfile/__init__.py
Normal file
61
fabfile/__init__.py
Normal file
@@ -0,0 +1,61 @@
|
||||
import sys
|
||||
|
||||
from fabric.api import task, env
|
||||
from fabric.colors import white
|
||||
|
||||
import databases as database
|
||||
import platforms as platform
|
||||
import webservers as webserver
|
||||
import django
|
||||
from conf import print_supported_configs
|
||||
from server_config import servers
|
||||
|
||||
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))
|
||||
|
||||
print_supported_configs()
|
||||
|
||||
|
||||
@task
|
||||
def install():
|
||||
"""
|
||||
Perform a complete install of Mayan EDMS on a host
|
||||
"""
|
||||
platform.install_dependencies()
|
||||
platform.install_mayan()
|
||||
platform.install_database_manager()
|
||||
database.create_database()
|
||||
django.database_config()
|
||||
django.syncdb()
|
||||
django.collectstatic()
|
||||
platform.fix_permissions()
|
||||
platform.install_webserver()
|
||||
webserver.install_site()
|
||||
webserver.restart()
|
||||
platform.post_install()
|
||||
|
||||
|
||||
@task
|
||||
def uninstall():
|
||||
"""
|
||||
Perform a complete removal of Mayan EDMS from a host
|
||||
"""
|
||||
platform.delete_mayan()
|
||||
webserver.remove_site()
|
||||
webserver.restart()
|
||||
|
||||
if env.drop_database:
|
||||
database.drop_database()
|
||||
database.drop_username()
|
||||
60
fabfile/conf.py
Normal file
60
fabfile/conf.py
Normal file
@@ -0,0 +1,60 @@
|
||||
import os
|
||||
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():
|
||||
# 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))
|
||||
|
||||
|
||||
@reduce_env
|
||||
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]
|
||||
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)')
|
||||
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]
|
||||
|
||||
env['django_database_driver'] = DJANGO_DB_DRIVERS[env.database_manager]
|
||||
|
||||
|
||||
def print_supported_configs():
|
||||
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')
|
||||
|
||||
|
||||
|
||||
|
||||
42
fabfile/databases/__init__.py
Normal file
42
fabfile/databases/__init__.py
Normal file
@@ -0,0 +1,42 @@
|
||||
from fabric.api import env, task
|
||||
from fabric.colors import green
|
||||
|
||||
from ..conf import setup_environment
|
||||
from ..literals import DB_MYSQL
|
||||
import mysql
|
||||
|
||||
|
||||
@task
|
||||
def create_database():
|
||||
"""
|
||||
Create the Mayan EDMS database
|
||||
"""
|
||||
setup_environment()
|
||||
print(green('Creating Mayan EDMS database', bold=True))
|
||||
|
||||
if env.database_manager == DB_MYSQL:
|
||||
mysql.create_database()
|
||||
|
||||
|
||||
@task
|
||||
def drop_database():
|
||||
"""
|
||||
Drop Mayan EDMS's database
|
||||
"""
|
||||
setup_environment()
|
||||
print(green('Droping Mayan EDMS database', bold=True))
|
||||
|
||||
if env.database_manager == DB_MYSQL:
|
||||
mysql.drop_database()
|
||||
|
||||
|
||||
@task
|
||||
def drop_username():
|
||||
"""
|
||||
Drop Mayan EDMS's username
|
||||
"""
|
||||
setup_environment()
|
||||
print(green('Droping Mayan EDMS username', bold=True))
|
||||
|
||||
if env.database_manager == DB_MYSQL:
|
||||
mysql.drop_username()
|
||||
30
fabfile/databases/mysql.py
Normal file
30
fabfile/databases/mysql.py
Normal file
@@ -0,0 +1,30 @@
|
||||
from fabric.api import run, env, task, settings
|
||||
from fabric.colors import green
|
||||
|
||||
|
||||
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\'@\'%(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():
|
||||
"""
|
||||
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)
|
||||
|
||||
|
||||
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)
|
||||
|
||||
34
fabfile/django/__init__.py
Normal file
34
fabfile/django/__init__.py
Normal file
@@ -0,0 +1,34 @@
|
||||
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))
|
||||
70
fabfile/literals.py
Normal file
70
fabfile/literals.py
Normal file
@@ -0,0 +1,70 @@
|
||||
OS_UBUNTU = 'ubuntu'
|
||||
OS_REDHAT = 'redhat'
|
||||
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',
|
||||
#OS_FREEBSD: 'FreeBSD',
|
||||
}
|
||||
|
||||
DEFAULT_INSTALL_PATH = {
|
||||
OS_UBUNTU: '/usr/share',
|
||||
OS_FEDORA: '/usr/share',
|
||||
OS_DEBIAN: '/usr/share',
|
||||
}
|
||||
|
||||
DEFAULT_VIRTUALENV_NAME = {
|
||||
OS_UBUNTU: 'mayan',
|
||||
OS_FEDORA: 'mayan',
|
||||
OS_DEBIAN: 'mayan',
|
||||
}
|
||||
|
||||
DEFAULT_REPOSITORY_NAME = {
|
||||
OS_UBUNTU: 'mayan',
|
||||
OS_FEDORA: 'mayan',
|
||||
OS_DEBIAN: 'mayan',
|
||||
}
|
||||
|
||||
DB_MYSQL = 'mysql'
|
||||
DB_PGSQL = 'pgsql'
|
||||
DB_SQLITE = 'sqlite'
|
||||
DB_ORACLE = 'oracle'
|
||||
|
||||
DB_CHOICES = {
|
||||
DB_MYSQL: 'MySQL',
|
||||
#DB_PGSQL: 'PostgreSQL',
|
||||
#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'
|
||||
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
|
||||
DEFAULT_DATABASE_USERNAME = 'mayan'
|
||||
DEFAULT_DATABASE_HOST = '127.0.0.1'
|
||||
DEFAULT_PASSWORD_LENGTH = 10
|
||||
100
fabfile/platforms/__init__.py
Normal file
100
fabfile/platforms/__init__.py
Normal file
@@ -0,0 +1,100 @@
|
||||
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
|
||||
|
||||
|
||||
@task
|
||||
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]:
|
||||
debian.install_dependencies()
|
||||
elif env.os == OS_FEDORA:
|
||||
fedora.install_dependencies()
|
||||
|
||||
|
||||
@task
|
||||
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]:
|
||||
linux.install_mayan()
|
||||
|
||||
|
||||
@task
|
||||
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]:
|
||||
debian.install_database_manager()
|
||||
elif env.os == OS_FEDORA:
|
||||
fedora.install_database_manager()
|
||||
|
||||
|
||||
@task
|
||||
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]:
|
||||
debian.fix_permissions()
|
||||
elif env.os == OS_FEDORA:
|
||||
fedora.fix_permissions()
|
||||
|
||||
|
||||
@task
|
||||
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]:
|
||||
debian.install_webserver()
|
||||
elif env.os == OS_FEDORA:
|
||||
fedora.install_webserver()
|
||||
|
||||
|
||||
@task
|
||||
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]:
|
||||
linux.delete_mayan()
|
||||
|
||||
|
||||
@task
|
||||
def post_install():
|
||||
"""
|
||||
Perform post install operations
|
||||
"""
|
||||
setup_environment()
|
||||
if env.os == OS_UBUNTU:
|
||||
ubuntu.post_install()
|
||||
elif env.os == OS_FEDORA:
|
||||
fedora.post_install()
|
||||
elif env.os == OS_DEBIAN:
|
||||
debian.post_install()
|
||||
50
fabfile/platforms/debian.py
Normal file
50
fabfile/platforms/debian.py
Normal file
@@ -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 python-dev')
|
||||
|
||||
|
||||
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
|
||||
62
fabfile/platforms/fedora.py
Normal file
62
fabfile/platforms/fedora.py
Normal file
@@ -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()
|
||||
20
fabfile/platforms/linux.py
Normal file
20
fabfile/platforms/linux.py
Normal file
@@ -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 %(virtualenv_path)s -Rf' % env)
|
||||
|
||||
|
||||
def install_mayan():
|
||||
"""
|
||||
Install Mayan EDMS on an Ubuntu system
|
||||
"""
|
||||
with cd(env.install_path):
|
||||
sudo('virtualenv --no-site-packages %(virtualenv_name)s' % env)
|
||||
|
||||
with cd(env.virtualenv_path):
|
||||
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)
|
||||
5
fabfile/platforms/ubuntu.py
Normal file
5
fabfile/platforms/ubuntu.py
Normal file
@@ -0,0 +1,5 @@
|
||||
def post_install():
|
||||
"""
|
||||
Post install operations on an Ubuntu system
|
||||
"""
|
||||
pass
|
||||
141
fabfile/server_config.py
Normal file
141
fabfile/server_config.py
Normal file
@@ -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
|
||||
20
fabfile/templates/apache_site
Normal file
20
fabfile/templates/apache_site
Normal file
@@ -0,0 +1,20 @@
|
||||
<VirtualHost *:80>
|
||||
# Uncomment if libapache2-mod-xsendfile is installed
|
||||
# XSendFile On
|
||||
# XSendFileAllowAbove On
|
||||
|
||||
WSGIScriptAlias / %(repository_path)s/wsgi/dispatch.wsgi
|
||||
|
||||
<Directory %(repository_path)s>
|
||||
Order deny,allow
|
||||
Allow from all
|
||||
</Directory>
|
||||
#ErrorLog /var/log/apache2/mayan_error.log
|
||||
LogLevel warn
|
||||
#CustomLog /var/log/apache2/mayan_access.log combined
|
||||
|
||||
Alias /mayan-static "%(repository_path)s/static/"
|
||||
<Location "/static">
|
||||
SetHandler None
|
||||
</Location>
|
||||
</VirtualHost>
|
||||
10
fabfile/templates/selinux.config
Normal file
10
fabfile/templates/selinux.config
Normal file
@@ -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
|
||||
55
fabfile/webservers/__init__.py
Normal file
55
fabfile/webservers/__init__.py
Normal file
@@ -0,0 +1,55 @@
|
||||
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
|
||||
|
||||
|
||||
@task
|
||||
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:
|
||||
apache.install_site()
|
||||
|
||||
|
||||
@task
|
||||
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:
|
||||
apache.remove_site()
|
||||
|
||||
|
||||
@task
|
||||
def restart():
|
||||
"""
|
||||
Restart the webserver
|
||||
"""
|
||||
setup_environment()
|
||||
print(green('Restarting the web server: %s' % env.webserver_name, bold=True))
|
||||
|
||||
if env.webserver == WEB_APACHE:
|
||||
apache.restart()
|
||||
|
||||
|
||||
@task
|
||||
def reload():
|
||||
"""
|
||||
Reload webserver configuration files
|
||||
"""
|
||||
setup_environment()
|
||||
print(green('Reloading the web server configuration files', bold=True))
|
||||
|
||||
if env.webserver == WEB_APACHE:
|
||||
apache.reload()
|
||||
50
fabfile/webservers/apache.py
Normal file
50
fabfile/webservers/apache.py
Normal file
@@ -0,0 +1,50 @@
|
||||
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, OS_DEBIAN
|
||||
|
||||
|
||||
def install_site():
|
||||
"""
|
||||
Install Mayan EDMS's site file in Apache configuration
|
||||
"""
|
||||
# TODO: configurable site name
|
||||
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:
|
||||
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
|
||||
"""
|
||||
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')
|
||||
|
||||
|
||||
def restart():
|
||||
"""
|
||||
Restart Apache
|
||||
"""
|
||||
if env.os in [OS_UBUNTU, OS_DEBIAN]:
|
||||
sudo('/etc/init.d/apache2 restart')
|
||||
elif env.os == OS_FEDORA:
|
||||
sudo('systemctl restart httpd.service')
|
||||
|
||||
|
||||
def reload():
|
||||
"""
|
||||
Reload Apache configuration files
|
||||
"""
|
||||
if env.os in [OS_UBUNTU, OS_DEBIAN]:
|
||||
sudo('/etc/init.d/apache2 reload')
|
||||
elif env.os == OS_FEDORA:
|
||||
sudo('systemctl reload httpd.service')
|
||||
3
misc/make_fabfile_tar.sh
Executable file
3
misc/make_fabfile_tar.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
find 'fabfile' -depth -name '*.pyc' -exec rm {} \;
|
||||
tar -czvf contrib/fabfile.tar.gz fabfile
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user