Initial changes to support the new Django 1.6 project structure

This commit is contained in:
Roberto Rosario
2014-06-15 13:13:21 +02:00
parent 7404e36385
commit ec1745b50b
1699 changed files with 160 additions and 73 deletions

View File

@@ -0,0 +1,89 @@
from __future__ import absolute_import
import logging
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
# from django.db.models.signals import post_save
# from django.dispatch import receiver
from acls.api import class_permissions
from documents.models import Document, DocumentVersion
from django_gpg.exceptions import GPGDecryptionError
from django_gpg.runtime import gpg
from navigation.api import register_links
from .links import (document_signature_delete, document_signature_download,
document_signature_upload, document_verify)
from .models import DocumentVersionSignature
from .permissions import (
PERMISSION_DOCUMENT_VERIFY,
PERMISSION_SIGNATURE_DELETE,
PERMISSION_SIGNATURE_DOWNLOAD,
PERMISSION_SIGNATURE_UPLOAD,
)
logger = logging.getLogger(__name__)
def document_pre_open_hook(descriptor, instance):
if DocumentVersionSignature.objects.has_embedded_signature(instance.document):
# If it has an embedded signature decrypt
try:
result = gpg.decrypt_file(descriptor, close_descriptor=False)
# gpg return a string, turn it into a file like object
except GPGDecryptionError:
# At least return the original raw content
descriptor.seek(0)
return descriptor
else:
descriptor.close()
return StringIO(result.data)
else:
# It no embedded signature pass along
# Doing this single DB lookup avoids trying to decrypt non signed
# files always, which could result in slow down for big non signed
# files
# descriptor.seek(0)
return descriptor
# try:
# result = gpg.decrypt_file(descriptor, close_descriptor=False)
# # gpg return a string, turn it into a file like object
# except GPGDecryptionError:
# # At least return the original raw content
# descriptor.seek(0)
# return descriptor
# else:
# descriptor.close()
# return StringIO(result.data)
def document_post_save_hook(instance):
if not instance.pk:
document_signature, created = DocumentVersionSignature.objects.get_or_create(
document_version=instance.latest_version,
)
# DocumentVersionSignature.objects.update_signed_state(instance.document)
# @receiver(post_save, dispatch_uid='check_document_signature_state', sender=DocumentVersion)
# def check_document_signature_state(sender, instance, **kwargs):
# if kwargs.get('created', False):
# DocumentVersionSignature.objects.signature_state(instance.document)
register_links(Document, [document_verify], menu_name='form_header')
register_links(['document_verify', 'document_signature_upload', 'document_signature_download', 'document_signature_delete'], [document_signature_upload, document_signature_download, document_signature_delete], menu_name='sidebar')
DocumentVersion.register_pre_open_hook(1, document_pre_open_hook)
DocumentVersion.register_post_save_hook(1, document_post_save_hook)
class_permissions(Document, [
PERMISSION_DOCUMENT_VERIFY,
PERMISSION_SIGNATURE_DELETE,
PERMISSION_SIGNATURE_DOWNLOAD,
PERMISSION_SIGNATURE_UPLOAD,
])

View File

@@ -0,0 +1,8 @@
from django import forms
from django.utils.translation import ugettext_lazy as _
class DetachedSignatureForm(forms.Form):
file = forms.FileField(
label=_(u'Signature file'),
)

View File

@@ -0,0 +1,25 @@
from __future__ import absolute_import
from django.utils.translation import ugettext_lazy as _
from .models import DocumentVersionSignature
from .permissions import (
PERMISSION_DOCUMENT_VERIFY,
PERMISSION_SIGNATURE_DELETE,
PERMISSION_SIGNATURE_DOWNLOAD,
PERMISSION_SIGNATURE_UPLOAD,
)
def has_embedded_signature(context):
return DocumentVersionSignature.objects.has_embedded_signature(context['object'])
def doesnt_have_detached_signature(context):
return DocumentVersionSignature.objects.has_detached_signature(context['object']) is False
document_signature_delete = {'text': _(u'delete signature'), 'view': 'document_signature_delete', 'args': 'object.pk', 'famfam': 'pencil_delete', 'permissions': [PERMISSION_SIGNATURE_DELETE], 'conditional_disable': doesnt_have_detached_signature}
document_signature_download = {'text': _(u'download signature'), 'view': 'document_signature_download', 'args': 'object.pk', 'famfam': 'disk', 'permissions': [PERMISSION_SIGNATURE_DOWNLOAD], 'conditional_disable': doesnt_have_detached_signature}
document_signature_upload = {'text': _(u'upload signature'), 'view': 'document_signature_upload', 'args': 'object.pk', 'famfam': 'pencil_add', 'permissions': [PERMISSION_SIGNATURE_UPLOAD], 'conditional_disable': has_embedded_signature}
document_verify = {'text': _(u'signatures'), 'view': 'document_verify', 'args': 'object.pk', 'famfam': 'text_signature', 'permissions': [PERMISSION_DOCUMENT_VERIFY]}

View File

@@ -0,0 +1,123 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Mohammed ALDOUB <voulnet@gmail.com>, 2013.
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2012-12-12 01:48-0400\n"
"PO-Revision-Date: 2013-01-26 08:47+0000\n"
"Last-Translator: Mohammed ALDOUB <voulnet@gmail.com>\n"
"Language-Team: Arabic (http://www.transifex.com/projects/p/mayan-edms/language/ar/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ar\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
#: __init__.py:83
msgid "upload signature"
msgstr "upload signature"
#: __init__.py:84
msgid "download signature"
msgstr "download signature"
#: __init__.py:85
msgid "signatures"
msgstr "signatures"
#: forms.py:11
msgid "Signature file"
msgstr "Signature file"
#: models.py:20
msgid "document version"
msgstr "document version"
#: models.py:21
msgid "signature file"
msgstr "signature file"
#: models.py:22
msgid "has embedded signature"
msgstr "has embedded signature"
#: models.py:37
msgid "document version signature"
msgstr "document version signature"
#: models.py:38
msgid "document version signatures"
msgstr "document version signatures"
#: permissions.py:7
msgid "Document signatures"
msgstr "Document signatures"
#: permissions.py:8
msgid "Verify document signatures"
msgstr "Verify document signatures"
#: permissions.py:9
msgid "Upload detached signatures"
msgstr "Upload detached signatures"
#: permissions.py:10
msgid "Download detached signatures"
msgstr "Download detached signatures"
#: views.py:47
#, python-format
msgid "Signature status: %(widget)s %(text)s"
msgstr "Signature status: %(widget)s %(text)s"
#: views.py:54
msgid "embedded"
msgstr "embedded"
#: views.py:56
msgid "detached"
msgstr "detached"
#: views.py:61
#, python-format
msgid "Signature ID: %s"
msgstr "Signature ID: %s"
#: views.py:62
#, python-format
msgid "Signature type: %s"
msgstr "Signature type: %s"
#: views.py:63
#, python-format
msgid "Key ID: %s"
msgstr "Key ID: %s"
#: views.py:64
#, python-format
msgid "Timestamp: %s"
msgstr "Timestamp: %s"
#: views.py:65
#, python-format
msgid "Signee: %s"
msgstr "Signee: %s"
#: views.py:70
#, python-format
msgid "signature properties for: %s"
msgstr "signature properties for: %s"
#: views.py:96
msgid "Detached signature uploaded successfully."
msgstr "Detached signature uploaded successfully."
#: views.py:105
#, python-format
msgid "Upload detached signature for: %s"
msgstr "Upload detached signature for: %s"

