diff --git a/apps/document_signatures/__init__.py b/apps/document_signatures/__init__.py
index e4e03435e1..8b13789179 100644
--- a/apps/document_signatures/__init__.py
+++ b/apps/document_signatures/__init__.py
@@ -1,85 +1 @@
-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 documents.models import Document, DocumentVersion
-from navigation.api import bind_links
-from django_gpg.runtime import gpg
-from django_gpg.exceptions import GPGDecryptionError
-from acls.api import class_permissions
-
-from .models import DocumentVersionSignature
-from .permissions import (
- PERMISSION_DOCUMENT_VERIFY, PERMISSION_SIGNATURE_UPLOAD,
- PERMISSION_SIGNATURE_DOWNLOAD, PERMISSION_SIGNATURE_DELETE
-)
-from .links import (document_signature_upload, document_signature_download,
- document_signature_delete, document_verify)
-
-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)
-
-
-bind_links([Document], [document_verify], menu_name='form_header')
-bind_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_UPLOAD,
- PERMISSION_SIGNATURE_DOWNLOAD, PERMISSION_SIGNATURE_DELETE
-])
diff --git a/apps/document_signatures/forms.py b/apps/document_signatures/forms.py
index 7e3f568b1b..a1bc6871ec 100644
--- a/apps/document_signatures/forms.py
+++ b/apps/document_signatures/forms.py
@@ -1,9 +1,5 @@
from django import forms
from django.utils.translation import ugettext_lazy as _
-#from django.utils.translation import ugettext
-#from django.core.urlresolvers import reverse
-#from django.utils.safestring import mark_safe
-#from django.conf import settings
class DetachedSignatureForm(forms.Form):
diff --git a/apps/document_signatures/icons.py b/apps/document_signatures/icons.py
new file mode 100644
index 0000000000..567c913947
--- /dev/null
+++ b/apps/document_signatures/icons.py
@@ -0,0 +1,9 @@
+from __future__ import absolute_import
+
+from icons.literals import PENCIL_ADD, DISK, PENCIL_DELETE, TEXT_SIGNATURE
+from icons import Icon
+
+icon_document_signature_upload = Icon(PENCIL_ADD)
+icon_document_signature_download = Icon(DISK)
+icon_document_signature_delete = Icon(PENCIL_DELETE)
+icon_document_verify = Icon(TEXT_SIGNATURE)
diff --git a/apps/document_signatures/links.py b/apps/document_signatures/links.py
index 5fd7ad0911..7647b5b42f 100644
--- a/apps/document_signatures/links.py
+++ b/apps/document_signatures/links.py
@@ -9,6 +9,8 @@ from .permissions import (
PERMISSION_DOCUMENT_VERIFY, PERMISSION_SIGNATURE_UPLOAD,
PERMISSION_SIGNATURE_DOWNLOAD, PERMISSION_SIGNATURE_DELETE
)
+from .icons import (icon_document_signature_upload, icon_document_signature_download,
+ icon_document_signature_delete, icon_document_verify)
def has_embedded_signature(context):
@@ -18,7 +20,8 @@ def has_embedded_signature(context):
def doesnt_have_detached_signature(context):
return DocumentVersionSignature.objects.has_detached_signature(context['object']) == False
-document_signature_upload = Link(text=_(u'upload signature'), view='document_signature_upload', args='object.pk', sprite='pencil_add', permissions=[PERMISSION_SIGNATURE_UPLOAD], conditional_disable=has_embedded_signature)
-document_signature_download = Link(text=_(u'download signature'), view='document_signature_download', args='object.pk', sprite='disk', permissions=[PERMISSION_SIGNATURE_DOWNLOAD], conditional_disable=doesnt_have_detached_signature)
-document_signature_delete = Link(text=_(u'delete signature'), view='document_signature_delete', args='object.pk', sprite='pencil_delete', permissions=[PERMISSION_SIGNATURE_DELETE], conditional_disable=doesnt_have_detached_signature)
-document_verify = Link(text=_(u'signatures'), view='document_verify', args='object.pk', sprite='text_signature', permissions=[PERMISSION_DOCUMENT_VERIFY])
+
+document_signature_upload = Link(text=_(u'upload signature'), view='document_signature_upload', args='object.pk', icon=icon_document_signature_upload, permissions=[PERMISSION_SIGNATURE_UPLOAD], conditional_disable=has_embedded_signature)
+document_signature_download = Link(text=_(u'download signature'), view='document_signature_download', args='object.pk', icon=icon_document_signature_download, permissions=[PERMISSION_SIGNATURE_DOWNLOAD], conditional_disable=doesnt_have_detached_signature)
+document_signature_delete = Link(text=_(u'delete signature'), view='document_signature_delete', args='object.pk', icon=icon_document_signature_delete, permissions=[PERMISSION_SIGNATURE_DELETE], conditional_disable=doesnt_have_detached_signature)
+document_verify = Link(text=_(u'signatures'), view='document_verify', args='object.pk', icon=icon_document_verify, permissions=[PERMISSION_DOCUMENT_VERIFY])
diff --git a/apps/document_signatures/managers.py b/apps/document_signatures/managers.py
index 1052d6d988..497679aa92 100644
--- a/apps/document_signatures/managers.py
+++ b/apps/document_signatures/managers.py
@@ -2,7 +2,6 @@ import logging
from django.db import models
-from django_gpg.runtime import gpg
from django_gpg.exceptions import GPGVerificationError
logger = logging.getLogger(__name__)
@@ -52,6 +51,8 @@ class DocumentVersionSignatureManager(models.Manager):
return document_signature.signature_file.storage.open(document_signature.signature_file.path)
def verify_signature(self, document):
+ from django_gpg.runtime import gpg
+
document_descriptor = document.open(raw=True)
detached_signature = None
if self.has_detached_signature(document):
diff --git a/apps/document_signatures/models.py b/apps/document_signatures/models.py
index 970826e709..1f007310f4 100644
--- a/apps/document_signatures/models.py
+++ b/apps/document_signatures/models.py
@@ -5,8 +5,6 @@ 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
@@ -18,7 +16,7 @@ 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)
+ signature_file = models.FileField(blank=True, null=True, upload_to=get_filename_from_uuid, verbose_name=_(u'signature file'), editable=False)
has_embedded_signature = models.BooleanField(default=False, verbose_name=_(u'has embedded signature'), editable=False)
objects = DocumentVersionSignatureManager()
@@ -27,6 +25,8 @@ class DocumentVersionSignature(models.Model):
self.signature_file.storage.delete(self.signature_file.path)
def save(self, *args, **kwargs):
+ from django_gpg.runtime import gpg
+
if not self.pk:
descriptor = self.document_version.open(raw=True)
self.has_embedded_signature = gpg.has_embedded_signature(descriptor)
diff --git a/apps/document_signatures/post_init.py b/apps/document_signatures/post_init.py
new file mode 100644
index 0000000000..404363cf57
--- /dev/null
+++ b/apps/document_signatures/post_init.py
@@ -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 documents.models import Document, DocumentVersion
+from navigation.api import bind_links
+from django_gpg.runtime import gpg
+from django_gpg.exceptions import GPGDecryptionError
+from acls.api import class_permissions
+from documents.settings import STORAGE_BACKEND
+
+from .models import DocumentVersionSignature
+from .permissions import (
+ PERMISSION_DOCUMENT_VERIFY, PERMISSION_SIGNATURE_UPLOAD,
+ PERMISSION_SIGNATURE_DOWNLOAD, PERMISSION_SIGNATURE_DELETE
+)
+from .links import (document_signature_upload, document_signature_download,
+ document_signature_delete, document_verify)
+
+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)
+
+def init_app():
+ bind_links([Document], [document_verify], menu_name='form_header')
+ bind_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_UPLOAD,
+ PERMISSION_SIGNATURE_DOWNLOAD, PERMISSION_SIGNATURE_DELETE
+ ])
+
+ DocumentVersionSignature._meta.get_field('signature_file').storage=STORAGE_BACKEND()
+
diff --git a/apps/document_signatures/registry.py b/apps/document_signatures/registry.py
new file mode 100644
index 0000000000..8a69cbea52
--- /dev/null
+++ b/apps/document_signatures/registry.py
@@ -0,0 +1,10 @@
+from __future__ import absolute_import
+
+from django.utils.translation import ugettext_lazy as _
+
+from .icons import icon_document_verify
+
+label = _(u'Document signatures')
+description = _(u'Handles document signatures.')
+dependencies = ['app_registry', 'icons', 'navigation', 'django_gpg', 'documents', 'permissions']
+icon = icon_document_verify
diff --git a/apps/document_signatures/views.py b/apps/document_signatures/views.py
index 2912e8a6c1..f2ebbfd4a5 100644
--- a/apps/document_signatures/views.py
+++ b/apps/document_signatures/views.py
@@ -20,7 +20,7 @@ from acls.models import AccessEntry
from django_gpg.api import SIGNATURE_STATES
-from . import (PERMISSION_DOCUMENT_VERIFY, PERMISSION_SIGNATURE_UPLOAD,
+from .permissions import (PERMISSION_DOCUMENT_VERIFY, PERMISSION_SIGNATURE_UPLOAD,
PERMISSION_SIGNATURE_DOWNLOAD, PERMISSION_SIGNATURE_DELETE)
from .forms import DetachedSignatureForm
from .models import DocumentVersionSignature
@@ -42,10 +42,9 @@ def document_verify(request, document_pk):
signature_state = SIGNATURE_STATES.get(getattr(signature, 'status', None))
- widget = (u'
' % (settings.STATIC_URL, signature_state['icon']))
paragraphs = [
- _(u'Signature status: %(widget)s %(text)s') % {
- 'widget': mark_safe(widget),
+ _(u'Signature status: %(icon)s %(text)s') % {
+ 'icon': signature_state['icon'].display_big(),
'text': signature_state['text']
},
]
diff --git a/apps/icons/classes.py b/apps/icons/classes.py
index 2a9b1c0a28..e3efeb1139 100644
--- a/apps/icons/classes.py
+++ b/apps/icons/classes.py
@@ -21,7 +21,7 @@ class Icon(object):
return IconSetBase.get_by_name(self.icon_set or ICON_SET).get_url(self, size)
def display(self, size): # TODO: move to widgets?
- return mark_safe('
' % (settings.STATIC_URL, self.get_url(size)))
+ return mark_safe('
' % (settings.STATIC_URL, self.get_url(size)))
def display_small(self):
return self.display(SIZE_SMALL)
diff --git a/apps/icons/iconsets/fat_cow.py b/apps/icons/iconsets/fat_cow.py
index c68b2d077e..3227a6e3f4 100644
--- a/apps/icons/iconsets/fat_cow.py
+++ b/apps/icons/iconsets/fat_cow.py
@@ -39,6 +39,7 @@ class IconSet(IconSetBase):
DATABASE_EDIT: 'database_edit.png',
DATABASE_DELETE: 'database_delete.png',
DELETE: 'delete.png',
+ DISK: 'disk.png',
DRAW_AIRBRUSH: 'draw_airbrush.png',
DOCUMENT_SIGNATURE: 'document_signature.png',
ERROR: 'error.png',
@@ -99,6 +100,8 @@ class IconSet(IconSetBase):
PAGE_WHITE_PICTURE: 'page_white_picture.png',
PAGE_WHITE_TEXT: 'page_white_text.png',
PAGE_WORLD: 'page_world.png',
+ PENCIL_ADD: 'pencil_add.png',
+ PENCIL_DELETE: 'pencil_delete.png',
PICTURES: 'pictures.png',
PILL: 'pill.png',
PLUGIN: 'plugin.png',
@@ -123,6 +126,7 @@ class IconSet(IconSetBase):
TAG_BLUE_DELETE: 'tag_blue_delete.png',
TAG_BLUE_EDIT: 'tag_blue_edit.png',
TEXT_DROPCAPS: 'text_dropcaps.png',
+ TEXT_SIGNATURE: 'text_signature.png',
TEXT_STRIKETHROUGH: 'text_strikethrough.png',
THEATER: 'theater.png',
TICK: 'tick.png',
@@ -131,7 +135,8 @@ class IconSet(IconSetBase):
USER: 'user.png',
USER_ADD:'user_add.png',
USER_EDIT: 'user_edit.png',
- USER_DELETE: 'user_delete.png',
+ USER_DELETE: 'user_delete.png',
+ USER_SILHOUETTE: 'user_silhouette.png',
VCARD: 'vcard.png',
VCARD_EDIT: 'vcard_edit.png',
WRENCH: 'wrench.png',
diff --git a/apps/icons/literals.py b/apps/icons/literals.py
index f54d313263..24fd50519f 100644
--- a/apps/icons/literals.py
+++ b/apps/icons/literals.py
@@ -33,6 +33,7 @@ DATABASE_ADD = 'database_add'
DATABASE_EDIT = 'database_edit'
DATABASE_DELETE = 'database_delete'
DELETE = 'delete'
+DISK = 'disk'
DRAW_AIRBRUSH = 'draw_airbrush'
DOCUMENT_SIGNATURE = 'document_signature'
ERROR = 'error'
@@ -95,6 +96,8 @@ PAGE_WHITE_EDIT = 'page_white_edit'
PAGE_WHITE_PICTURE = 'page_white_picture'
PAGE_WHITE_TEXT = 'page_white_text'
PAGE_WORLD = 'page_world'
+PENCIL_ADD = 'pencil_add'
+PENCIL_DELETE = 'pencil_delete'
PICTURES = 'pictures'
PILL = 'pill'
PLUGIN = 'plugin'
@@ -119,6 +122,7 @@ TAG_BLUE_ADD = 'tag_blue_add'
TAG_BLUE_DELETE = 'tag_blue_delete'
TAG_BLUE_EDIT = 'tag_blue_edit'
TEXT_DROPCAPS = 'text_dropcaps'
+TEXT_SIGNATURE = 'text_signature'
TEXT_STRIKETHROUGH = 'text_strikethrough'
THEATER = 'theater'
TICK = 'tick'
@@ -128,6 +132,7 @@ USER = 'user'
USER_ADD = 'user_add'
USER_EDIT = 'user_edit'
USER_DELETE = 'user_delete'
+USER_SILHOUETTE = 'user_silhouette'
VCARD = 'vcard'
VCARD_EDIT = 'vcard_edit'
WRENCH = 'wrench'
diff --git a/settings.py b/settings.py
index 6ac0ff15aa..acd8f3d1e6 100644
--- a/settings.py
+++ b/settings.py
@@ -175,7 +175,7 @@ INSTALLED_APPS = (
'folders',
'dynamic_search',
'document_comments',
- #'document_signatures',
+ 'document_signatures',
'linking',
'metadata',
'ocr',
diff --git a/urls.py b/urls.py
index c7e841be89..9f2a7e9cbe 100644
--- a/urls.py
+++ b/urls.py
@@ -29,7 +29,7 @@ urlpatterns = patterns('',
#(r'^document_acls/', include('document_acls.urls')),
(r'^api/', include('rest_api.urls')),
(r'^gpg/', include('django_gpg.urls')),
- #(r'^documents/signatures/', include('document_signatures.urls')),
+ (r'^documents/signatures/', include('document_signatures.urls')),
#(r'^mailer/', include('mailer.urls')),
#(r'^workflows/', include('workflows.urls')),
#(r'^checkouts/', include('checkouts.urls')),