Merge branch 'release/v0.12'
Conflicts: apps/documents/models.py apps/history/api.py apps/ocr/__init__.py
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -12,3 +12,4 @@ misc/mayan.geany
|
||||
image_cache/
|
||||
build/
|
||||
_build/
|
||||
gpg_home/
|
||||
|
||||
71
.tx/config
71
.tx/config
@@ -4,6 +4,8 @@ source_lang = en
|
||||
trans.es = apps/converter/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/converter/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/converter/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/converter/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/converter/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-common]
|
||||
source_file = apps/common/locale/en/LC_MESSAGES/django.po
|
||||
@@ -11,6 +13,8 @@ source_lang = en
|
||||
trans.es = apps/common/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/common/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/common/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/common/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/common/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-permissions]
|
||||
source_file = apps/permissions/locale/en/LC_MESSAGES/django.po
|
||||
@@ -18,6 +22,8 @@ source_lang = en
|
||||
trans.es = apps/permissions/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/permissions/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/permissions/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/permissions/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/permissions/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-sources]
|
||||
source_file = apps/sources/locale/en/LC_MESSAGES/django.po
|
||||
@@ -25,6 +31,8 @@ source_lang = en
|
||||
trans.es = apps/sources/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/sources/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/sources/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/sources/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/sources/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-document_indexing]
|
||||
source_file = apps/document_indexing/locale/en/LC_MESSAGES/django.po
|
||||
@@ -32,6 +40,8 @@ source_lang = en
|
||||
trans.es = apps/document_indexing/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/document_indexing/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/document_indexing/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/document_indexing/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/document_indexing/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-user_management]
|
||||
source_file = apps/user_management/locale/en/LC_MESSAGES/django.po
|
||||
@@ -39,6 +49,8 @@ source_lang = en
|
||||
trans.es = apps/user_management/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/user_management/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/user_management/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/user_management/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/user_management/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-main]
|
||||
source_file = apps/main/locale/en/LC_MESSAGES/django.po
|
||||
@@ -46,6 +58,8 @@ source_lang = en
|
||||
trans.es = apps/main/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/main/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/main/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/main/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/main/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-ocr]
|
||||
source_file = apps/ocr/locale/en/LC_MESSAGES/django.po
|
||||
@@ -53,6 +67,8 @@ source_lang = en
|
||||
trans.es = apps/ocr/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/ocr/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/ocr/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/ocr/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/ocr/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-project_setup]
|
||||
source_file = apps/project_setup/locale/en/LC_MESSAGES/django.po
|
||||
@@ -60,6 +76,8 @@ source_lang = en
|
||||
trans.es = apps/project_setup/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/project_setup/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/project_setup/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/project_setup/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/project_setup/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[main]
|
||||
host = https://www.transifex.net
|
||||
@@ -70,6 +88,8 @@ source_lang = en
|
||||
trans.es = apps/folders/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/folders/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/folders/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/folders/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/folders/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-history]
|
||||
source_file = apps/history/locale/en/LC_MESSAGES/django.po
|
||||
@@ -77,6 +97,8 @@ source_lang = en
|
||||
trans.es = apps/history/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/history/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/history/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/history/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/history/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-dynamic_search]
|
||||
source_file = apps/dynamic_search/locale/en/LC_MESSAGES/django.po
|
||||
@@ -84,6 +106,8 @@ source_lang = en
|
||||
trans.es = apps/dynamic_search/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/dynamic_search/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/dynamic_search/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/dynamic_search/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/dynamic_search/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-smart_settings]
|
||||
source_file = apps/smart_settings/locale/en/LC_MESSAGES/django.po
|
||||
@@ -91,6 +115,8 @@ source_lang = en
|
||||
trans.es = apps/smart_settings/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/smart_settings/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/smart_settings/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/smart_settings/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/smart_settings/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-navigation]
|
||||
source_file = apps/navigation/locale/en/LC_MESSAGES/django.po
|
||||
@@ -98,6 +124,8 @@ source_lang = en
|
||||
trans.es = apps/navigation/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/navigation/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/navigation/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/navigation/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/navigation/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-tags]
|
||||
source_file = apps/tags/locale/en/LC_MESSAGES/django.po
|
||||
@@ -105,6 +133,8 @@ source_lang = en
|
||||
trans.es = apps/tags/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/tags/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/tags/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/tags/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/tags/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-documents]
|
||||
source_file = apps/documents/locale/en/LC_MESSAGES/django.po
|
||||
@@ -112,6 +142,8 @@ source_lang = en
|
||||
trans.es = apps/documents/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/documents/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/documents/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/documents/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/documents/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-project_tools]
|
||||
source_file = apps/project_tools/locale/en/LC_MESSAGES/django.po
|
||||
@@ -119,6 +151,8 @@ source_lang = en
|
||||
trans.es = apps/project_tools/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/project_tools/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/project_tools/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/project_tools/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/project_tools/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-linking]
|
||||
source_file = apps/linking/locale/en/LC_MESSAGES/django.po
|
||||
@@ -126,6 +160,8 @@ source_lang = en
|
||||
trans.es = apps/linking/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/linking/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/linking/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/linking/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/linking/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-document_comments]
|
||||
source_file = apps/document_comments/locale/en/LC_MESSAGES/django.po
|
||||
@@ -133,6 +169,8 @@ source_lang = en
|
||||
trans.es = apps/document_comments/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/document_comments/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/document_comments/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/document_comments/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/document_comments/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-metadata]
|
||||
source_file = apps/metadata/locale/en/LC_MESSAGES/django.po
|
||||
@@ -140,6 +178,8 @@ source_lang = en
|
||||
trans.es = apps/metadata/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/metadata/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/metadata/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/metadata/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/metadata/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-web_theme]
|
||||
source_file = apps/web_theme/locale/en/LC_MESSAGES/django.po
|
||||
@@ -147,6 +187,8 @@ source_lang = en
|
||||
trans.es = apps/web_theme/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/web_theme/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/web_theme/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/web_theme/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/web_theme/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-django_gpg]
|
||||
source_file = apps/django_gpg/locale/en/LC_MESSAGES/django.po
|
||||
@@ -154,3 +196,32 @@ source_lang = en
|
||||
trans.es = apps/django_gpg/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/django_gpg/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/django_gpg/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/django_gpg/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/django_gpg/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-document_signatures]
|
||||
source_file = apps/document_signatures/locale/en/LC_MESSAGES/django.po
|
||||
source_lang = en
|
||||
trans.es = apps/document_signatures/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/document_signatures/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/document_signatures/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/document_signatures/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/document_signatures/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-acls]
|
||||
source_file = apps/acls/locale/en/LC_MESSAGES/django.po
|
||||
source_lang = en
|
||||
trans.es = apps/acls/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/acls/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/acls/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/acls/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/acls/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
[mayan-edms.apps-feedback]
|
||||
source_file = apps/feedback/locale/en/LC_MESSAGES/django.po
|
||||
source_lang = en
|
||||
trans.es = apps/feedback/locale/es/LC_MESSAGES/django.po
|
||||
trans.pt = apps/feedback/locale/pt/LC_MESSAGES/django.po
|
||||
trans.ru = apps/feedback/locale/ru/LC_MESSAGES/django.po
|
||||
trans.it = apps/feedback/locale/it/LC_MESSAGES/django.po
|
||||
trans.pl = apps/feedback/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
@@ -3,9 +3,7 @@ Mayan
|
||||
|
||||
Open source, Django based document manager with custom metadata indexing, file serving integration and OCR capabilities.
|
||||
|
||||
[Website](http://www.mayan-edms.com)
|
||||
|
||||
[Mailing list (via Google Groups)](http://groups.google.com/group/mayan-edms)
|
||||
[Website](http://bit.ly/mayan-edms)
|
||||
|
||||
[Video demostration](http://bit.ly/pADNXv)
|
||||
|
||||
@@ -13,6 +11,7 @@ Open source, Django based document manager with custom metadata indexing, file s
|
||||
|
||||
[Translations](https://www.transifex.net/projects/p/mayan-edms/)
|
||||
|
||||
[Mailing list (via Google Groups)](http://groups.google.com/group/mayan-edms)
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
from main import (__version__, __author__, __copyright__, __credits__,
|
||||
__license__, __maintainer__, __email__, __status__)
|
||||
|
||||
39
apps/acls/__init__.py
Normal file
39
apps/acls/__init__.py
Normal file
@@ -0,0 +1,39 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from navigation.api import register_links, register_multi_item_links
|
||||
from project_setup.api import register_setup
|
||||
|
||||
from .classes import (AccessHolder, AccessObjectClass, ClassAccessHolder,
|
||||
AccessObject)
|
||||
from .permissions import (ACLS_EDIT_ACL, ACLS_VIEW_ACL,
|
||||
ACLS_CLASS_EDIT_ACL, ACLS_CLASS_VIEW_ACL)
|
||||
|
||||
|
||||
acl_list = {'text': _(u'ACLs'), 'view': 'acl_list', 'famfam': 'lock', 'permissions': [ACLS_VIEW_ACL]}
|
||||
acl_detail = {'text': _(u'details'), 'view': 'acl_detail', 'args': ['access_object.gid', 'object.gid'], 'famfam': 'key_go', 'permissions': [ACLS_VIEW_ACL]}
|
||||
acl_grant = {'text': _(u'grant'), 'view': 'acl_multiple_grant', 'famfam': 'key_add', 'permissions': [ACLS_EDIT_ACL]}
|
||||
acl_revoke = {'text': _(u'revoke'), 'view': 'acl_multiple_revoke', 'famfam': 'key_delete', 'permissions': [ACLS_EDIT_ACL]}
|
||||
acl_holder_new = {'text': _(u'New holder'), 'view': 'acl_holder_new', 'args': 'access_object.gid', 'famfam': 'user', 'permissions': [ACLS_EDIT_ACL]}
|
||||
|
||||
acl_setup_valid_classes = {'text': _(u'Default ACLs'), 'view': 'acl_setup_valid_classes', 'icon': 'lock.png', 'permissions': [ACLS_CLASS_VIEW_ACL], 'children_view_regex': [r'^acl_class', r'^acl_setup']}
|
||||
acl_class_list = {'text': _(u'List of classes'), 'view': 'acl_setup_valid_classes', 'famfam': 'package', 'permissions': [ACLS_CLASS_VIEW_ACL]}
|
||||
acl_class_acl_list = {'text': _(u'ACLs for class'), 'view': 'acl_class_acl_list', 'args': 'object.gid', 'famfam': 'lock_go', 'permissions': [ACLS_CLASS_VIEW_ACL]}
|
||||
acl_class_acl_detail = {'text': _(u'details'), 'view': 'acl_class_acl_detail', 'args': ['access_object_class.gid', 'object.gid'], 'famfam': 'key_go', 'permissions': [ACLS_CLASS_VIEW_ACL]}
|
||||
acl_class_new_holder_for = {'text': _(u'New holder'), 'view': 'acl_class_new_holder_for', 'args': 'object.gid', 'famfam': 'user', 'permissions': [ACLS_CLASS_EDIT_ACL]}
|
||||
acl_class_grant = {'text': _(u'grant'), 'view': 'acl_class_multiple_grant', 'famfam': 'key_add', 'permissions': [ACLS_CLASS_EDIT_ACL]}
|
||||
acl_class_revoke = {'text': _(u'revoke'), 'view': 'acl_class_multiple_revoke', 'famfam': 'key_delete', 'permissions': [ACLS_CLASS_EDIT_ACL]}
|
||||
|
||||
register_links(AccessHolder, [acl_detail])
|
||||
register_multi_item_links(['acl_detail'], [acl_grant, acl_revoke])
|
||||
|
||||
register_links([AccessObject], [acl_holder_new], menu_name='sidebar')
|
||||
|
||||
register_setup(acl_setup_valid_classes)
|
||||
register_links(['acl_setup_valid_classes', 'acl_class_acl_list', 'acl_class_new_holder_for', 'acl_class_acl_detail', 'acl_class_multiple_grant', 'acl_class_multiple_revoke'], [acl_class_list], menu_name='secondary_menu')
|
||||
|
||||
register_links(ClassAccessHolder, [acl_class_acl_detail])
|
||||
|
||||
register_links(AccessObjectClass, [acl_class_acl_list, acl_class_new_holder_for])
|
||||
register_multi_item_links(['acl_class_acl_detail'], [acl_class_grant, acl_class_revoke])
|
||||
23
apps/acls/admin.py
Normal file
23
apps/acls/admin.py
Normal file
@@ -0,0 +1,23 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.contrib import admin
|
||||
|
||||
from .models import AccessEntry
|
||||
|
||||
|
||||
#class PermissionHolderInline(admin.StackedInline):
|
||||
# model = PermissionHolder
|
||||
# extra = 1
|
||||
# classes = ('collapse-open',)
|
||||
# allow_add = True#
|
||||
#
|
||||
class AccessEntryAdmin(admin.ModelAdmin):
|
||||
related_lookup_fields = {
|
||||
'generic': [['holder_type', 'holder_id'], ['content_type', 'object_id']],
|
||||
}
|
||||
#inlines = [PermissionHolderInline]
|
||||
list_display = ('pk', 'holder_object', 'permission', 'content_object')
|
||||
list_display_links = ('pk',)
|
||||
model = AccessEntry
|
||||
|
||||
admin.site.register(AccessEntry, AccessEntryAdmin)
|
||||
28
apps/acls/api.py
Normal file
28
apps/acls/api.py
Normal file
@@ -0,0 +1,28 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
_class_permissions = {}
|
||||
|
||||
|
||||
def class_permissions(cls, permission_list):
|
||||
"""
|
||||
Associate a permissions list to a class
|
||||
"""
|
||||
stored_permissions = _class_permissions.setdefault(cls, [])
|
||||
stored_permissions.extend(permission_list)
|
||||
|
||||
|
||||
def get_class_permissions_for(obj):
|
||||
"""
|
||||
Return a list of permissions associated with a content type
|
||||
"""
|
||||
content_type = ContentType.objects.get_for_model(obj)
|
||||
return _class_permissions.get(content_type.model_class(), [])
|
||||
|
||||
|
||||
def get_classes():
|
||||
"""
|
||||
Return a list of encapsulated classes that have been registered
|
||||
"""
|
||||
return _class_permissions.keys()
|
||||
158
apps/acls/classes.py
Normal file
158
apps/acls/classes.py
Normal file
@@ -0,0 +1,158 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import logging
|
||||
import sys
|
||||
import types
|
||||
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.db.models.base import ModelBase
|
||||
from django.template.defaultfilters import capfirst
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
|
||||
from common.models import AnonymousUserSingleton
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_cache = {}
|
||||
|
||||
|
||||
def get_source_object(obj):
|
||||
if isinstance(obj, EncapsulatedObject):
|
||||
return obj.source_object
|
||||
else:
|
||||
return obj
|
||||
|
||||
|
||||
class EncapsulatedObject(object):
|
||||
source_object_name = u'source_object'
|
||||
|
||||
@classmethod
|
||||
def object_key(cls, app_label=None, model=None, pk=None):
|
||||
if pk:
|
||||
return '%s.%s.%s.%s' % (cls.__name__, app_label, model, pk)
|
||||
else:
|
||||
return '%s.%s.%s' % (cls.__name__, app_label, model)
|
||||
|
||||
@classmethod
|
||||
def add_to_class(cls, name, value):
|
||||
if hasattr(value, 'contribute_to_class'):
|
||||
value.contribute_to_class(cls, name)
|
||||
else:
|
||||
setattr(cls, name, value)
|
||||
|
||||
@classmethod
|
||||
def set_source_object_name(cls, new_name):
|
||||
cls.source_object_name = new_name
|
||||
|
||||
#@classmethod
|
||||
#def encapsulate_list(cls, source_object=None, app_label=None, model=None, pk=None):
|
||||
|
||||
@classmethod
|
||||
def encapsulate(cls, source_object):
|
||||
source_object = AnonymousUserSingleton.objects.passthru_check(source_object)
|
||||
content_type = ContentType.objects.get_for_model(source_object)
|
||||
|
||||
if hasattr(source_object, 'pk'):
|
||||
# Object
|
||||
object_key = cls.object_key(content_type.app_label, content_type.model, source_object.pk)
|
||||
else:
|
||||
# Class
|
||||
object_key = cls.object_key(content_type.app_label, content_type.model)
|
||||
|
||||
try:
|
||||
return _cache[object_key]
|
||||
except KeyError:
|
||||
encapsulated_object = cls(source_object)
|
||||
_cache[object_key] = encapsulated_object
|
||||
return encapsulated_object
|
||||
|
||||
@classmethod
|
||||
def get(cls, gid):
|
||||
elements = gid.split('.')
|
||||
if len(elements) == 3:
|
||||
app_label, model, pk = elements[0], elements[1], elements[2]
|
||||
elif len(elements) == 2:
|
||||
app_label, model = elements[0], elements[1]
|
||||
pk = None
|
||||
|
||||
object_key = cls.object_key(*elements)
|
||||
|
||||
try:
|
||||
return _cache[object_key]
|
||||
except KeyError:
|
||||
try:
|
||||
content_type = ContentType.objects.get(app_label=app_label, model=model)
|
||||
except ContentType.DoesNotExist:
|
||||
#cls.add_to_class('DoesNotExist', subclass_exception('DoesNotExist', (ObjectDoesNotExist,), cls.__name__))
|
||||
#raise cls.DoesNotExist("%s matching query does not exist." % ContentType._meta.object_name)
|
||||
raise ObjectDoesNotExist("%s matching query does not exist." % ContentType._meta.object_name)
|
||||
else:
|
||||
source_object_model_class = content_type.model_class()
|
||||
if pk:
|
||||
try:
|
||||
source_object = content_type.get_object_for_this_type(pk=pk)
|
||||
except source_object_model_class.DoesNotExist:
|
||||
#cls.add_to_class('DoesNotExist', subclass_exception('DoesNotExist', (ObjectDoesNotExist,), cls.__name__))
|
||||
#raise cls.DoesNotExist("%s matching query does not exist." % source_object_model_class._meta.object_name)
|
||||
raise ObjectDoesNotExist("%s matching query does not exist." % source_object_model_class._meta.object_name)
|
||||
else:
|
||||
source_object = source_object_model_class
|
||||
|
||||
return cls.encapsulate(source_object)
|
||||
|
||||
def __init__(self, source_object):
|
||||
self.content_type = ContentType.objects.get_for_model(source_object)
|
||||
self.ct_fullname = '%s.%s' % (self.content_type.app_label, self.content_type.model)
|
||||
|
||||
if isinstance(source_object, ModelBase):
|
||||
# Class
|
||||
self.gid = '%s.%s' % (self.content_type.app_label, self.content_type.model)
|
||||
else:
|
||||
# Object
|
||||
self.gid = '%s.%s.%s' % (self.content_type.app_label, self.content_type.model, source_object.pk)
|
||||
|
||||
setattr(self, self.__class__.source_object_name, source_object)
|
||||
|
||||
def __unicode__(self):
|
||||
if isinstance(self.source_object, ModelBase):
|
||||
return capfirst(unicode(self.source_object._meta.verbose_name_plural))
|
||||
elif self.ct_fullname == 'auth.user':
|
||||
return u'%s %s' % (self.source_object._meta.verbose_name, self.source_object.get_full_name())
|
||||
elif self.ct_fullname == 'common.anonymoususersingleton':
|
||||
return unicode(self.source_object)
|
||||
elif self.ct_fullname == 'acls.creatorsingleton':
|
||||
return unicode(self.source_object)
|
||||
else:
|
||||
return u'%s %s' % (self.source_object._meta.verbose_name, self.source_object)
|
||||
|
||||
def __repr__(self):
|
||||
return self.__unicode__()
|
||||
|
||||
@property
|
||||
def source_object(self):
|
||||
return getattr(self, self.__class__.source_object_name, None)
|
||||
|
||||
|
||||
class AccessHolder(EncapsulatedObject):
|
||||
source_object_name = u'holder_object'
|
||||
|
||||
|
||||
class AccessObject(EncapsulatedObject):
|
||||
source_object_name = u'obj'
|
||||
|
||||
|
||||
class AccessObjectClass(EncapsulatedObject):
|
||||
source_object_name = u'cls'
|
||||
|
||||
|
||||
class ClassAccessHolder(EncapsulatedObject):
|
||||
source_object_name = u'class_holder'
|
||||
|
||||
|
||||
if sys.version_info < (2, 5):
|
||||
# Prior to Python 2.5, Exception was an old-style class
|
||||
def subclass_exception(name, parents, unused):
|
||||
return types.ClassType(name, parents, {})
|
||||
else:
|
||||
def subclass_exception(name, parents, module):
|
||||
return type(name, parents, {'__module__': module})
|
||||
58
apps/acls/forms.py
Normal file
58
apps/acls/forms.py
Normal file
@@ -0,0 +1,58 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.contrib.auth.models import User, Group
|
||||
|
||||
from permissions.models import Role
|
||||
from common.utils import get_object_name
|
||||
from common.models import AnonymousUserSingleton
|
||||
|
||||
from .classes import AccessHolder
|
||||
from .models import CreatorSingleton
|
||||
|
||||
|
||||
def _as_choice_list(holders):
|
||||
return sorted([(AccessHolder.encapsulate(holder).gid, get_object_name(holder, display_object_type=False)) for holder in holders], key=lambda x: x[1])
|
||||
|
||||
|
||||
class BaseHolderSelectionForm(forms.Form):
|
||||
holder_gid = forms.ChoiceField(
|
||||
label=_(u'New holder')
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
current_holders = kwargs.pop('current_holders', [])
|
||||
if current_holders:
|
||||
current_holders = [holder.source_object for holder in current_holders]
|
||||
|
||||
staff_users = User.objects.filter(is_staff=True)
|
||||
super_users = User.objects.filter(is_superuser=True)
|
||||
users = set(User.objects.filter(is_active=True)) - set(staff_users) - set(super_users) - set(current_holders)
|
||||
roles = set(Role.objects.all()) - set(current_holders)
|
||||
groups = set(Group.objects.all()) - set(current_holders)
|
||||
special = set(self.special_holders) - set(current_holders)
|
||||
|
||||
non_holder_list = []
|
||||
if users:
|
||||
non_holder_list.append((_(u'Users'), _as_choice_list(list(users))))
|
||||
|
||||
if groups:
|
||||
non_holder_list.append((_(u'Groups'), _as_choice_list(list(groups))))
|
||||
|
||||
if roles:
|
||||
non_holder_list.append((_(u'Roles'), _as_choice_list(list(roles))))
|
||||
|
||||
if special:
|
||||
non_holder_list.append((_(u'Special'), _as_choice_list(list(special))))
|
||||
|
||||
super(BaseHolderSelectionForm, self).__init__(*args, **kwargs)
|
||||
self.fields['holder_gid'].choices = non_holder_list
|
||||
|
||||
|
||||
class HolderSelectionForm(BaseHolderSelectionForm):
|
||||
special_holders = [AnonymousUserSingleton.objects.get()]
|
||||
|
||||
|
||||
class ClassHolderSelectionForm(BaseHolderSelectionForm):
|
||||
special_holders = [AnonymousUserSingleton.objects.get(), CreatorSingleton.objects.get()]
|
||||
13
apps/acls/literals.py
Normal file
13
apps/acls/literals.py
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
# Content type <-> fam fam icon mapping
|
||||
CONTENT_TYPE_ICON_MAP = {
|
||||
'auth.user': 'user',
|
||||
'auth.group': 'group',
|
||||
'documents.document': 'page',
|
||||
'permissions.role': 'medal_gold_1',
|
||||
'folders.folder': 'folder',
|
||||
'taggit.tag': 'tag_blue',
|
||||
'linking.smartlink': 'page_link',
|
||||
'common.anonymoususersingleton': 'user',
|
||||
'acls.creatorsingleton': 'user',
|
||||
}
|
||||
241
apps/acls/locale/en/LC_MESSAGES/django.po
Normal file
241
apps/acls/locale/en/LC_MESSAGES/django.po
Normal file
@@ -0,0 +1,241 @@
|
||||
# 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: 2012-02-12 15:20-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:14
|
||||
msgid "ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:15 __init__.py:23
|
||||
msgid "details"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:16 __init__.py:25
|
||||
msgid "grant"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:17 __init__.py:26
|
||||
msgid "revoke"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:18 __init__.py:24 forms.py:21
|
||||
msgid "New holder"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:20
|
||||
msgid "Default ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:21
|
||||
msgid "List of classes"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:22
|
||||
msgid "ACLs for class"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:38
|
||||
msgid "Users"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:41
|
||||
msgid "Groups"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:44
|
||||
msgid "Roles"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:47
|
||||
msgid "Special"
|
||||
msgstr ""
|
||||
|
||||
#: managers.py:116 managers.py:128
|
||||
msgid "Insufficient access."
|
||||
msgstr ""
|
||||
|
||||
#: models.py:27 models.py:69
|
||||
msgid "permission"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:53
|
||||
msgid "access entry"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:54
|
||||
msgid "access entries"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:90
|
||||
msgid "default access entry"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:91
|
||||
msgid "default access entries"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:109
|
||||
msgid "Creator"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:112 models.py:113
|
||||
msgid "creator"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:7 permissions.py:8
|
||||
msgid "Access control lists"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:10
|
||||
msgid "Edit ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:11
|
||||
msgid "View ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:13
|
||||
msgid "Edit class default ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:14
|
||||
msgid "View class default ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:47
|
||||
#, python-format
|
||||
msgid "access control lists for: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:49 views.py:411
|
||||
msgid "holder"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:50 views.py:412
|
||||
msgid "permissions"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:97
|
||||
#, python-format
|
||||
msgid "permissions available to: %(actor)s for %(obj)s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:104 views.py:444
|
||||
msgid "namespace"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:105 views.py:445
|
||||
msgid "label"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:107 views.py:447
|
||||
msgid "has permission"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:185 views.py:279 views.py:528 views.py:608
|
||||
msgid ", "
|
||||
msgstr ""
|
||||
|
||||
#: views.py:186 views.py:280 views.py:529 views.py:609
|
||||
#, python-format
|
||||
msgid " for %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:187 views.py:530
|
||||
#, python-format
|
||||
msgid " to %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:190 views.py:533
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to grant the permission %(title_suffix)s?"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:192 views.py:535
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to grant the permissions %(title_suffix)s?"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:199 views.py:542
|
||||
#, python-format
|
||||
msgid "Permission \"%(permission)s\" granted to %(actor)s for %(object)s."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:205 views.py:548
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%(actor)s, already had the permission \"%(permission)s\" granted for "
|
||||
"%(object)s."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:281 views.py:610
|
||||
#, python-format
|
||||
msgid " from %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:284 views.py:613
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to revoke the permission %(title_suffix)s?"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:286 views.py:615
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to revoke the permissions %(title_suffix)s?"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:293 views.py:622
|
||||
#, python-format
|
||||
msgid "Permission \"%(permission)s\" revoked of %(actor)s for %(object)s."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:299 views.py:628
|
||||
#, python-format
|
||||
msgid "%(actor)s, didn't had the permission \"%(permission)s\" for %(object)s."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:355
|
||||
#, python-format
|
||||
msgid "add new holder for: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:356 views.py:488
|
||||
msgid "Select"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:388
|
||||
msgid "classes"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:390
|
||||
msgid "class"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:409
|
||||
#, python-format
|
||||
msgid "default access control lists for class: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:437
|
||||
#, python-format
|
||||
msgid "permissions available to: %(actor)s for class %(class)s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:486
|
||||
#, python-format
|
||||
msgid "add new holder for class: %s"
|
||||
msgstr ""
|
||||
BIN
apps/acls/locale/es/LC_MESSAGES/django.mo
Normal file
BIN
apps/acls/locale/es/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
244
apps/acls/locale/es/LC_MESSAGES/django.po
Normal file
244
apps/acls/locale/es/LC_MESSAGES/django.po
Normal file
@@ -0,0 +1,244 @@
|
||||
# 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: \n"
|
||||
"POT-Creation-Date: 2012-02-12 15:20-0400\n"
|
||||
"PO-Revision-Date: 2012-02-12 00:16+0000\n"
|
||||
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
|
||||
"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/"
|
||||
"mayan-edms/team/es/)\n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
|
||||
#: __init__.py:14
|
||||
msgid "ACLs"
|
||||
msgstr "LCA"
|
||||
|
||||
#: __init__.py:15 __init__.py:23
|
||||
msgid "details"
|
||||
msgstr "detalles"
|
||||
|
||||
#: __init__.py:16 __init__.py:25
|
||||
msgid "grant"
|
||||
msgstr "otorgar"
|
||||
|
||||
#: __init__.py:17 __init__.py:26
|
||||
msgid "revoke"
|
||||
msgstr "revocar"
|
||||
|
||||
#: __init__.py:18 __init__.py:24 forms.py:21
|
||||
msgid "New holder"
|
||||
msgstr "Nuevo titular"
|
||||
|
||||
#: __init__.py:20
|
||||
msgid "Default ACLs"
|
||||
msgstr "LCA por defecto"
|
||||
|
||||
#: __init__.py:21
|
||||
msgid "List of classes"
|
||||
msgstr "Lista de clases"
|
||||
|
||||
#: __init__.py:22
|
||||
msgid "ACLs for class"
|
||||
msgstr "LCA para la clase"
|
||||
|
||||
#: forms.py:38
|
||||
msgid "Users"
|
||||
msgstr "Usuarios"
|
||||
|
||||
#: forms.py:41
|
||||
msgid "Groups"
|
||||
msgstr "Grupos"
|
||||
|
||||
#: forms.py:44
|
||||
msgid "Roles"
|
||||
msgstr "Funciones"
|
||||
|
||||
#: forms.py:47
|
||||
msgid "Special"
|
||||
msgstr "Especial"
|
||||
|
||||
#: managers.py:116 managers.py:128
|
||||
msgid "Insufficient access."
|
||||
msgstr "Acceso insuficiente."
|
||||
|
||||
#: models.py:27 models.py:69
|
||||
msgid "permission"
|
||||
msgstr "permiso"
|
||||
|
||||
#: models.py:53
|
||||
msgid "access entry"
|
||||
msgstr "entrada de acceso"
|
||||
|
||||
#: models.py:54
|
||||
msgid "access entries"
|
||||
msgstr "entradas de acceso"
|
||||
|
||||
#: models.py:90
|
||||
msgid "default access entry"
|
||||
msgstr "entrada de acceso por defecto"
|
||||
|
||||
#: models.py:91
|
||||
msgid "default access entries"
|
||||
msgstr "entradas de acceso por defecto"
|
||||
|
||||
#: models.py:109
|
||||
msgid "Creator"
|
||||
msgstr "Creador"
|
||||
|
||||
#: models.py:112 models.py:113
|
||||
msgid "creator"
|
||||
msgstr "creador"
|
||||
|
||||
#: permissions.py:7 permissions.py:8
|
||||
msgid "Access control lists"
|
||||
msgstr "Listas de control de acceso"
|
||||
|
||||
#: permissions.py:10
|
||||
msgid "Edit ACLs"
|
||||
msgstr "Editar LCA"
|
||||
|
||||
#: permissions.py:11
|
||||
msgid "View ACLs"
|
||||
msgstr "Ver LCA"
|
||||
|
||||
#: permissions.py:13
|
||||
msgid "Edit class default ACLs"
|
||||
msgstr "Editar LCA por defecto de la clase"
|
||||
|
||||
#: permissions.py:14
|
||||
msgid "View class default ACLs"
|
||||
msgstr "Ver LCA por defecto de la clase"
|
||||
|
||||
#: views.py:47
|
||||
#, python-format
|
||||
msgid "access control lists for: %s"
|
||||
msgstr "listas de control de acceso para: %s"
|
||||
|
||||
#: views.py:49 views.py:411
|
||||
msgid "holder"
|
||||
msgstr "titular"
|
||||
|
||||
#: views.py:50 views.py:412
|
||||
msgid "permissions"
|
||||
msgstr "permisos"
|
||||
|
||||
#: views.py:97
|
||||
#, python-format
|
||||
msgid "permissions available to: %(actor)s for %(obj)s"
|
||||
msgstr "permisos disponibles a: %(actor)s para %(obj)s "
|
||||
|
||||
#: views.py:104 views.py:444
|
||||
msgid "namespace"
|
||||
msgstr "espacio de nombres"
|
||||
|
||||
#: views.py:105 views.py:445
|
||||
msgid "label"
|
||||
msgstr "etiqueta"
|
||||
|
||||
#: views.py:107 views.py:447
|
||||
msgid "has permission"
|
||||
msgstr "tiene permiso"
|
||||
|
||||
#: views.py:185 views.py:279 views.py:528 views.py:608
|
||||
msgid ", "
|
||||
msgstr ", "
|
||||
|
||||
#: views.py:186 views.py:280 views.py:529 views.py:609
|
||||
#, python-format
|
||||
msgid " for %s"
|
||||
msgstr " para %s"
|
||||
|
||||
#: views.py:187 views.py:530
|
||||
#, python-format
|
||||
msgid " to %s"
|
||||
msgstr " a %s"
|
||||
|
||||
#: views.py:190 views.py:533
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to grant the permission %(title_suffix)s?"
|
||||
msgstr "¿Está seguro que desea conceder el permiso %(title_suffix)s?"
|
||||
|
||||
#: views.py:192 views.py:535
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to grant the permissions %(title_suffix)s?"
|
||||
msgstr "¿Está seguro que desea conceder los permisos de %(title_suffix)s?"
|
||||
|
||||
#: views.py:199 views.py:542
|
||||
#, python-format
|
||||
msgid "Permission \"%(permission)s\" granted to %(actor)s for %(object)s."
|
||||
msgstr "Permiso \"%(permission)s\" otorgado a %(actor)s para %(object)s."
|
||||
|
||||
#: views.py:205 views.py:548
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%(actor)s, already had the permission \"%(permission)s\" granted for "
|
||||
"%(object)s."
|
||||
msgstr ""
|
||||
"%(actor)s, ya tenía el permiso \"%(permission)s\", otorgado para %(object)s."
|
||||
|
||||
#: views.py:281 views.py:610
|
||||
#, python-format
|
||||
msgid " from %s"
|
||||
msgstr " de %s"
|
||||
|
||||
#: views.py:284 views.py:613
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to revoke the permission %(title_suffix)s?"
|
||||
msgstr "¿Está seguro que desea revocar el permiso %(title_suffix)s?"
|
||||
|
||||
#: views.py:286 views.py:615
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to revoke the permissions %(title_suffix)s?"
|
||||
msgstr "¿Está seguro de querer revocar los permisos %(title_suffix)s?"
|
||||
|
||||
#: views.py:293 views.py:622
|
||||
#, python-format
|
||||
msgid "Permission \"%(permission)s\" revoked of %(actor)s for %(object)s."
|
||||
msgstr "Permiso \"%(permission)s\" revocado del %(actor)s para %(object)s."
|
||||
|
||||
#: views.py:299 views.py:628
|
||||
#, python-format
|
||||
msgid "%(actor)s, didn't had the permission \"%(permission)s\" for %(object)s."
|
||||
msgstr "%(actor)s, no tenía el permiso \"%(permission)s\" para %(object)s."
|
||||
|
||||
#: views.py:355
|
||||
#, python-format
|
||||
msgid "add new holder for: %s"
|
||||
msgstr "añadir nuevo titular para: %s"
|
||||
|
||||
#: views.py:356 views.py:488
|
||||
msgid "Select"
|
||||
msgstr "Seleccionar"
|
||||
|
||||
#: views.py:388
|
||||
msgid "classes"
|
||||
msgstr "clases"
|
||||
|
||||
#: views.py:390
|
||||
msgid "class"
|
||||
msgstr "clase"
|
||||
|
||||
#: views.py:409
|
||||
#, python-format
|
||||
msgid "default access control lists for class: %s"
|
||||
msgstr "listas de control de acceso por defecto para la clase: %s"
|
||||
|
||||
#: views.py:437
|
||||
#, python-format
|
||||
msgid "permissions available to: %(actor)s for class %(class)s"
|
||||
msgstr "permisos disponibles para: %(actor)s para la clase %(class)s "
|
||||
|
||||
#: views.py:486
|
||||
#, python-format
|
||||
msgid "add new holder for class: %s"
|
||||
msgstr "añadir nuevo titular para la clase: %s"
|
||||
BIN
apps/acls/locale/it/LC_MESSAGES/django.mo
Normal file
BIN
apps/acls/locale/it/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
242
apps/acls/locale/it/LC_MESSAGES/django.po
Normal file
242
apps/acls/locale/it/LC_MESSAGES/django.po
Normal file
@@ -0,0 +1,242 @@
|
||||
# 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-02-12 15:20-0400\n"
|
||||
"PO-Revision-Date: 2012-02-21 00:41+0000\n"
|
||||
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
|
||||
"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: it\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
|
||||
#: __init__.py:14
|
||||
msgid "ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:15 __init__.py:23
|
||||
msgid "details"
|
||||
msgstr "dettagli"
|
||||
|
||||
#: __init__.py:16 __init__.py:25
|
||||
msgid "grant"
|
||||
msgstr "concedere"
|
||||
|
||||
#: __init__.py:17 __init__.py:26
|
||||
msgid "revoke"
|
||||
msgstr "revocare"
|
||||
|
||||
#: __init__.py:18 __init__.py:24 forms.py:21
|
||||
msgid "New holder"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:20
|
||||
msgid "Default ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:21
|
||||
msgid "List of classes"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:22
|
||||
msgid "ACLs for class"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:38
|
||||
msgid "Users"
|
||||
msgstr "Utenti"
|
||||
|
||||
#: forms.py:41
|
||||
msgid "Groups"
|
||||
msgstr "Gruppi"
|
||||
|
||||
#: forms.py:44
|
||||
msgid "Roles"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:47
|
||||
msgid "Special"
|
||||
msgstr "Speciale"
|
||||
|
||||
#: managers.py:116 managers.py:128
|
||||
msgid "Insufficient access."
|
||||
msgstr ""
|
||||
|
||||
#: models.py:27 models.py:69
|
||||
msgid "permission"
|
||||
msgstr "autorizzazione"
|
||||
|
||||
#: models.py:53
|
||||
msgid "access entry"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:54
|
||||
msgid "access entries"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:90
|
||||
msgid "default access entry"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:91
|
||||
msgid "default access entries"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:109
|
||||
msgid "Creator"
|
||||
msgstr "Creatore"
|
||||
|
||||
#: models.py:112 models.py:113
|
||||
msgid "creator"
|
||||
msgstr "creatore"
|
||||
|
||||
#: permissions.py:7 permissions.py:8
|
||||
msgid "Access control lists"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:10
|
||||
msgid "Edit ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:11
|
||||
msgid "View ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:13
|
||||
msgid "Edit class default ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:14
|
||||
msgid "View class default ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:47
|
||||
#, python-format
|
||||
msgid "access control lists for: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:49 views.py:411
|
||||
msgid "holder"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:50 views.py:412
|
||||
msgid "permissions"
|
||||
msgstr "le autorizzazioni"
|
||||
|
||||
#: views.py:97
|
||||
#, python-format
|
||||
msgid "permissions available to: %(actor)s for %(obj)s"
|
||||
msgstr "autorizzazioni disponibili per: %(actor)s per %(obj)s "
|
||||
|
||||
#: views.py:104 views.py:444
|
||||
msgid "namespace"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:105 views.py:445
|
||||
msgid "label"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:107 views.py:447
|
||||
msgid "has permission"
|
||||
msgstr "ha l'autorizzazione"
|
||||
|
||||
#: views.py:185 views.py:279 views.py:528 views.py:608
|
||||
msgid ", "
|
||||
msgstr ", "
|
||||
|
||||
#: views.py:186 views.py:280 views.py:529 views.py:609
|
||||
#, python-format
|
||||
msgid " for %s"
|
||||
msgstr "per %s"
|
||||
|
||||
#: views.py:187 views.py:530
|
||||
#, python-format
|
||||
msgid " to %s"
|
||||
msgstr "a %s"
|
||||
|
||||
#: views.py:190 views.py:533
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to grant the permission %(title_suffix)s?"
|
||||
msgstr "Sei sicuro di voler concedere l'autorizzazione %(title_suffix)s?"
|
||||
|
||||
#: views.py:192 views.py:535
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to grant the permissions %(title_suffix)s?"
|
||||
msgstr "Sei sicuro di voler concedere permessi %(title_suffix)s?"
|
||||
|
||||
#: views.py:199 views.py:542
|
||||
#, python-format
|
||||
msgid "Permission \"%(permission)s\" granted to %(actor)s for %(object)s."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:205 views.py:548
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%(actor)s, already had the permission \"%(permission)s\" granted for "
|
||||
"%(object)s."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:281 views.py:610
|
||||
#, python-format
|
||||
msgid " from %s"
|
||||
msgstr "da %s"
|
||||
|
||||
#: views.py:284 views.py:613
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to revoke the permission %(title_suffix)s?"
|
||||
msgstr "Sei sicuro di voler revocare l'autorizzazione %(title_suffix)s?"
|
||||
|
||||
#: views.py:286 views.py:615
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to revoke the permissions %(title_suffix)s?"
|
||||
msgstr "Sei sicuro di voler revocare permessi %(title_suffix)s?"
|
||||
|
||||
#: views.py:293 views.py:622
|
||||
#, python-format
|
||||
msgid "Permission \"%(permission)s\" revoked of %(actor)s for %(object)s."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:299 views.py:628
|
||||
#, python-format
|
||||
msgid "%(actor)s, didn't had the permission \"%(permission)s\" for %(object)s."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:355
|
||||
#, python-format
|
||||
msgid "add new holder for: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:356 views.py:488
|
||||
msgid "Select"
|
||||
msgstr "Selezionare"
|
||||
|
||||
#: views.py:388
|
||||
msgid "classes"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:390
|
||||
msgid "class"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:409
|
||||
#, python-format
|
||||
msgid "default access control lists for class: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:437
|
||||
#, python-format
|
||||
msgid "permissions available to: %(actor)s for class %(class)s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:486
|
||||
#, python-format
|
||||
msgid "add new holder for class: %s"
|
||||
msgstr ""
|
||||
BIN
apps/acls/locale/pl/LC_MESSAGES/django.mo
Normal file
BIN
apps/acls/locale/pl/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
241
apps/acls/locale/pl/LC_MESSAGES/django.po
Normal file
241
apps/acls/locale/pl/LC_MESSAGES/django.po
Normal file
@@ -0,0 +1,241 @@
|
||||
# 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-02-12 15:20-0400\n"
|
||||
"PO-Revision-Date: 2012-01-02 09:45+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Polish (http://www.transifex.net/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:14
|
||||
msgid "ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:15 __init__.py:23
|
||||
msgid "details"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:16 __init__.py:25
|
||||
msgid "grant"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:17 __init__.py:26
|
||||
msgid "revoke"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:18 __init__.py:24 forms.py:21
|
||||
msgid "New holder"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:20
|
||||
msgid "Default ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:21
|
||||
msgid "List of classes"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:22
|
||||
msgid "ACLs for class"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:38
|
||||
msgid "Users"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:41
|
||||
msgid "Groups"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:44
|
||||
msgid "Roles"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:47
|
||||
msgid "Special"
|
||||
msgstr ""
|
||||
|
||||
#: managers.py:116 managers.py:128
|
||||
msgid "Insufficient access."
|
||||
msgstr ""
|
||||
|
||||
#: models.py:27 models.py:69
|
||||
msgid "permission"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:53
|
||||
msgid "access entry"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:54
|
||||
msgid "access entries"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:90
|
||||
msgid "default access entry"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:91
|
||||
msgid "default access entries"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:109
|
||||
msgid "Creator"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:112 models.py:113
|
||||
msgid "creator"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:7 permissions.py:8
|
||||
msgid "Access control lists"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:10
|
||||
msgid "Edit ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:11
|
||||
msgid "View ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:13
|
||||
msgid "Edit class default ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:14
|
||||
msgid "View class default ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:47
|
||||
#, python-format
|
||||
msgid "access control lists for: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:49 views.py:411
|
||||
msgid "holder"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:50 views.py:412
|
||||
msgid "permissions"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:97
|
||||
#, python-format
|
||||
msgid "permissions available to: %(actor)s for %(obj)s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:104 views.py:444
|
||||
msgid "namespace"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:105 views.py:445
|
||||
msgid "label"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:107 views.py:447
|
||||
msgid "has permission"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:185 views.py:279 views.py:528 views.py:608
|
||||
msgid ", "
|
||||
msgstr ""
|
||||
|
||||
#: views.py:186 views.py:280 views.py:529 views.py:609
|
||||
#, python-format
|
||||
msgid " for %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:187 views.py:530
|
||||
#, python-format
|
||||
msgid " to %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:190 views.py:533
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to grant the permission %(title_suffix)s?"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:192 views.py:535
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to grant the permissions %(title_suffix)s?"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:199 views.py:542
|
||||
#, python-format
|
||||
msgid "Permission \"%(permission)s\" granted to %(actor)s for %(object)s."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:205 views.py:548
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%(actor)s, already had the permission \"%(permission)s\" granted for "
|
||||
"%(object)s."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:281 views.py:610
|
||||
#, python-format
|
||||
msgid " from %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:284 views.py:613
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to revoke the permission %(title_suffix)s?"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:286 views.py:615
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to revoke the permissions %(title_suffix)s?"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:293 views.py:622
|
||||
#, python-format
|
||||
msgid "Permission \"%(permission)s\" revoked of %(actor)s for %(object)s."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:299 views.py:628
|
||||
#, python-format
|
||||
msgid "%(actor)s, didn't had the permission \"%(permission)s\" for %(object)s."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:355
|
||||
#, python-format
|
||||
msgid "add new holder for: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:356 views.py:488
|
||||
msgid "Select"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:388
|
||||
msgid "classes"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:390
|
||||
msgid "class"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:409
|
||||
#, python-format
|
||||
msgid "default access control lists for class: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:437
|
||||
#, python-format
|
||||
msgid "permissions available to: %(actor)s for class %(class)s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:486
|
||||
#, python-format
|
||||
msgid "add new holder for class: %s"
|
||||
msgstr ""
|
||||
BIN
apps/acls/locale/pt/LC_MESSAGES/django.mo
Normal file
BIN
apps/acls/locale/pt/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
242
apps/acls/locale/pt/LC_MESSAGES/django.po
Normal file
242
apps/acls/locale/pt/LC_MESSAGES/django.po
Normal file
@@ -0,0 +1,242 @@
|
||||
# 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: \n"
|
||||
"POT-Creation-Date: 2012-02-12 15:20-0400\n"
|
||||
"PO-Revision-Date: 2012-02-02 18:20+0000\n"
|
||||
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
|
||||
"Language-Team: Portuguese (http://www.transifex.net/projects/p/mayan-edms/"
|
||||
"team/pt/)\n"
|
||||
"Language: pt\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
|
||||
#: __init__.py:14
|
||||
msgid "ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:15 __init__.py:23
|
||||
msgid "details"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:16 __init__.py:25
|
||||
msgid "grant"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:17 __init__.py:26
|
||||
msgid "revoke"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:18 __init__.py:24 forms.py:21
|
||||
msgid "New holder"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:20
|
||||
msgid "Default ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:21
|
||||
msgid "List of classes"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:22
|
||||
msgid "ACLs for class"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:38
|
||||
msgid "Users"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:41
|
||||
msgid "Groups"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:44
|
||||
msgid "Roles"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:47
|
||||
msgid "Special"
|
||||
msgstr ""
|
||||
|
||||
#: managers.py:116 managers.py:128
|
||||
msgid "Insufficient access."
|
||||
msgstr ""
|
||||
|
||||
#: models.py:27 models.py:69
|
||||
msgid "permission"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:53
|
||||
msgid "access entry"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:54
|
||||
msgid "access entries"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:90
|
||||
msgid "default access entry"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:91
|
||||
msgid "default access entries"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:109
|
||||
msgid "Creator"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:112 models.py:113
|
||||
msgid "creator"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:7 permissions.py:8
|
||||
msgid "Access control lists"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:10
|
||||
msgid "Edit ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:11
|
||||
msgid "View ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:13
|
||||
msgid "Edit class default ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:14
|
||||
msgid "View class default ACLs"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:47
|
||||
#, python-format
|
||||
msgid "access control lists for: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:49 views.py:411
|
||||
msgid "holder"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:50 views.py:412
|
||||
msgid "permissions"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:97
|
||||
#, python-format
|
||||
msgid "permissions available to: %(actor)s for %(obj)s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:104 views.py:444
|
||||
msgid "namespace"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:105 views.py:445
|
||||
msgid "label"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:107 views.py:447
|
||||
msgid "has permission"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:185 views.py:279 views.py:528 views.py:608
|
||||
msgid ", "
|
||||
msgstr ""
|
||||
|
||||
#: views.py:186 views.py:280 views.py:529 views.py:609
|
||||
#, python-format
|
||||
msgid " for %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:187 views.py:530
|
||||
#, python-format
|
||||
msgid " to %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:190 views.py:533
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to grant the permission %(title_suffix)s?"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:192 views.py:535
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to grant the permissions %(title_suffix)s?"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:199 views.py:542
|
||||
#, python-format
|
||||
msgid "Permission \"%(permission)s\" granted to %(actor)s for %(object)s."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:205 views.py:548
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%(actor)s, already had the permission \"%(permission)s\" granted for "
|
||||
"%(object)s."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:281 views.py:610
|
||||
#, python-format
|
||||
msgid " from %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:284 views.py:613
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to revoke the permission %(title_suffix)s?"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:286 views.py:615
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to revoke the permissions %(title_suffix)s?"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:293 views.py:622
|
||||
#, python-format
|
||||
msgid "Permission \"%(permission)s\" revoked of %(actor)s for %(object)s."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:299 views.py:628
|
||||
#, python-format
|
||||
msgid "%(actor)s, didn't had the permission \"%(permission)s\" for %(object)s."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:355
|
||||
#, python-format
|
||||
msgid "add new holder for: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:356 views.py:488
|
||||
msgid "Select"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:388
|
||||
msgid "classes"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:390
|
||||
msgid "class"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:409
|
||||
#, python-format
|
||||
msgid "default access control lists for class: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:437
|
||||
#, python-format
|
||||
msgid "permissions available to: %(actor)s for class %(class)s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:486
|
||||
#, python-format
|
||||
msgid "add new holder for class: %s"
|
||||
msgstr ""
|
||||
BIN
apps/acls/locale/ru/LC_MESSAGES/django.mo
Normal file
BIN
apps/acls/locale/ru/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
242
apps/acls/locale/ru/LC_MESSAGES/django.po
Normal file
242
apps/acls/locale/ru/LC_MESSAGES/django.po
Normal file
@@ -0,0 +1,242 @@
|
||||
# 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-02-12 15:20-0400\n"
|
||||
"PO-Revision-Date: 2012-02-27 04:26+0000\n"
|
||||
"Last-Translator: Sergey Glita <gsv70@mail.ru>\n"
|
||||
"Language-Team: Russian (http://www.transifex.net/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:14
|
||||
msgid "ACLs"
|
||||
msgstr "Списки ACL"
|
||||
|
||||
#: __init__.py:15 __init__.py:23
|
||||
msgid "details"
|
||||
msgstr "детали"
|
||||
|
||||
#: __init__.py:16 __init__.py:25
|
||||
msgid "grant"
|
||||
msgstr "предоставить"
|
||||
|
||||
#: __init__.py:17 __init__.py:26
|
||||
msgid "revoke"
|
||||
msgstr "отозвать"
|
||||
|
||||
#: __init__.py:18 __init__.py:24 forms.py:21
|
||||
msgid "New holder"
|
||||
msgstr "Новый владелец"
|
||||
|
||||
#: __init__.py:20
|
||||
msgid "Default ACLs"
|
||||
msgstr "ACL по умолчанию"
|
||||
|
||||
#: __init__.py:21
|
||||
msgid "List of classes"
|
||||
msgstr "Список классов"
|
||||
|
||||
#: __init__.py:22
|
||||
msgid "ACLs for class"
|
||||
msgstr "ACL для класса"
|
||||
|
||||
#: forms.py:38
|
||||
msgid "Users"
|
||||
msgstr "Пользователи"
|
||||
|
||||
#: forms.py:41
|
||||
msgid "Groups"
|
||||
msgstr "Группы"
|
||||
|
||||
#: forms.py:44
|
||||
msgid "Roles"
|
||||
msgstr "Роли"
|
||||
|
||||
#: forms.py:47
|
||||
msgid "Special"
|
||||
msgstr "Специальный"
|
||||
|
||||
#: managers.py:116 managers.py:128
|
||||
msgid "Insufficient access."
|
||||
msgstr "Недостаточный доступ."
|
||||
|
||||
#: models.py:27 models.py:69
|
||||
msgid "permission"
|
||||
msgstr "разрешение"
|
||||
|
||||
#: models.py:53
|
||||
msgid "access entry"
|
||||
msgstr "запись доступа"
|
||||
|
||||
#: models.py:54
|
||||
msgid "access entries"
|
||||
msgstr "записи доступа"
|
||||
|
||||
#: models.py:90
|
||||
msgid "default access entry"
|
||||
msgstr "запись доступа по умолчанию"
|
||||
|
||||
#: models.py:91
|
||||
msgid "default access entries"
|
||||
msgstr "записи доступа по умолчанию"
|
||||
|
||||
#: models.py:109
|
||||
msgid "Creator"
|
||||
msgstr "Создатель"
|
||||
|
||||
#: models.py:112 models.py:113
|
||||
msgid "creator"
|
||||
msgstr "создатель"
|
||||
|
||||
#: permissions.py:7 permissions.py:8
|
||||
msgid "Access control lists"
|
||||
msgstr "Списки контроля доступа"
|
||||
|
||||
#: permissions.py:10
|
||||
msgid "Edit ACLs"
|
||||
msgstr "Редактировать списки ACL"
|
||||
|
||||
#: permissions.py:11
|
||||
msgid "View ACLs"
|
||||
msgstr "Просмотр списков ACL"
|
||||
|
||||
#: permissions.py:13
|
||||
msgid "Edit class default ACLs"
|
||||
msgstr "Редактировать списки ACL класса по умолчанию"
|
||||
|
||||
#: permissions.py:14
|
||||
msgid "View class default ACLs"
|
||||
msgstr "Просмотр списков ACL класса по умолчанию"
|
||||
|
||||
#: views.py:47
|
||||
#, python-format
|
||||
msgid "access control lists for: %s"
|
||||
msgstr "списки контроля доступа для %s"
|
||||
|
||||
#: views.py:49 views.py:411
|
||||
msgid "holder"
|
||||
msgstr "владелец"
|
||||
|
||||
#: views.py:50 views.py:412
|
||||
msgid "permissions"
|
||||
msgstr "разрешения"
|
||||
|
||||
#: views.py:97
|
||||
#, python-format
|
||||
msgid "permissions available to: %(actor)s for %(obj)s"
|
||||
msgstr "разрешения, доступные %(actor)s для %(obj)s"
|
||||
|
||||
#: views.py:104 views.py:444
|
||||
msgid "namespace"
|
||||
msgstr "пространство имен"
|
||||
|
||||
#: views.py:105 views.py:445
|
||||
msgid "label"
|
||||
msgstr "этикетка"
|
||||
|
||||
#: views.py:107 views.py:447
|
||||
msgid "has permission"
|
||||
msgstr "имеет разрешение"
|
||||
|
||||
#: views.py:185 views.py:279 views.py:528 views.py:608
|
||||
msgid ", "
|
||||
msgstr ","
|
||||
|
||||
#: views.py:186 views.py:280 views.py:529 views.py:609
|
||||
#, python-format
|
||||
msgid " for %s"
|
||||
msgstr "для %s"
|
||||
|
||||
#: views.py:187 views.py:530
|
||||
#, python-format
|
||||
msgid " to %s"
|
||||
msgstr "до %s"
|
||||
|
||||
#: views.py:190 views.py:533
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to grant the permission %(title_suffix)s?"
|
||||
msgstr "Вы действительно хотите предоставить разрешение %(title_suffix)s?"
|
||||
|
||||
#: views.py:192 views.py:535
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to grant the permissions %(title_suffix)s?"
|
||||
msgstr "Вы уверены, что хотите предоставить разрешения %(title_suffix)s?"
|
||||
|
||||
#: views.py:199 views.py:542
|
||||
#, python-format
|
||||
msgid "Permission \"%(permission)s\" granted to %(actor)s for %(object)s."
|
||||
msgstr "Право \"%(permission)s\" проедоставлено %(actor)s для %(object)s."
|
||||
|
||||
#: views.py:205 views.py:548
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%(actor)s, already had the permission \"%(permission)s\" granted for "
|
||||
"%(object)s."
|
||||
msgstr "%(actor)s, уже имеет право \"%(permission)s\" для %(object)s."
|
||||
|
||||
#: views.py:281 views.py:610
|
||||
#, python-format
|
||||
msgid " from %s"
|
||||
msgstr "от%s"
|
||||
|
||||
#: views.py:284 views.py:613
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to revoke the permission %(title_suffix)s?"
|
||||
msgstr "Вы уверены, что хотите отменить разрешение %(title_suffix)s?"
|
||||
|
||||
#: views.py:286 views.py:615
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to revoke the permissions %(title_suffix)s?"
|
||||
msgstr "Вы уверены, что хотите отменить разрешение %(title_suffix)s?"
|
||||
|
||||
#: views.py:293 views.py:622
|
||||
#, python-format
|
||||
msgid "Permission \"%(permission)s\" revoked of %(actor)s for %(object)s."
|
||||
msgstr "Право \"%(permission)s\" для %(object)s отозвано у %(actor)s."
|
||||
|
||||
#: views.py:299 views.py:628
|
||||
#, python-format
|
||||
msgid "%(actor)s, didn't had the permission \"%(permission)s\" for %(object)s."
|
||||
msgstr "%(actor)s не имеет права \"%(permission)s\" для %(object)s."
|
||||
|
||||
#: views.py:355
|
||||
#, python-format
|
||||
msgid "add new holder for: %s"
|
||||
msgstr "добавить нового владельца для %s"
|
||||
|
||||
#: views.py:356 views.py:488
|
||||
msgid "Select"
|
||||
msgstr "Выбор"
|
||||
|
||||
#: views.py:388
|
||||
msgid "classes"
|
||||
msgstr "классы"
|
||||
|
||||
#: views.py:390
|
||||
msgid "class"
|
||||
msgstr "класс"
|
||||
|
||||
#: views.py:409
|
||||
#, python-format
|
||||
msgid "default access control lists for class: %s"
|
||||
msgstr "списки контроля доступа умолчанию для класса %s"
|
||||
|
||||
#: views.py:437
|
||||
#, python-format
|
||||
msgid "permissions available to: %(actor)s for class %(class)s"
|
||||
msgstr "разрешения доступные %(actor)s для класса %(class)s"
|
||||
|
||||
#: views.py:486
|
||||
#, python-format
|
||||
msgid "add new holder for class: %s"
|
||||
msgstr "добавить нового владельца для класса %s"
|
||||
325
apps/acls/managers.py
Normal file
325
apps/acls/managers.py
Normal file
@@ -0,0 +1,325 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import logging
|
||||
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db.models import Q
|
||||
|
||||
from common.models import AnonymousUserSingleton
|
||||
from permissions.models import Permission, RoleMember
|
||||
|
||||
from .classes import AccessHolder, ClassAccessHolder, get_source_object
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AccessEntryManager(models.Manager):
|
||||
"""
|
||||
Implement a 3 tier permission system, involving a permissions, an actor
|
||||
and an object
|
||||
"""
|
||||
def grant(self, permission, actor, obj):
|
||||
"""
|
||||
Grant a permission (what), (to) an actor, (on) a specific object
|
||||
"""
|
||||
obj = get_source_object(obj)
|
||||
actor = get_source_object(actor)
|
||||
|
||||
access_entry, created = self.model.objects.get_or_create(
|
||||
permission=permission,
|
||||
holder_type=ContentType.objects.get_for_model(actor),
|
||||
holder_id=actor.pk,
|
||||
content_type=ContentType.objects.get_for_model(obj),
|
||||
object_id=obj.pk
|
||||
)
|
||||
return created
|
||||
|
||||
def revoke(self, permission, actor, obj):
|
||||
"""
|
||||
Revoke a permission (what), (from) an actor, (on) a specific object
|
||||
"""
|
||||
obj = get_source_object(obj)
|
||||
actor = get_source_object(actor)
|
||||
|
||||
try:
|
||||
access_entry = self.model.objects.get(
|
||||
permission=permission,
|
||||
holder_type=ContentType.objects.get_for_model(actor),
|
||||
holder_id=actor.pk,
|
||||
content_type=ContentType.objects.get_for_model(obj),
|
||||
object_id=obj.pk
|
||||
)
|
||||
except self.model.DoesNotExist:
|
||||
return False
|
||||
else:
|
||||
access_entry.delete()
|
||||
return True
|
||||
|
||||
def has_access(self, permission, actor, obj, db_only=False):
|
||||
"""
|
||||
Returns whether an actor has a specific permission for an object
|
||||
"""
|
||||
obj = get_source_object(obj)
|
||||
actor = get_source_object(actor)
|
||||
|
||||
if isinstance(actor, User) and db_only == False:
|
||||
# db_only causes the return of only the stored permissions
|
||||
# and not the perceived permissions for an actor
|
||||
if actor.is_superuser or actor.is_staff:
|
||||
return True
|
||||
|
||||
actor = AnonymousUserSingleton.objects.passthru_check(actor)
|
||||
|
||||
try:
|
||||
self.model.objects.get(
|
||||
permission=permission.get_stored_permission(),
|
||||
holder_type=ContentType.objects.get_for_model(actor),
|
||||
holder_id=actor.pk,
|
||||
content_type=ContentType.objects.get_for_model(obj),
|
||||
object_id=obj.pk
|
||||
)
|
||||
except self.model.DoesNotExist:
|
||||
# If not check if the actor's memberships is one of
|
||||
# the access's holder?
|
||||
roles = RoleMember.objects.get_roles_for_member(actor)
|
||||
|
||||
if isinstance(actor, User):
|
||||
groups = actor.groups.all()
|
||||
else:
|
||||
groups = []
|
||||
|
||||
for membership in list(set(roles) | set(groups)):
|
||||
if self.has_access(permission, membership, obj, db_only):
|
||||
return True
|
||||
|
||||
logger.debug('Fallthru')
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def check_access(self, permission, actor, obj):
|
||||
# TODO: Merge with has_access
|
||||
obj = get_source_object(obj)
|
||||
actor = get_source_object(actor)
|
||||
|
||||
if self.has_access(permission, actor, obj):
|
||||
return True
|
||||
else:
|
||||
raise PermissionDenied(ugettext(u'Insufficient access.'))
|
||||
|
||||
def check_accesses(self, permission_list, actor, obj):
|
||||
"""
|
||||
Returns whether an actor has at least one of a list of permissions for an object
|
||||
"""
|
||||
obj = get_source_object(obj)
|
||||
actor = get_source_object(actor)
|
||||
for permission in permission_list:
|
||||
if self.has_access(permission, actor, obj):
|
||||
return True
|
||||
|
||||
raise PermissionDenied(ugettext(u'Insufficient access.'))
|
||||
|
||||
def get_allowed_class_objects(self, permission, actor, cls, related=None):
|
||||
logger.debug('related: %s' % related)
|
||||
|
||||
actor = AnonymousUserSingleton.objects.passthru_check(actor)
|
||||
actor_type = ContentType.objects.get_for_model(actor)
|
||||
content_type = ContentType.objects.get_for_model(cls)
|
||||
|
||||
# Calculate actor role membership ACL query
|
||||
total_queries = None
|
||||
for role in RoleMember.objects.get_roles_for_member(actor):
|
||||
role_type = ContentType.objects.get_for_model(role)
|
||||
if related:
|
||||
query = Q(holder_type=role_type, holder_id=role.pk, permission=permission.get_stored_permission)
|
||||
else:
|
||||
query = Q(holder_type=role_type, holder_id=role.pk, content_type=content_type, permission=permission.get_stored_permission)
|
||||
if total_queries is None:
|
||||
total_queries = query
|
||||
else:
|
||||
total_queries = total_queries | query
|
||||
|
||||
# Calculate actor group membership ACL query
|
||||
if isinstance(actor, User):
|
||||
groups = actor.groups.all()
|
||||
else:
|
||||
groups = []
|
||||
|
||||
for group in groups:
|
||||
group_type = ContentType.objects.get_for_model(group)
|
||||
if related:
|
||||
query = Q(holder_type=group_type, holder_id=group.pk, permission=permission.get_stored_permission)
|
||||
else:
|
||||
query = Q(holder_type=group_type, holder_id=group.pk, content_type=content_type, permission=permission.get_stored_permission)
|
||||
if total_queries is None:
|
||||
total_queries = query
|
||||
else:
|
||||
total_queries = total_queries | query
|
||||
|
||||
if related:
|
||||
actor_query = Q(holder_type=actor_type, holder_id=actor.pk, permission=permission.get_stored_permission)
|
||||
master_list = [obj.content_object for obj in self.model.objects.select_related().filter(actor_query | total_queries)]
|
||||
logger.debug('master_list: %s' % master_list)
|
||||
# TODO: update to use Q objects and check performance diff
|
||||
# kwargs = {'%s__in' % related: master_list}
|
||||
# Q(**kwargs)
|
||||
return (obj for obj in cls.objects.all() if getattr(obj, related) in master_list)
|
||||
else:
|
||||
actor_query = Q(holder_type=actor_type, holder_id=actor.pk, content_type=content_type, permission=permission.get_stored_permission)
|
||||
return (obj.content_object for obj in self.model.objects.filter(actor_query | total_queries))
|
||||
|
||||
def get_acl_url(self, obj):
|
||||
content_type = ContentType.objects.get_for_model(obj)
|
||||
return reverse('acl_list', args=[content_type.app_label, content_type.model, obj.pk])
|
||||
|
||||
def get_new_holder_url(self, obj):
|
||||
content_type = ContentType.objects.get_for_model(obj)
|
||||
return reverse('acl_new_holder_for', args=[content_type.app_label, content_type.model, obj.pk])
|
||||
|
||||
def get_holders_for(self, obj):
|
||||
content_type = ContentType.objects.get_for_model(obj)
|
||||
holder_list = []
|
||||
for access_entry in self.model.objects.filter(content_type=content_type, object_id=obj.pk):
|
||||
if access_entry.holder_object:
|
||||
# Don't add references to non existant content type objects
|
||||
entry = AccessHolder.encapsulate(access_entry.holder_object)
|
||||
|
||||
if entry not in holder_list:
|
||||
holder_list.append(entry)
|
||||
|
||||
return holder_list
|
||||
|
||||
def get_holder_permissions_for(self, obj, actor, db_only=False):
|
||||
"""
|
||||
Returns a list of actors that hold at least one permission for
|
||||
a specific object
|
||||
"""
|
||||
logger.debug('obj: %s' % obj)
|
||||
logger.debug('actor: %s' % actor)
|
||||
|
||||
if isinstance(actor, User) and db_only == False:
|
||||
if actor.is_superuser or actor.is_staff:
|
||||
return Permission.objects.all()
|
||||
|
||||
actor_type = ContentType.objects.get_for_model(actor)
|
||||
content_type = ContentType.objects.get_for_model(obj)
|
||||
return (access.permission for access in self.model.objects.filter(content_type=content_type, object_id=obj.pk, holder_type=actor_type, holder_id=actor.pk))
|
||||
|
||||
def filter_objects_by_access(self, permission, actor, object_list, exception_on_empty=False, related=None):
|
||||
"""
|
||||
Filter a list of objects or a QuerySet elements depending on
|
||||
whether the actor holds the specified permission
|
||||
"""
|
||||
logger.debug('exception_on_empty: %s' % exception_on_empty)
|
||||
logger.debug('object_list: %s' % object_list)
|
||||
|
||||
if isinstance(actor, User):
|
||||
if actor.is_superuser or actor.is_staff:
|
||||
return object_list
|
||||
|
||||
try:
|
||||
if object_list.count() == 0:
|
||||
return object_list
|
||||
except TypeError:
|
||||
# object_list is not a queryset
|
||||
if len(object_list) == 0:
|
||||
return object_list
|
||||
|
||||
try:
|
||||
# Try to process as a QuerySet
|
||||
qs = object_list.filter(pk__in=[obj.pk for obj in self.get_allowed_class_objects(permission, actor, object_list[0].__class__, related)])
|
||||
logger.debug('qs: %s' % qs)
|
||||
|
||||
if qs.count() == 0 and exception_on_empty == True:
|
||||
raise PermissionDenied
|
||||
|
||||
return qs
|
||||
except AttributeError:
|
||||
# Fallback to a filtered list
|
||||
object_list = list(set(object_list) & set(self.get_allowed_class_objects(permission, actor, object_list[0].__class__, related)))
|
||||
logger.debug('object_list: %s' % object_list)
|
||||
if len(object_list) == 0 and exception_on_empty == True:
|
||||
raise PermissionDenied
|
||||
|
||||
return object_list
|
||||
|
||||
|
||||
class DefaultAccessEntryManager(models.Manager):
|
||||
"""
|
||||
Implement a 3 tier permission system, involving a permission, an actor
|
||||
and a class or content type. This model keeps track of the access
|
||||
control lists that will be added when an instance of the recorded
|
||||
content type is created.
|
||||
"""
|
||||
def get_holders_for(self, cls):
|
||||
cls = get_source_object(cls)
|
||||
content_type = ContentType.objects.get_for_model(cls)
|
||||
holder_list = []
|
||||
for access_entry in self.model.objects.filter(content_type=content_type):
|
||||
if access_entry.holder_object:
|
||||
# Don't add references to non existant content type objects
|
||||
entry = ClassAccessHolder.encapsulate(access_entry.holder_object)
|
||||
|
||||
if entry not in holder_list:
|
||||
holder_list.append(entry)
|
||||
|
||||
return holder_list
|
||||
|
||||
def has_access(self, permission, actor, cls):
|
||||
if isinstance(actor, User):
|
||||
if actor.is_superuser or actor.is_staff:
|
||||
return True
|
||||
|
||||
try:
|
||||
self.model.objects.get(
|
||||
permission=permission.get_stored_permission(),
|
||||
holder_type=ContentType.objects.get_for_model(actor),
|
||||
holder_id=actor.pk,
|
||||
content_type=ContentType.objects.get_for_model(cls),
|
||||
)
|
||||
except self.model.DoesNotExist:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def grant(self, permission, actor, cls):
|
||||
"""
|
||||
Grant a permission (what), (to) an actor, (on) a specific class
|
||||
"""
|
||||
access_entry, created = self.model.objects.get_or_create(
|
||||
permission=permission,
|
||||
holder_type=ContentType.objects.get_for_model(actor),
|
||||
holder_id=actor.pk,
|
||||
content_type=ContentType.objects.get_for_model(cls),
|
||||
)
|
||||
return created
|
||||
|
||||
def revoke(self, permission, actor, cls):
|
||||
"""
|
||||
Revoke a permission (what), (from) an actor, (on) a specific class
|
||||
"""
|
||||
try:
|
||||
access_entry = self.model.objects.get(
|
||||
permission=permission,
|
||||
holder_type=ContentType.objects.get_for_model(actor),
|
||||
holder_id=actor.pk,
|
||||
content_type=ContentType.objects.get_for_model(cls),
|
||||
)
|
||||
access_entry.delete()
|
||||
return True
|
||||
except self.model.DoesNotExist:
|
||||
return False
|
||||
|
||||
def get_holder_permissions_for(self, cls, actor):
|
||||
if isinstance(actor, User):
|
||||
if actor.is_superuser or actor.is_staff:
|
||||
return Permission.objects.all()
|
||||
|
||||
actor_type = ContentType.objects.get_for_model(actor)
|
||||
content_type = ContentType.objects.get_for_model(cls)
|
||||
return [access.permission for access in self.model.objects.filter(content_type=content_type, holder_type=actor_type, holder_id=actor.pk)]
|
||||
112
apps/acls/models.py
Normal file
112
apps/acls/models.py
Normal file
@@ -0,0 +1,112 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import logging
|
||||
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import ugettext
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.contrib.contenttypes import generic
|
||||
|
||||
from permissions.models import StoredPermission
|
||||
from common.models import Singleton, SingletonManager
|
||||
|
||||
from .managers import AccessEntryManager, DefaultAccessEntryManager
|
||||
from .classes import AccessObjectClass
|
||||
from .api import get_classes
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AccessEntry(models.Model):
|
||||
"""
|
||||
Model that hold the permission, object, actor relationship
|
||||
"""
|
||||
permission = models.ForeignKey(StoredPermission, verbose_name=_(u'permission'))
|
||||
|
||||
holder_type = models.ForeignKey(
|
||||
ContentType,
|
||||
related_name='access_holder',
|
||||
limit_choices_to={'model__in': ('user', 'group', 'role')}
|
||||
)
|
||||
holder_id = models.PositiveIntegerField()
|
||||
holder_object = generic.GenericForeignKey(
|
||||
ct_field='holder_type',
|
||||
fk_field='holder_id'
|
||||
)
|
||||
|
||||
content_type = models.ForeignKey(
|
||||
ContentType,
|
||||
related_name='object_content_type'
|
||||
)
|
||||
object_id = models.PositiveIntegerField()
|
||||
content_object = generic.GenericForeignKey(
|
||||
ct_field='content_type',
|
||||
fk_field='object_id'
|
||||
)
|
||||
|
||||
objects = AccessEntryManager()
|
||||
|
||||
class Meta:
|
||||
verbose_name = _(u'access entry')
|
||||
verbose_name_plural = _(u'access entries')
|
||||
|
||||
def __unicode__(self):
|
||||
return u'%s: %s' % (self.content_type, self.content_object)
|
||||
|
||||
|
||||
class DefaultAccessEntry(models.Model):
|
||||
"""
|
||||
Model that holds the permission, class, actor relationship, that will
|
||||
be added upon the creation of an instance of said class
|
||||
"""
|
||||
@classmethod
|
||||
def get_classes(cls):
|
||||
return [AccessObjectClass.encapsulate(cls) for cls in get_classes()]
|
||||
|
||||
permission = models.ForeignKey(StoredPermission, verbose_name=_(u'permission'))
|
||||
|
||||
holder_type = models.ForeignKey(
|
||||
ContentType,
|
||||
limit_choices_to={'model__in': ('user', 'group', 'role')},
|
||||
related_name='default_access_entry_holder'
|
||||
)
|
||||
holder_id = models.PositiveIntegerField()
|
||||
holder_object = generic.GenericForeignKey(
|
||||
ct_field='holder_type',
|
||||
fk_field='holder_id'
|
||||
)
|
||||
|
||||
content_type = models.ForeignKey(
|
||||
ContentType,
|
||||
related_name='default_access_entry_class'
|
||||
)
|
||||
|
||||
objects = DefaultAccessEntryManager()
|
||||
|
||||
class Meta:
|
||||
verbose_name = _(u'default access entry')
|
||||
verbose_name_plural = _(u'default access entries')
|
||||
|
||||
def __unicode__(self):
|
||||
return u'%s: %s' % (self.content_type, self.content_object)
|
||||
|
||||
|
||||
class CreatorSingletonManager(SingletonManager):
|
||||
def passthru_check(self, holder, creator=None):
|
||||
if isinstance(holder, self.model):
|
||||
# TODO: raise explicit error if is instance and creator=None
|
||||
return creator
|
||||
else:
|
||||
return holder
|
||||
|
||||
|
||||
class CreatorSingleton(Singleton):
|
||||
objects = CreatorSingletonManager()
|
||||
|
||||
def __unicode__(self):
|
||||
return ugettext('Creator')
|
||||
|
||||
class Meta:
|
||||
verbose_name = _(u'creator')
|
||||
verbose_name_plural = _(u'creator')
|
||||
14
apps/acls/permissions.py
Normal file
14
apps/acls/permissions.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from permissions.models import PermissionNamespace, Permission
|
||||
|
||||
acls_namespace = PermissionNamespace('acls', _(u'Access control lists'))
|
||||
acls_setup_namespace = PermissionNamespace('acls_setup', _(u'Access control lists'))
|
||||
|
||||
ACLS_EDIT_ACL = Permission.objects.register(acls_namespace, 'acl_edit', _(u'Edit ACLs'))
|
||||
ACLS_VIEW_ACL = Permission.objects.register(acls_namespace, 'acl_view', _(u'View ACLs'))
|
||||
|
||||
ACLS_CLASS_EDIT_ACL = Permission.objects.register(acls_setup_namespace, 'acl_class_edit', _(u'Edit class default ACLs'))
|
||||
ACLS_CLASS_VIEW_ACL = Permission.objects.register(acls_setup_namespace, 'acl_class_view', _(u'View class default ACLs'))
|
||||
BIN
apps/acls/static/images/icons/lock.png
Normal file
BIN
apps/acls/static/images/icons/lock.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
71
apps/acls/templatetags/acl_tags.py
Normal file
71
apps/acls/templatetags/acl_tags.py
Normal file
@@ -0,0 +1,71 @@
|
||||
import logging
|
||||
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.template import (TemplateSyntaxError, Library,
|
||||
Node, Variable, VariableDoesNotExist)
|
||||
|
||||
|
||||
from acls.models import AccessEntry
|
||||
|
||||
register = Library()
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CheckAccessNode(Node):
|
||||
def __init__(self, permission_list=None, requester=None, obj=None, *args, **kwargs):
|
||||
self.requester = requester
|
||||
self.permission_list = permission_list
|
||||
self.obj = obj
|
||||
|
||||
def render(self, context):
|
||||
permission_list = Variable(self.permission_list).resolve(context)
|
||||
logger.debug('permission_list: %s' % u','.join([unicode(p) for p in permission_list]))
|
||||
|
||||
try:
|
||||
# Check access_object, useful for document_page views
|
||||
obj = Variable('access_object').resolve(context)
|
||||
logger.debug('access_object: %s' % obj)
|
||||
except VariableDoesNotExist:
|
||||
try:
|
||||
obj = Variable(self.obj).resolve(context)
|
||||
logger.debug('obj: %s' % obj)
|
||||
except VariableDoesNotExist:
|
||||
context[u'access'] = False
|
||||
logger.debug('no obj, access False')
|
||||
return u''
|
||||
|
||||
if not permission_list:
|
||||
# There is no permissions list to check against which means
|
||||
# this link is available for all
|
||||
context[u'access'] = True
|
||||
return u''
|
||||
|
||||
requester = Variable(self.requester).resolve(context)
|
||||
logger.debug('requester: %s' % requester)
|
||||
|
||||
if obj:
|
||||
try:
|
||||
AccessEntry.objects.check_accesses(permission_list, requester, obj)
|
||||
except PermissionDenied:
|
||||
context[u'access'] = False
|
||||
logger.debug('access: False')
|
||||
return u''
|
||||
else:
|
||||
context[u'access'] = True
|
||||
logger.debug('access: True')
|
||||
return u''
|
||||
else:
|
||||
context[u'access'] = False
|
||||
logger.debug('No object, access: False')
|
||||
return u''
|
||||
|
||||
|
||||
@register.tag
|
||||
def check_access(parser, token):
|
||||
try:
|
||||
# Splitting by None == splitting by spaces.
|
||||
tag_name, args = token.contents.split(None, 1)
|
||||
except ValueError:
|
||||
raise TemplateSyntaxError(u'%r tag requires arguments' % token.contents.split()[0])
|
||||
|
||||
return CheckAccessNode(*args.split())
|
||||
20
apps/acls/urls.py
Normal file
20
apps/acls/urls.py
Normal file
@@ -0,0 +1,20 @@
|
||||
from django.conf.urls.defaults import patterns, url
|
||||
|
||||
urlpatterns = patterns('acls.views',
|
||||
url(r'^new_holder_for/(?P<app_label>[-\w]+)/(?P<model_name>[-\w]+)/(?P<object_id>\d+)/$', 'acl_new_holder_for', (), 'acl_new_holder_for'),
|
||||
url(r'^list_for/(?P<app_label>[-\w]+)/(?P<model_name>[-\w]+)/(?P<object_id>\d+)/$', 'acl_list', (), 'acl_list'),
|
||||
url(r'^details/(?P<access_object_gid>[.\w]+)/holder/(?P<holder_object_gid>[.\w]+)/$', 'acl_detail', (), 'acl_detail'),
|
||||
url(r'^holder/new/(?P<access_object_gid>[.\w]+)/$', 'acl_holder_new', (), 'acl_holder_new'),
|
||||
|
||||
url(r'^multiple/grant/$', 'acl_grant', (), 'acl_multiple_grant'),
|
||||
url(r'^multiple/revoke/$', 'acl_revoke', (), 'acl_multiple_revoke'),
|
||||
|
||||
url(r'^class/$', 'acl_setup_valid_classes', (), 'acl_setup_valid_classes'),
|
||||
url(r'^class/details/(?P<access_object_class_gid>[.\w]+)/holder/(?P<holder_object_gid>[.\w]+)/$', 'acl_class_acl_detail', (), 'acl_class_acl_detail'),
|
||||
url(r'^class/list_for/(?P<access_object_class_gid>[.\w]+)/$', 'acl_class_acl_list', (), 'acl_class_acl_list'),
|
||||
url(r'^class/holder/new/(?P<access_object_class_gid>[.\w]+)/$', 'acl_class_new_holder_for', (), 'acl_class_new_holder_for'),
|
||||
|
||||
url(r'^class/multiple/grant/$', 'acl_class_multiple_grant', (), 'acl_class_multiple_grant'),
|
||||
url(r'^class/multiple/revoke/$', 'acl_class_multiple_revoke', (), 'acl_class_multiple_revoke'),
|
||||
|
||||
)
|
||||
34
apps/acls/utils.py
Normal file
34
apps/acls/utils.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import logging
|
||||
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
from common.models import AnonymousUserSingleton
|
||||
|
||||
from .models import AccessEntry, DefaultAccessEntry, CreatorSingleton
|
||||
from .classes import get_source_object
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def apply_default_acls(obj, actor=None):
|
||||
logger.debug('actor, init: %s' % actor)
|
||||
obj = get_source_object(obj)
|
||||
|
||||
if actor:
|
||||
actor = AnonymousUserSingleton.objects.passthru_check(actor)
|
||||
|
||||
content_type = ContentType.objects.get_for_model(obj)
|
||||
|
||||
for default_acl in DefaultAccessEntry.objects.filter(content_type=content_type):
|
||||
holder = CreatorSingleton.objects.passthru_check(default_acl.holder_object, actor)
|
||||
|
||||
if holder:
|
||||
# When the creator is admin
|
||||
access_entry = AccessEntry(
|
||||
permission=default_acl.permission,
|
||||
holder_object=holder,
|
||||
content_object=obj,
|
||||
)
|
||||
access_entry.save()
|
||||
649
apps/acls/views.py
Normal file
649
apps/acls/views.py
Normal file
File diff suppressed because it is too large
Load Diff
27
apps/acls/widgets.py
Normal file
27
apps/acls/widgets.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.db.models.base import ModelBase
|
||||
from django.template.defaultfilters import capfirst
|
||||
|
||||
from .literals import CONTENT_TYPE_ICON_MAP
|
||||
|
||||
|
||||
def content_type_icon(content_type):
|
||||
return mark_safe(u'<span class="famfam active famfam-%s"></span>' % CONTENT_TYPE_ICON_MAP.get('%s.%s' % (content_type.app_label, content_type.model), 'help'))
|
||||
|
||||
|
||||
def object_w_content_type_icon(obj):
|
||||
content_type = ContentType.objects.get_for_model(obj)
|
||||
|
||||
ct_fullname = '%s.%s' % (content_type.app_label, content_type.name)
|
||||
if isinstance(obj, ModelBase):
|
||||
label = getattr(obj._meta, 'verbose_name_plural', unicode(content_type))
|
||||
else:
|
||||
if ct_fullname == 'auth.user':
|
||||
label = obj.get_full_name()
|
||||
else:
|
||||
label = unicode(obj)
|
||||
|
||||
return mark_safe('%s<span>%s</span>' % (content_type_icon(content_type), capfirst(label)))
|
||||
@@ -1,14 +1,17 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import tempfile
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.contrib.auth import models as auth_models
|
||||
from django.contrib.auth.management import create_superuser
|
||||
from django.db.models import signals
|
||||
from django.dispatch import receiver
|
||||
from django.db.models.signals import post_syncdb
|
||||
|
||||
from navigation.api import register_links, register_top_menu
|
||||
|
||||
from common.conf import settings as common_settings
|
||||
from common.utils import validate_path
|
||||
from .conf import settings as common_settings
|
||||
from .utils import validate_path
|
||||
|
||||
|
||||
def has_usable_password(context):
|
||||
@@ -21,42 +24,38 @@ current_user_edit = {'text': _(u'edit details'), 'view': 'current_user_edit', 'f
|
||||
register_links(['current_user_details', 'current_user_edit', 'password_change_view'], [current_user_details, current_user_edit, password_change_view], menu_name='secondary_menu')
|
||||
|
||||
about_view = {'text': _('about'), 'view': 'about_view', 'famfam': 'information'}
|
||||
changelog_view = {'text': _('changelog'), 'view': 'changelog_view', 'famfam': 'book_open'}
|
||||
license_view = {'text': _('license'), 'view': 'license_view', 'famfam': 'script'}
|
||||
|
||||
register_links(['about_view', 'changelog_view', 'license_view'], [about_view, changelog_view, license_view], menu_name='secondary_menu')
|
||||
register_links(['about_view', 'license_view'], [about_view, license_view], menu_name='secondary_menu')
|
||||
|
||||
register_top_menu('about', link={'text': _(u'about'), 'view': 'about_view', 'famfam': 'information'}, position=-1)
|
||||
|
||||
|
||||
if common_settings.AUTO_CREATE_ADMIN:
|
||||
# From https://github.com/lambdalisue/django-qwert/blob/master/qwert/autoscript/__init__.py
|
||||
# From http://stackoverflow.com/questions/1466827/ --
|
||||
#
|
||||
# Prevent interactive question about wanting a superuser created. (This code
|
||||
# has to go in this otherwise empty "models" module so that it gets processed by
|
||||
# the "syncdb" command during database creation.)
|
||||
#
|
||||
# Create our own test user automatically.
|
||||
@receiver(post_syncdb, dispatch_uid='create_superuser', sender=auth_models)
|
||||
def create_superuser(sender, **kwargs):
|
||||
"""
|
||||
From https://github.com/lambdalisue/django-qwert/blob/master/qwert/autoscript/__init__.py
|
||||
From http://stackoverflow.com/questions/1466827/ --
|
||||
|
||||
def create_testuser(app, created_models, verbosity, **kwargs):
|
||||
Prevent interactive question about wanting a superuser created. (This code
|
||||
has to go in this otherwise empty "models" module so that it gets processed by
|
||||
the "syncdb" command during database creation.)
|
||||
|
||||
Create our own admin super user automatically.
|
||||
"""
|
||||
|
||||
if common_settings.AUTO_CREATE_ADMIN:
|
||||
USERNAME = common_settings.AUTO_ADMIN_USERNAME
|
||||
PASSWORD = common_settings.AUTO_ADMIN_PASSWORD
|
||||
try:
|
||||
auth_models.User.objects.get(username=USERNAME)
|
||||
except auth_models.User.DoesNotExist:
|
||||
print '*' * 80
|
||||
print 'Creating test user -- login: %s, password: %s' % (USERNAME, PASSWORD)
|
||||
print 'Creating super admin user -- login: %s, password: %s' % (USERNAME, PASSWORD)
|
||||
print '*' * 80
|
||||
assert auth_models.User.objects.create_superuser(USERNAME, 'x@x.com', PASSWORD)
|
||||
else:
|
||||
print 'Test user already exists. -- login: %s, password: %s' % (USERNAME, PASSWORD)
|
||||
signals.post_syncdb.disconnect(
|
||||
create_superuser,
|
||||
sender=auth_models,
|
||||
dispatch_uid='django.contrib.auth.management.create_superuser')
|
||||
signals.post_syncdb.connect(create_testuser,
|
||||
sender=auth_models, dispatch_uid='common.models.create_testuser')
|
||||
print 'Super admin user already exists. -- login: %s, password: %s' % (USERNAME, PASSWORD)
|
||||
|
||||
if (validate_path(common_settings.TEMPORARY_DIRECTORY) == False) or (not common_settings.TEMPORARY_DIRECTORY):
|
||||
setattr(common_settings, 'TEMPORARY_DIRECTORY', tempfile.mkdtemp())
|
||||
|
||||
84
apps/common/compressed_files.py
Normal file
84
apps/common/compressed_files.py
Normal file
@@ -0,0 +1,84 @@
|
||||
import zipfile
|
||||
|
||||
try:
|
||||
import zlib
|
||||
COMPRESSION = zipfile.ZIP_DEFLATED
|
||||
except:
|
||||
COMPRESSION = zipfile.ZIP_STORED
|
||||
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
except ImportError:
|
||||
from StringIO import StringIO
|
||||
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
|
||||
|
||||
class NotACompressedFile(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class CompressedFile(object):
|
||||
def __init__(self, file_input=None):
|
||||
if file_input:
|
||||
self._open(file_input)
|
||||
else:
|
||||
self._create()
|
||||
|
||||
def _create(self):
|
||||
self.descriptor = StringIO()
|
||||
self.zf = zipfile.ZipFile(self.descriptor, mode='w')
|
||||
|
||||
def _open(self, file_input):
|
||||
try:
|
||||
# Is it a file like object?
|
||||
file_input.seek(0)
|
||||
except AttributeError:
|
||||
# If not, try open it.
|
||||
self.descriptor = open(file_input, 'r+b')
|
||||
else:
|
||||
self.descriptor = file_input
|
||||
|
||||
try:
|
||||
test = zipfile.ZipFile(self.descriptor, mode='r')
|
||||
except zipfile.BadZipfile:
|
||||
raise NotACompressedFile
|
||||
else:
|
||||
test.close()
|
||||
self.descriptor.seek(0)
|
||||
self.zf = zipfile.ZipFile(self.descriptor, mode='a')
|
||||
|
||||
def add_file(self, file_input, arcname=None):
|
||||
try:
|
||||
# Is it a file like object?
|
||||
file_input.seek(0)
|
||||
except AttributeError:
|
||||
# If not, keep it
|
||||
self.zf.write(file_input, arcname=arcname, compress_type=COMPRESSION)
|
||||
else:
|
||||
self.zf.writestr(arcname, file_input.read())
|
||||
|
||||
def contents(self):
|
||||
return [filename for filename in self.zf.namelist() if not filename.endswith('/')]
|
||||
|
||||
def get_content(self, filename):
|
||||
return self.zf.read(filename)
|
||||
|
||||
def write(self, filename=None):
|
||||
# fix for Linux zip files read in Windows
|
||||
for file in self.zf.filelist:
|
||||
file.create_system = 0
|
||||
|
||||
self.descriptor.seek(0)
|
||||
|
||||
if filename:
|
||||
descriptor = open(filename, 'w')
|
||||
descriptor.write(self.descriptor.read())
|
||||
else:
|
||||
return self.descriptor
|
||||
|
||||
def as_file(self, filename):
|
||||
return SimpleUploadedFile(name=filename, content=self.write().read())
|
||||
|
||||
def close(self):
|
||||
self.zf.close()
|
||||
@@ -64,3 +64,12 @@ register_setting(
|
||||
default=u'username',
|
||||
description=_(u'Controls the mechanism used to authenticated user. Options are: username, email'),
|
||||
)
|
||||
|
||||
register_setting(
|
||||
namespace=u'common',
|
||||
module=u'common.conf.settings',
|
||||
name=u'ALLOW_ANONYMOUS_ACCESS',
|
||||
global_name=u'COMMON_ALLOW_ANONYMOUS_ACCESS',
|
||||
default=False,
|
||||
description=_(u'Allow non authenticated users, access to all views'),
|
||||
)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
|
||||
from django import forms
|
||||
@@ -8,9 +10,9 @@ from django.contrib.auth.forms import AuthenticationForm
|
||||
from django.contrib.auth import authenticate
|
||||
from django.conf import settings
|
||||
|
||||
from common.utils import return_attrib
|
||||
from common.widgets import DetailSelectMultiple, PlainWidget, \
|
||||
TextAreaDiv, EmailInput
|
||||
from .utils import return_attrib
|
||||
from .widgets import (DetailSelectMultiple, PlainWidget, TextAreaDiv,
|
||||
EmailInput)
|
||||
|
||||
|
||||
class DetailForm(forms.ModelForm):
|
||||
@@ -120,7 +122,7 @@ class UserForm(forms.ModelForm):
|
||||
"""
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ('first_name', 'last_name')
|
||||
fields = ('username', 'first_name', 'last_name', 'email')
|
||||
|
||||
|
||||
class EmailAuthenticationForm(AuthenticationForm):
|
||||
@@ -129,7 +131,7 @@ class EmailAuthenticationForm(AuthenticationForm):
|
||||
authentication
|
||||
"""
|
||||
email = forms.CharField(label=_(u'Email'), max_length=75,
|
||||
widget=EmailInput()
|
||||
widget=EmailInput(attrs={'style': 'width: 100%;'})
|
||||
)
|
||||
|
||||
def clean(self):
|
||||
@@ -151,7 +153,7 @@ EmailAuthenticationForm.base_fields.keyOrder = ['email', 'password']
|
||||
|
||||
class FileDisplayForm(forms.Form):
|
||||
text = forms.CharField(
|
||||
label='',#_(u'Text'),
|
||||
label='', # _(u'Text'),
|
||||
widget=forms.widgets.Textarea(
|
||||
attrs={'cols': 40, 'rows': 20, 'readonly': 'readonly'}
|
||||
)
|
||||
@@ -159,17 +161,12 @@ class FileDisplayForm(forms.Form):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(FileDisplayForm, self).__init__(*args, **kwargs)
|
||||
changelog_path = os.path.join(settings.PROJECT_ROOT, self.DIRECTORY, self.FILENAME)
|
||||
changelog_path = os.path.join(settings.PROJECT_ROOT, os.sep.join(self.DIRECTORY), self.FILENAME)
|
||||
fd = open(changelog_path)
|
||||
self.fields['text'].initial = fd.read()
|
||||
fd.close()
|
||||
|
||||
|
||||
class ChangelogForm(FileDisplayForm):
|
||||
FILENAME = u'changelog.rst'
|
||||
DIRECTORY = u'docs'
|
||||
|
||||
|
||||
class LicenseForm(FileDisplayForm):
|
||||
FILENAME = u'LICENSE'
|
||||
DIRECTORY = u'docs'
|
||||
DIRECTORY = [u'docs', u'credits']
|
||||
|
||||
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
|
||||
"POT-Creation-Date: 2012-02-12 15:20-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"
|
||||
@@ -17,45 +17,41 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: __init__.py:17
|
||||
#: __init__.py:20
|
||||
msgid "change password"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:18
|
||||
#: __init__.py:21
|
||||
msgid "user details"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:19
|
||||
#: __init__.py:22
|
||||
msgid "edit details"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:23 __init__.py:29
|
||||
#: __init__.py:26 __init__.py:31
|
||||
msgid "about"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:24
|
||||
msgid "changelog"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:25
|
||||
#: __init__.py:27
|
||||
msgid "license"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:99
|
||||
#: forms.py:101
|
||||
msgid "Selection"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:131
|
||||
#: forms.py:133
|
||||
msgid "Email"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:142
|
||||
#: forms.py:144
|
||||
msgid ""
|
||||
"Please enter a correct email and password. Note that the password fields is "
|
||||
"case-sensitive."
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:144
|
||||
#: forms.py:146
|
||||
msgid "This account is inactive."
|
||||
msgstr ""
|
||||
|
||||
@@ -99,68 +95,79 @@ msgstr ""
|
||||
msgid "Landscape"
|
||||
msgstr ""
|
||||
|
||||
#: utils.py:291
|
||||
#: models.py:16
|
||||
msgid "lock field"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:43
|
||||
msgid "Anonymous user"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:46 models.py:47
|
||||
msgid "anonymous user"
|
||||
msgstr ""
|
||||
|
||||
#: utils.py:295
|
||||
msgid "function found"
|
||||
msgstr ""
|
||||
|
||||
#: utils.py:293 utils.py:295
|
||||
#, python-format
|
||||
msgid "class found: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:24 templates/password_change_done.html:5
|
||||
msgid "Your password has been successfully changed."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:41
|
||||
#: views.py:36
|
||||
msgid "No action selected."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:45
|
||||
#: views.py:40
|
||||
msgid "Must select at least one item."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:86
|
||||
#: views.py:88
|
||||
#, python-format
|
||||
msgid "%(selection)s added successfully added to %(right_list_title)s."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:89 views.py:106
|
||||
#: views.py:94 views.py:121
|
||||
#, python-format
|
||||
msgid "Unable to add %(selection)s to %(right_list_title)s."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:103
|
||||
#: views.py:115
|
||||
#, python-format
|
||||
msgid "%(selection)s added successfully removed from %(right_list_title)s."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:121
|
||||
#: views.py:136
|
||||
msgid "Add"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:132
|
||||
#: views.py:147
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:155
|
||||
#: views.py:170
|
||||
msgid "current user details"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:172
|
||||
#: views.py:187
|
||||
msgid "E-mail conflict, another user has that same email."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:190
|
||||
msgid "Current user's details updated."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:181
|
||||
#: views.py:199
|
||||
msgid "edit current user details"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:207
|
||||
msgid "Changelog"
|
||||
#: views.py:230
|
||||
msgid "License"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:220
|
||||
msgid "License"
|
||||
#: views.py:239
|
||||
msgid "Current user password change"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:254 templates/password_change_done.html:5
|
||||
msgid "Your password has been successfully changed."
|
||||
msgstr ""
|
||||
|
||||
#: widgets.py:58
|
||||
@@ -180,6 +187,10 @@ msgid ""
|
||||
"email"
|
||||
msgstr ""
|
||||
|
||||
#: conf/settings.py:74
|
||||
msgid "Allow non authenticated users, access to all views"
|
||||
msgstr ""
|
||||
|
||||
#: templates/403.html:3 templates/403.html.py:7
|
||||
msgid "Insufficient permissions"
|
||||
msgstr ""
|
||||
@@ -260,28 +271,32 @@ msgid "No"
|
||||
msgstr ""
|
||||
|
||||
#: templates/generic_form_instance.html:37
|
||||
#: templates/generic_form_subtemplate.html:52
|
||||
#: templates/generic_form_subtemplate.html:56
|
||||
msgid "required"
|
||||
msgstr ""
|
||||
|
||||
#: templates/generic_form_subtemplate.html:76
|
||||
#: templates/generic_form_subtemplate.html:78
|
||||
#: templates/generic_form_subtemplate.html:80
|
||||
#: templates/generic_form_subtemplate.html:82
|
||||
#: templates/generic_list_horizontal_subtemplate.html:51
|
||||
#: templates/generic_list_horizontal_subtemplate.html:178
|
||||
#: templates/generic_list_horizontal_subtemplate.html:90
|
||||
#: templates/generic_list_subtemplate.html:52
|
||||
#: templates/generic_list_subtemplate.html:178
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: templates/generic_form_subtemplate.html:76
|
||||
#: templates/generic_form_subtemplate.html:78
|
||||
#: templates/generic_form_subtemplate.html:80
|
||||
#: templates/generic_form_subtemplate.html:82
|
||||
#: templates/generic_list_horizontal_subtemplate.html:51
|
||||
#: templates/generic_list_horizontal_subtemplate.html:178
|
||||
#: templates/generic_list_horizontal_subtemplate.html:90
|
||||
#: templates/generic_list_subtemplate.html:52
|
||||
#: templates/generic_list_subtemplate.html:178
|
||||
msgid "Submit"
|
||||
msgstr ""
|
||||
|
||||
#: templates/generic_form_subtemplate.html:87
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: templates/generic_list.html:6 templates/generic_list_horizontal.html:6
|
||||
#, python-format
|
||||
msgid "List of %(stripped_title)s"
|
||||
|
||||
Binary file not shown.
@@ -3,14 +3,14 @@
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Roberto Rosario <roberto.rosario.gonzalez@gmail.com>, 2011.
|
||||
# Roberto Rosario <roberto.rosario.gonzalez@gmail.com>, 2011, 2012.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Mayan EDMS\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
|
||||
"PO-Revision-Date: 2011-11-04 00:58+0000\n"
|
||||
"Last-Translator: rosarior <roberto.rosario.gonzalez@gmail.com>\n"
|
||||
"POT-Creation-Date: 2012-02-12 15:20-0400\n"
|
||||
"PO-Revision-Date: 2012-02-02 18:39+0000\n"
|
||||
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
|
||||
"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/"
|
||||
"mayan-edms/team/es/)\n"
|
||||
"Language: es\n"
|
||||
@@ -19,39 +19,35 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
|
||||
#: __init__.py:17
|
||||
#: __init__.py:20
|
||||
msgid "change password"
|
||||
msgstr "cambiar contraseña"
|
||||
|
||||
#: __init__.py:18
|
||||
#: __init__.py:21
|
||||
msgid "user details"
|
||||
msgstr "detalles de usuario"
|
||||
|
||||
#: __init__.py:19
|
||||
#: __init__.py:22
|
||||
msgid "edit details"
|
||||
msgstr "editar detalles"
|
||||
|
||||
#: __init__.py:23 __init__.py:29
|
||||
#: __init__.py:26 __init__.py:31
|
||||
msgid "about"
|
||||
msgstr "sobre"
|
||||
|
||||
#: __init__.py:24
|
||||
msgid "changelog"
|
||||
msgstr "cambios"
|
||||
|
||||
#: __init__.py:25
|
||||
#: __init__.py:27
|
||||
msgid "license"
|
||||
msgstr "licencia"
|
||||
|
||||
#: forms.py:99
|
||||
#: forms.py:101
|
||||
msgid "Selection"
|
||||
msgstr "Selección"
|
||||
|
||||
#: forms.py:131
|
||||
#: forms.py:133
|
||||
msgid "Email"
|
||||
msgstr "E-mail"
|
||||
|
||||
#: forms.py:142
|
||||
#: forms.py:144
|
||||
msgid ""
|
||||
"Please enter a correct email and password. Note that the password fields is "
|
||||
"case-sensitive."
|
||||
@@ -60,7 +56,7 @@ msgstr ""
|
||||
"correctas. Tenga en cuenta que los campos de contraseña distingue entre "
|
||||
"mayúsculas y minúsculas."
|
||||
|
||||
#: forms.py:144
|
||||
#: forms.py:146
|
||||
msgid "This account is inactive."
|
||||
msgstr "Esta cuenta está inactiva."
|
||||
|
||||
@@ -104,70 +100,83 @@ msgstr "Retrato"
|
||||
msgid "Landscape"
|
||||
msgstr "Paisaje"
|
||||
|
||||
#: utils.py:291
|
||||
#: models.py:16
|
||||
msgid "lock field"
|
||||
msgstr "campo de bloqueo"
|
||||
|
||||
#: models.py:43
|
||||
msgid "Anonymous user"
|
||||
msgstr "Usuario anónimo"
|
||||
|
||||
#: models.py:46 models.py:47
|
||||
msgid "anonymous user"
|
||||
msgstr "usuario anónimo"
|
||||
|
||||
#: utils.py:295
|
||||
msgid "function found"
|
||||
msgstr "función encontrada"
|
||||
|
||||
#: utils.py:293 utils.py:295
|
||||
#, python-format
|
||||
msgid "class found: %s"
|
||||
msgstr "clase encontrada: %s"
|
||||
|
||||
#: views.py:24 templates/password_change_done.html:5
|
||||
msgid "Your password has been successfully changed."
|
||||
msgstr "Su contraseña se ha modificado correctamente."
|
||||
|
||||
#: views.py:41
|
||||
#: views.py:36
|
||||
msgid "No action selected."
|
||||
msgstr "Ninguna acción seleccionada."
|
||||
|
||||
#: views.py:45
|
||||
#: views.py:40
|
||||
msgid "Must select at least one item."
|
||||
msgstr "Debe seleccionar al menos un artículo."
|
||||
|
||||
#: views.py:86
|
||||
#: views.py:88
|
||||
#, python-format
|
||||
msgid "%(selection)s added successfully added to %(right_list_title)s."
|
||||
msgstr "Se agrego exitosamente %(selection)s a %(right_list_title)s."
|
||||
|
||||
#: views.py:89 views.py:106
|
||||
#: views.py:94 views.py:121
|
||||
#, python-format
|
||||
msgid "Unable to add %(selection)s to %(right_list_title)s."
|
||||
msgstr "No se puede agregar %(selection)s a %(right_list_title)s."
|
||||
|
||||
#: views.py:103
|
||||
#: views.py:115
|
||||
#, python-format
|
||||
msgid "%(selection)s added successfully removed from %(right_list_title)s."
|
||||
msgstr "Se removió exitosamente %(selection)s de %(right_list_title)s."
|
||||
|
||||
#: views.py:121
|
||||
#: views.py:136
|
||||
msgid "Add"
|
||||
msgstr "Agregar"
|
||||
|
||||
#: views.py:132
|
||||
#: views.py:147
|
||||
msgid "Remove"
|
||||
msgstr "Remover"
|
||||
|
||||
#: views.py:155
|
||||
#: views.py:170
|
||||
msgid "current user details"
|
||||
msgstr "detalles del usuario corriente"
|
||||
|
||||
#: views.py:172
|
||||
#: views.py:187
|
||||
msgid "E-mail conflict, another user has that same email."
|
||||
msgstr ""
|
||||
"Conflicto de correo electrónica, otro usuario tiene ese mismo correo "
|
||||
"electrónico."
|
||||
|
||||
#: views.py:190
|
||||
msgid "Current user's details updated."
|
||||
msgstr "Datos del usuario corriente actualizados."
|
||||
|
||||
#: views.py:181
|
||||
#: views.py:199
|
||||
msgid "edit current user details"
|
||||
msgstr "editar detalles del usuario corriente"
|
||||
|
||||
#: views.py:207
|
||||
msgid "Changelog"
|
||||
msgstr "Cambios"
|
||||
|
||||
#: views.py:220
|
||||
#: views.py:230
|
||||
msgid "License"
|
||||
msgstr "Licencia"
|
||||
|
||||
#: views.py:239
|
||||
msgid "Current user password change"
|
||||
msgstr "Cambio de contraseña de usuario actual"
|
||||
|
||||
#: views.py:254 templates/password_change_done.html:5
|
||||
msgid "Your password has been successfully changed."
|
||||
msgstr "Su contraseña se ha modificado correctamente."
|
||||
|
||||
#: widgets.py:58
|
||||
msgid "None"
|
||||
msgstr "Ninguno"
|
||||
@@ -190,6 +199,11 @@ msgstr ""
|
||||
"Controla el mecanismo utilizado para el usuario autenticado. Las opciones "
|
||||
"son: 'username' nombre de usuario, 'email' correo electrónico"
|
||||
|
||||
#: conf/settings.py:74
|
||||
msgid "Allow non authenticated users, access to all views"
|
||||
msgstr ""
|
||||
"Permita a los usuarios no autenticados, el acceso a todas las pantallas"
|
||||
|
||||
#: templates/403.html:3 templates/403.html.py:7
|
||||
msgid "Insufficient permissions"
|
||||
msgstr "Permisos insuficientes"
|
||||
@@ -270,28 +284,32 @@ msgid "No"
|
||||
msgstr "No"
|
||||
|
||||
#: templates/generic_form_instance.html:37
|
||||
#: templates/generic_form_subtemplate.html:52
|
||||
#: templates/generic_form_subtemplate.html:56
|
||||
msgid "required"
|
||||
msgstr "requerido"
|
||||
|
||||
#: templates/generic_form_subtemplate.html:76
|
||||
#: templates/generic_form_subtemplate.html:78
|
||||
#: templates/generic_form_subtemplate.html:80
|
||||
#: templates/generic_form_subtemplate.html:82
|
||||
#: templates/generic_list_horizontal_subtemplate.html:51
|
||||
#: templates/generic_list_horizontal_subtemplate.html:178
|
||||
#: templates/generic_list_horizontal_subtemplate.html:90
|
||||
#: templates/generic_list_subtemplate.html:52
|
||||
#: templates/generic_list_subtemplate.html:178
|
||||
msgid "Save"
|
||||
msgstr "Guardar"
|
||||
|
||||
#: templates/generic_form_subtemplate.html:76
|
||||
#: templates/generic_form_subtemplate.html:78
|
||||
#: templates/generic_form_subtemplate.html:80
|
||||
#: templates/generic_form_subtemplate.html:82
|
||||
#: templates/generic_list_horizontal_subtemplate.html:51
|
||||
#: templates/generic_list_horizontal_subtemplate.html:178
|
||||
#: templates/generic_list_horizontal_subtemplate.html:90
|
||||
#: templates/generic_list_subtemplate.html:52
|
||||
#: templates/generic_list_subtemplate.html:178
|
||||
msgid "Submit"
|
||||
msgstr "Enviar"
|
||||
|
||||
#: templates/generic_form_subtemplate.html:87
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#: templates/generic_list.html:6 templates/generic_list_horizontal.html:6
|
||||
#, python-format
|
||||
msgid "List of %(stripped_title)s"
|
||||
@@ -330,6 +348,3 @@ msgstr "Iniciar sesión"
|
||||
#: templates/password_change_form.html:5
|
||||
msgid "Password change"
|
||||
msgstr "Cambio de contraseña"
|
||||
|
||||
#~ msgid "Cancel"
|
||||
#~ msgstr "Cancelar"
|
||||
|
||||
BIN
apps/common/locale/it/LC_MESSAGES/django.mo
Normal file
BIN
apps/common/locale/it/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
337
apps/common/locale/it/LC_MESSAGES/django.po
Normal file
337
apps/common/locale/it/LC_MESSAGES/django.po
Normal file
@@ -0,0 +1,337 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# <pierpaolo.baldan@gmail.com>, 2011.
|
||||
# Roberto Rosario <roberto.rosario.gonzalez@gmail.com>, 2012.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Mayan EDMS\n"
|
||||
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
|
||||
"POT-Creation-Date: 2012-02-12 15:20-0400\n"
|
||||
"PO-Revision-Date: 2012-02-21 16:35+0000\n"
|
||||
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
|
||||
"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/language/it/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: it\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
|
||||
#: __init__.py:20
|
||||
msgid "change password"
|
||||
msgstr "cambia password"
|
||||
|
||||
#: __init__.py:21
|
||||
msgid "user details"
|
||||
msgstr "dettaglio utente"
|
||||
|
||||
#: __init__.py:22
|
||||
msgid "edit details"
|
||||
msgstr "modifica dettagli"
|
||||
|
||||
#: __init__.py:26 __init__.py:31
|
||||
msgid "about"
|
||||
msgstr "a rigurdo"
|
||||
|
||||
#: __init__.py:27
|
||||
msgid "license"
|
||||
msgstr "licenza"
|
||||
|
||||
#: forms.py:101
|
||||
msgid "Selection"
|
||||
msgstr "Selezione"
|
||||
|
||||
#: forms.py:133
|
||||
msgid "Email"
|
||||
msgstr "Email"
|
||||
|
||||
#: forms.py:144
|
||||
msgid ""
|
||||
"Please enter a correct email and password. Note that the password fields is "
|
||||
"case-sensitive."
|
||||
msgstr "Inserisci un'indirizzo mail valido e una password. Ricorda che il campo password è case-sensitive"
|
||||
|
||||
#: forms.py:146
|
||||
msgid "This account is inactive."
|
||||
msgstr "Questo account è inattivo"
|
||||
|
||||
#: literals.py:24
|
||||
msgid "A5"
|
||||
msgstr "A5"
|
||||
|
||||
#: literals.py:25
|
||||
msgid "A4"
|
||||
msgstr "A4"
|
||||
|
||||
#: literals.py:26
|
||||
msgid "A3"
|
||||
msgstr "A3"
|
||||
|
||||
#: literals.py:27
|
||||
msgid "B5"
|
||||
msgstr "B5"
|
||||
|
||||
#: literals.py:28
|
||||
msgid "B4"
|
||||
msgstr "B4"
|
||||
|
||||
#: literals.py:29
|
||||
msgid "Letter"
|
||||
msgstr "Letter"
|
||||
|
||||
#: literals.py:30
|
||||
msgid "Legal"
|
||||
msgstr "Legal"
|
||||
|
||||
#: literals.py:31
|
||||
msgid "Ledger"
|
||||
msgstr "Mastro"
|
||||
|
||||
#: literals.py:38
|
||||
msgid "Portrait"
|
||||
msgstr "Verticale"
|
||||
|
||||
#: literals.py:39
|
||||
msgid "Landscape"
|
||||
msgstr "Orizontale"
|
||||
|
||||
#: models.py:16
|
||||
msgid "lock field"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:43
|
||||
msgid "Anonymous user"
|
||||
msgstr "Utente anonimo"
|
||||
|
||||
#: models.py:46 models.py:47
|
||||
msgid "anonymous user"
|
||||
msgstr "utente anonimo"
|
||||
|
||||
#: utils.py:295
|
||||
msgid "function found"
|
||||
msgstr "trovata funzione"
|
||||
|
||||
#: views.py:36
|
||||
msgid "No action selected."
|
||||
msgstr "Nessuna azione selezionata"
|
||||
|
||||
#: views.py:40
|
||||
msgid "Must select at least one item."
|
||||
msgstr "Devi selezionare un item"
|
||||
|
||||
#: views.py:88
|
||||
#, python-format
|
||||
msgid "%(selection)s added successfully added to %(right_list_title)s."
|
||||
msgstr "%(selection)s aggiunto con successo a %(right_list_title)s."
|
||||
|
||||
#: views.py:94 views.py:121
|
||||
#, python-format
|
||||
msgid "Unable to add %(selection)s to %(right_list_title)s."
|
||||
msgstr "Impossibile aggiungere %(selection)s a %(right_list_title)s."
|
||||
|
||||
#: views.py:115
|
||||
#, python-format
|
||||
msgid "%(selection)s added successfully removed from %(right_list_title)s."
|
||||
msgstr "%(selection)s aggiunto correttamente rimosso dal %(right_list_title)s."
|
||||
|
||||
#: views.py:136
|
||||
msgid "Add"
|
||||
msgstr "Aggiungi"
|
||||
|
||||
#: views.py:147
|
||||
msgid "Remove"
|
||||
msgstr "Rimuovi"
|
||||
|
||||
#: views.py:170
|
||||
msgid "current user details"
|
||||
msgstr "dettagli dell'utente corrente"
|
||||
|
||||
#: views.py:187
|
||||
msgid "E-mail conflict, another user has that same email."
|
||||
msgstr "E-mail conflitto, un altro utente ha quella stessa email."
|
||||
|
||||
#: views.py:190
|
||||
msgid "Current user's details updated."
|
||||
msgstr "Dettagli dell'utente corrente aggiornati"
|
||||
|
||||
#: views.py:199
|
||||
msgid "edit current user details"
|
||||
msgstr "modifica i dettagli dell'utente corrente"
|
||||
|
||||
#: views.py:230
|
||||
msgid "License"
|
||||
msgstr "Licenza"
|
||||
|
||||
#: views.py:239
|
||||
msgid "Current user password change"
|
||||
msgstr "Modifica della password dell'utente corrente"
|
||||
|
||||
#: views.py:254 templates/password_change_done.html:5
|
||||
msgid "Your password has been successfully changed."
|
||||
msgstr "La tua password è stata cambiata con successo"
|
||||
|
||||
#: widgets.py:58
|
||||
msgid "None"
|
||||
msgstr "Nessuno"
|
||||
|
||||
#: conf/settings.py:15
|
||||
msgid ""
|
||||
"Temporary directory used site wide to store thumbnails, previews and "
|
||||
"temporary files. If none is specified, one will be created using "
|
||||
"tempfile.mkdtemp()"
|
||||
msgstr "Directory temporanea utilizzata a livello di sito per thumbnails, anteprime e file temporanei. Se non viene specificato, ne verrà creata utilizzando tempfile.mkdtemp()"
|
||||
|
||||
#: conf/settings.py:65
|
||||
msgid ""
|
||||
"Controls the mechanism used to authenticated user. Options are: username, "
|
||||
"email"
|
||||
msgstr "Controllo del meccanismo di autenticazione. Le opzioni possibili sono:username,email"
|
||||
|
||||
#: conf/settings.py:74
|
||||
msgid "Allow non authenticated users, access to all views"
|
||||
msgstr "Consentire agli utenti non autenticati, l'accesso a tutte le viste"
|
||||
|
||||
#: templates/403.html:3 templates/403.html.py:7
|
||||
msgid "Insufficient permissions"
|
||||
msgstr "Permessi insufficienti"
|
||||
|
||||
#: templates/403.html:9
|
||||
msgid "You don't have enough permissions for this operation."
|
||||
msgstr "Non hai i permessi per effettuare questa operazione."
|
||||
|
||||
#: templates/404.html:3 templates/404.html.py:7
|
||||
msgid "Page not found"
|
||||
msgstr "Pagina non trovata"
|
||||
|
||||
#: templates/404.html:9
|
||||
msgid "Sorry, but the requested page could not be found."
|
||||
msgstr "Scusa ma la pagina richiesta non è disponibile"
|
||||
|
||||
#: templates/calculate_form_title.html:11
|
||||
#, python-format
|
||||
msgid "Details for %(object_name)s: %(object)s"
|
||||
msgstr "Dettagli per %(object_name)s: %(object)s"
|
||||
|
||||
#: templates/calculate_form_title.html:13
|
||||
#, python-format
|
||||
msgid "Details for: %(object)s"
|
||||
msgstr "Detaglio per: %(object)s"
|
||||
|
||||
#: templates/calculate_form_title.html:18
|
||||
#, python-format
|
||||
msgid "Edit %(object_name)s:"
|
||||
msgstr "Modifica %(object_name)s:"
|
||||
|
||||
#: templates/calculate_form_title.html:20
|
||||
msgid "Edit"
|
||||
msgstr "Modifica"
|
||||
|
||||
#: templates/calculate_form_title.html:24
|
||||
#, python-format
|
||||
msgid "Create new %(object_name)s"
|
||||
msgstr "Crea nuovo %(object_name)s"
|
||||
|
||||
#: templates/calculate_form_title.html:26
|
||||
msgid "Create"
|
||||
msgstr "Crea"
|
||||
|
||||
#: templates/generic_assign_remove.html:3
|
||||
#, python-format
|
||||
msgid "Assign %(title)s %(object)s"
|
||||
msgstr "Assigna %(title)s %(object)s"
|
||||
|
||||
#: templates/generic_confirm.html:3 templates/generic_confirm.html.py:18
|
||||
msgid "Confirm"
|
||||
msgstr "Conferma"
|
||||
|
||||
#: templates/generic_confirm.html:16
|
||||
msgid "Confirm delete"
|
||||
msgstr "Conferma la cancellazione"
|
||||
|
||||
#: templates/generic_confirm.html:32
|
||||
msgid "form icon"
|
||||
msgstr "icona del modulo"
|
||||
|
||||
#: templates/generic_confirm.html:40
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to delete %(object_name)s: %(object)s?"
|
||||
msgstr "Sei sicuro di voler cancellare %(object_name)s: %(object)s?"
|
||||
|
||||
#: templates/generic_confirm.html:42
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to delete: %(object)s?"
|
||||
msgstr "Sei sicuro di volr cancellare: %(object)s?"
|
||||
|
||||
#: templates/generic_confirm.html:50
|
||||
msgid "Yes"
|
||||
msgstr "Si"
|
||||
|
||||
#: templates/generic_confirm.html:54
|
||||
msgid "No"
|
||||
msgstr "No"
|
||||
|
||||
#: templates/generic_form_instance.html:37
|
||||
#: templates/generic_form_subtemplate.html:56
|
||||
msgid "required"
|
||||
msgstr "richiesto"
|
||||
|
||||
#: templates/generic_form_subtemplate.html:80
|
||||
#: templates/generic_form_subtemplate.html:82
|
||||
#: templates/generic_list_horizontal_subtemplate.html:51
|
||||
#: templates/generic_list_horizontal_subtemplate.html:90
|
||||
#: templates/generic_list_subtemplate.html:52
|
||||
#: templates/generic_list_subtemplate.html:178
|
||||
msgid "Save"
|
||||
msgstr "Salva"
|
||||
|
||||
#: templates/generic_form_subtemplate.html:80
|
||||
#: templates/generic_form_subtemplate.html:82
|
||||
#: templates/generic_list_horizontal_subtemplate.html:51
|
||||
#: templates/generic_list_horizontal_subtemplate.html:90
|
||||
#: templates/generic_list_subtemplate.html:52
|
||||
#: templates/generic_list_subtemplate.html:178
|
||||
msgid "Submit"
|
||||
msgstr "Sottometti"
|
||||
|
||||
#: templates/generic_form_subtemplate.html:87
|
||||
msgid "Cancel"
|
||||
msgstr "Annullare"
|
||||
|
||||
#: templates/generic_list.html:6 templates/generic_list_horizontal.html:6
|
||||
#, python-format
|
||||
msgid "List of %(stripped_title)s"
|
||||
msgstr "Lista di %(stripped_title)s"
|
||||
|
||||
#: templates/generic_list_horizontal_subtemplate.html:23
|
||||
#: templates/generic_list_subtemplate.html:24
|
||||
#, python-format
|
||||
msgid ""
|
||||
"List of %(title)s (%(start)s - %(end)s out of %(total)s) (Page "
|
||||
"%(page_number)s of %(total_pages)s)"
|
||||
msgstr "Lista di %(title)s (%(start)s - %(end)s fuori %(total)s) (Page %(page_number)s of %(total_pages)s)"
|
||||
|
||||
#: templates/generic_list_horizontal_subtemplate.html:25
|
||||
#: templates/generic_list_subtemplate.html:26
|
||||
#, python-format
|
||||
msgid "List of %(title)s (%(total)s)"
|
||||
msgstr "Lista di %(title)s (%(total)s)"
|
||||
|
||||
#: templates/generic_list_subtemplate.html:72
|
||||
msgid "Identifier"
|
||||
msgstr "Identificatore"
|
||||
|
||||
#: templates/generic_list_subtemplate.html:152
|
||||
#, python-format
|
||||
msgid "There are no %(stripped_title)s"
|
||||
msgstr "Non ci sono %(stripped_title)s"
|
||||
|
||||
#: templates/login.html:5
|
||||
msgid "Login"
|
||||
msgstr "Login"
|
||||
|
||||
#: templates/password_change_done.html:3 templates/password_change_form.html:3
|
||||
#: templates/password_change_form.html:5
|
||||
msgid "Password change"
|
||||
msgstr "Cambia password"
|
||||
BIN
apps/common/locale/pl/LC_MESSAGES/django.mo
Normal file
BIN
apps/common/locale/pl/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
339
apps/common/locale/pl/LC_MESSAGES/django.po
Normal file
339
apps/common/locale/pl/LC_MESSAGES/django.po
Normal file
@@ -0,0 +1,339 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# mic, 2012.
|
||||
# mic <diveaway12@gmail.com>, 2012.
|
||||
# <winterfall24@gmail.com>, 2012.
|
||||
# <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-02-12 15:20-0400\n"
|
||||
"PO-Revision-Date: 2012-02-21 15:17+0000\n"
|
||||
"Last-Translator: mic <winterfall24@gmail.com>\n"
|
||||
"Language-Team: Polish (http://www.transifex.net/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:20
|
||||
msgid "change password"
|
||||
msgstr "zmień hasło"
|
||||
|
||||
#: __init__.py:21
|
||||
msgid "user details"
|
||||
msgstr "szczegóły konta użytkownika"
|
||||
|
||||
#: __init__.py:22
|
||||
msgid "edit details"
|
||||
msgstr "edytuj szczegóły"
|
||||
|
||||
#: __init__.py:26 __init__.py:31
|
||||
msgid "about"
|
||||
msgstr "informacje o"
|
||||
|
||||
#: __init__.py:27
|
||||
msgid "license"
|
||||
msgstr "licencja"
|
||||
|
||||
#: forms.py:101
|
||||
msgid "Selection"
|
||||
msgstr "Zaznaczenie"
|
||||
|
||||
#: forms.py:133
|
||||
msgid "Email"
|
||||
msgstr "E-mail"
|
||||
|
||||
#: forms.py:144
|
||||
msgid ""
|
||||
"Please enter a correct email and password. Note that the password fields is "
|
||||
"case-sensitive."
|
||||
msgstr "Proszę wpisać poprawną nazwę użytkownika i hasło. Uwaga: wielkość liter ma znaczenie."
|
||||
|
||||
#: forms.py:146
|
||||
msgid "This account is inactive."
|
||||
msgstr "To konto jest nieaktywne."
|
||||
|
||||
#: literals.py:24
|
||||
msgid "A5"
|
||||
msgstr "A5"
|
||||
|
||||
#: literals.py:25
|
||||
msgid "A4"
|
||||
msgstr "A4"
|
||||
|
||||
#: literals.py:26
|
||||
msgid "A3"
|
||||
msgstr "A3"
|
||||
|
||||
#: literals.py:27
|
||||
msgid "B5"
|
||||
msgstr "B5"
|
||||
|
||||
#: literals.py:28
|
||||
msgid "B4"
|
||||
msgstr "B4"
|
||||
|
||||
#: literals.py:29
|
||||
msgid "Letter"
|
||||
msgstr "Letter"
|
||||
|
||||
#: literals.py:30
|
||||
msgid "Legal"
|
||||
msgstr "Legal"
|
||||
|
||||
#: literals.py:31
|
||||
msgid "Ledger"
|
||||
msgstr "Ledger"
|
||||
|
||||
#: literals.py:38
|
||||
msgid "Portrait"
|
||||
msgstr "Portrait"
|
||||
|
||||
#: literals.py:39
|
||||
msgid "Landscape"
|
||||
msgstr "Landscape"
|
||||
|
||||
#: models.py:16
|
||||
msgid "lock field"
|
||||
msgstr "zablokować pole"
|
||||
|
||||
#: models.py:43
|
||||
msgid "Anonymous user"
|
||||
msgstr "Użytkownik anonimowy"
|
||||
|
||||
#: models.py:46 models.py:47
|
||||
msgid "anonymous user"
|
||||
msgstr "użytkownik anonimowy"
|
||||
|
||||
#: utils.py:295
|
||||
msgid "function found"
|
||||
msgstr "znaleźć funkcję"
|
||||
|
||||
#: views.py:36
|
||||
msgid "No action selected."
|
||||
msgstr "Nie wybrano żadnego działania"
|
||||
|
||||
#: views.py:40
|
||||
msgid "Must select at least one item."
|
||||
msgstr "Musisz wybrać co najmniej jeden element."
|
||||
|
||||
#: views.py:88
|
||||
#, python-format
|
||||
msgid "%(selection)s added successfully added to %(right_list_title)s."
|
||||
msgstr " %(selection)s pomyślnie dodana do %(right_list_title)s."
|
||||
|
||||
#: views.py:94 views.py:121
|
||||
#, python-format
|
||||
msgid "Unable to add %(selection)s to %(right_list_title)s."
|
||||
msgstr "Nie można dodać %(selection)s do %(right_list_title)s."
|
||||
|
||||
#: views.py:115
|
||||
#, python-format
|
||||
msgid "%(selection)s added successfully removed from %(right_list_title)s."
|
||||
msgstr " %(selection)s pomyślnie dodana usunięty z %(right_list_title)s."
|
||||
|
||||
#: views.py:136
|
||||
msgid "Add"
|
||||
msgstr "Dodaj"
|
||||
|
||||
#: views.py:147
|
||||
msgid "Remove"
|
||||
msgstr "Usuń"
|
||||
|
||||
#: views.py:170
|
||||
msgid "current user details"
|
||||
msgstr "aktualne dane użytkownika"
|
||||
|
||||
#: views.py:187
|
||||
msgid "E-mail conflict, another user has that same email."
|
||||
msgstr "Użytkownik o podanym adresie e-mail już istnieje."
|
||||
|
||||
#: views.py:190
|
||||
msgid "Current user's details updated."
|
||||
msgstr "Aktualne dane użytkownika aktualizowane."
|
||||
|
||||
#: views.py:199
|
||||
msgid "edit current user details"
|
||||
msgstr "edytuj aktualne dane użytkownika"
|
||||
|
||||
#: views.py:230
|
||||
msgid "License"
|
||||
msgstr "Licencja"
|
||||
|
||||
#: views.py:239
|
||||
msgid "Current user password change"
|
||||
msgstr "Zmiana hasła użytkownika"
|
||||
|
||||
#: views.py:254 templates/password_change_done.html:5
|
||||
msgid "Your password has been successfully changed."
|
||||
msgstr "Twoje hasło zostało pomyślnie zmienione."
|
||||
|
||||
#: widgets.py:58
|
||||
msgid "None"
|
||||
msgstr "Brak"
|
||||
|
||||
#: conf/settings.py:15
|
||||
msgid ""
|
||||
"Temporary directory used site wide to store thumbnails, previews and "
|
||||
"temporary files. If none is specified, one will be created using "
|
||||
"tempfile.mkdtemp()"
|
||||
msgstr "Katalog tymczasowy używany do przechowywania całej witryny, miniatur, podglądów i plików tymczasowych. Jeśli nie zostanie określony, zostanie utworzony za pomocą tempfile.mkdtemp ()"
|
||||
|
||||
#: conf/settings.py:65
|
||||
msgid ""
|
||||
"Controls the mechanism used to authenticated user. Options are: username, "
|
||||
"email"
|
||||
msgstr ""
|
||||
|
||||
#: conf/settings.py:74
|
||||
msgid "Allow non authenticated users, access to all views"
|
||||
msgstr ""
|
||||
|
||||
#: templates/403.html:3 templates/403.html.py:7
|
||||
msgid "Insufficient permissions"
|
||||
msgstr "Niewystarczające uprawnienia"
|
||||
|
||||
#: templates/403.html:9
|
||||
msgid "You don't have enough permissions for this operation."
|
||||
msgstr "Nie masz wystarczających uprawnień do tej operacji."
|
||||
|
||||
#: templates/404.html:3 templates/404.html.py:7
|
||||
msgid "Page not found"
|
||||
msgstr "Nie znaleziono strony"
|
||||
|
||||
#: templates/404.html:9
|
||||
msgid "Sorry, but the requested page could not be found."
|
||||
msgstr "Przykro nam, ale żądana strona nie została odnaleziona."
|
||||
|
||||
#: templates/calculate_form_title.html:11
|
||||
#, python-format
|
||||
msgid "Details for %(object_name)s: %(object)s"
|
||||
msgstr "Szczegóły dla %(object_name)s : %(object)s "
|
||||
|
||||
#: templates/calculate_form_title.html:13
|
||||
#, python-format
|
||||
msgid "Details for: %(object)s"
|
||||
msgstr "Szczegóły: %(object)s "
|
||||
|
||||
#: templates/calculate_form_title.html:18
|
||||
#, python-format
|
||||
msgid "Edit %(object_name)s:"
|
||||
msgstr "Edytuj %(object_name)s :"
|
||||
|
||||
#: templates/calculate_form_title.html:20
|
||||
msgid "Edit"
|
||||
msgstr "Edytuj"
|
||||
|
||||
#: templates/calculate_form_title.html:24
|
||||
#, python-format
|
||||
msgid "Create new %(object_name)s"
|
||||
msgstr "Utwórz nową %(object_name)s "
|
||||
|
||||
#: templates/calculate_form_title.html:26
|
||||
msgid "Create"
|
||||
msgstr "Utwórz"
|
||||
|
||||
#: templates/generic_assign_remove.html:3
|
||||
#, python-format
|
||||
msgid "Assign %(title)s %(object)s"
|
||||
msgstr "Przypisz %(title)s %(object)s"
|
||||
|
||||
#: templates/generic_confirm.html:3 templates/generic_confirm.html.py:18
|
||||
msgid "Confirm"
|
||||
msgstr "Potwierdź"
|
||||
|
||||
#: templates/generic_confirm.html:16
|
||||
msgid "Confirm delete"
|
||||
msgstr "Potwierdź usunięcie"
|
||||
|
||||
#: templates/generic_confirm.html:32
|
||||
msgid "form icon"
|
||||
msgstr "form icon"
|
||||
|
||||
#: templates/generic_confirm.html:40
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to delete %(object_name)s: %(object)s?"
|
||||
msgstr "Czy na pewno chcesz usunąć %(object_name)s : %(object)s ?"
|
||||
|
||||
#: templates/generic_confirm.html:42
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to delete: %(object)s?"
|
||||
msgstr "Czy na pewno chcesz usunąć: %(object)s?"
|
||||
|
||||
#: templates/generic_confirm.html:50
|
||||
msgid "Yes"
|
||||
msgstr "Tak"
|
||||
|
||||
#: templates/generic_confirm.html:54
|
||||
msgid "No"
|
||||
msgstr "Nie"
|
||||
|
||||
#: templates/generic_form_instance.html:37
|
||||
#: templates/generic_form_subtemplate.html:56
|
||||
msgid "required"
|
||||
msgstr "wymagane"
|
||||
|
||||
#: templates/generic_form_subtemplate.html:80
|
||||
#: templates/generic_form_subtemplate.html:82
|
||||
#: templates/generic_list_horizontal_subtemplate.html:51
|
||||
#: templates/generic_list_horizontal_subtemplate.html:90
|
||||
#: templates/generic_list_subtemplate.html:52
|
||||
#: templates/generic_list_subtemplate.html:178
|
||||
msgid "Save"
|
||||
msgstr "Zapisz"
|
||||
|
||||
#: templates/generic_form_subtemplate.html:80
|
||||
#: templates/generic_form_subtemplate.html:82
|
||||
#: templates/generic_list_horizontal_subtemplate.html:51
|
||||
#: templates/generic_list_horizontal_subtemplate.html:90
|
||||
#: templates/generic_list_subtemplate.html:52
|
||||
#: templates/generic_list_subtemplate.html:178
|
||||
msgid "Submit"
|
||||
msgstr "Wyślij"
|
||||
|
||||
#: templates/generic_form_subtemplate.html:87
|
||||
msgid "Cancel"
|
||||
msgstr "Anuluj"
|
||||
|
||||
#: templates/generic_list.html:6 templates/generic_list_horizontal.html:6
|
||||
#, python-format
|
||||
msgid "List of %(stripped_title)s"
|
||||
msgstr "Wykaz %(stripped_title)s"
|
||||
|
||||
#: templates/generic_list_horizontal_subtemplate.html:23
|
||||
#: templates/generic_list_subtemplate.html:24
|
||||
#, python-format
|
||||
msgid ""
|
||||
"List of %(title)s (%(start)s - %(end)s out of %(total)s) (Page "
|
||||
"%(page_number)s of %(total_pages)s)"
|
||||
msgstr "Wykaz %(title)s (%(start)s - %(end)s z %(total)s) (Page %(page_number)s z %(total_pages)s)"
|
||||
|
||||
#: templates/generic_list_horizontal_subtemplate.html:25
|
||||
#: templates/generic_list_subtemplate.html:26
|
||||
#, python-format
|
||||
msgid "List of %(title)s (%(total)s)"
|
||||
msgstr "Wykaz %(title)s (%(total)s)"
|
||||
|
||||
#: templates/generic_list_subtemplate.html:72
|
||||
msgid "Identifier"
|
||||
msgstr "Identyfikator"
|
||||
|
||||
#: templates/generic_list_subtemplate.html:152
|
||||
#, python-format
|
||||
msgid "There are no %(stripped_title)s"
|
||||
msgstr "Brak %(stripped_title)s"
|
||||
|
||||
#: templates/login.html:5
|
||||
msgid "Login"
|
||||
msgstr "Zaloguj"
|
||||
|
||||
#: templates/password_change_done.html:3 templates/password_change_form.html:3
|
||||
#: templates/password_change_form.html:5
|
||||
msgid "Password change"
|
||||
msgstr "Zmiana hasła"
|
||||
Binary file not shown.
@@ -1,65 +1,59 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
#
|
||||
# Translators:
|
||||
# <dev.emerson@gmail.com>, 2011.
|
||||
# Roberto Rosario <roberto.rosario.gonzalez@gmail.com>, 2012.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Mayan EDMS\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
|
||||
"PO-Revision-Date: 2011-11-02 02:18+0000\n"
|
||||
"Last-Translator: emersonsoares <dev.emerson@gmail.com>\n"
|
||||
"Language-Team: Portuguese (http://www.transifex.net/projects/p/mayan-edms/"
|
||||
"team/pt/)\n"
|
||||
"Language: pt\n"
|
||||
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
|
||||
"POT-Creation-Date: 2012-02-12 15:20-0400\n"
|
||||
"PO-Revision-Date: 2012-02-21 15:07+0000\n"
|
||||
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
|
||||
"Language-Team: Portuguese (http://www.transifex.net/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:17
|
||||
#: __init__.py:20
|
||||
msgid "change password"
|
||||
msgstr "alterar a senha"
|
||||
|
||||
#: __init__.py:18
|
||||
#: __init__.py:21
|
||||
msgid "user details"
|
||||
msgstr "detalhes do usuário"
|
||||
|
||||
#: __init__.py:19
|
||||
#: __init__.py:22
|
||||
msgid "edit details"
|
||||
msgstr "editar detalhes"
|
||||
|
||||
#: __init__.py:23 __init__.py:29
|
||||
#: __init__.py:26 __init__.py:31
|
||||
msgid "about"
|
||||
msgstr "sobre"
|
||||
|
||||
#: __init__.py:24
|
||||
msgid "changelog"
|
||||
msgstr "log de alterações"
|
||||
|
||||
#: __init__.py:25
|
||||
#: __init__.py:27
|
||||
msgid "license"
|
||||
msgstr "licença"
|
||||
|
||||
#: forms.py:99
|
||||
#: forms.py:101
|
||||
msgid "Selection"
|
||||
msgstr "Seleção"
|
||||
|
||||
#: forms.py:131
|
||||
#: forms.py:133
|
||||
msgid "Email"
|
||||
msgstr "E-mail"
|
||||
|
||||
#: forms.py:142
|
||||
#: forms.py:144
|
||||
msgid ""
|
||||
"Please enter a correct email and password. Note that the password fields is "
|
||||
"case-sensitive."
|
||||
msgstr ""
|
||||
"Por favor insira o e-mail e senha corretos. Note que os campos de senha são "
|
||||
"case-sensitive."
|
||||
msgstr "Por favor insira o e-mail e senha corretos. Note que os campos de senha são case-sensitive."
|
||||
|
||||
#: forms.py:144
|
||||
#: forms.py:146
|
||||
msgid "This account is inactive."
|
||||
msgstr "Esta conta está inativa."
|
||||
|
||||
@@ -103,70 +97,81 @@ msgstr "Retrato"
|
||||
msgid "Landscape"
|
||||
msgstr "Paisagem"
|
||||
|
||||
#: utils.py:291
|
||||
#: models.py:16
|
||||
msgid "lock field"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:43
|
||||
msgid "Anonymous user"
|
||||
msgstr "Usuário anônimo"
|
||||
|
||||
#: models.py:46 models.py:47
|
||||
msgid "anonymous user"
|
||||
msgstr "usuário anônimo"
|
||||
|
||||
#: utils.py:295
|
||||
msgid "function found"
|
||||
msgstr "função encontrada"
|
||||
|
||||
#: utils.py:293 utils.py:295
|
||||
#, python-format
|
||||
msgid "class found: %s"
|
||||
msgstr "classe encontrada: %s"
|
||||
|
||||
#: views.py:24 templates/password_change_done.html:5
|
||||
msgid "Your password has been successfully changed."
|
||||
msgstr "Sua senha foi alterada com êxito."
|
||||
|
||||
#: views.py:41
|
||||
#: views.py:36
|
||||
msgid "No action selected."
|
||||
msgstr "Nenhuma ação selecionada."
|
||||
|
||||
#: views.py:45
|
||||
#: views.py:40
|
||||
msgid "Must select at least one item."
|
||||
msgstr "Deve selecionar pelo menos um item."
|
||||
|
||||
#: views.py:86
|
||||
#: views.py:88
|
||||
#, python-format
|
||||
msgid "%(selection)s added successfully added to %(right_list_title)s."
|
||||
msgstr "%(selection)s adicionadas com sucesso a %(right_list_title)s ."
|
||||
|
||||
#: views.py:89 views.py:106
|
||||
#: views.py:94 views.py:121
|
||||
#, python-format
|
||||
msgid "Unable to add %(selection)s to %(right_list_title)s."
|
||||
msgstr "Não foi possível adicionar %(selection)s para %(right_list_title)s ."
|
||||
|
||||
#: views.py:103
|
||||
#: views.py:115
|
||||
#, python-format
|
||||
msgid "%(selection)s added successfully removed from %(right_list_title)s."
|
||||
msgstr " %(selection)s adicionado com sucesso removidos %(right_list_title)s."
|
||||
|
||||
#: views.py:121
|
||||
#: views.py:136
|
||||
msgid "Add"
|
||||
msgstr "Adicionar"
|
||||
|
||||
#: views.py:132
|
||||
#: views.py:147
|
||||
msgid "Remove"
|
||||
msgstr "Remover"
|
||||
|
||||
#: views.py:155
|
||||
#: views.py:170
|
||||
msgid "current user details"
|
||||
msgstr "detalhes atuais do usuário"
|
||||
|
||||
#: views.py:172
|
||||
#: views.py:187
|
||||
msgid "E-mail conflict, another user has that same email."
|
||||
msgstr "E-mail conflito, outro usuário que tem mesmo e-mail."
|
||||
|
||||
#: views.py:190
|
||||
msgid "Current user's details updated."
|
||||
msgstr "Detalhes do usuário atual atualizados."
|
||||
|
||||
#: views.py:181
|
||||
#: views.py:199
|
||||
msgid "edit current user details"
|
||||
msgstr "editar os detalhes do usuário atual"
|
||||
|
||||
#: views.py:207
|
||||
msgid "Changelog"
|
||||
msgstr "Log de alterações"
|
||||
|
||||
#: views.py:220
|
||||
#: views.py:230
|
||||
msgid "License"
|
||||
msgstr "Licença"
|
||||
|
||||
#: views.py:239
|
||||
msgid "Current user password change"
|
||||
msgstr "Alteração de senha do usuário atual"
|
||||
|
||||
#: views.py:254 templates/password_change_done.html:5
|
||||
msgid "Your password has been successfully changed."
|
||||
msgstr "Sua senha foi alterada com êxito."
|
||||
|
||||
#: widgets.py:58
|
||||
msgid "None"
|
||||
msgstr "Nenhum"
|
||||
@@ -174,20 +179,19 @@ msgstr "Nenhum"
|
||||
#: conf/settings.py:15
|
||||
msgid ""
|
||||
"Temporary directory used site wide to store thumbnails, previews and "
|
||||
"temporary files. If none is specified, one will be created using tempfile."
|
||||
"mkdtemp()"
|
||||
msgstr ""
|
||||
"Diretório temporário usado para armazenar miniaturas, previews e arquivos "
|
||||
"temporários. Se nenhum for especificado, um será criado usando tempfile."
|
||||
"mkdtemp()"
|
||||
"temporary files. If none is specified, one will be created using "
|
||||
"tempfile.mkdtemp()"
|
||||
msgstr "Diretório temporário usado para armazenar miniaturas, previews e arquivos temporários. Se nenhum for especificado, um será criado usando tempfile.mkdtemp()"
|
||||
|
||||
#: conf/settings.py:65
|
||||
msgid ""
|
||||
"Controls the mechanism used to authenticated user. Options are: username, "
|
||||
"email"
|
||||
msgstr "Controla o mecanismo usado para usuário autenticado. As opções são: e-mail, nome de usuário,"
|
||||
|
||||
#: conf/settings.py:74
|
||||
msgid "Allow non authenticated users, access to all views"
|
||||
msgstr ""
|
||||
"Controla o mecanismo usado para usuário autenticado. As opções são: e-mail, "
|
||||
"nome de usuário,"
|
||||
|
||||
#: templates/403.html:3 templates/403.html.py:7
|
||||
msgid "Insufficient permissions"
|
||||
@@ -269,28 +273,32 @@ msgid "No"
|
||||
msgstr "Não"
|
||||
|
||||
#: templates/generic_form_instance.html:37
|
||||
#: templates/generic_form_subtemplate.html:52
|
||||
#: templates/generic_form_subtemplate.html:56
|
||||
msgid "required"
|
||||
msgstr "exigido"
|
||||
|
||||
#: templates/generic_form_subtemplate.html:76
|
||||
#: templates/generic_form_subtemplate.html:78
|
||||
#: templates/generic_form_subtemplate.html:80
|
||||
#: templates/generic_form_subtemplate.html:82
|
||||
#: templates/generic_list_horizontal_subtemplate.html:51
|
||||
#: templates/generic_list_horizontal_subtemplate.html:178
|
||||
#: templates/generic_list_horizontal_subtemplate.html:90
|
||||
#: templates/generic_list_subtemplate.html:52
|
||||
#: templates/generic_list_subtemplate.html:178
|
||||
msgid "Save"
|
||||
msgstr "Salvar"
|
||||
|
||||
#: templates/generic_form_subtemplate.html:76
|
||||
#: templates/generic_form_subtemplate.html:78
|
||||
#: templates/generic_form_subtemplate.html:80
|
||||
#: templates/generic_form_subtemplate.html:82
|
||||
#: templates/generic_list_horizontal_subtemplate.html:51
|
||||
#: templates/generic_list_horizontal_subtemplate.html:178
|
||||
#: templates/generic_list_horizontal_subtemplate.html:90
|
||||
#: templates/generic_list_subtemplate.html:52
|
||||
#: templates/generic_list_subtemplate.html:178
|
||||
msgid "Submit"
|
||||
msgstr "Submeter"
|
||||
|
||||
#: templates/generic_form_subtemplate.html:87
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#: templates/generic_list.html:6 templates/generic_list_horizontal.html:6
|
||||
#, python-format
|
||||
msgid "List of %(stripped_title)s"
|
||||
@@ -302,9 +310,7 @@ msgstr "Lista de %(stripped_title)s "
|
||||
msgid ""
|
||||
"List of %(title)s (%(start)s - %(end)s out of %(total)s) (Page "
|
||||
"%(page_number)s of %(total_pages)s)"
|
||||
msgstr ""
|
||||
"Lista de %(title)s (%(start)s - %(end)s de %(total)s) (Page %(page_number)s "
|
||||
"of %(total_pages)s)"
|
||||
msgstr "Lista de %(title)s (%(start)s - %(end)s de %(total)s) (Page %(page_number)s of %(total_pages)s)"
|
||||
|
||||
#: templates/generic_list_horizontal_subtemplate.html:25
|
||||
#: templates/generic_list_subtemplate.html:26
|
||||
@@ -329,6 +335,3 @@ msgstr "Login"
|
||||
#: templates/password_change_form.html:5
|
||||
msgid "Password change"
|
||||
msgstr "Alterar a senha"
|
||||
|
||||
#~ msgid "Cancel"
|
||||
#~ msgstr "Cancelar"
|
||||
|
||||
Binary file not shown.
@@ -1,56 +1,54 @@
|
||||
# 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>, 2011.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Mayan EDMS\n"
|
||||
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
|
||||
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
|
||||
"PO-Revision-Date: 2011-11-22 19:21+0000\n"
|
||||
"Last-Translator: gsv70 <gsv70@mail.ru>\n"
|
||||
"Language-Team: Russian (http://www.transifex.net/projects/p/mayan-edms/team/ru/)\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2012-02-12 15:20-0400\n"
|
||||
"PO-Revision-Date: 2012-02-02 18:18+0000\n"
|
||||
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
|
||||
"Language-Team: Russian (http://www.transifex.net/projects/p/mayan-edms/team/"
|
||||
"ru/)\n"
|
||||
"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"
|
||||
"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:17
|
||||
#: __init__.py:20
|
||||
msgid "change password"
|
||||
msgstr "Изменение пароля"
|
||||
|
||||
#: __init__.py:18
|
||||
#: __init__.py:21
|
||||
msgid "user details"
|
||||
msgstr "сведения о пользователе"
|
||||
|
||||
#: __init__.py:19
|
||||
#: __init__.py:22
|
||||
msgid "edit details"
|
||||
msgstr "изменение сведений"
|
||||
|
||||
#: __init__.py:23 __init__.py:29
|
||||
#: __init__.py:26 __init__.py:31
|
||||
msgid "about"
|
||||
msgstr "инфо"
|
||||
|
||||
#: __init__.py:24
|
||||
msgid "changelog"
|
||||
msgstr "изменения"
|
||||
|
||||
#: __init__.py:25
|
||||
#: __init__.py:27
|
||||
msgid "license"
|
||||
msgstr "лицензия"
|
||||
|
||||
#: forms.py:99
|
||||
#: forms.py:101
|
||||
msgid "Selection"
|
||||
msgstr "Выбор"
|
||||
|
||||
#: forms.py:131
|
||||
#: forms.py:133
|
||||
msgid "Email"
|
||||
msgstr "Email"
|
||||
|
||||
#: forms.py:142
|
||||
#: forms.py:144
|
||||
msgid ""
|
||||
"Please enter a correct email and password. Note that the password fields is "
|
||||
"case-sensitive."
|
||||
@@ -58,7 +56,7 @@ msgstr ""
|
||||
"Пожалуйста, введите правильный адрес электронной почты и пароль с учетом "
|
||||
"регистра."
|
||||
|
||||
#: forms.py:144
|
||||
#: forms.py:146
|
||||
msgid "This account is inactive."
|
||||
msgstr "Эта учетная запись неактивна."
|
||||
|
||||
@@ -102,70 +100,81 @@ msgstr "Портрет"
|
||||
msgid "Landscape"
|
||||
msgstr "Пейзаж"
|
||||
|
||||
#: utils.py:291
|
||||
#: models.py:16
|
||||
msgid "lock field"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:43
|
||||
msgid "Anonymous user"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:46 models.py:47
|
||||
msgid "anonymous user"
|
||||
msgstr ""
|
||||
|
||||
#: utils.py:295
|
||||
msgid "function found"
|
||||
msgstr "функция найдена"
|
||||
|
||||
#: utils.py:293 utils.py:295
|
||||
#, python-format
|
||||
msgid "class found: %s"
|
||||
msgstr "класс найден: %s."
|
||||
|
||||
#: views.py:24 templates/password_change_done.html:5
|
||||
msgid "Your password has been successfully changed."
|
||||
msgstr "Ваш пароль был изменен."
|
||||
|
||||
#: views.py:41
|
||||
#: views.py:36
|
||||
msgid "No action selected."
|
||||
msgstr "Никаких действий не выбрано."
|
||||
|
||||
#: views.py:45
|
||||
#: views.py:40
|
||||
msgid "Must select at least one item."
|
||||
msgstr "Необходимо выбрать хотя бы один элемент."
|
||||
|
||||
#: views.py:86
|
||||
#: views.py:88
|
||||
#, python-format
|
||||
msgid "%(selection)s added successfully added to %(right_list_title)s."
|
||||
msgstr "%(selection)s успешно добавлен в %(right_list_title)s ."
|
||||
|
||||
#: views.py:89 views.py:106
|
||||
#: views.py:94 views.py:121
|
||||
#, python-format
|
||||
msgid "Unable to add %(selection)s to %(right_list_title)s."
|
||||
msgstr "Не удалось добавить %(selection)s до %(right_list_title)s ."
|
||||
|
||||
#: views.py:103
|
||||
#: views.py:115
|
||||
#, python-format
|
||||
msgid "%(selection)s added successfully removed from %(right_list_title)s."
|
||||
msgstr "%(selection)s успешно удален из %(right_list_title)s ."
|
||||
|
||||
#: views.py:121
|
||||
#: views.py:136
|
||||
msgid "Add"
|
||||
msgstr "Добавить"
|
||||
|
||||
#: views.py:132
|
||||
#: views.py:147
|
||||
msgid "Remove"
|
||||
msgstr "Удалить"
|
||||
|
||||
#: views.py:155
|
||||
#: views.py:170
|
||||
msgid "current user details"
|
||||
msgstr "данные пользователя"
|
||||
|
||||
#: views.py:172
|
||||
#: views.py:187
|
||||
msgid "E-mail conflict, another user has that same email."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:190
|
||||
msgid "Current user's details updated."
|
||||
msgstr "Данные пользователя обновлены."
|
||||
|
||||
#: views.py:181
|
||||
#: views.py:199
|
||||
msgid "edit current user details"
|
||||
msgstr "редактировать данные пользователя"
|
||||
|
||||
#: views.py:207
|
||||
msgid "Changelog"
|
||||
msgstr "Изменения"
|
||||
|
||||
#: views.py:220
|
||||
#: views.py:230
|
||||
msgid "License"
|
||||
msgstr "Лицензия"
|
||||
|
||||
#: views.py:239
|
||||
msgid "Current user password change"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:254 templates/password_change_done.html:5
|
||||
msgid "Your password has been successfully changed."
|
||||
msgstr "Ваш пароль был изменен."
|
||||
|
||||
#: widgets.py:58
|
||||
msgid "None"
|
||||
msgstr "Ни один"
|
||||
@@ -173,8 +182,8 @@ msgstr "Ни один"
|
||||
#: conf/settings.py:15
|
||||
msgid ""
|
||||
"Temporary directory used site wide to store thumbnails, previews and "
|
||||
"temporary files. If none is specified, one will be created using "
|
||||
"tempfile.mkdtemp()"
|
||||
"temporary files. If none is specified, one will be created using tempfile."
|
||||
"mkdtemp()"
|
||||
msgstr ""
|
||||
"Временный каталог, используемый сайтом для хранения миниатюр, превью и "
|
||||
"временных файлов. Если он не указан, он будет создан с использованием "
|
||||
@@ -188,6 +197,10 @@ msgstr ""
|
||||
"Управление механизмом, используемым для аутентификации пользователя. "
|
||||
"Возможные варианты: имя пользователя, адрес электронной почты"
|
||||
|
||||
#: conf/settings.py:74
|
||||
msgid "Allow non authenticated users, access to all views"
|
||||
msgstr ""
|
||||
|
||||
#: templates/403.html:3 templates/403.html.py:7
|
||||
msgid "Insufficient permissions"
|
||||
msgstr "Недостаточно прав"
|
||||
@@ -268,28 +281,32 @@ msgid "No"
|
||||
msgstr "Нет"
|
||||
|
||||
#: templates/generic_form_instance.html:37
|
||||
#: templates/generic_form_subtemplate.html:52
|
||||
#: templates/generic_form_subtemplate.html:56
|
||||
msgid "required"
|
||||
msgstr "требуется"
|
||||
|
||||
#: templates/generic_form_subtemplate.html:76
|
||||
#: templates/generic_form_subtemplate.html:78
|
||||
#: templates/generic_form_subtemplate.html:80
|
||||
#: templates/generic_form_subtemplate.html:82
|
||||
#: templates/generic_list_horizontal_subtemplate.html:51
|
||||
#: templates/generic_list_horizontal_subtemplate.html:178
|
||||
#: templates/generic_list_horizontal_subtemplate.html:90
|
||||
#: templates/generic_list_subtemplate.html:52
|
||||
#: templates/generic_list_subtemplate.html:178
|
||||
msgid "Save"
|
||||
msgstr "Сохранить"
|
||||
|
||||
#: templates/generic_form_subtemplate.html:76
|
||||
#: templates/generic_form_subtemplate.html:78
|
||||
#: templates/generic_form_subtemplate.html:80
|
||||
#: templates/generic_form_subtemplate.html:82
|
||||
#: templates/generic_list_horizontal_subtemplate.html:51
|
||||
#: templates/generic_list_horizontal_subtemplate.html:178
|
||||
#: templates/generic_list_horizontal_subtemplate.html:90
|
||||
#: templates/generic_list_subtemplate.html:52
|
||||
#: templates/generic_list_subtemplate.html:178
|
||||
msgid "Submit"
|
||||
msgstr "Выполнить"
|
||||
|
||||
#: templates/generic_form_subtemplate.html:87
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: templates/generic_list.html:6 templates/generic_list_horizontal.html:6
|
||||
#, python-format
|
||||
msgid "List of %(stripped_title)s"
|
||||
@@ -302,8 +319,8 @@ msgid ""
|
||||
"List of %(title)s (%(start)s - %(end)s out of %(total)s) (Page "
|
||||
"%(page_number)s of %(total_pages)s)"
|
||||
msgstr ""
|
||||
"Список %(title)s (%(start)s - %(end)s из %(total)s) (Page %(page_number)s из"
|
||||
" %(total_pages)s)"
|
||||
"Список %(title)s (%(start)s - %(end)s из %(total)s) (Page %(page_number)s из "
|
||||
"%(total_pages)s)"
|
||||
|
||||
#: templates/generic_list_horizontal_subtemplate.html:25
|
||||
#: templates/generic_list_subtemplate.html:26
|
||||
@@ -328,5 +345,3 @@ msgstr "Войти"
|
||||
#: templates/password_change_form.html:5
|
||||
msgid "Password change"
|
||||
msgstr "Изменение пароля"
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import re
|
||||
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.conf import settings
|
||||
|
||||
from ..conf.settings import ALLOW_ANONYMOUS_ACCESS
|
||||
|
||||
EXEMPT_URLS = [re.compile(settings.LOGIN_URL.lstrip('/'))]
|
||||
if hasattr(settings, 'LOGIN_EXEMPT_URLS'):
|
||||
EXEMPT_URLS += [re.compile(expr) for expr in settings.LOGIN_EXEMPT_URLS]
|
||||
@@ -20,13 +24,14 @@ class LoginRequiredMiddleware:
|
||||
"""
|
||||
|
||||
def process_request(self, request):
|
||||
assert hasattr(request, 'user'), "The Login Required middleware\
|
||||
requires authentication middleware to be installed. Edit your\
|
||||
MIDDLEWARE_CLASSES setting to insert\
|
||||
'django.contrib.auth.middlware.AuthenticationMiddleware'. If that doesn't\
|
||||
work, ensure your TEMPLATE_CONTEXT_PROCESSORS setting includes\
|
||||
'django.core.context_processors.auth'."
|
||||
if not request.user.is_authenticated():
|
||||
path = request.path_info.lstrip('/')
|
||||
if not any(m.match(path) for m in EXEMPT_URLS):
|
||||
return HttpResponseRedirect(settings.LOGIN_URL)
|
||||
if not ALLOW_ANONYMOUS_ACCESS:
|
||||
assert hasattr(request, 'user'), "The Login Required middleware\
|
||||
requires authentication middleware to be installed. Edit your\
|
||||
MIDDLEWARE_CLASSES setting to insert\
|
||||
'django.contrib.auth.middlware.AuthenticationMiddleware'. If that doesn't\
|
||||
work, ensure your TEMPLATE_CONTEXT_PROCESSORS setting includes\
|
||||
'django.core.context_processors.auth'."
|
||||
if not request.user.is_authenticated():
|
||||
path = request.path_info.lstrip('/')
|
||||
if not any(m.match(path) for m in EXEMPT_URLS):
|
||||
return HttpResponseRedirect(settings.LOGIN_URL)
|
||||
|
||||
@@ -1,3 +1,47 @@
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import ugettext
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
|
||||
# Create your models here.
|
||||
SINGLETON_LOCK_ID = 1
|
||||
|
||||
|
||||
class SingletonManager(models.Manager):
|
||||
def get(self, **kwargs):
|
||||
instance, created = self.model.objects.get_or_create(lock_id=SINGLETON_LOCK_ID, **kwargs)
|
||||
return instance
|
||||
|
||||
|
||||
class Singleton(models.Model):
|
||||
lock_id = models.CharField(max_length=1, default=SINGLETON_LOCK_ID, editable=False, verbose_name=_(u'lock field'), unique=True)
|
||||
|
||||
objects = SingletonManager()
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.id = 1
|
||||
super(Singleton, self).save(*args, **kwargs)
|
||||
|
||||
def delete(self):
|
||||
pass
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
||||
class AnonymousUserSingletonManager(SingletonManager):
|
||||
def passthru_check(self, user):
|
||||
if isinstance(user, AnonymousUser):
|
||||
return self.model.objects.get()
|
||||
else:
|
||||
return user
|
||||
|
||||
|
||||
class AnonymousUserSingleton(Singleton):
|
||||
objects = AnonymousUserSingletonManager()
|
||||
|
||||
def __unicode__(self):
|
||||
return ugettext('Anonymous user')
|
||||
|
||||
class Meta:
|
||||
verbose_name = _(u'anonymous user')
|
||||
verbose_name_plural = _(u'anonymous user')
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
<input name="next" type="hidden" value="{{ next }}" />
|
||||
{% endif %}
|
||||
|
||||
{% if previous %}
|
||||
<input name="previous" type="hidden" value="{{ previous }}" />
|
||||
{% endif %}
|
||||
|
||||
{% for hidden_field in hidden_fields %}
|
||||
{{ hidden_field.as_hidden }}
|
||||
{% endfor %}
|
||||
@@ -77,6 +81,13 @@
|
||||
{% endif %}
|
||||
{% if submit_label %}{{ submit_label }}{% else %}{% if object %}{% trans "Save" %}{% else %}{% trans "Submit" %}{% endif %}{% endif %}
|
||||
</button>
|
||||
|
||||
{% if previous %}
|
||||
<a href="#header" onclick='{% if previous %}window.location.replace("{{ previous }}");{% else %}history.go(-1);{% endif %}' class="button">
|
||||
<img src="{{ STATIC_URL }}web_theme_media/images/icons/cross.png" alt="{% if cancel_label %}{{ cancel_label }}{% else %}{% trans 'Cancel' %}{% endif %}"/> {% if cancel_label %}{{ cancel_label }}{% else %}{% trans "Cancel" %}{% endif %}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% comment %}
|
||||
<a href="#header" class="button">
|
||||
<img src="{{ STATIC_URL }}web_theme_media/images/icons/cross.png" alt="{% trans 'Cancel' %}"/> {% trans 'Cancel' %}
|
||||
|
||||
@@ -59,95 +59,7 @@
|
||||
<div style="border: 1px solid; height: {{ scrollable_content_height }}; overflow: auto;">
|
||||
{% endif %}
|
||||
|
||||
{% comment %}
|
||||
<table class="table">
|
||||
<tbody>
|
||||
{% if not hide_header %}
|
||||
<tr>
|
||||
{% if multi_select or multi_select_as_buttons %}
|
||||
<th class="first"><input type="checkbox" class="checkbox toggle" /></th>
|
||||
{% endif %}
|
||||
|
||||
{% if not hide_object %}
|
||||
<th>{% trans "Identifier" %}</th>
|
||||
{% endif %}
|
||||
|
||||
{% for column in extra_columns_preffixed %}
|
||||
<th>{{ column.name|capfirst }}</th>
|
||||
{% endfor %}
|
||||
|
||||
{% for column in object_list.0|get_model_list_columns %}
|
||||
<th>{{ column.name|capfirst }}</th>
|
||||
{% endfor %}
|
||||
|
||||
{% for column in extra_columns %}
|
||||
<th>{{ column.name|capfirst }}</th>
|
||||
{% endfor %}
|
||||
|
||||
{% if not hide_links %}
|
||||
<th class=""> </th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% for object in object_list %}
|
||||
<tr class="{% cycle 'odd' 'even2' %}">
|
||||
{% if multi_select or multi_select_as_buttons %}
|
||||
<td><input type="checkbox" class="checkbox" name="pk_{{ object.pk }}" value="" /></td>
|
||||
{% endif %}
|
||||
{% if not hide_object %}
|
||||
{% if main_object %}
|
||||
{% with object|object_property:main_object as object %}
|
||||
<td>{% if not hide_link %}<a href="{{ object.get_absolute_url }}">{{ object }}</a>{% else %}{{ object }}{% endif %}</td>
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
<td>{% if not hide_link %}<a href="{{ object.get_absolute_url }}">{{ object }}</a>{% else %}{{ object }}{% endif %}</td>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% for column in extra_columns_preffixed %}
|
||||
{% if column.keep_together %}
|
||||
<td>
|
||||
{{ object|object_property:column.attribute|make_non_breakable }}
|
||||
</td>
|
||||
{% else %}
|
||||
<td>{{ object|object_property:column.attribute }}</td>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if not hide_columns %}
|
||||
{% for column in object|get_model_list_columns %}
|
||||
<td>{{ object|object_property:column.attribute }}</td>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% for column in extra_columns %}
|
||||
{% if column.keep_together %}
|
||||
<td>
|
||||
{{ object|object_property:column.attribute|make_non_breakable }}
|
||||
</td>
|
||||
{% else %}
|
||||
<td>{{ object|object_property:column.attribute }}</td>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if not hide_links %}
|
||||
{% if list_object_variable_name %}
|
||||
{% copy_variable object as list_object_variable_name %}
|
||||
{% copy_variable list_object_variable_name as "navigation_object_name" %}
|
||||
{% endif %}
|
||||
<td class="last">
|
||||
{% if navigation_object_links %}
|
||||
{% with navigation_object_links as overrided_object_links %}
|
||||
{% object_navigation_template %}
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
{% object_navigation_template %}
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr><td colspan=99 class="tc">{% blocktrans with title|striptags as stripped_title %}There are no {{ stripped_title }}{% endblocktrans %}</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endcomment %}
|
||||
<div class="group navform wat-cf">
|
||||
{% for object in object_list %}
|
||||
{{ object }}
|
||||
|
||||
32
apps/common/templatetags/set_var.py
Normal file
32
apps/common/templatetags/set_var.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from django import template
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
class SetVarNode(template.Node):
|
||||
def __init__(self, var_name, var_value):
|
||||
self.var_name = var_name
|
||||
self.var_value = var_value
|
||||
|
||||
def render(self, context):
|
||||
try:
|
||||
value = template.Variable(self.var_value).resolve(context)
|
||||
except template.VariableDoesNotExist:
|
||||
value = ""
|
||||
#context[self.var_name] = value
|
||||
# Make it global across all blocks
|
||||
context.dicts[0][self.var_name] = value
|
||||
|
||||
return u""
|
||||
|
||||
|
||||
def set_var(parser, token):
|
||||
"""
|
||||
{% set <var_name> = <var_value> %}
|
||||
"""
|
||||
parts = token.split_contents()
|
||||
if len(parts) < 4:
|
||||
raise template.TemplateSyntaxError("'set' tag must be of the form: {% set <var_name> = <var_value> %}")
|
||||
return SetVarNode(parts[1], parts[3])
|
||||
|
||||
register.tag('set', set_var)
|
||||
@@ -1,23 +0,0 @@
|
||||
"""
|
||||
This file demonstrates two different styles of tests (one doctest and one
|
||||
unittest). These will both pass when you run "manage.py test".
|
||||
|
||||
Replace these with more appropriate tests for your application.
|
||||
"""
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
class SimpleTest(TestCase):
|
||||
def test_basic_addition(self):
|
||||
"""
|
||||
Tests that 1 + 1 always equals 2.
|
||||
"""
|
||||
self.failUnlessEqual(1 + 1, 2)
|
||||
|
||||
__test__ = {"doctest": """
|
||||
Another way to test that 1 + 1 is equal to 2.
|
||||
|
||||
>>> 1 + 1 == 2
|
||||
True
|
||||
"""}
|
||||
|
||||
@@ -4,7 +4,6 @@ from django.conf import settings
|
||||
|
||||
urlpatterns = patterns('common.views',
|
||||
url(r'^about/$', direct_to_template, {'template': 'about.html'}, 'about_view'),
|
||||
url(r'^changelog/$', 'changelog_view', (), 'changelog_view'),
|
||||
url(r'^license/$', 'license_view', (), 'license_view'),
|
||||
url(r'^password/change/done/$', 'password_change_done', (), name='password_change_done'),
|
||||
url(r'^object/multiple/action/$', 'multi_object_action_view', (), name='multi_object_action_view'),
|
||||
@@ -13,12 +12,12 @@ urlpatterns = patterns('common.views',
|
||||
url(r'^user/edit/$', 'current_user_edit', (), 'current_user_edit'),
|
||||
|
||||
url(r'^login/$', 'login_view', (), name='login_view'),
|
||||
url(r'^password/change/$', 'password_change_view', (), name='password_change_view'),
|
||||
)
|
||||
|
||||
urlpatterns += patterns('',
|
||||
url(r'^logout/$', 'django.contrib.auth.views.logout', {'next_page': '/'}, name='logout_view'),
|
||||
|
||||
url(r'^password/change/$', 'django.contrib.auth.views.password_change', {'template_name': 'password_change_form.html', 'post_change_redirect': '/password/change/done/'}, name='password_change_view'),
|
||||
url(r'^password/reset/$', 'django.contrib.auth.views.password_reset', {'email_template_name': 'password_reset_email.html', 'template_name': 'password_reset_form.html', 'post_reset_redirect': '/password/reset/done'}, name='password_reset_view'),
|
||||
url(r'^password/reset/confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm', {'template_name': 'password_reset_confirm.html', 'post_reset_redirect': '/password/reset/complete/'}, name='password_reset_confirm_view'),
|
||||
url(r'^password/reset/complete/$', 'django.contrib.auth.views.password_reset_complete', {'template_name': 'password_reset_complete.html'}, name='password_reset_complete_view'),
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import re
|
||||
import types
|
||||
@@ -16,7 +18,7 @@ from django.contrib.auth.models import User
|
||||
|
||||
|
||||
def urlquote(link=None, get=None):
|
||||
u'''
|
||||
u"""
|
||||
This method does both: urlquote() and urlencode()
|
||||
|
||||
urlqoute(): Quote special characters in 'link'
|
||||
@@ -31,7 +33,7 @@ def urlquote(link=None, get=None):
|
||||
urlquote('/mypath/', {'key': 'value'}) --> '/mypath/?key=value'
|
||||
urlquote('/mypath/', {'key': ['value1', 'value2']}) --> '/mypath/?key=value1&key=value2'
|
||||
urlquote({'key': ['value1', 'value2']}) --> 'key=value1&key=value2'
|
||||
'''
|
||||
"""
|
||||
if get is None:
|
||||
get = []
|
||||
|
||||
@@ -110,7 +112,9 @@ def pretty_size_10(size):
|
||||
# http://www.johncardinal.com/tmgutil/capitalizenames.htm
|
||||
|
||||
def proper_name(name):
|
||||
"""Does the work of capitalizing a name (can be a full name)."""
|
||||
"""
|
||||
Does the work of capitalizing a name (can be a full name).
|
||||
"""
|
||||
mc = re.compile(r'^Mc(\w)(?=\w)', re.I)
|
||||
mac = re.compile(r'^Mac(\w)(?=\w)', re.I)
|
||||
suffixes = [
|
||||
@@ -290,11 +294,11 @@ def return_type(value):
|
||||
if isinstance(value, types.FunctionType):
|
||||
return value.__doc__ if value.__doc__ else _(u'function found')
|
||||
elif isinstance(value, types.ClassType):
|
||||
return _(u'class found: %s') % unicode(value).split("'")[1].split('.')[-1]
|
||||
return u'%s.%s' % (value.__class__.__module__, value.__class__.__name__)
|
||||
elif isinstance(value, types.TypeType):
|
||||
return _(u'class found: %s') % unicode(value).split("'")[1].split('.')[-1]
|
||||
return u'%s.%s' % (value.__module__, value.__name__)
|
||||
elif isinstance(value, types.DictType) or isinstance(value, types.DictionaryType):
|
||||
return ','.join(list(value))
|
||||
return u', '.join(list(value))
|
||||
else:
|
||||
return value
|
||||
|
||||
@@ -326,6 +330,24 @@ def generate_choices_w_labels(choices, display_object_type=True):
|
||||
return sorted(results, key=lambda x: x[1])
|
||||
|
||||
|
||||
def get_object_name(obj, display_object_type=True):
|
||||
ct_label = ContentType.objects.get_for_model(obj).name
|
||||
if isinstance(obj, User):
|
||||
label = obj.get_full_name() if obj.get_full_name() else obj
|
||||
else:
|
||||
label = unicode(obj)
|
||||
|
||||
if display_object_type:
|
||||
try:
|
||||
verbose_name = unicode(obj._meta.verbose_name)
|
||||
except AttributeError:
|
||||
verbose_name = ct_label
|
||||
|
||||
return u'%s: %s' % (verbose_name, label)
|
||||
else:
|
||||
return u'%s' % (label)
|
||||
|
||||
|
||||
def return_diff(old_obj, new_obj, attrib_list=None):
|
||||
diff_dict = {}
|
||||
if not attrib_list:
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.shortcuts import redirect
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.http import HttpResponseRedirect
|
||||
@@ -9,20 +11,13 @@ from django.core.urlresolvers import reverse
|
||||
from django.utils.http import urlencode
|
||||
from django.contrib.auth.views import login
|
||||
from django.utils.simplejson import dumps, loads
|
||||
from django.contrib.auth.views import password_change
|
||||
from django.contrib.auth.models import User
|
||||
from django.conf import settings
|
||||
|
||||
from common.forms import ChoiceForm, UserForm, UserForm_view, \
|
||||
ChangelogForm, LicenseForm
|
||||
from common.forms import EmailAuthenticationForm
|
||||
from common.conf.settings import LOGIN_METHOD
|
||||
|
||||
|
||||
def password_change_done(request):
|
||||
"""
|
||||
View called when the new user password has been accepted
|
||||
"""
|
||||
|
||||
messages.success(request, _(u'Your password has been successfully changed.'))
|
||||
return redirect('home')
|
||||
from .forms import (ChoiceForm, UserForm, UserForm_view, LicenseForm,
|
||||
EmailAuthenticationForm)
|
||||
from .conf.settings import LOGIN_METHOD
|
||||
|
||||
|
||||
def multi_object_action_view(request):
|
||||
@@ -65,7 +60,7 @@ def get_obj_from_content_type_string(string):
|
||||
return ct.get_object_for_this_type(pk=pk)
|
||||
|
||||
|
||||
def assign_remove(request, left_list, right_list, add_method, remove_method, left_list_title, right_list_title, decode_content_type=False, extra_context=None):
|
||||
def assign_remove(request, left_list, right_list, add_method, remove_method, left_list_title, right_list_title, decode_content_type=False, extra_context=None, grouped=False):
|
||||
left_list_name = u'left_list'
|
||||
right_list_name = u'right_list'
|
||||
|
||||
@@ -76,7 +71,14 @@ def assign_remove(request, left_list, right_list, add_method, remove_method, lef
|
||||
choices=left_list())
|
||||
if unselected_list.is_valid():
|
||||
for selection in unselected_list.cleaned_data['selection']:
|
||||
label = dict(left_list())[selection]
|
||||
if grouped:
|
||||
flat_list = []
|
||||
for group in left_list():
|
||||
flat_list.extend(group[1])
|
||||
else:
|
||||
flat_list = left_list()
|
||||
|
||||
label = dict(flat_list)[selection]
|
||||
if decode_content_type:
|
||||
selection_obj = get_obj_from_content_type_string(selection)
|
||||
else:
|
||||
@@ -86,8 +88,11 @@ def assign_remove(request, left_list, right_list, add_method, remove_method, lef
|
||||
messages.success(request, _(u'%(selection)s added successfully added to %(right_list_title)s.') % {
|
||||
'selection': label, 'right_list_title': right_list_title})
|
||||
except:
|
||||
messages.error(request, _(u'Unable to add %(selection)s to %(right_list_title)s.') % {
|
||||
'selection': label, 'right_list_title': right_list_title})
|
||||
if settings.DEBUG:
|
||||
raise
|
||||
else:
|
||||
messages.error(request, _(u'Unable to add %(selection)s to %(right_list_title)s.') % {
|
||||
'selection': label, 'right_list_title': right_list_title})
|
||||
|
||||
elif u'%s-submit' % right_list_name in request.POST.keys():
|
||||
selected_list = ChoiceForm(request.POST,
|
||||
@@ -95,7 +100,14 @@ def assign_remove(request, left_list, right_list, add_method, remove_method, lef
|
||||
choices=right_list())
|
||||
if selected_list.is_valid():
|
||||
for selection in selected_list.cleaned_data['selection']:
|
||||
label = dict(right_list())[selection]
|
||||
if grouped:
|
||||
flat_list = []
|
||||
for group in right_list():
|
||||
flat_list.extend(group[1])
|
||||
else:
|
||||
flat_list = right_list()
|
||||
|
||||
label = dict(flat_list)[selection]
|
||||
if decode_content_type:
|
||||
selection = get_obj_from_content_type_string(selection)
|
||||
try:
|
||||
@@ -103,8 +115,11 @@ def assign_remove(request, left_list, right_list, add_method, remove_method, lef
|
||||
messages.success(request, _(u'%(selection)s added successfully removed from %(right_list_title)s.') % {
|
||||
'selection': label, 'right_list_title': right_list_title})
|
||||
except:
|
||||
messages.error(request, _(u'Unable to add %(selection)s to %(right_list_title)s.') % {
|
||||
'selection': label, 'right_list_title': right_list_title})
|
||||
if settings.DEBUG:
|
||||
raise
|
||||
else:
|
||||
messages.error(request, _(u'Unable to add %(selection)s to %(right_list_title)s.') % {
|
||||
'selection': label, 'right_list_title': right_list_title})
|
||||
unselected_list = ChoiceForm(prefix=left_list_name,
|
||||
choices=left_list())
|
||||
selected_list = ChoiceForm(prefix=right_list_name,
|
||||
@@ -168,9 +183,12 @@ def current_user_edit(request):
|
||||
if request.method == 'POST':
|
||||
form = UserForm(instance=request.user, data=request.POST)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
messages.success(request, _(u'Current user\'s details updated.'))
|
||||
return HttpResponseRedirect(next)
|
||||
if User.objects.filter(email=form.cleaned_data['email']).exclude(pk=request.user.pk).count():
|
||||
messages.error(request, _(u'E-mail conflict, another user has that same email.'))
|
||||
else:
|
||||
form.save()
|
||||
messages.success(request, _(u'Current user\'s details updated.'))
|
||||
return HttpResponseRedirect(next)
|
||||
else:
|
||||
form = UserForm(instance=request.user)
|
||||
|
||||
@@ -185,34 +203,26 @@ def current_user_edit(request):
|
||||
|
||||
def login_view(request):
|
||||
"""
|
||||
Control how the use is to be authenticated, options are 'email' and
|
||||
Control how the use is to be authenticated, options are 'email' and
|
||||
'username'
|
||||
"""
|
||||
"""
|
||||
kwargs = {'template_name': 'login.html'}
|
||||
|
||||
|
||||
if LOGIN_METHOD == 'email':
|
||||
kwargs['authentication_form'] = EmailAuthenticationForm
|
||||
|
||||
return login(request, **kwargs)
|
||||
if not request.user.is_authenticated():
|
||||
context = {'web_theme_view_type': 'plain'}
|
||||
else:
|
||||
context = {}
|
||||
|
||||
|
||||
def changelog_view(request):
|
||||
"""
|
||||
Display the included Changelog.txt file from the about menu
|
||||
"""
|
||||
form = ChangelogForm()
|
||||
return render_to_response(
|
||||
'generic_detail.html', {
|
||||
'form': form,
|
||||
'title': _(u'Changelog'),
|
||||
},
|
||||
context_instance=RequestContext(request))
|
||||
return login(request, extra_context=context, **kwargs)
|
||||
|
||||
|
||||
def license_view(request):
|
||||
"""
|
||||
Display the included LICENSE file from the about menu
|
||||
"""
|
||||
"""
|
||||
form = LicenseForm()
|
||||
return render_to_response(
|
||||
'generic_detail.html', {
|
||||
@@ -220,3 +230,26 @@ def license_view(request):
|
||||
'title': _(u'License'),
|
||||
},
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def password_change_view(request):
|
||||
"""
|
||||
Password change wrapper for better control
|
||||
"""
|
||||
context={'title': _(u'Current user password change')}
|
||||
|
||||
return password_change(
|
||||
request,
|
||||
extra_context=context,
|
||||
template_name='password_change_form.html',
|
||||
post_change_redirect=reverse('password_change_done'),
|
||||
)
|
||||
|
||||
|
||||
def password_change_done(request):
|
||||
"""
|
||||
View called when the new user password has been accepted
|
||||
"""
|
||||
|
||||
messages.success(request, _(u'Your password has been successfully changed.'))
|
||||
return redirect('current_user_details')
|
||||
|
||||
@@ -13,7 +13,7 @@ class PlainWidget(forms.widgets.Widget):
|
||||
"""
|
||||
Class to define a form widget that effectively nulls the htmls of a
|
||||
widget and reduces the output to only it's value
|
||||
"""
|
||||
"""
|
||||
def render(self, name, value, attrs=None):
|
||||
return mark_safe(u'%s' % value)
|
||||
|
||||
@@ -77,8 +77,8 @@ class TextAreaDiv(forms.widgets.Widget):
|
||||
"""
|
||||
Class to define a form widget that simulates the behavior of a
|
||||
Textarea widget but using a div tag instead
|
||||
"""
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, attrs=None):
|
||||
# The 'rows' and 'cols' attributes are required for HTML correctness.
|
||||
default_attrs = {'class': 'text_area_div'}
|
||||
@@ -99,9 +99,9 @@ class TextAreaDiv(forms.widgets.Widget):
|
||||
# From: http://www.peterbe.com/plog/emailinput-html5-django
|
||||
class EmailInput(forms.widgets.Input):
|
||||
"""
|
||||
Class for a login form widget that accepts only well formated
|
||||
Class for a login form widget that accepts only well formated
|
||||
email address
|
||||
"""
|
||||
"""
|
||||
input_type = 'email'
|
||||
|
||||
def render(self, name, value, attrs=None):
|
||||
@@ -120,7 +120,8 @@ class ScrollableCheckboxSelectMultiple(forms.widgets.CheckboxSelectMultiple):
|
||||
exceds the height of the div
|
||||
"""
|
||||
def render(self, name, value, attrs=None, choices=()):
|
||||
if value is None: value = []
|
||||
if value is None:
|
||||
value = []
|
||||
has_id = attrs and 'id' in attrs
|
||||
final_attrs = self.build_attrs(attrs, name=name)
|
||||
output = [u'<ul class="undecorated_list" style="margin-left: 5px; margin-top: 3px; margin-bottom: 3px;">']
|
||||
@@ -141,5 +142,5 @@ class ScrollableCheckboxSelectMultiple(forms.widgets.CheckboxSelectMultiple):
|
||||
option_label = conditional_escape(force_unicode(option_label))
|
||||
output.append(u'<li><label%s>%s %s</label></li>' % (label_for, rendered_cb, option_label))
|
||||
output.append(u'</ul>')
|
||||
|
||||
|
||||
return mark_safe(u'<div class="text_area_div">%s</div>' % u'\n'.join(output))
|
||||
|
||||
@@ -15,7 +15,8 @@ __all__ = ('security_hash', 'BoundFormWizard')
|
||||
|
||||
|
||||
def security_hash_new(form, exclude=None, *args):
|
||||
"""Calculates a security hash for the given Form/FormSet instance.
|
||||
"""
|
||||
Calculates a security hash for the given Form/FormSet instance.
|
||||
|
||||
This creates a list of the form field names/values in a deterministic
|
||||
order, pickles the result with the SECRET_KEY setting, then takes an md5
|
||||
@@ -51,19 +52,24 @@ def security_hash_new(form, exclude=None, *args):
|
||||
|
||||
|
||||
class BoundFormWizard(FormWizard):
|
||||
"""Render prev_fields as a list of bound form fields in the template
|
||||
context rather than raw html."""
|
||||
"""
|
||||
Render prev_fields as a list of bound form fields in the template
|
||||
context rather than raw html.
|
||||
"""
|
||||
|
||||
def security_hash(self, request, form):
|
||||
"""Calculates the security hash for the given HttpRequest and
|
||||
"""
|
||||
Calculates the security hash for the given HttpRequest and
|
||||
Form/FormSet instances.
|
||||
|
||||
Subclasses may want to take into account request-specific information,
|
||||
such as the IP address.
|
||||
"""
|
||||
|
||||
return security_hash_new(form)
|
||||
|
||||
def render(self, form, request, step, context=None):
|
||||
"Renders the given Form object, returning an HttpResponse."
|
||||
'Renders the given Form object, returning an HttpResponse.'
|
||||
old_data = request.POST
|
||||
prev_fields = []
|
||||
if old_data:
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
|
||||
from navigation.api import register_sidebar_template
|
||||
from project_tools.api import register_tool
|
||||
|
||||
from converter.utils import load_backend
|
||||
from converter.conf.settings import GRAPHICS_BACKEND
|
||||
from .utils import load_backend
|
||||
from .conf.settings import GRAPHICS_BACKEND
|
||||
|
||||
formats_list = {'text': _('file formats'), 'view': 'formats_list', 'famfam': 'pictures', 'icon': 'pictures.png'}
|
||||
def is_superuser(context):
|
||||
return context['request'].user.is_staff or context['request'].user.is_superuser
|
||||
|
||||
formats_list = {'text': _('file formats'), 'view': 'formats_list', 'famfam': 'pictures', 'icon': 'pictures.png', 'condition': is_superuser, 'children_view_regex': [r'formats_list']}
|
||||
|
||||
register_sidebar_template(['formats_list'], 'converter_file_formats_help.html')
|
||||
|
||||
|
||||
@@ -1,25 +1,26 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import hashlib
|
||||
|
||||
from django.utils.encoding import smart_str
|
||||
|
||||
from common.conf.settings import TEMPORARY_DIRECTORY
|
||||
|
||||
from converter.literals import DEFAULT_PAGE_NUMBER, \
|
||||
DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION, DEFAULT_FILE_FORMAT
|
||||
|
||||
from converter import backend
|
||||
from converter.literals import TRANSFORMATION_CHOICES
|
||||
from converter.literals import TRANSFORMATION_RESIZE, \
|
||||
TRANSFORMATION_ROTATE, TRANSFORMATION_ZOOM
|
||||
from converter.literals import DIMENSION_SEPARATOR
|
||||
from converter.literals import FILE_FORMATS
|
||||
from converter.utils import cleanup
|
||||
from converter.runtime import office_converter
|
||||
from converter.exceptions import OfficeConversionError
|
||||
from .literals import (DEFAULT_PAGE_NUMBER,
|
||||
DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION, DEFAULT_FILE_FORMAT)
|
||||
from . import backend
|
||||
from .literals import (TRANSFORMATION_CHOICES, TRANSFORMATION_RESIZE,
|
||||
TRANSFORMATION_ROTATE, TRANSFORMATION_ZOOM, DIMENSION_SEPARATOR,
|
||||
FILE_FORMATS)
|
||||
from .utils import cleanup
|
||||
from .runtime import office_converter
|
||||
from .exceptions import OfficeConversionError, UnknownFileFormat
|
||||
|
||||
HASH_FUNCTION = lambda x: hashlib.sha256(x).hexdigest()
|
||||
|
||||
|
||||
|
||||
def cache_cleanup(input_filepath, *args, **kwargs):
|
||||
try:
|
||||
os.remove(create_image_cache_filename(input_filepath, *args, **kwargs))
|
||||
@@ -29,7 +30,7 @@ def cache_cleanup(input_filepath, *args, **kwargs):
|
||||
|
||||
def create_image_cache_filename(input_filepath, *args, **kwargs):
|
||||
if input_filepath:
|
||||
hash_value = HASH_FUNCTION(u''.join([input_filepath, unicode(args), unicode(kwargs)]))
|
||||
hash_value = HASH_FUNCTION(u''.join([HASH_FUNCTION(smart_str(input_filepath)), unicode(args), unicode(kwargs)]))
|
||||
return os.path.join(TEMPORARY_DIRECTORY, hash_value)
|
||||
else:
|
||||
return None
|
||||
@@ -42,13 +43,13 @@ def convert(input_filepath, output_filepath=None, cleanup_files=False, mimetype=
|
||||
rotation = kwargs.get('rotation', DEFAULT_ROTATION)
|
||||
page = kwargs.get('page', DEFAULT_PAGE_NUMBER)
|
||||
transformations = kwargs.get('transformations', [])
|
||||
|
||||
|
||||
if transformations is None:
|
||||
transformations = []
|
||||
|
||||
if output_filepath is None:
|
||||
output_filepath = create_image_cache_filename(input_filepath, *args, **kwargs)
|
||||
|
||||
|
||||
if os.path.exists(output_filepath):
|
||||
return output_filepath
|
||||
|
||||
@@ -79,7 +80,7 @@ def convert(input_filepath, output_filepath=None, cleanup_files=False, mimetype=
|
||||
'transformation': TRANSFORMATION_ZOOM,
|
||||
'arguments': {'percent': zoom}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
if rotation != 0 and rotation != 360:
|
||||
transformations.append(
|
||||
@@ -87,7 +88,7 @@ def convert(input_filepath, output_filepath=None, cleanup_files=False, mimetype=
|
||||
'transformation': TRANSFORMATION_ROTATE,
|
||||
'arguments': {'degrees': rotation}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
try:
|
||||
backend.convert_file(input_filepath=input_filepath, output_filepath=output_filepath, transformations=transformations, page=page, file_format=file_format, mimetype=mimetype)
|
||||
@@ -106,8 +107,8 @@ def get_page_count(input_filepath):
|
||||
input_filepath = office_converter.output_filepath
|
||||
|
||||
except OfficeConversionError:
|
||||
raise UnknownFileFormat('office converter exception')
|
||||
|
||||
raise UnknownFileFormat('office converter exception')
|
||||
|
||||
return backend.get_page_count(input_filepath)
|
||||
|
||||
'''
|
||||
@@ -127,8 +128,7 @@ def get_available_transformations_choices():
|
||||
result.append([transformation, transformation_template])
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
||||
|
||||
def get_format_list():
|
||||
return [(format, FILE_FORMATS.get(format, u'')) for format in backend.get_format_list()]
|
||||
|
||||
|
||||
@@ -30,7 +30,11 @@ class ConverterClass(ConverterBase):
|
||||
# If file is a PDF open it with slate to determine the page
|
||||
# count
|
||||
with open(input_filepath) as fd:
|
||||
pages = slate.PDF(fd)
|
||||
try:
|
||||
pages = slate.PDF(fd)
|
||||
except:
|
||||
return 1
|
||||
# TODO: Maybe return UnknownFileFormat to display proper unknwon file format message in document description
|
||||
return len(pages)
|
||||
|
||||
try:
|
||||
|
||||
@@ -53,7 +53,7 @@ FILE_FORMATS = {
|
||||
'8BIN': _(u'Photoshop resource format'),
|
||||
'8BIMTEXT': _(u'Photoshop resource text format'),
|
||||
'8BIMWTEXT': _(u'Photoshop resource wide text format'),
|
||||
|
||||
|
||||
'A': _(u'Raw alpha samples'),
|
||||
'AI': _(u'Adobe Illustrator CS2'),
|
||||
'APP1': _(u'Raw application information'),
|
||||
@@ -62,7 +62,7 @@ FILE_FORMATS = {
|
||||
'ARW': _(u'Sony Alpha DSLR Raw Image Format'),
|
||||
'AVI': _(u'Microsoft Audio/Visual Interleaved'),
|
||||
'AVS': _(u'AVS X image'),
|
||||
|
||||
|
||||
'B': _(u'Raw blue samples'),
|
||||
'BGR': _(u'Raw blue, green, and red samples'),
|
||||
'BGRA': _(u'Raw blue, green, red and alpha samples'),
|
||||
@@ -95,7 +95,7 @@ FILE_FORMATS = {
|
||||
'DJVU': _(u'Déjà vu'),
|
||||
'DNG': _(u'Adobe Digital Negative'),
|
||||
'DOT': _(u'Graphviz'),
|
||||
'DPX': _(u'SMPTE 268M-2003 (DPX 2.0)'),
|
||||
'DPX': _(u'SMPTE 268M-2003 (DPX 2.0)'),
|
||||
|
||||
'EPDF': _(u'Encapsulated Portable Document Format'),
|
||||
'EPI': _(u'Adobe Encapsulated PostScript Interchange format'),
|
||||
@@ -110,7 +110,7 @@ FILE_FORMATS = {
|
||||
'ERF': _(u'Epson RAW Format'),
|
||||
'EXIF': _(u'Exif digital camera binary data'),
|
||||
'EXR': _(u'High Dynamic-range (HDR)'),
|
||||
|
||||
|
||||
'FAX': _(u'Group 3 FAX (Not TIFF Group3 FAX)'),
|
||||
'FLI': _(u'Autodesk FLI animations file'),
|
||||
'FLC': _(u'Autodesk FLC animations file'),
|
||||
|
||||
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
|
||||
"POT-Creation-Date: 2012-02-12 15:20-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"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: __init__.py:10
|
||||
#: __init__.py:15
|
||||
msgid "file formats"
|
||||
msgstr ""
|
||||
|
||||
@@ -879,15 +879,15 @@ msgstr ""
|
||||
msgid "CCIR 601 4:1:1 or 4:2:2 (8-bit only)"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:15
|
||||
#: views.py:17
|
||||
msgid "suported file formats"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:20
|
||||
#: views.py:22
|
||||
msgid "name"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:24
|
||||
#: views.py:26
|
||||
msgid "description"
|
||||
msgstr ""
|
||||
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
apps/converter/locale/it/LC_MESSAGES/django.mo
Normal file
BIN
apps/converter/locale/it/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
946
apps/converter/locale/it/LC_MESSAGES/django.po
Normal file
946
apps/converter/locale/it/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
BIN
apps/converter/locale/pl/LC_MESSAGES/django.mo
Normal file
BIN
apps/converter/locale/pl/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
933
apps/converter/locale/pl/LC_MESSAGES/django.po
Normal file
933
apps/converter/locale/pl/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -9,9 +9,9 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Mayan EDMS\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
|
||||
"PO-Revision-Date: 2011-11-04 00:24+0000\n"
|
||||
"Last-Translator: emersonsoares <dev.emerson@gmail.com>\n"
|
||||
"POT-Creation-Date: 2012-02-12 15:20-0400\n"
|
||||
"PO-Revision-Date: 2011-11-22 15:26+0000\n"
|
||||
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
|
||||
"Language-Team: Portuguese (http://www.transifex.net/projects/p/mayan-edms/"
|
||||
"team/pt/)\n"
|
||||
"Language: pt\n"
|
||||
@@ -20,7 +20,7 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
|
||||
#: __init__.py:10
|
||||
#: __init__.py:15
|
||||
msgid "file formats"
|
||||
msgstr "formatos de arquivo"
|
||||
|
||||
@@ -888,15 +888,15 @@ msgstr "Amostras Raw amarelas"
|
||||
msgid "CCIR 601 4:1:1 or 4:2:2 (8-bit only)"
|
||||
msgstr "CCIR 601 4:1:1 or 4:2:2 (8-bit only)"
|
||||
|
||||
#: views.py:15
|
||||
#: views.py:17
|
||||
msgid "suported file formats"
|
||||
msgstr "formatos de arquivo suportados"
|
||||
|
||||
#: views.py:20
|
||||
#: views.py:22
|
||||
msgid "name"
|
||||
msgstr "nome"
|
||||
|
||||
#: views.py:24
|
||||
#: views.py:26
|
||||
msgid "description"
|
||||
msgstr "descrição"
|
||||
|
||||
@@ -921,9 +921,8 @@ msgstr ""
|
||||
"imagemagick, converter.backends.graphicsmagick and converter.backends.python."
|
||||
|
||||
#: conf/settings.py:16
|
||||
#, fuzzy
|
||||
msgid "Path to the unoconv program."
|
||||
msgstr "Caminho do arquivo para o programa imagemagick converter."
|
||||
msgstr ""
|
||||
|
||||
#: conf/settings.py:17
|
||||
msgid ""
|
||||
|
||||
Binary file not shown.
@@ -1,24 +1,26 @@
|
||||
# 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>, 2011.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Mayan EDMS\n"
|
||||
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
|
||||
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2012-02-12 15:20-0400\n"
|
||||
"PO-Revision-Date: 2011-11-22 19:01+0000\n"
|
||||
"Last-Translator: gsv70 <gsv70@mail.ru>\n"
|
||||
"Language-Team: Russian (http://www.transifex.net/projects/p/mayan-edms/team/ru/)\n"
|
||||
"Last-Translator: Sergey Glita <gsv70@mail.ru>\n"
|
||||
"Language-Team: Russian (http://www.transifex.net/projects/p/mayan-edms/team/"
|
||||
"ru/)\n"
|
||||
"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"
|
||||
"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:10
|
||||
#: __init__.py:15
|
||||
msgid "file formats"
|
||||
msgstr "форматы файлов"
|
||||
|
||||
@@ -630,8 +632,7 @@ msgstr "Joint Photographic Experts Group JFIF format (62)"
|
||||
|
||||
#: literals.py:226
|
||||
msgid "Portable Network Graphics (libpng 1.2.42,1.2.44, zlib 1.2.3.3,1.2.3.4)"
|
||||
msgstr ""
|
||||
"Portable Network Graphics (libpng 1.2.42,1.2.44, zlib 1.2.3.3,1.2.3.4)"
|
||||
msgstr "Portable Network Graphics (libpng 1.2.42,1.2.44, zlib 1.2.3.3,1.2.3.4)"
|
||||
|
||||
#: literals.py:227
|
||||
msgid ""
|
||||
@@ -887,15 +888,15 @@ msgstr "Raw yellow samples"
|
||||
msgid "CCIR 601 4:1:1 or 4:2:2 (8-bit only)"
|
||||
msgstr "CCIR 601 4:1:1 or 4:2:2 (8-bit only)"
|
||||
|
||||
#: views.py:15
|
||||
#: views.py:17
|
||||
msgid "suported file formats"
|
||||
msgstr "поддерживаемые форматы файлов"
|
||||
|
||||
#: views.py:20
|
||||
#: views.py:22
|
||||
msgid "name"
|
||||
msgstr "имя"
|
||||
|
||||
#: views.py:24
|
||||
#: views.py:26
|
||||
msgid "description"
|
||||
msgstr "описание"
|
||||
|
||||
@@ -913,13 +914,11 @@ msgstr "Путь к файлу программs GraphicsMagick."
|
||||
|
||||
#: conf/settings.py:15
|
||||
msgid ""
|
||||
"Graphics conversion backend to use. Options are: "
|
||||
"converter.backends.imagemagick, converter.backends.graphicsmagick and "
|
||||
"converter.backends.python."
|
||||
"Graphics conversion backend to use. Options are: converter.backends."
|
||||
"imagemagick, converter.backends.graphicsmagick and converter.backends.python."
|
||||
msgstr ""
|
||||
"Конвертер графических файлов. Возможные варианты: "
|
||||
"converter.backends.imagemagick, converter.backends.graphicsmagick и "
|
||||
"converter.backends.python."
|
||||
"Конвертер графических файлов. Возможные варианты: converter.backends."
|
||||
"imagemagick, converter.backends.graphicsmagick и converter.backends.python."
|
||||
|
||||
#: conf/settings.py:16
|
||||
msgid "Path to the unoconv program."
|
||||
@@ -927,8 +926,8 @@ msgstr "Путь к программе unoconv."
|
||||
|
||||
#: conf/settings.py:17
|
||||
msgid ""
|
||||
"Use alternate method of connection to LibreOffice using a pipe, it is slower"
|
||||
" but less prone to segmentation faults."
|
||||
"Use alternate method of connection to LibreOffice using a pipe, it is slower "
|
||||
"but less prone to segmentation faults."
|
||||
msgstr ""
|
||||
"Использовать альтернативный способ подключения к LibreOffice использованием "
|
||||
"конвейера pipe, это медленнее, но менее опасно ошибкой сегментации."
|
||||
@@ -944,5 +943,3 @@ msgid ""
|
||||
"backend. In this case: '%(backend)s'"
|
||||
msgstr ""
|
||||
"Эти форматы поддерживают выбранный конвертер. Сейчас это: '%(backend)s'"
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import logging
|
||||
@@ -6,19 +8,19 @@ from mimetype.api import get_mimetype
|
||||
from common.conf.settings import TEMPORARY_DIRECTORY
|
||||
from common.utils import id_generator
|
||||
|
||||
from converter.conf.settings import UNOCONV_PATH, UNOCONV_USE_PIPE
|
||||
from converter.exceptions import (OfficeConversionError,
|
||||
from .conf.settings import UNOCONV_PATH, UNOCONV_USE_PIPE
|
||||
from .exceptions import (OfficeConversionError,
|
||||
OfficeBackendError, UnknownFileFormat)
|
||||
|
||||
CACHED_FILE_SUFFIX = u'_office_converter'
|
||||
|
||||
|
||||
CONVERTER_OFFICE_FILE_MIMETYPES = [
|
||||
u'application/msword',
|
||||
u'application/mswrite',
|
||||
u'application/mspowerpoint',
|
||||
u'application/msexcel',
|
||||
u'application/vnd.ms-excel',
|
||||
u'application/vnd.ms-powerpoint',
|
||||
u'application/vnd.ms-powerpoint',
|
||||
u'application/vnd.oasis.opendocument.presentation',
|
||||
u'application/vnd.oasis.opendocument.text',
|
||||
u'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
@@ -41,7 +43,7 @@ class OfficeConverter(object):
|
||||
self.exists = False
|
||||
self.mimetype = None
|
||||
self.encoding = None
|
||||
|
||||
|
||||
def mimetypes(self):
|
||||
return CONVERTER_OFFICE_FILE_MIMETYPES
|
||||
|
||||
@@ -49,7 +51,7 @@ class OfficeConverter(object):
|
||||
self.exists = False
|
||||
self.mimetype = None
|
||||
self.encoding = None
|
||||
|
||||
|
||||
self.input_filepath = input_filepath
|
||||
|
||||
# Make sure file is of a known office format
|
||||
@@ -69,13 +71,13 @@ class OfficeConverter(object):
|
||||
except OfficeBackendError, msg:
|
||||
# convert exception so that at least the mime type icon is displayed
|
||||
raise UnknownFileFormat(msg)
|
||||
|
||||
|
||||
def __unicode__(self):
|
||||
return getattr(self, 'output_filepath', None)
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return str(self.__unicode__())
|
||||
|
||||
|
||||
|
||||
class OfficeConverterBackendUnoconv(object):
|
||||
def __init__(self):
|
||||
@@ -89,7 +91,7 @@ class OfficeConverterBackendUnoconv(object):
|
||||
'''
|
||||
self.input_filepath = input_filepath
|
||||
self.output_filepath = output_filepath
|
||||
|
||||
|
||||
command = []
|
||||
command.append(self.unoconv_path)
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
from converter.office_converter import OfficeConverter
|
||||
from converter.exceptions import OfficeBackendError
|
||||
from __future__ import absolute_import
|
||||
|
||||
from .office_converter import OfficeConverter
|
||||
from .exceptions import OfficeBackendError
|
||||
|
||||
|
||||
try:
|
||||
|
||||
@@ -20,4 +20,3 @@ Another way to test that 1 + 1 is equal to 2.
|
||||
>>> 1 + 1 == 2
|
||||
True
|
||||
"""}
|
||||
|
||||
|
||||
@@ -1,32 +1,36 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.shortcuts import render_to_response
|
||||
from django.template import RequestContext
|
||||
from django.core.exceptions import PermissionDenied
|
||||
|
||||
from common.utils import encapsulate
|
||||
|
||||
from converter.api import get_format_list
|
||||
from converter.conf.settings import GRAPHICS_BACKEND
|
||||
from .api import get_format_list
|
||||
from .conf.settings import GRAPHICS_BACKEND
|
||||
|
||||
|
||||
def formats_list(request):
|
||||
#check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW])
|
||||
if request.user.is_superuser or request.user.is_staff:
|
||||
context = {
|
||||
'title': _(u'suported file formats'),
|
||||
'hide_object': True,
|
||||
'object_list': sorted(get_format_list()),
|
||||
'extra_columns': [
|
||||
{
|
||||
'name': _(u'name'),
|
||||
'attribute': encapsulate(lambda x: x[0])
|
||||
},
|
||||
{
|
||||
'name': _(u'description'),
|
||||
'attribute': encapsulate(lambda x: x[1])
|
||||
}
|
||||
],
|
||||
'backend': GRAPHICS_BACKEND,
|
||||
}
|
||||
|
||||
context = {
|
||||
'title': _(u'suported file formats'),
|
||||
'hide_object': True,
|
||||
'object_list': sorted(get_format_list()),
|
||||
'extra_columns': [
|
||||
{
|
||||
'name': _(u'name'),
|
||||
'attribute': encapsulate(lambda x: x[0])
|
||||
},
|
||||
{
|
||||
'name': _(u'description'),
|
||||
'attribute': encapsulate(lambda x: x[1])
|
||||
}
|
||||
],
|
||||
'backend': GRAPHICS_BACKEND,
|
||||
}
|
||||
|
||||
return render_to_response('generic_list.html', context,
|
||||
context_instance=RequestContext(request))
|
||||
return render_to_response('generic_list.html', context,
|
||||
context_instance=RequestContext(request))
|
||||
else:
|
||||
raise PermissionDenied
|
||||
|
||||
@@ -1,39 +1,14 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from documents.models import Document
|
||||
from navigation.api import register_links, register_top_menu, \
|
||||
register_model_list_columns, register_multi_item_links, \
|
||||
register_sidebar_template
|
||||
from main.api import register_diagnostic, register_maintenance_links
|
||||
from permissions.api import register_permission, set_namespace_title
|
||||
from navigation.api import register_links
|
||||
from project_setup.api import register_setup
|
||||
from hkp import Key as KeyServerKey
|
||||
|
||||
from django_gpg.api import Key
|
||||
|
||||
PERMISSION_DOCUMENT_VERIFY = {'namespace': 'django_gpg', 'name': 'document_verify', 'label': _(u'Verify document signatures')}
|
||||
PERMISSION_KEY_VIEW = {'namespace': 'django_gpg', 'name': 'key_view', 'label': _(u'View keys')}
|
||||
PERMISSION_KEY_DELETE = {'namespace': 'django_gpg', 'name': 'key_delete', 'label': _(u'Delete keys')}
|
||||
PERMISSION_KEYSERVER_QUERY = {'namespace': 'django_gpg', 'name': 'keyserver_query', 'label': _(u'Query keyservers')}
|
||||
PERMISSION_KEY_RECEIVE = {'namespace': 'django_gpg', 'name': 'key_receive', 'label': _(u'Import key from keyservers')}
|
||||
PERMISSION_SIGNATURE_UPLOAD = {'namespace': 'django_gpg', 'name': 'signature_upload', 'label': _(u'Upload detached signatures')}
|
||||
PERMISSION_SIGNATURE_DOWNLOAD = {'namespace': 'django_gpg', 'name': 'key_receive', 'label': _(u'Download detached signatures')}
|
||||
|
||||
# Permission setup
|
||||
set_namespace_title('django_gpg', _(u'Signatures'))
|
||||
register_permission(PERMISSION_DOCUMENT_VERIFY)
|
||||
register_permission(PERMISSION_KEY_VIEW)
|
||||
register_permission(PERMISSION_KEY_DELETE)
|
||||
register_permission(PERMISSION_KEYSERVER_QUERY)
|
||||
register_permission(PERMISSION_KEY_RECEIVE)
|
||||
register_permission(PERMISSION_SIGNATURE_UPLOAD)
|
||||
register_permission(PERMISSION_SIGNATURE_DOWNLOAD)
|
||||
|
||||
def has_embedded_signature(context):
|
||||
return context['object'].signature_state
|
||||
|
||||
def doesnt_have_detached_signature(context):
|
||||
return context['object'].has_detached_signature() == False
|
||||
from .api import Key
|
||||
from .permissions import (PERMISSION_KEY_VIEW, PERMISSION_KEY_DELETE,
|
||||
PERMISSION_KEYSERVER_QUERY, PERMISSION_KEY_RECEIVE)
|
||||
|
||||
# Setup views
|
||||
private_keys = {'text': _(u'private keys'), 'view': 'key_private_list', 'args': 'object.pk', 'famfam': 'key', 'icon': 'key.png', 'permissions': [PERMISSION_KEY_VIEW]}
|
||||
@@ -41,16 +16,7 @@ public_keys = {'text': _(u'public keys'), 'view': 'key_public_list', 'args': 'ob
|
||||
key_delete = {'text': _(u'delete'), 'view': 'key_delete', 'args': ['object.fingerprint', 'object.type'], 'famfam': 'key_delete', 'permissions': [PERMISSION_KEY_DELETE]}
|
||||
key_query = {'text': _(u'query keyservers'), 'view': 'key_query', 'famfam': 'zoom', 'permissions': [PERMISSION_KEYSERVER_QUERY]}
|
||||
key_receive = {'text': _(u'import'), 'view': 'key_receive', 'args': 'object.keyid', 'famfam': 'key_add', 'keep_query': True, 'permissions': [PERMISSION_KEY_RECEIVE]}
|
||||
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_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}
|
||||
key_setup = {'text': _(u'key management'), 'view': 'key_public_list', 'args': 'object.pk', 'famfam': 'key', 'icon': 'key.png', 'permissions': [PERMISSION_KEY_VIEW]}
|
||||
|
||||
# Document views
|
||||
document_verify = {'text': _(u'signatures'), 'view': 'document_verify', 'args': 'object.pk', 'famfam': 'text_signature', 'permissions': [PERMISSION_DOCUMENT_VERIFY]}
|
||||
|
||||
register_links(Document, [document_verify], menu_name='form_header')
|
||||
|
||||
register_links(['document_verify', 'document_signature_upload', 'document_signature_download'], [document_signature_upload, document_signature_download], menu_name='sidebar')
|
||||
key_setup = {'text': _(u'key management'), 'view': 'key_public_list', 'args': 'object.pk', 'famfam': 'key', 'icon': 'key.png', 'permissions': [PERMISSION_KEY_VIEW], 'children_view_regex': [r'^key_']}
|
||||
|
||||
#register_links(['key_delete', 'key_private_list', 'key_public_list', 'key_query'], [private_keys, public_keys, key_query], menu_name='sidebar')
|
||||
register_links(['key_delete', 'key_public_list', 'key_query'], [public_keys, key_query], menu_name='sidebar')
|
||||
@@ -59,6 +25,3 @@ register_links(Key, [key_delete])
|
||||
register_links(KeyServerKey, [key_receive])
|
||||
|
||||
register_setup(key_setup)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
import types
|
||||
from StringIO import StringIO
|
||||
from pickle import dumps
|
||||
from __future__ import absolute_import
|
||||
|
||||
import logging
|
||||
import tempfile
|
||||
import os
|
||||
|
||||
from django.core.files.base import File
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
except ImportError:
|
||||
from StringIO import StringIO
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.http import urlquote_plus
|
||||
|
||||
from hkp import KeyServer
|
||||
import gnupg
|
||||
|
||||
from django_gpg.exceptions import (GPGVerificationError, GPGSigningError,
|
||||
from .exceptions import (GPGVerificationError, GPGSigningError,
|
||||
GPGDecryptionError, KeyDeleteError, KeyGenerationError,
|
||||
KeyFetchingError, KeyDoesNotExist, KeyImportError)
|
||||
|
||||
@@ -71,7 +73,7 @@ SIGNATURE_STATES = {
|
||||
'text': _(u'Document is signed with a valid signature.'),
|
||||
'icon': 'document_signature.png'
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Key(object):
|
||||
@@ -108,7 +110,7 @@ class Key(object):
|
||||
keys = gpg.gpg.list_keys(secret=secret)
|
||||
key = next((key for key in keys if key['keyid'] == key_id), None)
|
||||
if not key:
|
||||
if search_keyservers and secret==False:
|
||||
if search_keyservers and secret == False:
|
||||
try:
|
||||
gpg.receive_key(key_id)
|
||||
return Key(gpg, key_id)
|
||||
@@ -151,6 +153,17 @@ class Key(object):
|
||||
|
||||
|
||||
class GPG(object):
|
||||
@staticmethod
|
||||
def get_descriptor(file_input):
|
||||
try:
|
||||
# Is it a file like object?
|
||||
file_input.seek(0)
|
||||
except AttributeError:
|
||||
# If not, try open it.
|
||||
return open(file_input, 'rb')
|
||||
else:
|
||||
return file_input
|
||||
|
||||
def __init__(self, binary_path=None, home=None, keyring=None, keyservers=None):
|
||||
kwargs = {}
|
||||
if binary_path:
|
||||
@@ -166,60 +179,45 @@ class GPG(object):
|
||||
|
||||
self.gpg = gnupg.GPG(**kwargs)
|
||||
|
||||
def verify_w_retry(self, file_input, detached_signature=None):
|
||||
if isinstance(file_input, types.StringTypes):
|
||||
input_descriptor = open(file_input, 'rb')
|
||||
elif isinstance(file_input, types.FileType) or isinstance(file_input, File):
|
||||
input_descriptor = file_input
|
||||
elif issubclass(file_input.__class__, StringIO):
|
||||
input_descriptor = file_input
|
||||
else:
|
||||
raise ValueError('Invalid file_input argument type')
|
||||
|
||||
try:
|
||||
verify = self.verify_file(input_descriptor, detached_signature)
|
||||
if verify.status == 'no public key':
|
||||
# Try to fetch the public key from the keyservers
|
||||
try:
|
||||
self.receive_key(verify.key_id)
|
||||
return self.verify_w_retry(file_input, detached_signature)
|
||||
except KeyFetchingError:
|
||||
return verify
|
||||
else:
|
||||
return verify
|
||||
except IOError:
|
||||
return False
|
||||
|
||||
def verify_file(self, file_input, detached_signature=None):
|
||||
def verify_file(self, file_input, detached_signature=None, fetch_key=False):
|
||||
"""
|
||||
Verify the signature of a file.
|
||||
"""
|
||||
if isinstance(file_input, types.StringTypes):
|
||||
descriptor = open(file_input, 'rb')
|
||||
elif isinstance(file_input, types.FileType) or isinstance(file_input, File) or isinstance(file_input, StringIO):
|
||||
descriptor = file_input
|
||||
else:
|
||||
raise ValueError('Invalid file_input argument type')
|
||||
|
||||
|
||||
input_descriptor = GPG.get_descriptor(file_input)
|
||||
|
||||
if detached_signature:
|
||||
# Save the original data and invert the argument order
|
||||
# Signature first, file second
|
||||
file_descriptor, filename = tempfile.mkstemp(prefix='django_gpg')
|
||||
file_data = file_input.read()
|
||||
file_input.close()
|
||||
os.write(file_descriptor, file_data)
|
||||
os.write(file_descriptor, input_descriptor.read())
|
||||
os.close(file_descriptor)
|
||||
verify = self.gpg.verify_file(detached_signature, data_filename=filename)
|
||||
|
||||
detached_signature = GPG.get_descriptor(detached_signature)
|
||||
signature_file = StringIO()
|
||||
signature_file.write(detached_signature.read())
|
||||
signature_file.seek(0)
|
||||
verify = self.gpg.verify_file(signature_file, data_filename=filename)
|
||||
signature_file.close()
|
||||
else:
|
||||
verify = self.gpg.verify_file(descriptor)
|
||||
descriptor.close()
|
||||
|
||||
verify = self.gpg.verify_file(input_descriptor)
|
||||
|
||||
logger.debug('verify.status: %s' % getattr(verify, 'status', None))
|
||||
if verify:
|
||||
logger.debug('verify ok')
|
||||
return verify
|
||||
#elif getattr(verify, 'status', None) == 'no public key':
|
||||
# # Exception to the rule, to be able to query the keyservers
|
||||
# return verify
|
||||
elif getattr(verify, 'status', None) == 'no public key':
|
||||
# Exception to the rule, to be able to query the keyservers
|
||||
if fetch_key:
|
||||
try:
|
||||
self.receive_key(verify.key_id)
|
||||
return self.verify_file(input_descriptor, detached_signature, fetch_key=False)
|
||||
except KeyFetchingError:
|
||||
return verify
|
||||
else:
|
||||
return verify
|
||||
else:
|
||||
logger.debug('No verify')
|
||||
raise GPGVerificationError()
|
||||
|
||||
def verify(self, data):
|
||||
@@ -238,6 +236,7 @@ class GPG(object):
|
||||
overrided if it already exists), if no destination file name is
|
||||
provided the signature is returned.
|
||||
"""
|
||||
|
||||
kwargs = {}
|
||||
kwargs['clearsign'] = clearsign
|
||||
|
||||
@@ -250,14 +249,7 @@ class GPG(object):
|
||||
if passphrase:
|
||||
kwargs['passphrase'] = passphrase
|
||||
|
||||
if isinstance(file_input, types.StringTypes):
|
||||
input_descriptor = open(file_input, 'rb')
|
||||
elif isinstance(file_input, types.FileType) or isinstance(file_input, File):
|
||||
input_descriptor = file_input
|
||||
elif issubclass(file_input.__class__, StringIO):
|
||||
input_descriptor = file_input
|
||||
else:
|
||||
raise ValueError('Invalid file_input argument type')
|
||||
input_descriptor = GPG.get_descriptor(file_input)
|
||||
|
||||
if destination:
|
||||
output_descriptor = open(destination, 'wb')
|
||||
@@ -277,21 +269,26 @@ class GPG(object):
|
||||
if not destination:
|
||||
return signed_data
|
||||
|
||||
def decrypt_file(self, file_input):
|
||||
if isinstance(file_input, types.StringTypes):
|
||||
input_descriptor = open(file_input, 'rb')
|
||||
elif isinstance(file_input, types.FileType) or isinstance(file_input, File) or isinstance(file_input, StringIO):
|
||||
input_descriptor = file_input
|
||||
def has_embedded_signature(self, *args, **kwargs):
|
||||
try:
|
||||
self.decrypt_file(*args, **kwargs)
|
||||
except GPGDecryptionError:
|
||||
return False
|
||||
else:
|
||||
raise ValueError('Invalid file_input argument type')
|
||||
return True
|
||||
|
||||
def decrypt_file(self, file_input, close_descriptor=True):
|
||||
input_descriptor = GPG.get_descriptor(file_input)
|
||||
|
||||
result = self.gpg.decrypt_file(input_descriptor)
|
||||
input_descriptor.close()
|
||||
if close_descriptor:
|
||||
input_descriptor.close()
|
||||
|
||||
if not result.status:
|
||||
raise GPGDecryptionError('Unable to decrypt file')
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def create_key(self, *args, **kwargs):
|
||||
if kwargs.get('passphrase') == u'':
|
||||
kwargs.pop('passphrase')
|
||||
@@ -318,7 +315,7 @@ class GPG(object):
|
||||
return Key.get(self, import_result.fingerprints[0], secret=False)
|
||||
|
||||
raise KeyFetchingError
|
||||
|
||||
|
||||
def query(self, term):
|
||||
results = {}
|
||||
for keyserver in self.keyservers:
|
||||
@@ -330,14 +327,14 @@ class GPG(object):
|
||||
results[key.keyid] = key
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
return results.values()
|
||||
|
||||
|
||||
def import_key(self, key_data):
|
||||
import_result = self.gpg.import_keys(key_data)
|
||||
logger.debug('import_result: %s' % import_result)
|
||||
|
||||
|
||||
if import_result:
|
||||
return Key.get(self, import_result.fingerprints[0], secret=False)
|
||||
|
||||
raise KeyImportError
|
||||
raise KeyImportError(import_result.results)
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
'''
|
||||
"""
|
||||
Configuration options for the django_gpg app
|
||||
'''
|
||||
"""
|
||||
import os
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.conf import settings
|
||||
|
||||
from smart_settings.api import register_settings
|
||||
|
||||
@@ -11,5 +13,6 @@ register_settings(
|
||||
module=u'django_gpg.conf.settings',
|
||||
settings=[
|
||||
{'name': u'KEYSERVERS', 'global_name': u'SIGNATURES_KEYSERVERS', 'default': ['pool.sks-keyservers.net'], 'description': _(u'List of keyservers to be queried for unknown keys.')},
|
||||
{'name': u'GPG_HOME', 'global_name': u'SIGNATURES_GPG_HOME', 'default': os.path.join(settings.PROJECT_ROOT, u'gpg_home'), 'description': _(u'Home directory used to store keys as well as configuration files.')},
|
||||
]
|
||||
)
|
||||
|
||||
@@ -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 KeySearchForm(forms.Form):
|
||||
@@ -11,9 +7,3 @@ class KeySearchForm(forms.Form):
|
||||
label=_(u'Term'),
|
||||
help_text=_(u'Name, e-mail, key ID or key fingerprint to look for.')
|
||||
)
|
||||
|
||||
|
||||
class DetachedSignatureForm(forms.Form):
|
||||
file = forms.FileField(
|
||||
label=_(u'Signature file'),
|
||||
)
|
||||
|
||||
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-12-06 02:06-0400\n"
|
||||
"POT-Creation-Date: 2012-02-12 15:20-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"
|
||||
@@ -17,142 +17,114 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: __init__.py:14
|
||||
msgid "Verify document signatures"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:15
|
||||
msgid "View keys"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:16
|
||||
msgid "Delete keys"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:17
|
||||
msgid "Query keyservers"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:18
|
||||
msgid "Import key from keyservers"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:19
|
||||
msgid "Upload detached signatures"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:20
|
||||
msgid "Download detached signatures"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:23
|
||||
msgid "Signatures"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:39 views.py:67
|
||||
#: __init__.py:14 views.py:67
|
||||
msgid "private keys"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:40 views.py:70
|
||||
#: __init__.py:15 views.py:70
|
||||
msgid "public keys"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:41
|
||||
#: __init__.py:16
|
||||
msgid "delete"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:42
|
||||
#: __init__.py:17
|
||||
msgid "query keyservers"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:43
|
||||
#: __init__.py:18
|
||||
msgid "import"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:44
|
||||
msgid "upload signature"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:45
|
||||
msgid "download signature"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:46
|
||||
#: __init__.py:19
|
||||
msgid "key management"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:49
|
||||
msgid "signatures"
|
||||
msgstr ""
|
||||
|
||||
#: api.py:22
|
||||
#: api.py:19
|
||||
msgid "Public"
|
||||
msgstr ""
|
||||
|
||||
#: api.py:23
|
||||
#: api.py:20
|
||||
msgid "Secret"
|
||||
msgstr ""
|
||||
|
||||
#: api.py:31 api.py:36
|
||||
#: api.py:28 api.py:33
|
||||
msgid "RSA"
|
||||
msgstr ""
|
||||
|
||||
#: api.py:32
|
||||
#: api.py:29
|
||||
msgid "DSA"
|
||||
msgstr ""
|
||||
|
||||
#: api.py:37
|
||||
#: api.py:34
|
||||
msgid "Elgamal"
|
||||
msgstr ""
|
||||
|
||||
#: api.py:51
|
||||
#: api.py:48
|
||||
msgid "Bad signature."
|
||||
msgstr ""
|
||||
|
||||
#: api.py:55
|
||||
#: api.py:52
|
||||
msgid "Document not signed or invalid signature."
|
||||
msgstr ""
|
||||
|
||||
#: api.py:59
|
||||
#: api.py:56
|
||||
msgid "Signature error."
|
||||
msgstr ""
|
||||
|
||||
#: api.py:63
|
||||
#: api.py:60
|
||||
msgid "Document is signed but no public key is available for verification."
|
||||
msgstr ""
|
||||
|
||||
#: api.py:67
|
||||
#: api.py:64
|
||||
msgid "Document is signed, and signature is good."
|
||||
msgstr ""
|
||||
|
||||
#: api.py:71
|
||||
#: api.py:68
|
||||
msgid "Document is signed with a valid signature."
|
||||
msgstr ""
|
||||
|
||||
#: api.py:144
|
||||
#: api.py:141
|
||||
msgid "unknown"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:11
|
||||
#: forms.py:8
|
||||
msgid "Term"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:12
|
||||
#: forms.py:9
|
||||
msgid "Name, e-mail, key ID or key fingerprint to look for."
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:18
|
||||
msgid "Signature file"
|
||||
#: permissions.py:7
|
||||
msgid "Key management"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:45
|
||||
#: permissions.py:9
|
||||
msgid "View keys"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:10
|
||||
msgid "Delete keys"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:11
|
||||
msgid "Query keyservers"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:12
|
||||
msgid "Import keys from keyservers"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:38
|
||||
#, python-format
|
||||
msgid "Key: %s, imported successfully."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:48
|
||||
#: views.py:43
|
||||
#, python-format
|
||||
msgid "Unable to import key id: %s"
|
||||
msgid "Unable to import key id: %(key_id)s; %(error)s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:52
|
||||
@@ -233,58 +205,10 @@ msgstr ""
|
||||
msgid "Identifies"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:205
|
||||
#, python-format
|
||||
msgid "Signature status: %(widget)s %(text)s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:212
|
||||
msgid "embedded"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:214
|
||||
msgid "detached"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:219
|
||||
#, python-format
|
||||
msgid "Signature ID: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:220
|
||||
#, python-format
|
||||
msgid "Signature type: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:221
|
||||
#, python-format
|
||||
msgid "Key ID: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:222
|
||||
#, python-format
|
||||
msgid "Timestamp: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:223
|
||||
#, python-format
|
||||
msgid "Signee: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:228
|
||||
#, python-format
|
||||
msgid "signature properties for: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:250
|
||||
msgid "Detached signature uploaded successfully."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:259
|
||||
#, python-format
|
||||
msgid "Upload detached signature for: %s"
|
||||
msgstr ""
|
||||
|
||||
#: conf/settings.py:13
|
||||
#: conf/settings.py:15
|
||||
msgid "List of keyservers to be queried for unknown keys."
|
||||
msgstr ""
|
||||
|
||||
#: conf/settings.py:16
|
||||
msgid "Home directory used to store keys as well as configuration files."
|
||||
msgstr ""
|
||||
|
||||
Binary file not shown.
@@ -1,164 +1,137 @@
|
||||
# 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>, 2011.
|
||||
# Roberto Rosario <roberto.rosario.gonzalez@gmail.com>, 2011, 2012.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Mayan EDMS\n"
|
||||
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
|
||||
"POT-Creation-Date: 2011-12-06 02:06-0400\n"
|
||||
"PO-Revision-Date: 2011-12-06 06:14+0000\n"
|
||||
"Last-Translator: rosarior <roberto.rosario.gonzalez@gmail.com>\n"
|
||||
"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/mayan-edms/team/es/)\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2012-02-12 15:20-0400\n"
|
||||
"PO-Revision-Date: 2012-02-02 18:37+0000\n"
|
||||
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
|
||||
"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/"
|
||||
"mayan-edms/team/es/)\n"
|
||||
"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:14
|
||||
msgid "Verify document signatures"
|
||||
msgstr "Verificar las firmas de documentos"
|
||||
|
||||
#: __init__.py:15
|
||||
msgid "View keys"
|
||||
msgstr "Ver llaves"
|
||||
|
||||
#: __init__.py:16
|
||||
msgid "Delete keys"
|
||||
msgstr "Borrar llaves"
|
||||
|
||||
#: __init__.py:17
|
||||
msgid "Query keyservers"
|
||||
msgstr "Hacer búsquedas en servidores de llaves"
|
||||
|
||||
#: __init__.py:18
|
||||
msgid "Import key from keyservers"
|
||||
msgstr "Importar llaves de los servidores de llaves"
|
||||
|
||||
#: __init__.py:19
|
||||
msgid "Upload detached signatures"
|
||||
msgstr "Subir una firma a parte"
|
||||
|
||||
#: __init__.py:20
|
||||
msgid "Download detached signatures"
|
||||
msgstr "Descargar la fima"
|
||||
|
||||
#: __init__.py:23
|
||||
msgid "Signatures"
|
||||
msgstr "Firmas"
|
||||
|
||||
#: __init__.py:39 views.py:67
|
||||
#: __init__.py:14 views.py:67
|
||||
msgid "private keys"
|
||||
msgstr "llaves privadas"
|
||||
|
||||
#: __init__.py:40 views.py:70
|
||||
#: __init__.py:15 views.py:70
|
||||
msgid "public keys"
|
||||
msgstr "llaves públicas"
|
||||
|
||||
#: __init__.py:41
|
||||
#: __init__.py:16
|
||||
msgid "delete"
|
||||
msgstr "borrar"
|
||||
|
||||
#: __init__.py:42
|
||||
#: __init__.py:17
|
||||
msgid "query keyservers"
|
||||
msgstr "consultar servidor de llaves"
|
||||
|
||||
#: __init__.py:43
|
||||
#: __init__.py:18
|
||||
msgid "import"
|
||||
msgstr "importar"
|
||||
|
||||
#: __init__.py:44
|
||||
msgid "upload signature"
|
||||
msgstr "subir firma"
|
||||
|
||||
#: __init__.py:45
|
||||
msgid "download signature"
|
||||
msgstr "descargar firma"
|
||||
|
||||
#: __init__.py:46
|
||||
#: __init__.py:19
|
||||
msgid "key management"
|
||||
msgstr "manejo de llaves"
|
||||
|
||||
#: __init__.py:49
|
||||
msgid "signatures"
|
||||
msgstr "firmas"
|
||||
|
||||
#: api.py:22
|
||||
#: api.py:19
|
||||
msgid "Public"
|
||||
msgstr "Pública"
|
||||
|
||||
#: api.py:23
|
||||
#: api.py:20
|
||||
msgid "Secret"
|
||||
msgstr "Secreta"
|
||||
|
||||
#: api.py:31 api.py:36
|
||||
#: api.py:28 api.py:33
|
||||
msgid "RSA"
|
||||
msgstr "RSA"
|
||||
|
||||
#: api.py:32
|
||||
#: api.py:29
|
||||
msgid "DSA"
|
||||
msgstr "DSA"
|
||||
|
||||
#: api.py:37
|
||||
#: api.py:34
|
||||
msgid "Elgamal"
|
||||
msgstr "Elgamal"
|
||||
|
||||
#: api.py:51
|
||||
#: api.py:48
|
||||
msgid "Bad signature."
|
||||
msgstr "Firma invalida."
|
||||
|
||||
#: api.py:55
|
||||
#: api.py:52
|
||||
msgid "Document not signed or invalid signature."
|
||||
msgstr "Documento no firmado o firma invalida."
|
||||
|
||||
#: api.py:59
|
||||
#: api.py:56
|
||||
msgid "Signature error."
|
||||
msgstr "Error de firma."
|
||||
|
||||
#: api.py:63
|
||||
#: api.py:60
|
||||
msgid "Document is signed but no public key is available for verification."
|
||||
msgstr ""
|
||||
"El document ha sido firmado pero no hay llave pública disponible para "
|
||||
"verificación."
|
||||
|
||||
#: api.py:67
|
||||
#: api.py:64
|
||||
msgid "Document is signed, and signature is good."
|
||||
msgstr "El document ha sido firmado y la firma esta es buen estado."
|
||||
|
||||
#: api.py:71
|
||||
#: api.py:68
|
||||
msgid "Document is signed with a valid signature."
|
||||
msgstr "El document ha sido firmado y la firma ha sido validada."
|
||||
|
||||
#: api.py:144
|
||||
#: api.py:141
|
||||
msgid "unknown"
|
||||
msgstr "desconocida"
|
||||
|
||||
#: forms.py:11
|
||||
#: forms.py:8
|
||||
msgid "Term"
|
||||
msgstr "Término"
|
||||
|
||||
#: forms.py:12
|
||||
#: forms.py:9
|
||||
msgid "Name, e-mail, key ID or key fingerprint to look for."
|
||||
msgstr ""
|
||||
"Nombre, dirección de correo electrónico, identificador de llave or huella "
|
||||
"digital de llave a buscar."
|
||||
|
||||
#: forms.py:18
|
||||
msgid "Signature file"
|
||||
msgstr "Archivo de firma"
|
||||
#: permissions.py:7
|
||||
msgid "Key management"
|
||||
msgstr "Gestión de llaves"
|
||||
|
||||
#: views.py:45
|
||||
#: permissions.py:9
|
||||
msgid "View keys"
|
||||
msgstr "Ver llaves"
|
||||
|
||||
#: permissions.py:10
|
||||
msgid "Delete keys"
|
||||
msgstr "Borrar llaves"
|
||||
|
||||
#: permissions.py:11
|
||||
msgid "Query keyservers"
|
||||
msgstr "Hacer búsquedas en servidores de llaves"
|
||||
|
||||
#: permissions.py:12
|
||||
msgid "Import keys from keyservers"
|
||||
msgstr "Importar llaves del servidores de llaves"
|
||||
|
||||
#: views.py:38
|
||||
#, python-format
|
||||
msgid "Key: %s, imported successfully."
|
||||
msgstr "Llave: %s, importada exitosamente."
|
||||
|
||||
#: views.py:48
|
||||
#: views.py:43
|
||||
#, python-format
|
||||
msgid "Unable to import key id: %s"
|
||||
msgstr "No se pudo importa la llave: %s"
|
||||
msgid "Unable to import key id: %(key_id)s; %(error)s"
|
||||
msgstr "No se pudo importar la llave: %(key_id)s ; %(error)s "
|
||||
|
||||
#: views.py:52
|
||||
msgid "Import key"
|
||||
@@ -194,8 +167,8 @@ msgid ""
|
||||
"well."
|
||||
msgstr ""
|
||||
"¿Esta seguro que desea borrar la llave: %s? Si trata de borrar una llave "
|
||||
"pública que es parte de un par público/privado la llave privada será borrada"
|
||||
" también."
|
||||
"pública que es parte de un par público/privado la llave privada será borrada "
|
||||
"también."
|
||||
|
||||
#: views.py:129
|
||||
msgid "Query key server"
|
||||
@@ -241,62 +214,14 @@ msgstr "revocada"
|
||||
msgid "Identifies"
|
||||
msgstr "Identidades"
|
||||
|
||||
#: views.py:205
|
||||
#, python-format
|
||||
msgid "Signature status: %(widget)s %(text)s"
|
||||
msgstr "Estado de la firma: %(widget)s %(text)s"
|
||||
|
||||
#: views.py:212
|
||||
msgid "embedded"
|
||||
msgstr "integrada"
|
||||
|
||||
#: views.py:214
|
||||
msgid "detached"
|
||||
msgstr "a parte"
|
||||
|
||||
#: views.py:219
|
||||
#, python-format
|
||||
msgid "Signature ID: %s"
|
||||
msgstr "ID de la firma: %s"
|
||||
|
||||
#: views.py:220
|
||||
#, python-format
|
||||
msgid "Signature type: %s"
|
||||
msgstr "Tipo de firma: %s"
|
||||
|
||||
#: views.py:221
|
||||
#, python-format
|
||||
msgid "Key ID: %s"
|
||||
msgstr "ID de la llave: %s"
|
||||
|
||||
#: views.py:222
|
||||
#, python-format
|
||||
msgid "Timestamp: %s"
|
||||
msgstr "Fecha y hora: %s"
|
||||
|
||||
#: views.py:223
|
||||
#, python-format
|
||||
msgid "Signee: %s"
|
||||
msgstr "Firmantes: %s"
|
||||
|
||||
#: views.py:228
|
||||
#, python-format
|
||||
msgid "signature properties for: %s"
|
||||
msgstr "propiedades de firma para: %s"
|
||||
|
||||
#: views.py:250
|
||||
msgid "Detached signature uploaded successfully."
|
||||
msgstr "El archivo de firma fue subido exitosamente."
|
||||
|
||||
#: views.py:259
|
||||
#, python-format
|
||||
msgid "Upload detached signature for: %s"
|
||||
msgstr "Subir firma a parte para: %s"
|
||||
|
||||
#: conf/settings.py:13
|
||||
#: conf/settings.py:15
|
||||
msgid "List of keyservers to be queried for unknown keys."
|
||||
msgstr ""
|
||||
"Lista de servidores de llaves a ser utilizados para buscar llaves "
|
||||
"desconocidas."
|
||||
|
||||
|
||||
#: conf/settings.py:16
|
||||
msgid "Home directory used to store keys as well as configuration files."
|
||||
msgstr ""
|
||||
"Directorio de inicio utilizado para almacenar las llaves, así como los "
|
||||
"archivos de configuración."
|
||||
|
||||
BIN
apps/django_gpg/locale/it/LC_MESSAGES/django.mo
Normal file
BIN
apps/django_gpg/locale/it/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
221
apps/django_gpg/locale/it/LC_MESSAGES/django.po
Normal file
221
apps/django_gpg/locale/it/LC_MESSAGES/django.po
Normal file
@@ -0,0 +1,221 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# <pierpaolo.baldan@gmail.com>, 2011.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Mayan EDMS\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2012-02-12 15:20-0400\n"
|
||||
"PO-Revision-Date: 2012-02-02 18:20+0000\n"
|
||||
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
|
||||
"Language-Team: Italian (http://www.transifex.net/projects/p/mayan-edms/team/"
|
||||
"it/)\n"
|
||||
"Language: it\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
|
||||
#: __init__.py:14 views.py:67
|
||||
msgid "private keys"
|
||||
msgstr "Chiave privata"
|
||||
|
||||
#: __init__.py:15 views.py:70
|
||||
msgid "public keys"
|
||||
msgstr "Chiave pubblica"
|
||||
|
||||
#: __init__.py:16
|
||||
msgid "delete"
|
||||
msgstr "cancella"
|
||||
|
||||
#: __init__.py:17
|
||||
msgid "query keyservers"
|
||||
msgstr "Interroga il server delle chiavi"
|
||||
|
||||
#: __init__.py:18
|
||||
msgid "import"
|
||||
msgstr "import"
|
||||
|
||||
#: __init__.py:19
|
||||
msgid "key management"
|
||||
msgstr "gestione della firma"
|
||||
|
||||
#: api.py:19
|
||||
msgid "Public"
|
||||
msgstr "Pubblica"
|
||||
|
||||
#: api.py:20
|
||||
msgid "Secret"
|
||||
msgstr "Segreta"
|
||||
|
||||
#: api.py:28 api.py:33
|
||||
msgid "RSA"
|
||||
msgstr "RSA"
|
||||
|
||||
#: api.py:29
|
||||
msgid "DSA"
|
||||
msgstr "DSA"
|
||||
|
||||
#: api.py:34
|
||||
msgid "Elgamal"
|
||||
msgstr "Elgamal"
|
||||
|
||||
#: api.py:48
|
||||
msgid "Bad signature."
|
||||
msgstr "Firma cattiva."
|
||||
|
||||
#: api.py:52
|
||||
msgid "Document not signed or invalid signature."
|
||||
msgstr "Documento non firmato o firma invalida."
|
||||
|
||||
#: api.py:56
|
||||
msgid "Signature error."
|
||||
msgstr "Errore di firma"
|
||||
|
||||
#: api.py:60
|
||||
msgid "Document is signed but no public key is available for verification."
|
||||
msgstr ""
|
||||
"Il documento è stato firmato, ma la chiave pubblica non è disponibile per la "
|
||||
"verifica"
|
||||
|
||||
#: api.py:64
|
||||
msgid "Document is signed, and signature is good."
|
||||
msgstr "Documento firmato e firma è buona."
|
||||
|
||||
#: api.py:68
|
||||
msgid "Document is signed with a valid signature."
|
||||
msgstr "Il documento è firmato con una firma valida."
|
||||
|
||||
#: api.py:141
|
||||
msgid "unknown"
|
||||
msgstr "sconosciuto"
|
||||
|
||||
#: forms.py:8
|
||||
msgid "Term"
|
||||
msgstr "Scadenza"
|
||||
|
||||
#: forms.py:9
|
||||
msgid "Name, e-mail, key ID or key fingerprint to look for."
|
||||
msgstr "Nome, e-mail,key ID , impronte digitali per cercare"
|
||||
|
||||
#: permissions.py:7
|
||||
msgid "Key management"
|
||||
msgstr ""
|
||||
|
||||
#: permissions.py:9
|
||||
msgid "View keys"
|
||||
msgstr "Vista delle chiavi"
|
||||
|
||||
#: permissions.py:10
|
||||
msgid "Delete keys"
|
||||
msgstr "Cancella chiavi"
|
||||
|
||||
#: permissions.py:11
|
||||
msgid "Query keyservers"
|
||||
msgstr "Interroga l'autorità per le chiavi"
|
||||
|
||||
#: permissions.py:12
|
||||
msgid "Import keys from keyservers"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:38
|
||||
#, python-format
|
||||
msgid "Key: %s, imported successfully."
|
||||
msgstr "Chiave: %s, importata con successo."
|
||||
|
||||
#: views.py:43
|
||||
#, python-format
|
||||
msgid "Unable to import key id: %(key_id)s; %(error)s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:52
|
||||
msgid "Import key"
|
||||
msgstr "Importa chiave"
|
||||
|
||||
#: views.py:53
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to import key id: %s?"
|
||||
msgstr "Sei sicuro di voler importare la chiave id: %s?"
|
||||
|
||||
#: views.py:78
|
||||
msgid "Key ID"
|
||||
msgstr "chiave ID"
|
||||
|
||||
#: views.py:82
|
||||
msgid "Owner"
|
||||
msgstr "Proprietario"
|
||||
|
||||
#: views.py:102
|
||||
#, python-format
|
||||
msgid "Key: %s, deleted successfully."
|
||||
msgstr "chiave: %s, cancellata con successo."
|
||||
|
||||
#: views.py:109
|
||||
msgid "Delete key"
|
||||
msgstr "Cancella chiave"
|
||||
|
||||
#: views.py:111
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Are you sure you wish to delete key: %s? If you try to delete a public key "
|
||||
"that is part of a public/private pair the private key will be deleted as "
|
||||
"well."
|
||||
msgstr ""
|
||||
"Sei sicuro di voler cancellare la chiave: %s? Se provi a cancellare una "
|
||||
"chiave pubblica che è parte di una coppia publica/privata anche la chiave "
|
||||
"privata sarà cancellata"
|
||||
|
||||
#: views.py:129
|
||||
msgid "Query key server"
|
||||
msgstr "Interroga il server delle chiavi"
|
||||
|
||||
#: views.py:142
|
||||
msgid "results"
|
||||
msgstr "risultati"
|
||||
|
||||
#: views.py:147
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#: views.py:151
|
||||
msgid "type"
|
||||
msgstr "tipo"
|
||||
|
||||
#: views.py:155
|
||||
msgid "creation date"
|
||||
msgstr "data di crezione"
|
||||
|
||||
#: views.py:159
|
||||
msgid "disabled"
|
||||
msgstr "disabilitata"
|
||||
|
||||
#: views.py:163
|
||||
msgid "expiration date"
|
||||
msgstr "data scadenza"
|
||||
|
||||
#: views.py:167
|
||||
msgid "expired"
|
||||
msgstr "scaduta"
|
||||
|
||||
#: views.py:171
|
||||
msgid "length"
|
||||
msgstr "lunghezza"
|
||||
|
||||
#: views.py:175
|
||||
msgid "revoked"
|
||||
msgstr "revocata"
|
||||
|
||||
#: views.py:180
|
||||
msgid "Identifies"
|
||||
msgstr "Identifica"
|
||||
|
||||
#: conf/settings.py:15
|
||||
msgid "List of keyservers to be queried for unknown keys."
|
||||
msgstr "Lista di server per chiavi che si possono interrogare."
|
||||
|
||||
#: conf/settings.py:16
|
||||
msgid "Home directory used to store keys as well as configuration files."
|
||||
msgstr ""
|
||||
BIN
apps/django_gpg/locale/pl/LC_MESSAGES/django.mo
Normal file
BIN
apps/django_gpg/locale/pl/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
215
apps/django_gpg/locale/pl/LC_MESSAGES/django.po
Normal file
215
apps/django_gpg/locale/pl/LC_MESSAGES/django.po
Normal file
@@ -0,0 +1,215 @@
|
||||
# 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-02-12 15:20-0400\n"
|
||||
"PO-Revision-Date: 2012-02-21 20:34+0000\n"
|
||||
"Last-Translator: mic <winterfall24@gmail.com>\n"
|
||||
"Language-Team: Polish (http://www.transifex.net/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:14 views.py:67
|
||||
msgid "private keys"
|
||||
msgstr "private keys"
|
||||
|
||||
#: __init__.py:15 views.py:70
|
||||
msgid "public keys"
|
||||
msgstr "public keys"
|
||||
|
||||
#: __init__.py:16
|
||||
msgid "delete"
|
||||
msgstr "usunąć"
|
||||
|
||||
#: __init__.py:17
|
||||
msgid "query keyservers"
|
||||
msgstr "query keyservers"
|
||||
|
||||
#: __init__.py:18
|
||||
msgid "import"
|
||||
msgstr "import"
|
||||
|
||||
#: __init__.py:19
|
||||
msgid "key management"
|
||||
msgstr "zarządzanie kluczami"
|
||||
|
||||
#: api.py:19
|
||||
msgid "Public"
|
||||
msgstr "Publiczny"
|
||||
|
||||
#: api.py:20
|
||||
msgid "Secret"
|
||||
msgstr "Secret"
|
||||
|
||||
#: api.py:28 api.py:33
|
||||
msgid "RSA"
|
||||
msgstr "RSA"
|
||||
|
||||
#: api.py:29
|
||||
msgid "DSA"
|
||||
msgstr "DSA"
|
||||
|
||||
#: api.py:34
|
||||
msgid "Elgamal"
|
||||
msgstr "Elgamal"
|
||||
|
||||
#: api.py:48
|
||||
msgid "Bad signature."
|
||||
msgstr "Zły podpis."
|
||||
|
||||
#: api.py:52
|
||||
msgid "Document not signed or invalid signature."
|
||||
msgstr "Dokumentu nie podpisany lub nieprawidłowy podpis."
|
||||
|
||||
#: api.py:56
|
||||
msgid "Signature error."
|
||||
msgstr "Błąd podpisu."
|
||||
|
||||
#: api.py:60
|
||||
msgid "Document is signed but no public key is available for verification."
|
||||
msgstr "Dokument został podpisany, ale klucz publiczny nie jest dostępny do weryfikacji."
|
||||
|
||||
#: api.py:64
|
||||
msgid "Document is signed, and signature is good."
|
||||
msgstr "Dokument został podpisany, a podpis jest dobry."
|
||||
|
||||
#: api.py:68
|
||||
msgid "Document is signed with a valid signature."
|
||||
msgstr "Dokument podpisany za pomocą ważnego podpisu."
|
||||
|
||||
#: api.py:141
|
||||
msgid "unknown"
|
||||
msgstr "nieznany"
|
||||
|
||||
#: forms.py:8
|
||||
msgid "Term"
|
||||
msgstr "Term"
|
||||
|
||||
#: forms.py:9
|
||||
msgid "Name, e-mail, key ID or key fingerprint to look for."
|
||||
msgstr "Imię i nazwisko, e-mail, key ID lub key fingerprint kluc szukać."
|
||||
|
||||
#: permissions.py:7
|
||||
msgid "Key management"
|
||||
msgstr "Zarządzanie kluczami"
|
||||
|
||||
#: permissions.py:9
|
||||
msgid "View keys"
|
||||
msgstr "View keys"
|
||||
|
||||
#: permissions.py:10
|
||||
msgid "Delete keys"
|
||||
msgstr "Delete keys"
|
||||
|
||||
#: permissions.py:11
|
||||
msgid "Query keyservers"
|
||||
msgstr "Query keyservers"
|
||||
|
||||
#: permissions.py:12
|
||||
msgid "Import keys from keyservers"
|
||||
msgstr "Import keys from keyservers"
|
||||
|
||||
#: views.py:38
|
||||
#, python-format
|
||||
msgid "Key: %s, imported successfully."
|
||||
msgstr "Klucz:%s, zaimportowany."
|
||||
|
||||
#: views.py:43
|
||||
#, python-format
|
||||
msgid "Unable to import key id: %(key_id)s; %(error)s"
|
||||
msgstr "Nie można zaimportować ID klucza: %(key_id)s ; %(error)s "
|
||||
|
||||
#: views.py:52
|
||||
msgid "Import key"
|
||||
msgstr "Importuj klucz"
|
||||
|
||||
#: views.py:53
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to import key id: %s?"
|
||||
msgstr "Czy na pewno chcesz importować ID klucza:%s?"
|
||||
|
||||
#: views.py:78
|
||||
msgid "Key ID"
|
||||
msgstr "Key ID"
|
||||
|
||||
#: views.py:82
|
||||
msgid "Owner"
|
||||
msgstr "Właściciel"
|
||||
|
||||
#: views.py:102
|
||||
#, python-format
|
||||
msgid "Key: %s, deleted successfully."
|
||||
msgstr "Klucz:%s, został usunięty."
|
||||
|
||||
#: views.py:109
|
||||
msgid "Delete key"
|
||||
msgstr "Usuń klucz"
|
||||
|
||||
#: views.py:111
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Are you sure you wish to delete key: %s? If you try to delete a public key "
|
||||
"that is part of a public/private pair the private key will be deleted as "
|
||||
"well."
|
||||
msgstr "Czy na pewno chcesz usunąć klucz:%s? Jeśli próbujesz usunąć klucza publiczny, który jest częścią pary publiczny / prywatny klucz prywatny zostanie usunięty również."
|
||||
|
||||
#: views.py:129
|
||||
msgid "Query key server"
|
||||
msgstr "Query key server"
|
||||
|
||||
#: views.py:142
|
||||
msgid "results"
|
||||
msgstr "wyniki"
|
||||
|
||||
#: views.py:147
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#: views.py:151
|
||||
msgid "type"
|
||||
msgstr "typ"
|
||||
|
||||
#: views.py:155
|
||||
msgid "creation date"
|
||||
msgstr "creation date"
|
||||
|
||||
#: views.py:159
|
||||
msgid "disabled"
|
||||
msgstr "wyłączone"
|
||||
|
||||
#: views.py:163
|
||||
msgid "expiration date"
|
||||
msgstr "data ważności"
|
||||
|
||||
#: views.py:167
|
||||
msgid "expired"
|
||||
msgstr "wygasł"
|
||||
|
||||
#: views.py:171
|
||||
msgid "length"
|
||||
msgstr "długość"
|
||||
|
||||
#: views.py:175
|
||||
msgid "revoked"
|
||||
msgstr "odwołany"
|
||||
|
||||
#: views.py:180
|
||||
msgid "Identifies"
|
||||
msgstr "Identyfikuje"
|
||||
|
||||
#: conf/settings.py:15
|
||||
msgid "List of keyservers to be queried for unknown keys."
|
||||
msgstr "List of keyservers to be queried for unknown keys."
|
||||
|
||||
#: conf/settings.py:16
|
||||
msgid "Home directory used to store keys as well as configuration files."
|
||||
msgstr "Katalog domowy używany do przechowywania kluczy oraz plików konfiguracyjnych."
|
||||
Binary file not shown.
@@ -3,13 +3,14 @@
|
||||
# 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: \n"
|
||||
"POT-Creation-Date: 2011-12-06 02:06-0400\n"
|
||||
"PO-Revision-Date: 2011-12-05 17:43+0000\n"
|
||||
"Last-Translator: rosarior <roberto.rosario.gonzalez@gmail.com>\n"
|
||||
"POT-Creation-Date: 2012-02-12 15:20-0400\n"
|
||||
"PO-Revision-Date: 2012-02-02 18:20+0000\n"
|
||||
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
|
||||
"Language-Team: Portuguese (http://www.transifex.net/projects/p/mayan-edms/"
|
||||
"team/pt/)\n"
|
||||
"Language: pt\n"
|
||||
@@ -18,169 +19,141 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
|
||||
#: __init__.py:14
|
||||
msgid "Verify document signatures"
|
||||
msgstr ""
|
||||
#: __init__.py:14 views.py:67
|
||||
msgid "private keys"
|
||||
msgstr "chaves privadas"
|
||||
|
||||
#: __init__.py:15
|
||||
msgid "View keys"
|
||||
msgstr ""
|
||||
#: __init__.py:15 views.py:70
|
||||
msgid "public keys"
|
||||
msgstr "chaves públicas"
|
||||
|
||||
#: __init__.py:16
|
||||
msgid "Delete keys"
|
||||
msgstr ""
|
||||
msgid "delete"
|
||||
msgstr "excluir"
|
||||
|
||||
#: __init__.py:17
|
||||
msgid "Query keyservers"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:18
|
||||
msgid "Import key from keyservers"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:19
|
||||
msgid "Upload detached signatures"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:20
|
||||
msgid "Download detached signatures"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:23
|
||||
msgid "Signatures"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:39 views.py:67
|
||||
msgid "private keys"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:40 views.py:70
|
||||
msgid "public keys"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:41
|
||||
msgid "delete"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:42
|
||||
msgid "query keyservers"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:43
|
||||
#: __init__.py:18
|
||||
msgid "import"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:44
|
||||
msgid "upload signature"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:45
|
||||
msgid "download signature"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:46
|
||||
#: __init__.py:19
|
||||
msgid "key management"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:49
|
||||
msgid "signatures"
|
||||
msgstr ""
|
||||
|
||||
#: api.py:22
|
||||
#: api.py:19
|
||||
msgid "Public"
|
||||
msgstr ""
|
||||
msgstr "Público"
|
||||
|
||||
#: api.py:23
|
||||
#: api.py:20
|
||||
msgid "Secret"
|
||||
msgstr ""
|
||||
msgstr "Segredo"
|
||||
|
||||
#: api.py:31 api.py:36
|
||||
#: api.py:28 api.py:33
|
||||
msgid "RSA"
|
||||
msgstr ""
|
||||
msgstr "RSA"
|
||||
|
||||
#: api.py:32
|
||||
#: api.py:29
|
||||
msgid "DSA"
|
||||
msgstr ""
|
||||
msgstr "DSA"
|
||||
|
||||
#: api.py:37
|
||||
#: api.py:34
|
||||
msgid "Elgamal"
|
||||
msgstr ""
|
||||
msgstr "Elgamal"
|
||||
|
||||
#: api.py:51
|
||||
#: api.py:48
|
||||
msgid "Bad signature."
|
||||
msgstr ""
|
||||
msgstr "Assinatura ruim."
|
||||
|
||||
#: api.py:55
|
||||
#: api.py:52
|
||||
msgid "Document not signed or invalid signature."
|
||||
msgstr ""
|
||||
msgstr "Documento não assinado ou inválido assinatura."
|
||||
|
||||
#: api.py:59
|
||||
#: api.py:56
|
||||
msgid "Signature error."
|
||||
msgstr ""
|
||||
msgstr "Erro de assinatura."
|
||||
|
||||
#: api.py:63
|
||||
#: api.py:60
|
||||
msgid "Document is signed but no public key is available for verification."
|
||||
msgstr ""
|
||||
|
||||
#: api.py:67
|
||||
#: api.py:64
|
||||
msgid "Document is signed, and signature is good."
|
||||
msgstr ""
|
||||
|
||||
#: api.py:71
|
||||
#: api.py:68
|
||||
msgid "Document is signed with a valid signature."
|
||||
msgstr ""
|
||||
|
||||
#: api.py:144
|
||||
#: api.py:141
|
||||
msgid "unknown"
|
||||
msgstr ""
|
||||
msgstr "desconhecido"
|
||||
|
||||
#: forms.py:11
|
||||
#: forms.py:8
|
||||
msgid "Term"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:12
|
||||
#: forms.py:9
|
||||
msgid "Name, e-mail, key ID or key fingerprint to look for."
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:18
|
||||
msgid "Signature file"
|
||||
#: permissions.py:7
|
||||
msgid "Key management"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:45
|
||||
#: permissions.py:9
|
||||
msgid "View keys"
|
||||
msgstr "Ver as chaves"
|
||||
|
||||
#: permissions.py:10
|
||||
msgid "Delete keys"
|
||||
msgstr "Excluir chaves"
|
||||
|
||||
#: permissions.py:11
|
||||
msgid "Query keyservers"
|
||||
msgstr "Consulta servidores de chaves"
|
||||
|
||||
#: permissions.py:12
|
||||
msgid "Import keys from keyservers"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:38
|
||||
#, python-format
|
||||
msgid "Key: %s, imported successfully."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:48
|
||||
#: views.py:43
|
||||
#, python-format
|
||||
msgid "Unable to import key id: %s"
|
||||
msgid "Unable to import key id: %(key_id)s; %(error)s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:52
|
||||
msgid "Import key"
|
||||
msgstr ""
|
||||
msgstr "Importar chave"
|
||||
|
||||
#: views.py:53
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to import key id: %s?"
|
||||
msgstr ""
|
||||
msgstr "Você tem certeza que deseja importar chave: %s?"
|
||||
|
||||
#: views.py:78
|
||||
msgid "Key ID"
|
||||
msgstr ""
|
||||
msgstr "ID da chave"
|
||||
|
||||
#: views.py:82
|
||||
msgid "Owner"
|
||||
msgstr ""
|
||||
msgstr "Proprietário"
|
||||
|
||||
#: views.py:102
|
||||
#, python-format
|
||||
msgid "Key: %s, deleted successfully."
|
||||
msgstr ""
|
||||
msgstr "Chave: %s, apagado com sucesso."
|
||||
|
||||
#: views.py:109
|
||||
msgid "Delete key"
|
||||
msgstr ""
|
||||
msgstr "Excluir chave"
|
||||
|
||||
#: views.py:111
|
||||
#, python-format
|
||||
@@ -192,39 +165,39 @@ msgstr ""
|
||||
|
||||
#: views.py:129
|
||||
msgid "Query key server"
|
||||
msgstr ""
|
||||
msgstr "Consultar servidor de chaves"
|
||||
|
||||
#: views.py:142
|
||||
msgid "results"
|
||||
msgstr ""
|
||||
msgstr "resultados"
|
||||
|
||||
#: views.py:147
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
msgstr "ID"
|
||||
|
||||
#: views.py:151
|
||||
msgid "type"
|
||||
msgstr ""
|
||||
msgstr "tipo"
|
||||
|
||||
#: views.py:155
|
||||
msgid "creation date"
|
||||
msgstr ""
|
||||
msgstr "data de criação"
|
||||
|
||||
#: views.py:159
|
||||
msgid "disabled"
|
||||
msgstr ""
|
||||
msgstr "desativada"
|
||||
|
||||
#: views.py:163
|
||||
msgid "expiration date"
|
||||
msgstr ""
|
||||
msgstr "data de validade"
|
||||
|
||||
#: views.py:167
|
||||
msgid "expired"
|
||||
msgstr ""
|
||||
msgstr "expirado"
|
||||
|
||||
#: views.py:171
|
||||
msgid "length"
|
||||
msgstr ""
|
||||
msgstr "comprimento"
|
||||
|
||||
#: views.py:175
|
||||
msgid "revoked"
|
||||
@@ -234,58 +207,10 @@ msgstr ""
|
||||
msgid "Identifies"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:205
|
||||
#, python-format
|
||||
msgid "Signature status: %(widget)s %(text)s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:212
|
||||
msgid "embedded"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:214
|
||||
msgid "detached"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:219
|
||||
#, python-format
|
||||
msgid "Signature ID: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:220
|
||||
#, python-format
|
||||
msgid "Signature type: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:221
|
||||
#, python-format
|
||||
msgid "Key ID: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:222
|
||||
#, python-format
|
||||
msgid "Timestamp: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:223
|
||||
#, python-format
|
||||
msgid "Signee: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:228
|
||||
#, python-format
|
||||
msgid "signature properties for: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:250
|
||||
msgid "Detached signature uploaded successfully."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:259
|
||||
#, python-format
|
||||
msgid "Upload detached signature for: %s"
|
||||
msgstr ""
|
||||
|
||||
#: conf/settings.py:13
|
||||
#: conf/settings.py:15
|
||||
msgid "List of keyservers to be queried for unknown keys."
|
||||
msgstr ""
|
||||
|
||||
#: conf/settings.py:16
|
||||
msgid "Home directory used to store keys as well as configuration files."
|
||||
msgstr ""
|
||||
|
||||
Binary file not shown.
@@ -3,13 +3,14 @@
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Sergey Glita <gsv70@mail.ru>, 2011.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Mayan EDMS\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-12-06 02:06-0400\n"
|
||||
"PO-Revision-Date: 2011-12-05 17:43+0000\n"
|
||||
"Last-Translator: rosarior <roberto.rosario.gonzalez@gmail.com>\n"
|
||||
"POT-Creation-Date: 2012-02-12 15:20-0400\n"
|
||||
"PO-Revision-Date: 2012-02-02 18:20+0000\n"
|
||||
"Last-Translator: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>\n"
|
||||
"Language-Team: Russian (http://www.transifex.net/projects/p/mayan-edms/team/"
|
||||
"ru/)\n"
|
||||
"Language: ru\n"
|
||||
@@ -19,169 +20,141 @@ msgstr ""
|
||||
"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:14
|
||||
msgid "Verify document signatures"
|
||||
msgstr ""
|
||||
#: __init__.py:14 views.py:67
|
||||
msgid "private keys"
|
||||
msgstr "секретные ключи"
|
||||
|
||||
#: __init__.py:15
|
||||
msgid "View keys"
|
||||
msgstr ""
|
||||
#: __init__.py:15 views.py:70
|
||||
msgid "public keys"
|
||||
msgstr "открытые ключи"
|
||||
|
||||
#: __init__.py:16
|
||||
msgid "Delete keys"
|
||||
msgstr ""
|
||||
msgid "delete"
|
||||
msgstr "удалить"
|
||||
|
||||
#: __init__.py:17
|
||||
msgid "Query keyservers"
|
||||
msgstr ""
|
||||
msgid "query keyservers"
|
||||
msgstr "запрос ключевых серверов"
|
||||
|
||||
#: __init__.py:18
|
||||
msgid "Import key from keyservers"
|
||||
msgstr ""
|
||||
msgid "import"
|
||||
msgstr "получить"
|
||||
|
||||
#: __init__.py:19
|
||||
msgid "Upload detached signatures"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:20
|
||||
msgid "Download detached signatures"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:23
|
||||
msgid "Signatures"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:39 views.py:67
|
||||
msgid "private keys"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:40 views.py:70
|
||||
msgid "public keys"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:41
|
||||
msgid "delete"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:42
|
||||
msgid "query keyservers"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:43
|
||||
msgid "import"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:44
|
||||
msgid "upload signature"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:45
|
||||
msgid "download signature"
|
||||
msgstr ""
|
||||
|
||||
#: __init__.py:46
|
||||
msgid "key management"
|
||||
msgstr ""
|
||||
msgstr "управление ключами"
|
||||
|
||||
#: __init__.py:49
|
||||
msgid "signatures"
|
||||
msgstr ""
|
||||
|
||||
#: api.py:22
|
||||
#: api.py:19
|
||||
msgid "Public"
|
||||
msgstr ""
|
||||
msgstr "Открытый"
|
||||
|
||||
#: api.py:23
|
||||
#: api.py:20
|
||||
msgid "Secret"
|
||||
msgstr ""
|
||||
msgstr "секретный"
|
||||
|
||||
#: api.py:31 api.py:36
|
||||
#: api.py:28 api.py:33
|
||||
msgid "RSA"
|
||||
msgstr ""
|
||||
msgstr "RSA"
|
||||
|
||||
#: api.py:32
|
||||
#: api.py:29
|
||||
msgid "DSA"
|
||||
msgstr ""
|
||||
msgstr "DSA"
|
||||
|
||||
#: api.py:37
|
||||
#: api.py:34
|
||||
msgid "Elgamal"
|
||||
msgstr ""
|
||||
msgstr "Elgamal"
|
||||
|
||||
#: api.py:51
|
||||
#: api.py:48
|
||||
msgid "Bad signature."
|
||||
msgstr ""
|
||||
msgstr "Неверная подпись"
|
||||
|
||||
#: api.py:55
|
||||
#: api.py:52
|
||||
msgid "Document not signed or invalid signature."
|
||||
msgstr ""
|
||||
msgstr "Документ не подписан, либо подпись неверна."
|
||||
|
||||
#: api.py:59
|
||||
#: api.py:56
|
||||
msgid "Signature error."
|
||||
msgstr ""
|
||||
msgstr "Ошибка подписи."
|
||||
|
||||
#: api.py:63
|
||||
#: api.py:60
|
||||
msgid "Document is signed but no public key is available for verification."
|
||||
msgstr ""
|
||||
msgstr "Документ подписан, но нет открытого ключа для проверки."
|
||||
|
||||
#: api.py:67
|
||||
#: api.py:64
|
||||
msgid "Document is signed, and signature is good."
|
||||
msgstr ""
|
||||
msgstr "Документ подписан и подпись верна."
|
||||
|
||||
#: api.py:71
|
||||
#: api.py:68
|
||||
msgid "Document is signed with a valid signature."
|
||||
msgstr ""
|
||||
msgstr "Документ подписан допустимой подписью."
|
||||
|
||||
#: api.py:144
|
||||
#: api.py:141
|
||||
msgid "unknown"
|
||||
msgstr ""
|
||||
msgstr "неизвестно"
|
||||
|
||||
#: forms.py:11
|
||||
#: forms.py:8
|
||||
msgid "Term"
|
||||
msgstr ""
|
||||
msgstr "Term"
|
||||
|
||||
#: forms.py:12
|
||||
#: forms.py:9
|
||||
msgid "Name, e-mail, key ID or key fingerprint to look for."
|
||||
msgstr "Имя, e-mail, ID ключа или отпечаток для поиска."
|
||||
|
||||
#: permissions.py:7
|
||||
msgid "Key management"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:18
|
||||
msgid "Signature file"
|
||||
#: permissions.py:9
|
||||
msgid "View keys"
|
||||
msgstr "Просмотр ключей"
|
||||
|
||||
#: permissions.py:10
|
||||
msgid "Delete keys"
|
||||
msgstr "Удалить ключи"
|
||||
|
||||
#: permissions.py:11
|
||||
msgid "Query keyservers"
|
||||
msgstr "Запрос к серверам ключей"
|
||||
|
||||
#: permissions.py:12
|
||||
msgid "Import keys from keyservers"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:45
|
||||
#: views.py:38
|
||||
#, python-format
|
||||
msgid "Key: %s, imported successfully."
|
||||
msgstr ""
|
||||
msgstr "Ключ %s, получен."
|
||||
|
||||
#: views.py:48
|
||||
#: views.py:43
|
||||
#, python-format
|
||||
msgid "Unable to import key id: %s"
|
||||
msgid "Unable to import key id: %(key_id)s; %(error)s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:52
|
||||
msgid "Import key"
|
||||
msgstr ""
|
||||
msgstr "Получить ключ"
|
||||
|
||||
#: views.py:53
|
||||
#, python-format
|
||||
msgid "Are you sure you wish to import key id: %s?"
|
||||
msgstr ""
|
||||
msgstr "Хотите получить ключ id: %s?"
|
||||
|
||||
#: views.py:78
|
||||
msgid "Key ID"
|
||||
msgstr ""
|
||||
msgstr "ID ключа"
|
||||
|
||||
#: views.py:82
|
||||
msgid "Owner"
|
||||
msgstr ""
|
||||
msgstr "Владелец"
|
||||
|
||||
#: views.py:102
|
||||
#, python-format
|
||||
msgid "Key: %s, deleted successfully."
|
||||
msgstr ""
|
||||
msgstr "Ключ %s удалён."
|
||||
|
||||
#: views.py:109
|
||||
msgid "Delete key"
|
||||
msgstr ""
|
||||
msgstr "Удалить ключ."
|
||||
|
||||
#: views.py:111
|
||||
#, python-format
|
||||
@@ -190,103 +163,57 @@ msgid ""
|
||||
"that is part of a public/private pair the private key will be deleted as "
|
||||
"well."
|
||||
msgstr ""
|
||||
"Вы уверены, что хотите удалить ключ %s? Если вы удалите открытый ключ то "
|
||||
"соответствующий ему закрытый ключ тоже будет удалён."
|
||||
|
||||
#: views.py:129
|
||||
msgid "Query key server"
|
||||
msgstr ""
|
||||
msgstr "Запросить сервер ключей"
|
||||
|
||||
#: views.py:142
|
||||
msgid "results"
|
||||
msgstr ""
|
||||
msgstr "результаты"
|
||||
|
||||
#: views.py:147
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
msgstr "ID"
|
||||
|
||||
#: views.py:151
|
||||
msgid "type"
|
||||
msgstr ""
|
||||
msgstr "тип"
|
||||
|
||||
#: views.py:155
|
||||
msgid "creation date"
|
||||
msgstr ""
|
||||
msgstr "дата создания"
|
||||
|
||||
#: views.py:159
|
||||
msgid "disabled"
|
||||
msgstr ""
|
||||
msgstr "запрещено"
|
||||
|
||||
#: views.py:163
|
||||
msgid "expiration date"
|
||||
msgstr ""
|
||||
msgstr "дата окончания"
|
||||
|
||||
#: views.py:167
|
||||
msgid "expired"
|
||||
msgstr ""
|
||||
msgstr "истекло"
|
||||
|
||||
#: views.py:171
|
||||
msgid "length"
|
||||
msgstr ""
|
||||
msgstr "длина"
|
||||
|
||||
#: views.py:175
|
||||
msgid "revoked"
|
||||
msgstr ""
|
||||
msgstr "отозван"
|
||||
|
||||
#: views.py:180
|
||||
msgid "Identifies"
|
||||
msgstr ""
|
||||
msgstr "Identifies"
|
||||
|
||||
#: views.py:205
|
||||
#, python-format
|
||||
msgid "Signature status: %(widget)s %(text)s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:212
|
||||
msgid "embedded"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:214
|
||||
msgid "detached"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:219
|
||||
#, python-format
|
||||
msgid "Signature ID: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:220
|
||||
#, python-format
|
||||
msgid "Signature type: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:221
|
||||
#, python-format
|
||||
msgid "Key ID: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:222
|
||||
#, python-format
|
||||
msgid "Timestamp: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:223
|
||||
#, python-format
|
||||
msgid "Signee: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:228
|
||||
#, python-format
|
||||
msgid "signature properties for: %s"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:250
|
||||
msgid "Detached signature uploaded successfully."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:259
|
||||
#, python-format
|
||||
msgid "Upload detached signature for: %s"
|
||||
msgstr ""
|
||||
|
||||
#: conf/settings.py:13
|
||||
#: conf/settings.py:15
|
||||
msgid "List of keyservers to be queried for unknown keys."
|
||||
msgstr "Список ключевых серверов для запроса неизвестных ключей."
|
||||
|
||||
#: conf/settings.py:16
|
||||
msgid "Home directory used to store keys as well as configuration files."
|
||||
msgstr ""
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
|
||||
12
apps/django_gpg/permissions.py
Normal file
12
apps/django_gpg/permissions.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from permissions.models import PermissionNamespace, Permission
|
||||
|
||||
django_gpg_namespace = PermissionNamespace('django_gpg', _(u'Key management'))
|
||||
|
||||
PERMISSION_KEY_VIEW = Permission.objects.register(django_gpg_namespace, 'key_view', _(u'View keys'))
|
||||
PERMISSION_KEY_DELETE = Permission.objects.register(django_gpg_namespace, 'key_delete', _(u'Delete keys'))
|
||||
PERMISSION_KEYSERVER_QUERY = Permission.objects.register(django_gpg_namespace, 'keyserver_query', _(u'Query keyservers'))
|
||||
PERMISSION_KEY_RECEIVE = Permission.objects.register(django_gpg_namespace, 'key_receive', _(u'Import keys from keyservers'))
|
||||
@@ -1,4 +1,13 @@
|
||||
from django_gpg.api import GPG
|
||||
from django_gpg.conf.settings import KEYSERVERS
|
||||
from __future__ import absolute_import
|
||||
|
||||
gpg = GPG(keyservers=KEYSERVERS)
|
||||
import sys
|
||||
|
||||
from .api import GPG
|
||||
from .conf.settings import KEYSERVERS, GPG_HOME
|
||||
|
||||
try:
|
||||
gpg = GPG(home=GPG_HOME, keyservers=KEYSERVERS)
|
||||
except Exception, e:
|
||||
gpg = GPG(keyservers=KEYSERVERS)
|
||||
sys.stderr.write(u'ERROR: GPG initialization error: %s\n' % e)
|
||||
sys.stderr.write(u'INFO: Initializating GPG with system default home\n')
|
||||
|
||||
@@ -4,9 +4,6 @@ urlpatterns = patterns('django_gpg.views',
|
||||
url(r'^delete/(?P<fingerprint>.+)/(?P<key_type>\w+)/$', 'key_delete', (), 'key_delete'),
|
||||
url(r'^list/private/$', 'key_list', {'secret': True}, 'key_private_list'),
|
||||
url(r'^list/public/$', 'key_list', {'secret': False}, 'key_public_list'),
|
||||
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'^query/$', 'key_query', (), 'key_query'),
|
||||
url(r'^receive/(?P<key_id>.+)/$', 'key_receive', (), 'key_receive'),
|
||||
)
|
||||
|
||||
@@ -1,38 +1,29 @@
|
||||
from datetime import datetime
|
||||
from __future__ import absolute_import
|
||||
|
||||
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.shortcuts import render_to_response
|
||||
from django.template import RequestContext
|
||||
from django.contrib import messages
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.conf import settings
|
||||
from django.template.defaultfilters import force_escape
|
||||
|
||||
from documents.models import Document, RecentDocument
|
||||
from permissions.api import check_permissions
|
||||
from common.utils import pretty_size, parse_range, urlquote, \
|
||||
return_diff, encapsulate
|
||||
from filetransfers.api import serve_file
|
||||
|
||||
from django_gpg.api import Key, SIGNATURE_STATES
|
||||
from django_gpg.runtime import gpg
|
||||
from django_gpg.exceptions import (GPGVerificationError, KeyFetchingError,
|
||||
KeyImportError)
|
||||
from django_gpg import (PERMISSION_DOCUMENT_VERIFY, PERMISSION_KEY_VIEW,
|
||||
PERMISSION_KEY_DELETE, PERMISSION_KEYSERVER_QUERY,
|
||||
PERMISSION_KEY_RECEIVE, PERMISSION_SIGNATURE_UPLOAD,
|
||||
PERMISSION_SIGNATURE_DOWNLOAD)
|
||||
from django_gpg.forms import KeySearchForm, DetachedSignatureForm
|
||||
from permissions.models import Permission
|
||||
from common.utils import encapsulate
|
||||
|
||||
from .api import Key
|
||||
from .runtime import gpg
|
||||
from .exceptions import KeyFetchingError, KeyImportError
|
||||
from .forms import KeySearchForm
|
||||
from .permissions import (PERMISSION_KEY_VIEW, PERMISSION_KEY_DELETE,
|
||||
PERMISSION_KEYSERVER_QUERY, PERMISSION_KEY_RECEIVE)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def key_receive(request, key_id):
|
||||
check_permissions(request.user, [PERMISSION_KEY_RECEIVE])
|
||||
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_KEY_RECEIVE])
|
||||
|
||||
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', '/')))
|
||||
@@ -45,8 +36,15 @@ def key_receive(request, key_id):
|
||||
key = gpg.import_key(keys_dict[key_id].key)
|
||||
messages.success(request, _(u'Key: %s, imported successfully.') % key)
|
||||
return HttpResponseRedirect(next)
|
||||
except (KeyImportError, KeyError, TypeError):
|
||||
messages.error(request, _(u'Unable to import key id: %s') % key_id)
|
||||
except (KeyImportError, KeyError, TypeError), e:
|
||||
messages.error(
|
||||
request,
|
||||
_(u'Unable to import key id: %(key_id)s; %(error)s') %
|
||||
{
|
||||
'key_id': key_id,
|
||||
'error': e,
|
||||
}
|
||||
)
|
||||
return HttpResponseRedirect(previous)
|
||||
|
||||
return render_to_response('generic_confirm.html', {
|
||||
@@ -56,13 +54,13 @@ def key_receive(request, key_id):
|
||||
'next': next,
|
||||
'previous': previous,
|
||||
'submit_method': 'GET',
|
||||
|
||||
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
|
||||
|
||||
def key_list(request, secret=True):
|
||||
check_permissions(request.user, [PERMISSION_KEY_VIEW])
|
||||
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_KEY_VIEW])
|
||||
|
||||
if secret:
|
||||
object_list = Key.get_all(gpg, secret=True)
|
||||
title = _(u'private keys')
|
||||
@@ -88,8 +86,8 @@ def key_list(request, secret=True):
|
||||
|
||||
|
||||
def key_delete(request, fingerprint, key_type):
|
||||
check_permissions(request.user, [PERMISSION_KEY_DELETE])
|
||||
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_KEY_DELETE])
|
||||
|
||||
secret = key_type == 'sec'
|
||||
key = Key.get(gpg, fingerprint, secret=secret)
|
||||
|
||||
@@ -117,8 +115,8 @@ def key_delete(request, fingerprint, key_type):
|
||||
|
||||
|
||||
def key_query(request):
|
||||
check_permissions(request.user, [PERMISSION_KEYSERVER_QUERY])
|
||||
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_KEYSERVER_QUERY])
|
||||
|
||||
subtemplates_list = []
|
||||
term = request.GET.get('term')
|
||||
|
||||
@@ -132,8 +130,8 @@ def key_query(request):
|
||||
'submit_method': 'GET',
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
if term:
|
||||
results = gpg.query(term)
|
||||
subtemplates_list.append(
|
||||
@@ -155,132 +153,37 @@ def key_query(request):
|
||||
{
|
||||
'name': _(u'creation date'),
|
||||
'attribute': 'creation_date',
|
||||
},
|
||||
},
|
||||
{
|
||||
'name': _(u'disabled'),
|
||||
'attribute': 'disabled',
|
||||
},
|
||||
},
|
||||
{
|
||||
'name': _(u'expiration date'),
|
||||
'attribute': 'expiration_date',
|
||||
},
|
||||
},
|
||||
{
|
||||
'name': _(u'expired'),
|
||||
'attribute': 'expired',
|
||||
},
|
||||
},
|
||||
{
|
||||
'name': _(u'length'),
|
||||
'attribute': 'key_length',
|
||||
},
|
||||
},
|
||||
{
|
||||
'name': _(u'revoked'),
|
||||
'attribute': 'revoked',
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
'name': _(u'Identifies'),
|
||||
'attribute': encapsulate(lambda x: u', '.join([identity.uid for identity in x.identities])),
|
||||
},
|
||||
]
|
||||
]
|
||||
},
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
return render_to_response('generic_form.html', {
|
||||
'subtemplates_list': subtemplates_list,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def document_verify(request, document_pk):
|
||||
check_permissions(request.user, [PERMISSION_DOCUMENT_VERIFY])
|
||||
document = get_object_or_404(Document, pk=document_pk)
|
||||
|
||||
RecentDocument.objects.add_document_for_user(request.user, document)
|
||||
|
||||
signature = document.verify_signature()
|
||||
|
||||
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 document.signature_state:
|
||||
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):
|
||||
check_permissions(request.user, [PERMISSION_SIGNATURE_UPLOAD])
|
||||
document = get_object_or_404(Document, pk=document_pk)
|
||||
|
||||
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:
|
||||
document.add_detached_signature(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):
|
||||
check_permissions(request.user, [PERMISSION_SIGNATURE_DOWNLOAD])
|
||||
document = get_object_or_404(Document, pk=document_pk)
|
||||
|
||||
try:
|
||||
if document.has_detached_signature():
|
||||
signature = document.detached_signature()
|
||||
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'])
|
||||
|
||||
15
apps/document_acls/__init__.py
Normal file
15
apps/document_acls/__init__.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from documents.models import Document
|
||||
from navigation.api import register_links
|
||||
from acls import ACLS_VIEW_ACL, ACLS_EDIT_ACL
|
||||
from acls.api import class_permissions
|
||||
|
||||
acl_list = {'text': _(u'ACLs'), 'view': 'document_acl_list', 'args': 'object.pk', 'famfam': 'lock', 'permissions': [ACLS_VIEW_ACL]}
|
||||
|
||||
register_links(Document, [acl_list], menu_name='form_header')
|
||||
|
||||
class_permissions(Document, [
|
||||
ACLS_VIEW_ACL,
|
||||
ACLS_EDIT_ACL
|
||||
])
|
||||
5
apps/document_acls/urls.py
Normal file
5
apps/document_acls/urls.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from django.conf.urls.defaults import patterns, url
|
||||
|
||||
urlpatterns = patterns('document_acls.views',
|
||||
url(r'^list_for/document/(?P<document_id>\d+)/$', 'document_acl_list', (), 'document_acl_list'),
|
||||
)
|
||||
16
apps/document_acls/views.py
Normal file
16
apps/document_acls/views.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from documents.models import Document
|
||||
from acls.views import acl_list_for
|
||||
|
||||
|
||||
def document_acl_list(request, document_id):
|
||||
document = get_object_or_404(Document, pk=document_id)
|
||||
return acl_list_for(
|
||||
request,
|
||||
document,
|
||||
extra_context={
|
||||
'object': document,
|
||||
}
|
||||
)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user