View File

@@ -0,0 +1,123 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# <pkoldamov@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-12-12 01:48-0400\n"
"PO-Revision-Date: 2012-12-12 06:05+0000\n"
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
"Language-Team: Bulgarian (http://www.transifex.com/projects/p/mayan-edms/language/bg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: __init__.py:83
msgid "upload signature"
msgstr "качете сигнатура"
#: __init__.py:84
msgid "download signature"
msgstr "изтеглете сигнатура"
#: __init__.py:85
msgid "signatures"
msgstr "сигнатура"
#: forms.py:11
msgid "Signature file"
msgstr "Файл със сигнатура"
#: models.py:20
msgid "document version"
msgstr "версия на документа"
#: models.py:21
msgid "signature file"
msgstr "файл със сигнатура"
#: models.py:22
msgid "has embedded signature"
msgstr "има вградена сигнатура"
#: models.py:37
msgid "document version signature"
msgstr "сигнатура за версията на документа"
#: models.py:38
msgid "document version signatures"
msgstr "сигнатури за версията на документа"
#: permissions.py:7
msgid "Document signatures"
msgstr "Сигнатури на документа"
#: permissions.py:8
msgid "Verify document signatures"
msgstr "Проверете сигнатурите на документа"
#: permissions.py:9
msgid "Upload detached signatures"
msgstr "Качете несвързаните сигнатури"
#: permissions.py:10
msgid "Download detached signatures"
msgstr "Свалете несвързаните сигнатури"
#: views.py:47
#, python-format
msgid "Signature status: %(widget)s %(text)s"
msgstr "Състояние на сигнатура: %(widget)s %(text)s"
#: views.py:54
msgid "embedded"
msgstr "вградено"
#: views.py:56
msgid "detached"
msgstr "несвързано"
#: views.py:61
#, python-format
msgid "Signature ID: %s"
msgstr "Номер на сигнатура: %s"
#: views.py:62
#, python-format
msgid "Signature type: %s"
msgstr "Вид сигнатура: %s"
#: views.py:63
#, python-format
msgid "Key ID: %s"
msgstr "Номер на ключ: %s"
#: views.py:64
#, python-format
msgid "Timestamp: %s"
msgstr "Време: %s"
#: views.py:65
#, python-format
msgid "Signee: %s"
msgstr "Подписал: %s"
#: views.py:70
#, python-format
msgid "signature properties for: %s"
msgstr "опции на сигнатурата за: %s"
#: views.py:96
msgid "Detached signature uploaded successfully."
msgstr "Несвързаните сигнатури са качени успешно."
#: views.py:105
#, python-format
msgid "Upload detached signature for: %s"
msgstr "Качване на несвързани сигнатури за: %s"

View File

@@ -0,0 +1,124 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Manticor <sl@suchreflex.de>, 2012
# tetjarediske <tetja.rediske@googlemail.com>, 2012
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-12-12 01:48-0400\n"
"PO-Revision-Date: 2014-03-12 16:11+0000\n"
"Last-Translator: yangoon <mathiasb@m9s.biz>\n"
"Language-Team: German (Germany) (http://www.transifex.com/projects/p/mayan-edms/language/de_DE/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: de_DE\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: __init__.py:83
msgid "upload signature"
msgstr "Signatur hochladen"
#: __init__.py:84
msgid "download signature"
msgstr "Signatur herunterladen"
#: __init__.py:85
msgid "signatures"
msgstr "Signaturen"
#: forms.py:11
msgid "Signature file"
msgstr "Signaturdatei"
#: models.py:20
msgid "document version"
msgstr "Dokumentenversion"
#: models.py:21
msgid "signature file"
msgstr "Signaturdatei"
#: models.py:22
msgid "has embedded signature"
msgstr "Eingebettete Signatur"
#: models.py:37
msgid "document version signature"
msgstr "Dokumentenversionssignatur"
#: models.py:38
msgid "document version signatures"
msgstr "Dokumentenversionssignaturen"
#: permissions.py:7
msgid "Document signatures"
msgstr "Dokumentensignaturen"
#: permissions.py:8
msgid "Verify document signatures"
msgstr "Dokumentensignaturen überprüfen"
#: permissions.py:9
msgid "Upload detached signatures"
msgstr "Separate Signaturen hochladen"
#: permissions.py:10
msgid "Download detached signatures"
msgstr "Separate Signaturen herunterladen"
#: views.py:47
#, python-format
msgid "Signature status: %(widget)s %(text)s"
msgstr "Signaturstatus: %(widget)s %(text)s"
#: views.py:54
msgid "embedded"
msgstr "Eingebettet"
#: views.py:56
msgid "detached"
msgstr "Separat"
#: views.py:61
#, python-format
msgid "Signature ID: %s"
msgstr "Signatur-ID: %s"
#: views.py:62
#, python-format
msgid "Signature type: %s"
msgstr "Signaturtyp: %s"
#: views.py:63
#, python-format
msgid "Key ID: %s"
msgstr "Schlüssel-ID: %s"
#: views.py:64
#, python-format
msgid "Timestamp: %s"
msgstr "Zeitstempel: %s"
#: views.py:65
#, python-format
msgid "Signee: %s"
msgstr "Unterschreibender: %s"
#: views.py:70
#, python-format
msgid "signature properties for: %s"
msgstr "Signatureigenschaften für %s"
#: views.py:96
msgid "Detached signature uploaded successfully."
msgstr "Separate Signatur erfolgreich hochgeladen."
#: views.py:105
#, python-format
msgid "Upload detached signature for: %s"
msgstr "Externe Signatur hochladen für %s"

View File

@@ -0,0 +1,122 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-01-25 20:11-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: __init__.py:83
msgid "upload signature"
msgstr ""
#: __init__.py:84
msgid "download signature"
msgstr ""
#: __init__.py:85
msgid "signatures"
msgstr ""
#: forms.py:11
msgid "Signature file"
msgstr ""
#: models.py:20
msgid "document version"
msgstr ""
#: models.py:21
msgid "signature file"
msgstr ""
#: models.py:22
msgid "has embedded signature"
msgstr ""
#: models.py:37
msgid "document version signature"
msgstr ""
#: models.py:38
msgid "document version signatures"
msgstr ""
#: permissions.py:7
msgid "Document signatures"
msgstr ""
#: permissions.py:8
msgid "Verify document signatures"
msgstr ""
#: permissions.py:9
msgid "Upload detached signatures"
msgstr ""
#: permissions.py:10
msgid "Download detached signatures"
msgstr ""
#: views.py:47
#, python-format
msgid "Signature status: %(widget)s %(text)s"
msgstr ""
#: views.py:54
msgid "embedded"
msgstr ""
#: views.py:56
msgid "detached"
msgstr ""
#: views.py:61
#, python-format
msgid "Signature ID: %s"
msgstr ""
#: views.py:62
#, python-format
msgid "Signature type: %s"
msgstr ""
#: views.py:63
#, python-format
msgid "Key ID: %s"
msgstr ""
#: views.py:64
#, python-format
msgid "Timestamp: %s"
msgstr ""
#: views.py:65
#, python-format
msgid "Signee: %s"
msgstr ""
#: views.py:70
#, python-format
msgid "signature properties for: %s"
msgstr ""
#: views.py:96
msgid "Detached signature uploaded successfully."
msgstr ""
#: views.py:105
#, python-format
msgid "Upload detached signature for: %s"
msgstr ""

View File

@@ -0,0 +1,123 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# 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-12-12 01:48-0400\n"
"PO-Revision-Date: 2012-12-12 06:05+0000\n"
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
"Language-Team: Spanish (http://www.transifex.com/projects/p/mayan-edms/language/es/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: __init__.py:83
msgid "upload signature"
msgstr "subir firma"
#: __init__.py:84
msgid "download signature"
msgstr "descargar firma"
#: __init__.py:85
msgid "signatures"
msgstr "firmas"
#: forms.py:11
msgid "Signature file"
msgstr "Archivo de firma"
#: models.py:20
msgid "document version"
msgstr "versión del documento"
#: models.py:21
msgid "signature file"
msgstr "archivo de firma"
#: models.py:22
msgid "has embedded signature"
msgstr "tiene firma integrada"
#: models.py:37
msgid "document version signature"
msgstr "firma de la versión de documento"
#: models.py:38
msgid "document version signatures"
msgstr "firmas de las versiónes de documentos"
#: permissions.py:7
msgid "Document signatures"
msgstr "Firmas de documentos"
#: permissions.py:8
msgid "Verify document signatures"
msgstr "Verificar firmas de documentos"
#: permissions.py:9
msgid "Upload detached signatures"
msgstr "Subir firmas aparte"
#: permissions.py:10
msgid "Download detached signatures"
msgstr "Descargar firmas aparte"
#: views.py:47
#, python-format
msgid "Signature status: %(widget)s %(text)s"
msgstr "Estado de la firma: %(widget)s %(text)s"
#: views.py:54
msgid "embedded"
msgstr "integrada"
#: views.py:56
msgid "detached"
msgstr "aparte"
#: views.py:61
#, python-format
msgid "Signature ID: %s"
msgstr "ID de la firma: %s"
#: views.py:62
#, python-format
msgid "Signature type: %s"
msgstr "Tipo de firma: %s"
#: views.py:63
#, python-format
msgid "Key ID: %s"
msgstr "ID de la llave: %s"
#: views.py:64
#, python-format
msgid "Timestamp: %s"
msgstr "Marca de tiempo: %s"
#: views.py:65
#, python-format
msgid "Signee: %s"
msgstr "Firmante: %s"
#: views.py:70
#, python-format
msgid "signature properties for: %s"
msgstr "propiedades de la firma para: %s"
#: views.py:96
msgid "Detached signature uploaded successfully."
msgstr "Firma aparte subida exitosamente."
#: views.py:105
#, python-format
msgid "Upload detached signature for: %s"
msgstr "Subir firma aparte para: %s"

View File

@@ -0,0 +1,123 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Pierre Lhoste <peter.cathbad.host@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-12-12 01:48-0400\n"
"PO-Revision-Date: 2012-12-12 06:05+0000\n"
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
"Language-Team: French (http://www.transifex.com/projects/p/mayan-edms/language/fr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: fr\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: __init__.py:83
msgid "upload signature"
msgstr "importer une signature"
#: __init__.py:84
msgid "download signature"
msgstr "télécharger une signature"
#: __init__.py:85
msgid "signatures"
msgstr "signatures"
#: forms.py:11
msgid "Signature file"
msgstr "Fichier de signature"
#: models.py:20
msgid "document version"
msgstr "version du document"
#: models.py:21
msgid "signature file"
msgstr "fichier de signature"
#: models.py:22
msgid "has embedded signature"
msgstr "possède une signature intégrée"
#: models.py:37
msgid "document version signature"
msgstr "signature de la version du document"
#: models.py:38
msgid "document version signatures"
msgstr "signatures pour la version du document"
#: permissions.py:7
msgid "Document signatures"
msgstr "Signatures du document"
#: permissions.py:8
msgid "Verify document signatures"
msgstr "Vérifier les signatures du document"
#: permissions.py:9
msgid "Upload detached signatures"
msgstr "Importer des signatures externes"
#: permissions.py:10
msgid "Download detached signatures"
msgstr "Télécharger des signatures externes"
#: views.py:47
#, python-format
msgid "Signature status: %(widget)s %(text)s"
msgstr "Statut de la signature: %(widget)s %(text)s"
#: views.py:54
msgid "embedded"
msgstr "intégré"
#: views.py:56
msgid "detached"
msgstr "externe"
#: views.py:61
#, python-format
msgid "Signature ID: %s"
msgstr "ID de signature: %s"
#: views.py:62
#, python-format
msgid "Signature type: %s"
msgstr "Type de signature: %s"
#: views.py:63
#, python-format
msgid "Key ID: %s"
msgstr "ID de clé: %s"
#: views.py:64
#, python-format
msgid "Timestamp: %s"
msgstr "Horodatage: %s"
#: views.py:65
#, python-format
msgid "Signee: %s"
msgstr "Signataire: %s"
#: views.py:70
#, python-format
msgid "signature properties for: %s"
msgstr "Propriétés de signature pour: %s"
#: views.py:96
msgid "Detached signature uploaded successfully."
msgstr "Signature externe importée avec succès"
#: views.py:105
#, python-format
msgid "Upload detached signature for: %s"
msgstr "Importer la signature externe pour: %s"

View File

@@ -0,0 +1,124 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Carlo Zanatto <>, 2012.
# 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-12-12 01:48-0400\n"
"PO-Revision-Date: 2012-12-12 06:05+0000\n"
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
"Language-Team: Italian (http://www.transifex.com/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
msgid "upload signature"
msgstr "aggiorna firma"
#: __init__.py:84
msgid "download signature"
msgstr "scarica firma"
#: __init__.py:85
msgid "signatures"
msgstr "firma"
#: forms.py:11
msgid "Signature file"
msgstr "File della firma"
#: models.py:20
msgid "document version"
msgstr "versione del documento"
#: models.py:21
msgid "signature file"
msgstr "file della firma"
#: models.py:22
msgid "has embedded signature"
msgstr "ha incorporato la firma"
#: models.py:37
msgid "document version signature"
msgstr "versione della firma del documento"
#: models.py:38
msgid "document version signatures"
msgstr "versione delle firme documento "
#: permissions.py:7
msgid "Document signatures"
msgstr "Firme documento"
#: permissions.py:8
msgid "Verify document signatures"
msgstr "Verifica la firma del documento"
#: permissions.py:9
msgid "Upload detached signatures"
msgstr "Carica firme separatamente"
#: permissions.py:10
msgid "Download detached signatures"
msgstr "Scarica firme separatamente"
#: views.py:47
#, python-format
msgid "Signature status: %(widget)s %(text)s"
msgstr "Status della firma: %(widget)s %(text)s"
#: views.py:54
msgid "embedded"
msgstr "incorporato"
#: views.py:56
msgid "detached"
msgstr "scaduto"
#: views.py:61
#, python-format
msgid "Signature ID: %s"
msgstr "ID Firma: %s"
#: views.py:62
#, python-format
msgid "Signature type: %s"
msgstr "Tipo di firma: %s"
#: views.py:63
#, python-format
msgid "Key ID: %s"
msgstr "Chiave ID: %s"
#: views.py:64
#, python-format
msgid "Timestamp: %s"
msgstr "Timestamp: %s"
#: views.py:65
#, python-format
msgid "Signee: %s"
msgstr "Signee: %s"
#: views.py:70
#, python-format
msgid "signature properties for: %s"
msgstr "Proprietà per la firma: %s"
#: views.py:96
msgid "Detached signature uploaded successfully."
msgstr "Firma scaduta aggiornata con successo."
#: views.py:105
#, python-format
msgid "Upload detached signature for: %s"
msgstr "Aggiornata firma scaduta per: %s"

View File

@@ -0,0 +1,122 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2012-12-12 01:48-0400\n"
"PO-Revision-Date: 2012-12-12 06:05+0000\n"
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
"Language-Team: Dutch (Netherlands) (http://www.transifex.com/projects/p/mayan-edms/language/nl_NL/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: nl_NL\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: __init__.py:83
msgid "upload signature"
msgstr ""
#: __init__.py:84
msgid "download signature"
msgstr ""
#: __init__.py:85
msgid "signatures"
msgstr ""
#: forms.py:11
msgid "Signature file"
msgstr ""
#: models.py:20
msgid "document version"
msgstr ""
#: models.py:21
msgid "signature file"
msgstr ""
#: models.py:22
msgid "has embedded signature"
msgstr ""
#: models.py:37
msgid "document version signature"
msgstr ""
#: models.py:38
msgid "document version signatures"
msgstr ""
#: permissions.py:7
msgid "Document signatures"
msgstr ""
#: permissions.py:8
msgid "Verify document signatures"
msgstr ""
#: permissions.py:9
msgid "Upload detached signatures"
msgstr ""
#: permissions.py:10
msgid "Download detached signatures"
msgstr ""
#: views.py:47
#, python-format
msgid "Signature status: %(widget)s %(text)s"
msgstr ""
#: views.py:54
msgid "embedded"
msgstr ""
#: views.py:56
msgid "detached"
msgstr ""
#: views.py:61
#, python-format
msgid "Signature ID: %s"
msgstr ""
#: views.py:62
#, python-format
msgid "Signature type: %s"
msgstr ""
#: views.py:63
#, python-format
msgid "Key ID: %s"
msgstr ""
#: views.py:64
#, python-format
msgid "Timestamp: %s"
msgstr ""
#: views.py:65
#, python-format
msgid "Signee: %s"
msgstr ""
#: views.py:70
#, python-format
msgid "signature properties for: %s"
msgstr ""
#: views.py:96
msgid "Detached signature uploaded successfully."
msgstr ""
#: views.py:105
#, python-format
msgid "Upload detached signature for: %s"
msgstr ""

View File

@@ -0,0 +1,123 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# <winterfall24@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-12-12 01:48-0400\n"
"PO-Revision-Date: 2012-12-12 06:05+0000\n"
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
"Language-Team: Polish (http://www.transifex.com/projects/p/mayan-edms/language/pl/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pl\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#: __init__.py:83
msgid "upload signature"
msgstr "upload signature"
#: __init__.py:84
msgid "download signature"
msgstr "download signature"
#: __init__.py:85
msgid "signatures"
msgstr "signatures"
#: forms.py:11
msgid "Signature file"
msgstr "Signature file"
#: models.py:20
msgid "document version"
msgstr "document version"
#: models.py:21
msgid "signature file"
msgstr "signature file"
#: models.py:22
msgid "has embedded signature"
msgstr "has embedded signature"
#: models.py:37
msgid "document version signature"
msgstr "document version signature"
#: models.py:38
msgid "document version signatures"
msgstr "document version signatures"
#: permissions.py:7
msgid "Document signatures"
msgstr "Document signatures"
#: permissions.py:8
msgid "Verify document signatures"
msgstr "Verify document signatures"
#: permissions.py:9
msgid "Upload detached signatures"
msgstr "Upload detached signatures"
#: permissions.py:10
msgid "Download detached signatures"
msgstr "Download detached signatures"
#: views.py:47
#, python-format
msgid "Signature status: %(widget)s %(text)s"
msgstr "Signature status: %(widget)s %(text)s"
#: views.py:54
msgid "embedded"
msgstr "embedded"
#: views.py:56
msgid "detached"
msgstr "detached"
#: views.py:61
#, python-format
msgid "Signature ID: %s"
msgstr "Signature ID: %s"
#: views.py:62
#, python-format
msgid "Signature type: %s"
msgstr "Signature type: %s"
#: views.py:63
#, python-format
msgid "Key ID: %s"
msgstr "Key ID: %s"
#: views.py:64
#, python-format
msgid "Timestamp: %s"
msgstr "Timestamp: %s"
#: views.py:65
#, python-format
msgid "Signee: %s"
msgstr "Signee: %s"
#: views.py:70
#, python-format
msgid "signature properties for: %s"
msgstr "signature properties for: %s"
#: views.py:96
msgid "Detached signature uploaded successfully."
msgstr "Detached signature uploaded successfully."
#: views.py:105
#, python-format
msgid "Upload detached signature for: %s"
msgstr "Upload detached signature for: %s"

View File

@@ -0,0 +1,123 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Vítor Figueiró <vfigueiro@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-12-12 01:48-0400\n"
"PO-Revision-Date: 2012-12-12 06:05+0000\n"
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
"Language-Team: Portuguese (http://www.transifex.com/projects/p/mayan-edms/language/pt/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pt\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: __init__.py:83
msgid "upload signature"
msgstr "enviar assinatura"
#: __init__.py:84
msgid "download signature"
msgstr "descarregar assinatura"
#: __init__.py:85
msgid "signatures"
msgstr "assinaturas"
#: forms.py:11
msgid "Signature file"
msgstr "Ficheiro de assinatura"
#: models.py:20
msgid "document version"
msgstr "versão do documento"
#: models.py:21
msgid "signature file"
msgstr "ficheiro de assinatura"
#: models.py:22
msgid "has embedded signature"
msgstr "tem assinatura embutida"
#: models.py:37
msgid "document version signature"
msgstr "assinatura da versão do documento"
#: models.py:38
msgid "document version signatures"
msgstr "assinaturas da versão do documento"
#: permissions.py:7
msgid "Document signatures"
msgstr "Assinaturas do documento"
#: permissions.py:8
msgid "Verify document signatures"
msgstr "Verificar as assinaturas do documento"
#: permissions.py:9
msgid "Upload detached signatures"
msgstr "Enviar assinaturas avulsas"
#: permissions.py:10
msgid "Download detached signatures"
msgstr "Descarregar assinaturas avulsas"
#: views.py:47
#, python-format
msgid "Signature status: %(widget)s %(text)s"
msgstr "Estado da assinatura: %(widget)s %(text)s"
#: views.py:54
msgid "embedded"
msgstr "embutido"
#: views.py:56
msgid "detached"
msgstr "avulso"
#: views.py:61
#, python-format
msgid "Signature ID: %s"
msgstr "ID da assinatura: %s"
#: views.py:62
#, python-format
msgid "Signature type: %s"
msgstr "Tipo de assinatura: %s"
#: views.py:63
#, python-format
msgid "Key ID: %s"
msgstr "ID da chave: %s"
#: views.py:64
#, python-format
msgid "Timestamp: %s"
msgstr "Data/hora: %s"
#: views.py:65
#, python-format
msgid "Signee: %s"
msgstr "Assinado por: %s"
#: views.py:70
#, python-format
msgid "signature properties for: %s"
msgstr "propriedades da assinatura para: %s"
#: views.py:96
msgid "Detached signature uploaded successfully."
msgstr "Assinatura avulsa enviada com sucesso."
#: views.py:105
#, python-format
msgid "Upload detached signature for: %s"
msgstr "Envio de assinatura avulsa para: %s"

View File

@@ -0,0 +1,122 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2012-12-12 01:48-0400\n"
"PO-Revision-Date: 2012-12-12 06:05+0000\n"
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
"Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/mayan-edms/language/pt_BR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pt_BR\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: __init__.py:83
msgid "upload signature"
msgstr "upload do assinatura"
#: __init__.py:84
msgid "download signature"
msgstr "download do assinatura"
#: __init__.py:85
msgid "signatures"
msgstr "assinaturas"
#: forms.py:11
msgid "Signature file"
msgstr "Arquivo de assinatura"
#: models.py:20
msgid "document version"
msgstr "versão do documento"
#: models.py:21
msgid "signature file"
msgstr "arquivo do assinatura"
#: models.py:22
msgid "has embedded signature"
msgstr ""
#: models.py:37
msgid "document version signature"
msgstr "assinatura do versão do documento"
#: models.py:38
msgid "document version signatures"
msgstr "assinaturas de versão de documentos"
#: permissions.py:7
msgid "Document signatures"
msgstr "Assinaturas de documentos"
#: permissions.py:8
msgid "Verify document signatures"
msgstr "Verificar as assinaturas de documentos"
#: permissions.py:9
msgid "Upload detached signatures"
msgstr "Upload de assinaturas destacadas"
#: permissions.py:10
msgid "Download detached signatures"
msgstr "Download assinaturas destacadas"
#: views.py:47
#, python-format
msgid "Signature status: %(widget)s %(text)s"
msgstr "Status da assinatura: %(widget)s %(text)s"
#: views.py:54
msgid "embedded"
msgstr "embutido"
#: views.py:56
msgid "detached"
msgstr "destacado"
#: views.py:61
#, python-format
msgid "Signature ID: %s"
msgstr "ID assinatura: %s"
#: views.py:62
#, python-format
msgid "Signature type: %s"
msgstr "Tipo de assinatura: %s"
#: views.py:63
#, python-format
msgid "Key ID: %s"
msgstr "ID da chave: %s"
#: views.py:64
#, python-format
msgid "Timestamp: %s"
msgstr "Timestamp: %s"
#: views.py:65
#, python-format
msgid "Signee: %s"
msgstr "Signee: %s"
#: views.py:70
#, python-format
msgid "signature properties for: %s"
msgstr "propriedades da assinatura para: %s"
#: views.py:96
msgid "Detached signature uploaded successfully."
msgstr "Assinatura separado enviado com sucesso."
#: views.py:105
#, python-format
msgid "Upload detached signature for: %s"
msgstr "Upload de assinatura separada para: %s"

View File

@@ -0,0 +1,123 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Sergey Glita <gsv70@mail.ru>, 2012.
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2012-12-12 01:48-0400\n"
"PO-Revision-Date: 2012-12-12 06:05+0000\n"
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
"Language-Team: Russian (http://www.transifex.com/projects/p/mayan-edms/language/ru/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ru\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#: __init__.py:83
msgid "upload signature"
msgstr "выложить подпись"
#: __init__.py:84
msgid "download signature"
msgstr "скачать подпись"
#: __init__.py:85
msgid "signatures"
msgstr "подписи"
#: forms.py:11
msgid "Signature file"
msgstr "Файл подписи"
#: models.py:20
msgid "document version"
msgstr "версия документа"
#: models.py:21
msgid "signature file"
msgstr "файл подписи"
#: models.py:22
msgid "has embedded signature"
msgstr "имеет встроенную подпись"
#: models.py:37
msgid "document version signature"
msgstr "подпись версии документа"
#: models.py:38
msgid "document version signatures"
msgstr "подписи версии документа"
#: permissions.py:7
msgid "Document signatures"
msgstr "Подписи документа"
#: permissions.py:8
msgid "Verify document signatures"
msgstr "Проверить подпись документа"
#: permissions.py:9
msgid "Upload detached signatures"
msgstr "Выложить отделённые подписи"
#: permissions.py:10
msgid "Download detached signatures"
msgstr "Скачать отделенные подписи"
#: views.py:47
#, python-format
msgid "Signature status: %(widget)s %(text)s"
msgstr "Статус подписи: %(widget)s %(text)s"
#: views.py:54
msgid "embedded"
msgstr "присоединён"
#: views.py:56
msgid "detached"
msgstr "отделён"
#: views.py:61
#, python-format
msgid "Signature ID: %s"
msgstr "Подпись ID: %s"
#: views.py:62
#, python-format
msgid "Signature type: %s"
msgstr "Тип подписи: %s"
#: views.py:63
#, python-format
msgid "Key ID: %s"
msgstr "ID ключа: %s"
#: views.py:64
#, python-format
msgid "Timestamp: %s"
msgstr "Отметка времени: %s"
#: views.py:65
#, python-format
msgid "Signee: %s"
msgstr "Подписано: %s"
#: views.py:70
#, python-format
msgid "signature properties for: %s"
msgstr "свойства подписи для %s"
#: views.py:96
msgid "Detached signature uploaded successfully."
msgstr "Отделённая подпись выложена."
#: views.py:105
#, python-format
msgid "Upload detached signature for: %s"
msgstr "Выложить отделённую подпись для %s"

View File

@@ -0,0 +1,122 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2012-12-12 01:48-0400\n"
"PO-Revision-Date: 2012-12-12 06:05+0000\n"
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
"Language-Team: Slovenian (Slovenia) (http://www.transifex.com/projects/p/mayan-edms/language/sl_SI/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: sl_SI\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n"
#: __init__.py:83
msgid "upload signature"
msgstr ""
#: __init__.py:84
msgid "download signature"
msgstr ""
#: __init__.py:85
msgid "signatures"
msgstr ""
#: forms.py:11
msgid "Signature file"
msgstr ""
#: models.py:20
msgid "document version"
msgstr ""
#: models.py:21
msgid "signature file"
msgstr ""
#: models.py:22
msgid "has embedded signature"
msgstr ""
#: models.py:37
msgid "document version signature"
msgstr ""
#: models.py:38
msgid "document version signatures"
msgstr ""
#: permissions.py:7
msgid "Document signatures"
msgstr ""
#: permissions.py:8
msgid "Verify document signatures"
msgstr ""
#: permissions.py:9
msgid "Upload detached signatures"
msgstr ""
#: permissions.py:10
msgid "Download detached signatures"
msgstr ""
#: views.py:47
#, python-format
msgid "Signature status: %(widget)s %(text)s"
msgstr ""
#: views.py:54
msgid "embedded"
msgstr ""
#: views.py:56
msgid "detached"
msgstr ""
#: views.py:61
#, python-format
msgid "Signature ID: %s"
msgstr ""
#: views.py:62
#, python-format
msgid "Signature type: %s"
msgstr ""
#: views.py:63
#, python-format
msgid "Key ID: %s"
msgstr ""
#: views.py:64
#, python-format
msgid "Timestamp: %s"
msgstr ""
#: views.py:65
#, python-format
msgid "Signee: %s"
msgstr ""
#: views.py:70
#, python-format
msgid "signature properties for: %s"
msgstr ""
#: views.py:96
msgid "Detached signature uploaded successfully."
msgstr ""
#: views.py:105
#, python-format
msgid "Upload detached signature for: %s"
msgstr ""

View File

@@ -0,0 +1,123 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Trung Phan Minh <navmobile@gmail.com>, 2013.
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2012-12-12 01:48-0400\n"
"PO-Revision-Date: 2013-01-25 08:02+0000\n"
"Last-Translator: trungpm <navmobile@gmail.com>\n"
"Language-Team: Vietnamese (Viet Nam) (http://www.transifex.com/projects/p/mayan-edms/language/vi_VN/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: vi_VN\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: __init__.py:83
msgid "upload signature"
msgstr "tải lên chữ kí"
#: __init__.py:84
msgid "download signature"
msgstr "tải xuống chữ kí"
#: __init__.py:85
msgid "signatures"
msgstr "chữ kí"
#: forms.py:11
msgid "Signature file"
msgstr "File lưu chữ kí"
#: models.py:20
msgid "document version"
msgstr "phiên bản tài liệu"
#: models.py:21
msgid "signature file"
msgstr "file chữ kí"
#: models.py:22
msgid "has embedded signature"
msgstr "has embedded signature"
#: models.py:37
msgid "document version signature"
msgstr "chữ kí phiên bản tài liệu"
#: models.py:38
msgid "document version signatures"
msgstr "chữ kí phiên bản tài liệu"
#: permissions.py:7
msgid "Document signatures"
msgstr "Chữ kí tài liệu"
#: permissions.py:8
msgid "Verify document signatures"
msgstr "xác nhận chữ kí tài liệu"
#: permissions.py:9
msgid "Upload detached signatures"
msgstr "Tải lên chữ kí đã tách ra"
#: permissions.py:10
msgid "Download detached signatures"
msgstr "ống chữ kí đã tách ra"
#: views.py:47
#, python-format
msgid "Signature status: %(widget)s %(text)s"
msgstr "Trạng thái kí: %(widget)s %(text)s"
#: views.py:54
msgid "embedded"
msgstr "đã nhúng"
#: views.py:56
msgid "detached"
msgstr "đã tách ra"
#: views.py:61
#, python-format
msgid "Signature ID: %s"
msgstr "ID chữ kí: %s"
#: views.py:62
#, python-format
msgid "Signature type: %s"
msgstr "Kiểu chũ kí: %s"
#: views.py:63
#, python-format
msgid "Key ID: %s"
msgstr "Key ID: %s"
#: views.py:64
#, python-format
msgid "Timestamp: %s"
msgstr "Thời gian: %s"
#: views.py:65
#, python-format
msgid "Signee: %s"
msgstr "Người kí: %s"
#: views.py:70
#, python-format
msgid "signature properties for: %s"
msgstr "signature properties for: %s"
#: views.py:96
msgid "Detached signature uploaded successfully."
msgstr "Detached signature uploaded successfully."
#: views.py:105
#, python-format
msgid "Upload detached signature for: %s"
msgstr "Upload detached signature for: %s"

View File

@@ -0,0 +1,80 @@
import logging
from django.db import models
from django_gpg.runtime import gpg
from django_gpg.exceptions import GPGVerificationError
logger = logging.getLogger(__name__)
class DocumentVersionSignatureManager(models.Manager):
def get_document_signature(self, document):
document_signature, created = self.model.objects.get_or_create(
document_version=document.latest_version,
)
return document_signature
def add_detached_signature(self, document, detached_signature):
document_signature = self.get_document_signature(document)
if document_signature.has_embedded_signature:
raise Exception('document already has an embedded signature')
else:
if document_signature.signature_file:
logger.debug('Existing detached signature')
document_signature.delete_detached_signature_file()
document_signature.signature_file = None
document_signature.save()
document_signature.signature_file = detached_signature
document_signature.save()
def has_detached_signature(self, document):
document_signature = self.get_document_signature(document)
if document_signature.signature_file:
return True
else:
return False
def has_embedded_signature(self, document):
logger.debug('document: %s' % document)
document_signature = self.get_document_signature(document)
return document_signature.has_embedded_signature
def detached_signature(self, document):
document_signature = self.get_document_signature(document)
return document_signature.signature_file.storage.open(document_signature.signature_file.path)
def verify_signature(self, document):
document_descriptor = document.open(raw=True)
detached_signature = None
if self.has_detached_signature(document):
logger.debug('has detached signature')
detached_signature = self.detached_signature(document)
args = (document_descriptor, detached_signature)
else:
args = (document_descriptor,)
try:
return gpg.verify_file(*args, fetch_key=True)
except GPGVerificationError:
return None
finally:
document_descriptor.close()
if detached_signature:
detached_signature.close()
def clear_detached_signature(self, document):
document_signature = self.get_document_signature(document)
if not document_signature.signature_file:
raise Exception('document doesn\'t have a detached signature')
document_signature.delete_detached_signature_file()
document_signature.signature_file = None
document_signature.save()

View File

@@ -0,0 +1,140 @@
# encoding: 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):
# Adding model 'DocumentVersionSignature'
db.create_table('document_signatures_documentversionsignature', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('document_version', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['documents.DocumentVersion'])),
('signature_state', self.gf('django.db.models.fields.CharField')(max_length=16, null=True, blank=True)),
('signature_file', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True, blank=True)),
))
db.send_create_signal('document_signatures', ['DocumentVersionSignature'])
def backwards(self, orm):
# Deleting model 'DocumentVersionSignature'
db.delete_table('document_signatures_documentversionsignature')
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'})
},
'document_signatures.documentversionsignature': {
'Meta': {'object_name': 'DocumentVersionSignature'},
'document_version': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['documents.DocumentVersion']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'signature_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'signature_state': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'blank': 'True'})
},
'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.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.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', [], {'default': "''", 'max_length': '64'}),
'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', [], {'default': "''", 'max_length': '64'}),
'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'}),
'signature_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'signature_state': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'blank': 'True'}),
'timestamp': ('django.db.models.fields.DateTimeField', [], {})
},
'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', 'db_index': 'True'})
},
'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 = ['document_signatures']

View File

@@ -0,0 +1,145 @@
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models
class Migration(DataMigration):
depends_on = (
('documents', '0012_auto__add_field_documentversion_signature_file'),
)
def forwards(self, orm):
for document_version in orm['documents.DocumentVersion'].objects.all():
if document_version.signature_state or document_version.signature_file:
document_signature = orm.DocumentVersionSignature(
document_version=document_version,
signature_state=document_version.signature_state,
signature_file=document_version.signature_file,
)
document_signature.save()
def backwards(self, orm):
for document_signature in orm.DocumentVersionSignature.objects.all():
document_version = document_signature.document_version
document_version.signature_state=document_signature.signature_state
document_version.signature_file=document_signature.signature_file
document_version.save()
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'})
},
'document_signatures.documentversionsignature': {
'Meta': {'object_name': 'DocumentVersionSignature'},
'document_version': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['documents.DocumentVersion']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'signature_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'signature_state': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'blank': 'True'})
},
'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.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.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', [], {'default': "''", 'max_length': '64'}),
'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', [], {'default': "''", 'max_length': '64'}),
'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'}),
'signature_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'signature_state': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'blank': 'True'}),
'timestamp': ('django.db.models.fields.DateTimeField', [], {})
},
'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', 'db_index': 'True'})
},
'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 = ['document_signatures']

View File

@@ -0,0 +1,133 @@
# encoding: 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):
# Adding field 'DocumentVersionSignature.has_embedded_signature'
db.add_column('document_signatures_documentversionsignature', 'has_embedded_signature', self.gf('django.db.models.fields.BooleanField')(default=False), keep_default=False)
def backwards(self, orm):
# Deleting field 'DocumentVersionSignature.has_embedded_signature'
db.delete_column('document_signatures_documentversionsignature', 'has_embedded_signature')
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'})
},
'document_signatures.documentversionsignature': {
'Meta': {'object_name': 'DocumentVersionSignature'},
'document_version': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['documents.DocumentVersion']"}),
'has_embedded_signature': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'signature_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'signature_state': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'blank': 'True'})
},
'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.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.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', [], {'default': "''", 'max_length': '64'}),
'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', [], {'default': "''", 'max_length': '64'}),
'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', [], {})
},
'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', 'db_index': 'True'})
},
'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 = ['document_signatures']

View File

@@ -0,0 +1,136 @@
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models
class Migration(DataMigration):
def forwards(self, orm):
for document_signature in orm.DocumentVersionSignature.objects.all():
if document_signature.signature_state:
document_signature.has_embedded_signature = True
else:
document_signature.has_embedded_signature = False
document_signature.save()
def backwards(self, orm):
# The content of signature_state is lost during the forward migration
# No way to revert
raise RuntimeError("Cannot reverse this migration.")
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'})
},
'document_signatures.documentversionsignature': {
'Meta': {'object_name': 'DocumentVersionSignature'},
'document_version': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['documents.DocumentVersion']"}),
'has_embedded_signature': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'signature_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'signature_state': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'blank': 'True'})
},
'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.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.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', [], {'default': "''", 'max_length': '64'}),
'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', [], {'default': "''", 'max_length': '64'}),
'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', [], {})
},
'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', 'db_index': 'True'})
},
'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 = ['document_signatures']

View File

@@ -0,0 +1,132 @@
# encoding: 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):
# Deleting field 'DocumentVersionSignature.signature_state'
db.delete_column('document_signatures_documentversionsignature', 'signature_state')
def backwards(self, orm):
# Adding field 'DocumentVersionSignature.signature_state'
db.add_column('document_signatures_documentversionsignature', 'signature_state', self.gf('django.db.models.fields.CharField')(max_length=16, null=True, blank=True), keep_default=False)
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'})
},
'document_signatures.documentversionsignature': {
'Meta': {'object_name': 'DocumentVersionSignature'},
'document_version': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['documents.DocumentVersion']"}),
'has_embedded_signature': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'signature_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
},
'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.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.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', [], {'default': "''", 'max_length': '64'}),
'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', [], {'default': "''", 'max_length': '64'}),
'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', [], {})
},
'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', 'db_index': 'True'})
},
'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 = ['document_signatures']

View File

@@ -0,0 +1,38 @@
from __future__ import absolute_import
import logging
from django.db import models
from django.utils.translation import ugettext_lazy as _
from documents.models import DocumentVersion, get_filename_from_uuid
from documents.conf.settings import STORAGE_BACKEND
from django_gpg.runtime import gpg
from .managers import DocumentVersionSignatureManager
logger = logging.getLogger(__name__)
class DocumentVersionSignature(models.Model):
"""
Model that describes a document version signature properties
"""
document_version = models.ForeignKey(DocumentVersion, verbose_name=_(u'document version'), editable=False)
signature_file = models.FileField(blank=True, null=True, upload_to=get_filename_from_uuid, storage=STORAGE_BACKEND(), verbose_name=_(u'signature file'), editable=False)
has_embedded_signature = models.BooleanField(default=False, verbose_name=_(u'has embedded signature'), editable=False)
objects = DocumentVersionSignatureManager()
def delete_detached_signature_file(self):
self.signature_file.storage.delete(self.signature_file.path)
def save(self, *args, **kwargs):
if not self.pk:
descriptor = self.document_version.open(raw=True)
self.has_embedded_signature = gpg.has_embedded_signature(descriptor)
descriptor.close()
super(DocumentVersionSignature, self).save(*args, **kwargs)
class Meta:
verbose_name = _(u'document version signature')
verbose_name_plural = _(u'document version signatures')

View File

@@ -0,0 +1,11 @@
from __future__ import absolute_import
from django.utils.translation import ugettext_lazy as _
from permissions.models import PermissionNamespace, Permission
document_signatures_namespace = PermissionNamespace('document_signatures', _(u'Document signatures'))
PERMISSION_DOCUMENT_VERIFY = Permission.objects.register(document_signatures_namespace, 'document_verify', _(u'Verify document signatures'))
PERMISSION_SIGNATURE_DELETE = Permission.objects.register(document_signatures_namespace, 'signature_delete', _(u'Delete detached signatures'))
PERMISSION_SIGNATURE_DOWNLOAD = Permission.objects.register(document_signatures_namespace, 'signature_download', _(u'Download detached signatures'))
PERMISSION_SIGNATURE_UPLOAD = Permission.objects.register(document_signatures_namespace, 'signature_upload', _(u'Upload detached signatures'))

View File

@@ -0,0 +1,71 @@
from __future__ import absolute_import
import os
from django.utils import unittest
from django.conf import settings
from django.core.files.base import File
from django_gpg.api import SIGNATURE_STATE_VALID
from documents.models import Document, DocumentType
from documents.literals import VERSION_UPDATE_MAJOR, RELEASE_LEVEL_FINAL
from .models import DocumentVersionSignature
class DocumentTestCase(unittest.TestCase):
def setUp(self):
self.document_type = DocumentType(name='test doc type')
self.document_type.save()
self.document = Document(
document_type=self.document_type,
description='description',
)
self.document.save()
file_object = open(os.path.join(settings.PROJECT_ROOT, 'contrib', 'mayan_11_1.pdf'))
new_version = self.document.new_version(file=File(file_object, name='mayan_11_1.pdf'))
file_object.close()
def test_document_no_signature(self):
self.failUnlessEqual(DocumentVersionSignature.objects.has_detached_signature(self.document), False)
def test_new_document_version_signed(self):
file_object = open(os.path.join(settings.PROJECT_ROOT, 'contrib', 'mayan_11_1.pdf.gpg'))
new_version_data = {
'comment': 'test comment 1',
'version_update': VERSION_UPDATE_MAJOR,
'release_level': RELEASE_LEVEL_FINAL,
'serial': 0,
}
self.failUnlessEqual(DocumentVersionSignature.objects.has_detached_signature(self.document), False)
# self.failUnlessEqual(DocumentVersionSignature.objects.verify_signature(self.document).status, SIGNATURE_STATE_VALID)
# TODO: verify_signature is failing, check
def test_detached_signatures(self):
new_version_data = {
'comment': 'test comment 2',
'version_update': VERSION_UPDATE_MAJOR,
'release_level': RELEASE_LEVEL_FINAL,
'serial': 0,
}
file_object = open(os.path.join(settings.PROJECT_ROOT, 'contrib', 'mayan_11_1.pdf'))
new_version = self.document.new_version(file=File(file_object), **new_version_data)
file_object.close()
# GPGVerificationError
self.failUnlessEqual(DocumentVersionSignature.objects.verify_signature(self.document), None)
file_object = open(os.path.join(settings.PROJECT_ROOT, 'contrib', 'mayan_11_1.pdf.sig'), 'rb')
DocumentVersionSignature.objects.add_detached_signature(self.document, File(file_object))
file_object.close()
self.failUnlessEqual(DocumentVersionSignature.objects.has_detached_signature(self.document), True)
# self.failUnlessEqual(DocumentVersionSignature.objects.verify_signature(self.document).status, SIGNATURE_STATE_VALID)
# TODO: verify_signature is failing, check
def tearDown(self):
self.document.delete()
self.document_type.delete()

View File

@@ -0,0 +1,8 @@
from django.conf.urls.defaults import patterns, url
urlpatterns = patterns('document_signatures.views',
url(r'^verify/(?P<document_pk>\d+)/$', 'document_verify', (), 'document_verify'),
url(r'^upload/signature/(?P<document_pk>\d+)/$', 'document_signature_upload', (), 'document_signature_upload'),
url(r'^download/signature/(?P<document_pk>\d+)/$', 'document_signature_download', (), 'document_signature_download'),
url(r'^document/(?P<document_pk>\d+)/signature/delete/$', 'document_signature_delete', (), 'document_signature_delete'),
)

View File

@@ -0,0 +1,168 @@
from __future__ import absolute_import
from datetime import datetime
import logging
from django.utils.translation import ugettext_lazy as _
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext
from django.contrib import messages
from django.utils.safestring import mark_safe
from django.conf import settings
from django.template.defaultfilters import force_escape
from django.core.exceptions import PermissionDenied
from documents.models import Document, RecentDocument
from permissions.models import Permission
from filetransfers.api import serve_file
from acls.models import AccessEntry
from django_gpg.api import SIGNATURE_STATES
from . import (PERMISSION_DOCUMENT_VERIFY, PERMISSION_SIGNATURE_UPLOAD,
PERMISSION_SIGNATURE_DOWNLOAD, PERMISSION_SIGNATURE_DELETE)
from .forms import DetachedSignatureForm
from .models import DocumentVersionSignature
logger = logging.getLogger(__name__)
def document_verify(request, document_pk):
document = get_object_or_404(Document, pk=document_pk)
try:
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VERIFY])
except PermissionDenied:
AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VERIFY, request.user, document)
RecentDocument.objects.add_document_for_user(request.user, document)
signature = DocumentVersionSignature.objects.verify_signature(document)
signature_state = SIGNATURE_STATES.get(getattr(signature, 'status', None))
widget = (u'<img style="vertical-align: middle;" src="%simages/icons/%s" />' % (settings.STATIC_URL, signature_state['icon']))
paragraphs = [
_(u'Signature status: %(widget)s %(text)s') % {
'widget': mark_safe(widget),
'text': signature_state['text']
},
]
if DocumentVersionSignature.objects.has_embedded_signature(document):
signature_type = _(u'embedded')
else:
signature_type = _(u'detached')
if signature:
paragraphs.extend(
[
_(u'Signature ID: %s') % signature.signature_id,
_(u'Signature type: %s') % signature_type,
_(u'Key ID: %s') % signature.key_id,
_(u'Timestamp: %s') % datetime.fromtimestamp(int(signature.sig_timestamp)),
_(u'Signee: %s') % force_escape(getattr(signature, 'username', u'')),
]
)
return render_to_response('generic_template.html', {
'title': _(u'signature properties for: %s') % document,
'object': document,
'document': document,
'paragraphs': paragraphs,
}, context_instance=RequestContext(request))
def document_signature_upload(request, document_pk):
document = get_object_or_404(Document, pk=document_pk)
try:
Permission.objects.check_permissions(request.user, [PERMISSION_SIGNATURE_UPLOAD])
except PermissionDenied:
AccessEntry.objects.check_access(PERMISSION_SIGNATURE_UPLOAD, request.user, document)
RecentDocument.objects.add_document_for_user(request.user, document)
post_action_redirect = None
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/')))
next = request.POST.get('next', request.GET.get('next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', '/')))
if request.method == 'POST':
form = DetachedSignatureForm(request.POST, request.FILES)
if form.is_valid():
try:
DocumentVersionSignature.objects.add_detached_signature(document, request.FILES['file'])
messages.success(request, _(u'Detached signature uploaded successfully.'))
return HttpResponseRedirect(next)
except Exception, msg:
messages.error(request, msg)
return HttpResponseRedirect(previous)
else:
form = DetachedSignatureForm()
return render_to_response('generic_form.html', {
'title': _(u'Upload detached signature for: %s') % document,
'form_icon': 'key_delete.png',
'next': next,
'form': form,
'previous': previous,
'object': document,
}, context_instance=RequestContext(request))
def document_signature_download(request, document_pk):
document = get_object_or_404(Document, pk=document_pk)
try:
Permission.objects.check_permissions(request.user, [PERMISSION_SIGNATURE_DOWNLOAD])
except PermissionDenied:
AccessEntry.objects.check_access(PERMISSION_SIGNATURE_DOWNLOAD, request.user, document)
try:
if DocumentVersionSignature.objects.has_detached_signature(document):
signature = DocumentVersionSignature.objects.detached_signature(document)
return serve_file(
request,
signature,
save_as=u'"%s.sig"' % document.filename,
content_type=u'application/octet-stream'
)
except Exception, e:
messages.error(request, e)
return HttpResponseRedirect(request.META['HTTP_REFERER'])
return HttpResponseRedirect(request.META['HTTP_REFERER'])
def document_signature_delete(request, document_pk):
document = get_object_or_404(Document, pk=document_pk)
try:
Permission.objects.check_permissions(request.user, [PERMISSION_SIGNATURE_DELETE])
except PermissionDenied:
AccessEntry.objects.check_access(PERMISSION_SIGNATURE_DELETE, request.user, document)
RecentDocument.objects.add_document_for_user(request.user, document)
post_action_redirect = None
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/')))
next = request.POST.get('next', request.GET.get('next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', '/')))
if request.method == 'POST':
try:
DocumentVersionSignature.objects.clear_detached_signature(document)
messages.success(request, _(u'Detached signature deleted successfully.'))
return HttpResponseRedirect(next)
except Exception, exc:
messages.error(request, _(u'Error while deleting the detached signature; %s') % exc)
return HttpResponseRedirect(previous)
return render_to_response('generic_confirm.html', {
'title': _(u'Are you sure you wish to delete the detached signature from document: %s?') % document,
'form_icon': 'pencil_delete.png',
'next': next,
'previous': previous,
'object': document,
'delete_view': True,
}, context_instance=RequestContext(request))