diff --git a/apps/acls/__init__.py b/apps/acls/__init__.py index 64becbdef5..33493dd232 100644 --- a/apps/acls/__init__.py +++ b/apps/acls/__init__.py @@ -7,7 +7,7 @@ from project_setup.api import register_setup from .classes import (AccessHolder, AccessObjectClass, ClassAccessHolder, AccessObject) -from .permissions import (ACLS_EDIT_ACL, ACLS_VIEW_ACL, +from .permissions import (ACLS_EDIT_ACL, ACLS_VIEW_ACL, ACLS_CLASS_EDIT_ACL, ACLS_CLASS_VIEW_ACL) diff --git a/apps/acls/admin.py b/apps/acls/admin.py index 6608e6799b..61c12d9498 100644 --- a/apps/acls/admin.py +++ b/apps/acls/admin.py @@ -1,8 +1,6 @@ from __future__ import absolute_import from django.contrib import admin -from django.contrib.contenttypes import generic -from django.contrib.contenttypes.models import ContentType from .models import AccessEntry @@ -21,5 +19,5 @@ class AccessEntryAdmin(admin.ModelAdmin): list_display = ('pk', 'holder_object', 'permission', 'content_object') list_display_links = ('pk',) model = AccessEntry - + admin.site.register(AccessEntry, AccessEntryAdmin) diff --git a/apps/acls/classes.py b/apps/acls/classes.py index 016a4ca797..f2b7c36ef2 100644 --- a/apps/acls/classes.py +++ b/apps/acls/classes.py @@ -4,21 +4,21 @@ import logging import sys import types -from django.db import models 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 = {} class EncapsulatedObject(object): source_object_name = u'source_object' - + @classmethod def object_key(cls, app_label=None, model=None, pk=None): if pk: @@ -31,21 +31,20 @@ class EncapsulatedObject(object): if hasattr(value, 'contribute_to_class'): value.contribute_to_class(cls, name) else: - setattr(cls, name, value) + 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) @@ -68,9 +67,9 @@ class EncapsulatedObject(object): 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: @@ -91,9 +90,9 @@ class EncapsulatedObject(object): 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.name) @@ -102,15 +101,15 @@ class EncapsulatedObject(object): # Class self.gid = '%s.%s' % (self.content_type.app_label, self.content_type.model) else: - # Object + # 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()) else: @@ -118,19 +117,19 @@ class EncapsulatedObject(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' - + source_object_name = u'obj' + class AccessObjectClass(EncapsulatedObject): source_object_name = u'cls' diff --git a/apps/acls/forms.py b/apps/acls/forms.py index 7f651f7f1b..e5a55a006c 100644 --- a/apps/acls/forms.py +++ b/apps/acls/forms.py @@ -4,8 +4,8 @@ from django import forms from django.utils.translation import ugettext_lazy as _ from django.contrib.auth.models import User, Group -from permissions.models import Permission, Role -from common.utils import generate_choices_w_labels, encapsulate, get_object_name +from permissions.models import Role +from common.utils import get_object_name from common.models import AnonymousUserSingleton from .classes import AccessHolder @@ -14,11 +14,12 @@ from .classes import AccessHolder 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 HolderSelectionForm(forms.Form): holder_gid = forms.ChoiceField( label=_(u'New holder') ) - + def __init__(self, *args, **kwargs): current_holders = kwargs.pop('current_holders', []) if current_holders: @@ -29,14 +30,14 @@ class HolderSelectionForm(forms.Form): 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) - + 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)))) diff --git a/apps/acls/managers.py b/apps/acls/managers.py index a2cb9ff17f..ffe3d08d7a 100644 --- a/apps/acls/managers.py +++ b/apps/acls/managers.py @@ -8,8 +8,10 @@ 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 common.models import AnonymousUserSingleton +from permissions.models import Permission from .classes import EncapsulatedObject, AccessHolder, ClassAccessHolder @@ -17,19 +19,23 @@ logger = logging.getLogger(__name__) class AccessEntryManager(models.Manager): + """ + Implement a 3 tier permission system, involving a permissions, an actor + and an object + """ def source_object(self, obj): if isinstance(obj, EncapsulatedObject): return obj.source_object else: return obj - + def grant(self, permission, actor, obj): - ''' + """ Grant a permission (what), (to) an actor, (on) a specific object - ''' + """ obj = self.source_object(obj) actor = self.source_object(actor) - + access_entry, created = self.model.objects.get_or_create( permission=permission, holder_type=ContentType.objects.get_for_model(actor), @@ -40,9 +46,9 @@ class AccessEntryManager(models.Manager): return created def revoke(self, permission, actor, obj): - ''' + """ Revoke a permission (what), (from) an actor, (on) a specific object - ''' + """ obj = self.source_object(obj) actor = self.source_object(actor) @@ -57,12 +63,15 @@ class AccessEntryManager(models.Manager): access_entry.delete() return True except self.model.DoesNotExist: - return False + return False def has_access(self, permission, actor, obj): + """ + Returns whether an actor has a specific permission for an object + """ obj = self.source_object(obj) actor = self.source_object(actor) - + if isinstance(actor, User): if actor.is_superuser or actor.is_staff: return True @@ -70,18 +79,20 @@ class AccessEntryManager(models.Manager): actor = AnonymousUserSingleton.objects.passthru_check(actor) try: - access_entry = self.model.objects.get( + 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 ) - return True except self.model.DoesNotExist: return False - + else: + return True + def check_access(self, permission, actor, obj): + # TODO: Merge with has_access obj = self.source_object(obj) actor = self.source_object(actor) @@ -89,8 +100,11 @@ class AccessEntryManager(models.Manager): 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 = self.source_object(obj) actor = self.source_object(actor) for permission in permission_list: @@ -101,7 +115,7 @@ class AccessEntryManager(models.Manager): 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) @@ -122,22 +136,26 @@ class AccessEntryManager(models.Manager): 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): 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): + """ + 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): if actor.is_superuser or actor.is_staff: return Permission.objects.all() @@ -147,13 +165,17 @@ class AccessEntryManager(models.Manager): 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 @@ -161,15 +183,15 @@ class AccessEntryManager(models.Manager): # 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 @@ -182,6 +204,12 @@ class AccessEntryManager(models.Manager): 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): if isinstance(cls, EncapsulatedObject): cls = cls.source_object @@ -190,32 +218,33 @@ class DefaultAccessEntryManager(models.Manager): holder_list = [] for access_entry in self.model.objects.filter(content_type=content_type): 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: - access_entry = self.model.objects.get( + 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), ) - return True 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), @@ -225,9 +254,9 @@ class DefaultAccessEntryManager(models.Manager): 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, @@ -238,13 +267,13 @@ class DefaultAccessEntryManager(models.Manager): access_entry.delete() return True except self.model.DoesNotExist: - return False + 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)] diff --git a/apps/acls/models.py b/apps/acls/models.py index 865e44e567..a255348760 100644 --- a/apps/acls/models.py +++ b/apps/acls/models.py @@ -8,9 +8,7 @@ from django.utils.translation import ugettext from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes import generic from django.core.exceptions import PermissionDenied -from django.core.urlresolvers import reverse from django.core.exceptions import ObjectDoesNotExist -from django.shortcuts import get_object_or_404 from permissions.models import StoredPermission @@ -20,11 +18,11 @@ 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( @@ -59,14 +57,14 @@ class AccessEntry(models.Model): 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( diff --git a/apps/acls/templatetags/acl_tags.py b/apps/acls/templatetags/acl_tags.py index 20e96dbb2f..68ce30263d 100644 --- a/apps/acls/templatetags/acl_tags.py +++ b/apps/acls/templatetags/acl_tags.py @@ -3,7 +3,7 @@ import logging from django.core.exceptions import PermissionDenied from django.template import (TemplateSyntaxError, Library, Node, Variable, VariableDoesNotExist) - + from acls.models import AccessEntry @@ -33,7 +33,7 @@ class CheckAccessNode(Node): 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 diff --git a/apps/acls/urls.py b/apps/acls/urls.py index a544274b5b..ba9aa8be92 100644 --- a/apps/acls/urls.py +++ b/apps/acls/urls.py @@ -5,13 +5,13 @@ urlpatterns = patterns('acls.views', url(r'^list_for/(?P[-\w]+)/(?P[-\w]+)/(?P\d+)/$', 'acl_list', (), 'acl_list'), url(r'^details/(?P[.\w]+)/holder/(?P[.\w]+)/$', 'acl_detail', (), 'acl_detail'), url(r'^holder/new/(?P[.\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[.\w]+)/holder/(?P[.\w]+)/$', 'acl_class_acl_detail', (), 'acl_class_acl_detail'), - url(r'^class/list_for/(?P[.\w]+)/$', 'acl_class_acl_list', (), 'acl_class_acl_list'), + url(r'^class/list_for/(?P[.\w]+)/$', 'acl_class_acl_list', (), 'acl_class_acl_list'), url(r'^class/holder/new/(?P[.\w]+)/$', 'acl_class_new_holder_for', (), 'acl_class_new_holder_for'), url(r'^class/multiple/grant/$', 'acl_class_multiple_grant', (), 'acl_class_multiple_grant'), diff --git a/apps/acls/views.py b/apps/acls/views.py index d0a71b79a7..45af37d086 100644 --- a/apps/acls/views.py +++ b/apps/acls/views.py @@ -1,43 +1,39 @@ from __future__ import absolute_import import logging -import operator -import itertools from django.utils.translation import ugettext_lazy as _ from django.http import HttpResponseRedirect, Http404 from django.shortcuts import render_to_response, get_object_or_404 from django.template import RequestContext from django.contrib import messages -from django.views.generic.list_detail import object_list from django.core.urlresolvers import reverse from django.contrib.contenttypes.models import ContentType -from django.contrib.auth.models import User, Group from django.core.exceptions import ObjectDoesNotExist from django.utils.simplejson import loads from django.core.exceptions import PermissionDenied from django.utils.http import urlencode -from permissions.models import Permission, Role -from common.utils import generate_choices_w_labels, encapsulate +from permissions.models import Permission +from common.utils import encapsulate from common.widgets import two_state_template -from .permissions import (ACLS_EDIT_ACL, ACLS_VIEW_ACL, +from .permissions import (ACLS_EDIT_ACL, ACLS_VIEW_ACL, ACLS_CLASS_EDIT_ACL, ACLS_CLASS_VIEW_ACL) from .models import AccessEntry, DefaultAccessEntry from .classes import (AccessHolder, AccessObject, AccessObjectClass, ClassAccessHolder) from .widgets import object_w_content_type_icon from .forms import HolderSelectionForm -from .api import get_class_permissions_for, get_classes +from .api import get_class_permissions_for logger = logging.getLogger(__name__) def _permission_titles(permission_list): return u', '.join([unicode(permission) for permission in permission_list]) - - + + def acl_list_for(request, obj, extra_context=None): try: Permission.objects.check_permissions(request.user, [ACLS_VIEW_ACL]) @@ -46,7 +42,6 @@ def acl_list_for(request, obj, extra_context=None): logger.debug('obj: %s' % obj) - ct = ContentType.objects.get_for_model(obj) context = { 'object_list': AccessEntry.objects.get_holders_for(obj), 'title': _(u'access control lists for: %s' % obj), @@ -60,14 +55,14 @@ def acl_list_for(request, obj, extra_context=None): 'navigation_object_list': [ {'object': 'object'}, {'object': 'access_object'} - ], + ], } if extra_context: context.update(extra_context) return render_to_response('generic_list.html', context, - context_instance=RequestContext(request)) + context_instance=RequestContext(request)) def acl_list(request, app_label, model_name, object_id): @@ -90,10 +85,10 @@ def acl_detail_for(request, actor, obj): try: Permission.objects.check_permissions(request.user, [ACLS_VIEW_ACL]) except PermissionDenied: - AccessEntry.objects.check_accesses([ACLS_VIEW_ACL], actor, obj) + AccessEntry.objects.check_accesses([ACLS_VIEW_ACL], actor, obj) permission_list = get_class_permissions_for(obj) - + #TODO : get all globally assigned permission, new function get_permissions_for_holder (roles aware) subtemplates_list = [ { @@ -139,7 +134,7 @@ def acl_detail_for(request, actor, obj): context, context_instance=RequestContext(request) ) - + def acl_grant(request): items_property_list = loads(request.GET.get('items_property_list', [])) @@ -152,13 +147,13 @@ def acl_grant(request): title_suffix = [] navigation_object = None navigation_object_count = 0 - + for item_properties in items_property_list: try: permission = Permission.objects.get({'pk': item_properties['permission_pk']}) except Permission.DoesNotExist: - raise Http404 - + raise Http404 + try: requester = AccessHolder.get(gid=item_properties['holder_gid']) access_object = AccessObject.get(gid=item_properties['object_gid']) @@ -184,13 +179,13 @@ def acl_grant(request): items[requester][access_object].append(permission) navigation_object = access_object navigation_object_count += 1 - + for requester, obj_ps in items.items(): for obj, ps in obj_ps.items(): title_suffix.append(_(u', ').join([u'"%s"' % unicode(p) for p in ps])) title_suffix.append(_(u' for %s') % obj) title_suffix.append(_(u' to %s') % requester) - + if len(items_property_list) == 1: title_prefix = _(u'Are you sure you wish to grant the permission %(title_suffix)s?') else: @@ -200,7 +195,7 @@ def acl_grant(request): for requester, object_permissions in items.items(): for obj, permissions in object_permissions.items(): for permission in permissions: - if AccessEntry.objects.grant(permission, requester.source_object, obj.source_object): + if AccessEntry.objects.grant(permission, requester.source_object, obj.source_object): messages.success(request, _(u'Permission "%(permission)s" granted to %(actor)s for %(object)s.') % { 'permission': permission, 'actor': requester, @@ -225,7 +220,7 @@ def acl_grant(request): context['title'] = title_prefix % { 'title_suffix': u''.join(title_suffix), } - + logger.debug('navigation_object_count: %d' % navigation_object_count) logger.debug('navigation_object: %s' % navigation_object) if navigation_object_count == 1: @@ -251,21 +246,21 @@ def acl_revoke(request): try: permission = Permission.objects.get({'pk': item_properties['permission_pk']}) except Permission.DoesNotExist: - raise Http404 + raise Http404 try: requester = AccessHolder.get(gid=item_properties['holder_gid']) access_object = AccessObject.get(gid=item_properties['object_gid']) except ObjectDoesNotExist: raise Http404 - + try: Permission.objects.check_permissions(request.user, [ACLS_EDIT_ACL]) except PermissionDenied: try: AccessEntry.objects.check_access(ACLS_EDIT_ACL, request.user, access_object) except PermissionDenied: - raise + raise else: items.setdefault(requester, {}) items[requester].setdefault(access_object, []) @@ -277,14 +272,14 @@ def acl_revoke(request): items[requester].setdefault(access_object, []) items[requester][access_object].append(permission) navigation_object = access_object - navigation_object_count += 1 - + navigation_object_count += 1 + for requester, obj_ps in items.items(): for obj, ps in obj_ps.items(): title_suffix.append(_(u', ').join([u'"%s"' % unicode(p) for p in ps])) title_suffix.append(_(u' for %s') % obj) title_suffix.append(_(u' from %s') % requester) - + if len(items_property_list) == 1: title_prefix = _(u'Are you sure you wish to revoke the permission %(title_suffix)s?') else: @@ -294,7 +289,7 @@ def acl_revoke(request): for requester, object_permissions in items.items(): for obj, permissions in object_permissions.items(): for permission in permissions: - if AccessEntry.objects.revoke(permission, requester.source_object, obj.source_object): + if AccessEntry.objects.revoke(permission, requester.source_object, obj.source_object): messages.success(request, _(u'Permission "%(permission)s" revoked of %(actor)s for %(object)s.') % { 'permission': permission, 'actor': requester, @@ -319,7 +314,7 @@ def acl_revoke(request): context['title'] = title_prefix % { 'title_suffix': u''.join(title_suffix), } - + logger.debug('navigation_object_count: %d' % navigation_object_count) logger.debug('navigation_object: %s' % navigation_object) if navigation_object_count == 1: @@ -349,7 +344,7 @@ def acl_new_holder_for(request, obj, extra_context=None, navigation_object=None) reverse('acl_detail', args=[access_object.gid, access_holder.gid]), urlencode(query_string) ) - ) + ) except ObjectDoesNotExist: raise Http404 else: @@ -365,12 +360,12 @@ def acl_new_holder_for(request, obj, extra_context=None, navigation_object=None) 'navigation_object_list': [ {'object': 'object'}, {'object': 'access_object'}, - ], + ], } - + if extra_context: context.update(extra_context) - + return render_to_response('generic_form.html', context, context_instance=RequestContext(request)) @@ -381,7 +376,7 @@ def acl_holder_new(request, access_object_gid): except ObjectDoesNotExist: raise Http404 - return acl_new_holder_for(request, access_object.source_object)#, extra_context={'access_object': access_object}) + return acl_new_holder_for(request, access_object.source_object) # , extra_context={'access_object': access_object}) # Setup views @@ -399,12 +394,12 @@ def acl_setup_valid_classes(request): } return render_to_response('generic_list.html', context, - context_instance=RequestContext(request)) + context_instance=RequestContext(request)) def acl_class_acl_list(request, access_object_class_gid): Permission.objects.check_permissions(request.user, [ACLS_CLASS_VIEW_ACL]) - + access_object_class = AccessObjectClass.get(gid=access_object_class_gid) context = { 'object_list': DefaultAccessEntry.objects.get_holders_for(access_object_class.source_object), @@ -419,7 +414,7 @@ def acl_class_acl_list(request, access_object_class_gid): } return render_to_response('generic_list.html', context, - context_instance=RequestContext(request)) + context_instance=RequestContext(request)) def acl_class_acl_detail(request, access_object_class_gid, holder_object_gid): @@ -429,7 +424,7 @@ def acl_class_acl_detail(request, access_object_class_gid, holder_object_gid): access_object_class = AccessObjectClass.get(gid=access_object_class_gid) except ObjectDoesNotExist: raise Http404 - + #permission_list = list(access_object_class.get_class_permissions()) permission_list = get_class_permissions_for(access_object_class.content_type.model_class()) #TODO : get all globally assigned permission, new function get_permissions_for_holder (roles aware) @@ -464,9 +459,9 @@ def acl_class_acl_detail(request, access_object_class_gid, holder_object_gid): 'permission_pk': lambda x: x.pk, 'holder_gid': lambda x: actor.gid, 'access_object_class_gid': lambda x: access_object_class.gid, - }, + }, }, context_instance=RequestContext(request)) - + def acl_class_new_holder_for(request, access_object_class_gid): Permission.objects.check_permissions(request.user, [ACLS_CLASS_EDIT_ACL]) @@ -489,11 +484,11 @@ def acl_class_new_holder_for(request, access_object_class_gid): 'title': _(u'add new holder for class: %s') % unicode(access_object_class), 'object': access_object_class, 'submit_label': _(u'Select'), - 'submit_icon_famfam': 'tick' + 'submit_icon_famfam': 'tick' } - + return render_to_response('generic_form.html', context, - context_instance=RequestContext(request)) + context_instance=RequestContext(request)) def acl_class_multiple_grant(request): @@ -513,25 +508,25 @@ def acl_class_multiple_grant(request): try: permission = Permission.objects.get({'pk': item_properties['permission_pk']}) except Permission.DoesNotExist: - raise Http404 + raise Http404 try: requester = AccessHolder.get(gid=item_properties['holder_gid']) access_object_class = AccessObjectClass.get(gid=item_properties['access_object_class_gid']) except ObjectDoesNotExist: raise Http404 - + items.setdefault(requester, {}) items[requester].setdefault(access_object_class, []) items[requester][access_object_class].append(permission) navigation_object = access_object_class navigation_object_count += 1 - + for requester, obj_ps in items.items(): for obj, ps in obj_ps.items(): title_suffix.append(_(u', ').join([u'"%s"' % unicode(p) for p in ps])) title_suffix.append(_(u' for %s') % obj) title_suffix.append(_(u' to %s') % requester) - + if len(items_property_list) == 1: title_prefix = _(u'Are you sure you wish to grant the permission %(title_suffix)s?') else: @@ -566,7 +561,7 @@ def acl_class_multiple_grant(request): context['title'] = title_prefix % { 'title_suffix': u''.join(title_suffix), } - + logger.debug('navigation_object_count: %d' % navigation_object_count) logger.debug('navigation_object: %s' % navigation_object) if navigation_object_count == 1: @@ -593,25 +588,25 @@ def acl_class_multiple_revoke(request): try: permission = Permission.objects.get({'pk': item_properties['permission_pk']}) except Permission.DoesNotExist: - raise Http404 + raise Http404 try: requester = AccessHolder.get(gid=item_properties['holder_gid']) access_object_class = AccessObjectClass.get(gid=item_properties['access_object_class_gid']) except ObjectDoesNotExist: raise Http404 - + items.setdefault(requester, {}) items[requester].setdefault(access_object_class, []) items[requester][access_object_class].append(permission) navigation_object = access_object_class navigation_object_count += 1 - + for requester, obj_ps in items.items(): for obj, ps in obj_ps.items(): title_suffix.append(_(u', ').join([u'"%s"' % unicode(p) for p in ps])) title_suffix.append(_(u' for %s') % obj) title_suffix.append(_(u' from %s') % requester) - + if len(items_property_list) == 1: title_prefix = _(u'Are you sure you wish to revoke the permission %(title_suffix)s?') else: @@ -621,7 +616,7 @@ def acl_class_multiple_revoke(request): for requester, object_permissions in items.items(): for obj, permissions in object_permissions.items(): for permission in permissions: - if DefaultAccessEntry.objects.revoke(permission, requester.source_object, obj.source_object): + if DefaultAccessEntry.objects.revoke(permission, requester.source_object, obj.source_object): messages.success(request, _(u'Permission "%(permission)s" revoked of %(actor)s for %(object)s.') % { 'permission': permission, 'actor': requester, @@ -646,7 +641,7 @@ def acl_class_multiple_revoke(request): context['title'] = title_prefix % { 'title_suffix': u''.join(title_suffix), } - + logger.debug('navigation_object_count: %d' % navigation_object_count) logger.debug('navigation_object: %s' % navigation_object) if navigation_object_count == 1: diff --git a/apps/acls/widgets.py b/apps/acls/widgets.py index 3c13fce54b..896d99611b 100644 --- a/apps/acls/widgets.py +++ b/apps/acls/widgets.py @@ -1,11 +1,6 @@ from __future__ import absolute_import -from django.utils.translation import ugettext_lazy as _ from django.utils.safestring import mark_safe -from django import forms -from django.forms.util import flatatt -from django.utils.html import conditional_escape -from django.utils.encoding import force_unicode from django.contrib.contenttypes.models import ContentType from django.db.models.base import ModelBase from django.template.defaultfilters import capfirst @@ -28,5 +23,5 @@ def object_w_content_type_icon(obj): label = obj.get_full_name() else: label = unicode(obj) - + return mark_safe('%s%s' % (content_type_icon(content_type), capfirst(label))) diff --git a/apps/common/__init__.py b/apps/common/__init__.py index 9dcd406a4f..928a5d36b7 100644 --- a/apps/common/__init__.py +++ b/apps/common/__init__.py @@ -5,7 +5,6 @@ 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 diff --git a/apps/common/compressed_files.py b/apps/common/compressed_files.py index 6737bbc9ed..2350f1ace1 100644 --- a/apps/common/compressed_files.py +++ b/apps/common/compressed_files.py @@ -1,4 +1,4 @@ -import os, tempfile, zipfile +import zipfile try: import zlib @@ -24,11 +24,11 @@ class CompressedFile(object): 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? @@ -37,7 +37,7 @@ class CompressedFile(object): # If not, try open it. self.descriptor = open(file_input, 'r+b') else: - self.descriptor = file_input + self.descriptor = file_input try: test = zipfile.ZipFile(self.descriptor, mode='r') @@ -54,23 +54,23 @@ class CompressedFile(object): file_input.seek(0) except AttributeError: # If not, keep it - self.zf.write(filename, arcname=arcname, compress_type=COMPRESSION) + 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: + # 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()) diff --git a/apps/common/forms.py b/apps/common/forms.py index 91aff0b67e..11d91d0c2c 100644 --- a/apps/common/forms.py +++ b/apps/common/forms.py @@ -92,10 +92,10 @@ class FilterForm(forms.Form): class ChoiceForm(forms.Form): - ''' + """ Form to be used in side by side templates used to add or remove items from a many to many field - ''' + """ def __init__(self, *args, **kwargs): choices = kwargs.pop('choices', []) label = kwargs.pop('label', _(u'Selection')) @@ -108,28 +108,28 @@ class ChoiceForm(forms.Form): class UserForm_view(DetailForm): - ''' + """ Form used to display an user's public details - ''' + """ class Meta: model = User fields = ('username', 'first_name', 'last_name', 'email', 'is_staff', 'is_superuser', 'last_login', 'date_joined', 'groups') class UserForm(forms.ModelForm): - ''' + """ Form used to edit an user's mininal fields by the user himself - ''' + """ class Meta: model = User fields = ('first_name', 'last_name') class EmailAuthenticationForm(AuthenticationForm): - ''' + """ Override the default authentication form to use email address authentication - ''' + """ email = forms.CharField(label=_(u'Email'), max_length=75, widget=EmailInput() ) @@ -153,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'} ) diff --git a/apps/common/models.py b/apps/common/models.py index cb9a98d91c..effe8196ed 100644 --- a/apps/common/models.py +++ b/apps/common/models.py @@ -34,14 +34,14 @@ class AnonymousUserSingletonManager(SingletonManager): 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') diff --git a/apps/common/templatetags/set_var.py b/apps/common/templatetags/set_var.py index c818a7188c..3d1f8c0084 100644 --- a/apps/common/templatetags/set_var.py +++ b/apps/common/templatetags/set_var.py @@ -1,12 +1,13 @@ 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) @@ -17,7 +18,8 @@ class SetVarNode(template.Node): context.dicts[0][self.var_name] = value return u"" - + + def set_var(parser, token): """ {% set = %} @@ -26,5 +28,5 @@ def set_var(parser, token): if len(parts) < 4: raise template.TemplateSyntaxError("'set' tag must be of the form: {% set = %}") return SetVarNode(parts[1], parts[3]) - + register.tag('set', set_var) diff --git a/apps/common/tests.py b/apps/common/tests.py index 2247054b35..3b31148896 100644 --- a/apps/common/tests.py +++ b/apps/common/tests.py @@ -20,4 +20,3 @@ Another way to test that 1 + 1 is equal to 2. >>> 1 + 1 == 2 True """} - diff --git a/apps/common/utils.py b/apps/common/utils.py index e472a00d3b..3905be558c 100644 --- a/apps/common/utils.py +++ b/apps/common/utils.py @@ -1,4 +1,4 @@ - # -*- coding: utf-8 -*- +# -*- coding: utf-8 -*- from __future__ import absolute_import import os @@ -18,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' @@ -33,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 = [] @@ -112,9 +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). - ''' + """ mc = re.compile(r'^Mc(\w)(?=\w)', re.I) mac = re.compile(r'^Mac(\w)(?=\w)', re.I) suffixes = [ @@ -330,7 +330,7 @@ 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): +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 @@ -342,7 +342,7 @@ def get_object_name(obj, display_object_type=True): 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) diff --git a/apps/common/views.py b/apps/common/views.py index 4d0030b0be..46aa782bad 100644 --- a/apps/common/views.py +++ b/apps/common/views.py @@ -18,19 +18,19 @@ from .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') def multi_object_action_view(request): - ''' + """ Proxy view called first when using a multi object action, which then redirects to the appropiate specialized view - ''' + """ next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', '/'))) @@ -83,7 +83,7 @@ def assign_remove(request, left_list, right_list, add_method, remove_method, lef 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) @@ -109,7 +109,7 @@ def assign_remove(request, left_list, right_list, add_method, remove_method, lef 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) @@ -159,9 +159,9 @@ def assign_remove(request, left_list, right_list, add_method, remove_method, lef def current_user_details(request): - ''' + """ Display the current user's details - ''' + """ form = UserForm_view(instance=request.user) return render_to_response( @@ -174,9 +174,9 @@ def current_user_details(request): def current_user_edit(request): - ''' + """ Allow an user to edit his own details - ''' + """ next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', reverse('current_user_details')))) @@ -199,15 +199,15 @@ 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 - + if not request.user.is_authenticated(): context = {'web_theme_view_type': 'plain'} else: @@ -217,9 +217,9 @@ def login_view(request): def changelog_view(request): - ''' + """ Display the included Changelog.txt file from the about menu - ''' + """ form = ChangelogForm() return render_to_response( 'generic_detail.html', { @@ -230,9 +230,9 @@ def changelog_view(request): def license_view(request): - ''' + """ Display the included LICENSE file from the about menu - ''' + """ form = LicenseForm() return render_to_response( 'generic_detail.html', { diff --git a/apps/common/widgets.py b/apps/common/widgets.py index bfedfaa776..c2f7906c56 100644 --- a/apps/common/widgets.py +++ b/apps/common/widgets.py @@ -10,10 +10,10 @@ from django.utils.encoding import force_unicode 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) @@ -74,11 +74,11 @@ def two_state_template(state, famfam_ok_icon=u'tick', famfam_fail_icon=u'cross') 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'} @@ -98,10 +98,10 @@ 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): @@ -114,13 +114,14 @@ class EmailInput(forms.widgets.Input): class ScrollableCheckboxSelectMultiple(forms.widgets.CheckboxSelectMultiple): - ''' + """ Class for a form widget composed of a selection of checkboxes wrapped in a div tag with automatic overflow to add scrollbars when the list 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'
    '] @@ -141,5 +142,5 @@ class ScrollableCheckboxSelectMultiple(forms.widgets.CheckboxSelectMultiple): option_label = conditional_escape(force_unicode(option_label)) output.append(u'
  • %s %s
  • ' % (label_for, rendered_cb, option_label)) output.append(u'
') - + return mark_safe(u'
%s
' % u'\n'.join(output)) diff --git a/apps/common/wizard.py b/apps/common/wizard.py index 914dcd062a..5454277135 100644 --- a/apps/common/wizard.py +++ b/apps/common/wizard.py @@ -1,4 +1,4 @@ -'''Common abstract classes for forms.''' +"""Common abstract classes for forms.""" try: import cPickle as pickle except ImportError: @@ -15,13 +15,13 @@ __all__ = ('security_hash', 'BoundFormWizard') def security_hash_new(form, exclude=None, *args): - ''' + """ 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 hash of that. - ''' + """ data = [] if exclude is None: @@ -52,20 +52,20 @@ 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. - ''' - + """ + def security_hash(self, request, form): - ''' + """ 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): diff --git a/apps/converter/api.py b/apps/converter/api.py index 8d1239afd2..2c3269fab9 100644 --- a/apps/converter/api.py +++ b/apps/converter/api.py @@ -15,11 +15,11 @@ from .literals import (TRANSFORMATION_CHOICES, TRANSFORMATION_RESIZE, FILE_FORMATS) from .utils import cleanup from .runtime import office_converter -from .exceptions import OfficeConversionError +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)) @@ -42,13 +42,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 +79,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 +87,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) @@ -107,7 +107,7 @@ def get_page_count(input_filepath): except OfficeConversionError: raise UnknownFileFormat('office converter exception') - + return backend.get_page_count(input_filepath) ''' @@ -127,8 +127,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()] - diff --git a/apps/converter/exceptions.py b/apps/converter/exceptions.py index 74b13a7c56..1423d38002 100644 --- a/apps/converter/exceptions.py +++ b/apps/converter/exceptions.py @@ -1,29 +1,29 @@ class ConvertError(Exception): - ''' + """ Base exception for all coverter app exceptions - ''' + """ pass class UnknownFileFormat(ConvertError): - ''' + """ Raised when the converter backend can't understand a file - ''' + """ pass class IdentifyError(ConvertError): - ''' + """ Raised by the graphcismagick and imagemagics identify program - ''' + """ pass class UnkownConvertError(ConvertError): - ''' + """ Raised when an error is found but there is no disernible way to identify the kind of error - ''' + """ pass diff --git a/apps/converter/literals.py b/apps/converter/literals.py index 14df18106d..aa66218874 100644 --- a/apps/converter/literals.py +++ b/apps/converter/literals.py @@ -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'), diff --git a/apps/converter/office_converter.py b/apps/converter/office_converter.py index 8df298ceed..07c7a28f62 100644 --- a/apps/converter/office_converter.py +++ b/apps/converter/office_converter.py @@ -13,14 +13,14 @@ 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', @@ -43,7 +43,7 @@ class OfficeConverter(object): self.exists = False self.mimetype = None self.encoding = None - + def mimetypes(self): return CONVERTER_OFFICE_FILE_MIMETYPES @@ -51,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 @@ -71,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): @@ -91,7 +91,7 @@ class OfficeConverterBackendUnoconv(object): ''' self.input_filepath = input_filepath self.output_filepath = output_filepath - + command = [] command.append(self.unoconv_path) diff --git a/apps/converter/tests.py b/apps/converter/tests.py index 2247054b35..3b31148896 100644 --- a/apps/converter/tests.py +++ b/apps/converter/tests.py @@ -20,4 +20,3 @@ Another way to test that 1 + 1 is equal to 2. >>> 1 + 1 == 2 True """} - diff --git a/apps/django_gpg/__init__.py b/apps/django_gpg/__init__.py index 558dae9371..6448d825da 100644 --- a/apps/django_gpg/__init__.py +++ b/apps/django_gpg/__init__.py @@ -2,10 +2,7 @@ from __future__ import absolute_import from django.utils.translation import ugettext_lazy as _ -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 navigation.api import register_links from project_setup.api import register_setup from hkp import Key as KeyServerKey diff --git a/apps/django_gpg/api.py b/apps/django_gpg/api.py index 329ffe612e..7e188f8d4c 100644 --- a/apps/django_gpg/api.py +++ b/apps/django_gpg/api.py @@ -1,15 +1,10 @@ from __future__ import absolute_import -import types - -from pickle import dumps import logging import tempfile import os -from django.core.files.base import File from django.utils.translation import ugettext_lazy as _ -from django.utils.http import urlquote_plus from hkp import KeyServer import gnupg @@ -73,7 +68,7 @@ SIGNATURE_STATES = { 'text': _(u'Document is signed with a valid signature.'), 'icon': 'document_signature.png' }, -} +} class Key(object): @@ -110,7 +105,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) @@ -162,8 +157,8 @@ class GPG(object): # If not, try open it. return open(file_input, 'rb') else: - return file_input - + return file_input + def __init__(self, binary_path=None, home=None, keyring=None, keyservers=None): kwargs = {} if binary_path: @@ -203,9 +198,9 @@ class GPG(object): ''' Verify the signature of a file. ''' - + input_descriptor = GPG.get_descriptor(file_input) - + if detached_signature: # Save the original data and invert the argument order # Signature first, file second @@ -217,10 +212,10 @@ class GPG(object): verify = self.gpg.verify_file(detached_signature, data_filename=filename) else: verify = self.gpg.verify_file(input_descriptor) - + if close_descriptor: input_descriptor.close() - + if verify: return verify #elif getattr(verify, 'status', None) == 'no public key': @@ -245,7 +240,7 @@ class GPG(object): overrided if it already exists), if no destination file name is provided the signature is returned. ''' - + kwargs = {} kwargs['clearsign'] = clearsign @@ -292,12 +287,12 @@ class GPG(object): result = self.gpg.decrypt_file(input_descriptor) 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') @@ -324,7 +319,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: @@ -336,14 +331,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 diff --git a/apps/django_gpg/forms.py b/apps/django_gpg/forms.py index 619035fd5d..9a9514fdb3 100644 --- a/apps/django_gpg/forms.py +++ b/apps/django_gpg/forms.py @@ -1,9 +1,6 @@ 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): diff --git a/apps/django_gpg/models.py b/apps/django_gpg/models.py index 8b13789179..e69de29bb2 100644 --- a/apps/django_gpg/models.py +++ b/apps/django_gpg/models.py @@ -1 +0,0 @@ - diff --git a/apps/django_gpg/views.py b/apps/django_gpg/views.py index 60d400b018..e3dcd4981e 100644 --- a/apps/django_gpg/views.py +++ b/apps/django_gpg/views.py @@ -1,22 +1,16 @@ from __future__ import absolute_import -from datetime import datetime import logging from django.utils.translation import ugettext_lazy as _ from django.http import HttpResponseRedirect -from django.shortcuts import render_to_response, get_object_or_404 +from django.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 permissions.models import Permission -from common.utils import pretty_size, parse_range, urlquote, \ - return_diff, encapsulate - +from common.utils import (urlquote, encapsulate) + from .api import Key, SIGNATURE_STATES from .runtime import gpg from .exceptions import (GPGVerificationError, KeyFetchingError, @@ -30,7 +24,7 @@ logger = logging.getLogger(__name__) def key_receive(request, key_id): 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', '/'))) @@ -54,13 +48,13 @@ def key_receive(request, key_id): 'next': next, 'previous': previous, 'submit_method': 'GET', - + }, context_instance=RequestContext(request)) - + def key_list(request, secret=True): Permission.objects.check_permissions(request.user, [PERMISSION_KEY_VIEW]) - + if secret: object_list = Key.get_all(gpg, secret=True) title = _(u'private keys') @@ -87,7 +81,7 @@ def key_list(request, secret=True): def key_delete(request, fingerprint, key_type): Permission.objects.check_permissions(request.user, [PERMISSION_KEY_DELETE]) - + secret = key_type == 'sec' key = Key.get(gpg, fingerprint, secret=secret) @@ -116,7 +110,7 @@ def key_delete(request, fingerprint, key_type): def key_query(request): Permission.objects.check_permissions(request.user, [PERMISSION_KEYSERVER_QUERY]) - + subtemplates_list = [] term = request.GET.get('term') @@ -130,8 +124,8 @@ def key_query(request): 'submit_method': 'GET', }, } - ) - + ) + if term: results = gpg.query(term) subtemplates_list.append( @@ -153,36 +147,36 @@ 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, diff --git a/apps/document_acls/__init__.py b/apps/document_acls/__init__.py index a904759f4d..376b048843 100644 --- a/apps/document_acls/__init__.py +++ b/apps/document_acls/__init__.py @@ -1,8 +1,7 @@ from django.utils.translation import ugettext_lazy as _ from documents.models import Document -from navigation.api import register_links, register_multi_item_links -from project_setup.api import register_setup +from navigation.api import register_links from acls import ACLS_VIEW_ACL, ACLS_EDIT_ACL from acls.api import class_permissions diff --git a/apps/document_acls/views.py b/apps/document_acls/views.py index 4b20a038ee..5938fec434 100644 --- a/apps/document_acls/views.py +++ b/apps/document_acls/views.py @@ -1,17 +1,16 @@ -from django.shortcuts import render_to_response, get_object_or_404 +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 -from acls.models import AccessEntry 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, - } - ) + document = get_object_or_404(Document, pk=document_id) + return acl_list_for( + request, + document, + extra_context={ + 'object': document, + } + ) diff --git a/apps/document_comments/__init__.py b/apps/document_comments/__init__.py index 6758a06811..2356f36885 100644 --- a/apps/document_comments/__init__.py +++ b/apps/document_comments/__init__.py @@ -6,7 +6,6 @@ from django.contrib.comments.models import Comment from django.contrib.contenttypes import generic from navigation.api import register_links, register_model_list_columns -from permissions.models import PermissionNamespace, Permission from common.utils import encapsulate from acls.api import class_permissions from documents.models import Document @@ -16,7 +15,7 @@ if 'django.contrib.comments' not in settings.INSTALLED_APPS: from .permissions import (PERMISSION_COMMENT_CREATE, PERMISSION_COMMENT_DELETE, PERMISSION_COMMENT_VIEW) - + comment_delete = {'text': _('delete'), 'view': 'comment_delete', 'args': 'object.pk', 'famfam': 'comment_delete', 'permissions': [PERMISSION_COMMENT_DELETE]} comment_multiple_delete = {'text': _('delete'), 'view': 'comment_multiple_delete', 'args': 'object.pk', 'famfam': 'comments_delete', 'permissions': [PERMISSION_COMMENT_DELETE]} comment_add = {'text': _('add comment'), 'view': 'comment_add', 'args': 'object.pk', 'famfam': 'comment_add', 'permissions': [PERMISSION_COMMENT_CREATE]} diff --git a/apps/document_comments/views.py b/apps/document_comments/views.py index cb9cc0a92e..7c089b3cda 100644 --- a/apps/document_comments/views.py +++ b/apps/document_comments/views.py @@ -31,7 +31,7 @@ def comment_delete(request, comment_id=None, comment_id_list=None): Permission.objects.check_permissions(request.user, [PERMISSION_COMMENT_DELETE]) except PermissionDenied: comments = AccessEntry.objects.filter_objects_by_access(PERMISSION_COMMENT_DELETE, request.user, comments, related='content_object') - + if not comments: messages.error(request, _(u'Must provide at least one comment.')) return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) @@ -81,7 +81,7 @@ def comment_add(request, document_id): Permission.objects.check_permissions(request.user, [PERMISSION_COMMENT_CREATE]) except PermissionDenied: AccessEntry.objects.check_access(PERMISSION_COMMENT_CREATE, request.user, document) - + post_action_redirect = None next = request.POST.get('next', request.GET.get('next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', '/'))) diff --git a/apps/document_indexing/filesystem.py b/apps/document_indexing/filesystem.py index 4b24a9d4d6..7c732007cc 100644 --- a/apps/document_indexing/filesystem.py +++ b/apps/document_indexing/filesystem.py @@ -40,7 +40,7 @@ def fs_create_document_link(index_instance, document, suffix=0): if FILESERVING_ENABLE: filename = assemble_suffixed_filename(document.file.name, suffix) filepath = assemble_path_from_list([FILESERVING_PATH, get_instance_path(index_instance), filename]) - + try: os.symlink(document.file.path, filepath) except OSError, exc: diff --git a/apps/document_indexing/os_specifics.py b/apps/document_indexing/os_specifics.py index 97bdc426e4..d57eae409c 100644 --- a/apps/document_indexing/os_specifics.py +++ b/apps/document_indexing/os_specifics.py @@ -6,16 +6,16 @@ from .conf.settings import SUFFIX_SEPARATOR def assemble_suffixed_filename(filename, suffix=0): - ''' + """ Split document filename, to attach suffix to the name part then re attacht the extension - ''' - + """ + if suffix: name, extension = filename.split(os.split(os.extsep)) return SUFFIX_SEPARATOR.join([name, unicode(suffix), os.extsep, extension]) else: - return file_filename + return filename def assemble_path_from_list(directory_list): diff --git a/apps/document_indexing/tests.py b/apps/document_indexing/tests.py index 2247054b35..3b31148896 100644 --- a/apps/document_indexing/tests.py +++ b/apps/document_indexing/tests.py @@ -20,4 +20,3 @@ Another way to test that 1 + 1 is equal to 2. >>> 1 + 1 == 2 True """} - diff --git a/apps/document_indexing/views.py b/apps/document_indexing/views.py index 0505ad5cac..8d405fc3d5 100644 --- a/apps/document_indexing/views.py +++ b/apps/document_indexing/views.py @@ -59,7 +59,7 @@ def index_instance_list(request, index_id=None): }, { 'name': _(u'items'), - 'attribute': encapsulate(lambda x: x.documents.count() if x.index.link_documents else x.get_children().count() ) + 'attribute': encapsulate(lambda x: x.documents.count() if x.index.link_documents else x.get_children().count()) } ], 'title': title, diff --git a/apps/document_signatures/__init__.py b/apps/document_signatures/__init__.py index cd9a120cc3..ac4eb1413e 100644 --- a/apps/document_signatures/__init__.py +++ b/apps/document_signatures/__init__.py @@ -72,7 +72,7 @@ def document_post_save_hook(instance): if not instance.pk: document_signature, created = DocumentVersionSignature.objects.get_or_create( document_version=instance.latest_version, - ) + ) #DocumentVersionSignature.objects.update_signed_state(instance.document) #@receiver(post_save, dispatch_uid='check_document_signature_state', sender=DocumentVersion) diff --git a/apps/document_signatures/managers.py b/apps/document_signatures/managers.py index 915fba4644..f1c7bd39dc 100644 --- a/apps/document_signatures/managers.py +++ b/apps/document_signatures/managers.py @@ -13,12 +13,12 @@ class DocumentVersionSignatureManager(models.Manager): document_signature, created = self.model.objects.get_or_create( document_version=document.latest_version, ) - + return document_signature - + def add_detached_signature(self, document, detached_signature): document_signature = self.get_document_signature(document) - + if document_signature.has_embedded_signature: raise Exception('document already has an embedded signature') else: @@ -27,13 +27,13 @@ class DocumentVersionSignatureManager(models.Manager): document_signature.delete_detached_signature() document_signature.signature_file = None document_signature.save() - + document_signature.signature_file = detached_signature document_signature.save() def has_detached_signature(self, document): document_signature = self.get_document_signature(document) - + if document_signature.signature_file: return True else: @@ -43,12 +43,12 @@ class DocumentVersionSignatureManager(models.Manager): logger.debug('document: %s' % document) document_signature = self.get_document_signature(document) - + return document_signature.has_embedded_signature def detached_signature(self, document): document_signature = self.get_document_signature(document) - + return document_signature.signature_file.storage.open(document_signature.signature_file.path) def verify_signature(self, document): diff --git a/apps/document_signatures/migrations/0002_move_signatures_to_new_app.py b/apps/document_signatures/migrations/0002_move_signatures_to_new_app.py index 06cc84f703..e48ba547b2 100644 --- a/apps/document_signatures/migrations/0002_move_signatures_to_new_app.py +++ b/apps/document_signatures/migrations/0002_move_signatures_to_new_app.py @@ -23,14 +23,10 @@ class Migration(DataMigration): def backwards(self, orm): for document_signature in orm.DocumentVersionSignature.objects.all(): - try: - document_version = orm['documents.DocumentVersion'].objects.get(document_version=document_version) - except orm['documents.DocumentVersion'].DoesNotExists: - pass - else: - document_version.signature_state=document_signature.signature_state - document_version.signature_file=document_signature.signature_file - document_version.save() + document_version = document_signature.document_version + document_version.signature_state=document_signature.signature_state + document_version.signature_file=document_signature.signature_file + document_version.save() models = { diff --git a/apps/document_signatures/models.py b/apps/document_signatures/models.py index 2c15523574..7ae215f675 100644 --- a/apps/document_signatures/models.py +++ b/apps/document_signatures/models.py @@ -14,9 +14,9 @@ logger = logging.getLogger(__name__) class DocumentVersionSignature(models.Model): - ''' + """ Model that describes a document version signature properties - ''' + """ document_version = models.ForeignKey(DocumentVersion, verbose_name=_(u'document version'), editable=False) signature_file = models.FileField(blank=True, null=True, upload_to=get_filename_from_uuid, storage=STORAGE_BACKEND(), verbose_name=_(u'signature file'), editable=False) has_embedded_signature = models.BooleanField(default=False, verbose_name=_(u'has embedded signature'), editable=False) @@ -28,7 +28,7 @@ class DocumentVersionSignature(models.Model): def save(self, *args, **kwargs): if not self.pk: - self.has_embedded_signature = gpg.has_embedded_signature(self.document_version.open(raw=True)) + self.has_embedded_signature = gpg.has_embedded_signature(self.document_version.open(raw=True)) super(DocumentVersionSignature, self).save(*args, **kwargs) class Meta: diff --git a/apps/document_signatures/views.py b/apps/document_signatures/views.py index fc33c87a2a..024f59ffb4 100644 --- a/apps/document_signatures/views.py +++ b/apps/document_signatures/views.py @@ -117,7 +117,7 @@ def document_signature_download(request, document_pk): try: Permission.objects.check_permissions(request.user, [PERMISSION_SIGNATURE_DOWNLOAD]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_SIGNATURE_DOWNLOAD, request.user, document) + AccessEntry.objects.check_access(PERMISSION_SIGNATURE_DOWNLOAD, request.user, document) try: if DocumentVersionSignature.objects.has_detached_signature(document): diff --git a/apps/documents/__init__.py b/apps/documents/__init__.py index 1d052cfa24..f7f1e4a043 100644 --- a/apps/documents/__init__.py +++ b/apps/documents/__init__.py @@ -34,6 +34,8 @@ from .conf import settings as document_settings from .widgets import document_thumbnail # Document page links expressions + + def is_first_page(context): return context['page'].page_number <= 1 @@ -179,7 +181,7 @@ register_top_menu( r'^documents/[^t]', r'^metadata/[^s]', r'comments', r'tags/document', r'grouping/[^s]', r'history/list/for_object/documents' ], #children_view_regex=[r'upload'], - children_views=['document_folder_list', 'folder_add_document', 'document_index_list', 'upload_version',], + children_views=['document_folder_list', 'folder_add_document', 'document_index_list', 'upload_version', ], position=1 ) @@ -197,7 +199,7 @@ if (validate_path(document_settings.CACHE_PATH) == False) or (not document_setti register_setup(document_type_setup) class_permissions(Document, [ - PERMISSION_DOCUMENT_PROPERTIES_EDIT, + PERMISSION_DOCUMENT_PROPERTIES_EDIT, PERMISSION_DOCUMENT_EDIT, PERMISSION_DOCUMENT_VIEW, PERMISSION_DOCUMENT_DELETE, @@ -205,5 +207,5 @@ class_permissions(Document, [ PERMISSION_DOCUMENT_TRANSFORM, PERMISSION_DOCUMENT_NEW_VERSION, PERMISSION_DOCUMENT_VERSION_REVERT, - PERMISSION_HISTORY_VIEW + PERMISSION_HISTORY_VIEW ]) diff --git a/apps/documents/admin.py b/apps/documents/admin.py index 40ac5d0a2b..91ee0ac22c 100644 --- a/apps/documents/admin.py +++ b/apps/documents/admin.py @@ -25,8 +25,8 @@ class DocumentVersionInline(admin.StackedInline): #inlines = [ # DocumentPageInline, #] - - + + class DocumentTypeFilenameInline(admin.StackedInline): model = DocumentTypeFilename extra = 1 diff --git a/apps/documents/forms.py b/apps/documents/forms.py index 88cfa46395..398e9f59ae 100644 --- a/apps/documents/forms.py +++ b/apps/documents/forms.py @@ -5,13 +5,11 @@ 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 from common.forms import DetailForm from common.literals import PAGE_SIZE_CHOICES, PAGE_ORIENTATION_CHOICES -from common.conf.settings import DEFAULT_PAPER_SIZE -from common.conf.settings import DEFAULT_PAGE_ORIENTATION -from common.widgets import TextAreaDiv +from common.conf.settings import DEFAULT_PAPER_SIZE, DEFAULT_PAGE_ORIENTATION +from common.widgets import TextAreaDiv from .models import (Document, DocumentType, DocumentPage, DocumentPageTransformation, DocumentTypeFilename, @@ -19,6 +17,7 @@ from .models import (Document, DocumentType, from .widgets import document_html_widget from .literals import (RELEASE_LEVEL_FINAL, RELEASE_LEVEL_CHOICES) + # Document page forms class DocumentPageTransformationForm(forms.ModelForm): class Meta: @@ -105,7 +104,7 @@ class DocumentPagesCarouselWidget(forms.widgets.Widget): output.append(u'
') for page in value.pages.all(): - + output.append(u'
') output.append(u'
%(page_string)s %(page)s
' % {'page_string': ugettext(u'Page'), 'page': page.page_number}) output.append( @@ -180,24 +179,24 @@ class DocumentForm(forms.ModelForm): if instance: self.version_fields(instance) - + def version_fields(self, document): self.fields['version_update'] = forms.ChoiceField( label=_(u'Version update'), choices=DocumentVersion.get_version_update_choices(document.latest_version) ) - + self.fields['release_level'] = forms.ChoiceField( label=_(u'Release level'), choices=RELEASE_LEVEL_CHOICES, initial=RELEASE_LEVEL_FINAL, ) - + self.fields['serial'] = forms.IntegerField( label=_(u'Release level serial'), initial=0, widget=forms.widgets.TextInput( - attrs = {'style': 'width: auto;'} + attrs={'style': 'width: auto;'} ), ) @@ -210,7 +209,7 @@ class DocumentForm(forms.ModelForm): new_filename = forms.CharField( label=_('New document filename'), required=False ) - + def clean(self): cleaned_data = self.cleaned_data cleaned_data['new_version_data'] = { @@ -221,7 +220,8 @@ class DocumentForm(forms.ModelForm): } # Always return the full collection of cleaned data. - return cleaned_data + return cleaned_data + class DocumentForm_edit(DocumentForm): """ @@ -230,7 +230,7 @@ class DocumentForm_edit(DocumentForm): class Meta: model = Document exclude = ('file', 'document_type', 'tags') - + def __init__(self, *args, **kwargs): super(DocumentForm_edit, self).__init__(*args, **kwargs) self.fields.pop('serial') diff --git a/apps/documents/managers.py b/apps/documents/managers.py index b564d44885..83555b9568 100644 --- a/apps/documents/managers.py +++ b/apps/documents/managers.py @@ -4,7 +4,6 @@ from ast import literal_eval from datetime import datetime from django.db import models -from django.contrib.auth.models import AnonymousUser from .conf.settings import RECENT_COUNT @@ -18,7 +17,7 @@ class RecentDocumentManager(models.Manager): to_delete = self.model.objects.filter(user=user)[RECENT_COUNT:] for recent_to_delete in to_delete: recent_to_delete.delete() - + def get_for_user(self, user): if user.is_authenticated(): return [recent_document.document for recent_document in self.model.objects.filter(user=user)] diff --git a/apps/documents/models.py b/apps/documents/models.py index 963a5e056f..135e2e3825 100644 --- a/apps/documents/models.py +++ b/apps/documents/models.py @@ -11,8 +11,8 @@ import logging try: from cStringIO import StringIO except ImportError: - from StringIO import StringIO - + from StringIO import StringIO + from django.db import models from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext @@ -30,7 +30,7 @@ from converter.literals import (DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION, DEFAULT_PAGE_NUMBER) from .conf.settings import (CHECKSUM_FUNCTION, UUID_FUNCTION, - STORAGE_BACKEND, PREVIEW_SIZE, DISPLAY_SIZE, CACHE_PATH, + STORAGE_BACKEND, DISPLAY_SIZE, CACHE_PATH, ZOOM_MAX_LEVEL, ZOOM_MIN_LEVEL) from .managers import (RecentDocumentManager, DocumentPageTransformationManager) @@ -70,9 +70,9 @@ class DocumentType(models.Model): class Document(models.Model): - ''' + """ Defines a single document with it's fields and properties - ''' + """ uuid = models.CharField(max_length=48, blank=True, editable=False) document_type = models.ForeignKey(DocumentType, verbose_name=_(u'document type'), null=True, blank=True) description = models.TextField(blank=True, null=True, verbose_name=_(u'description')) @@ -133,7 +133,7 @@ class Document(models.Model): zoom = ZOOM_MAX_LEVEL rotation = rotation % 360 - + try: file_path = self.get_valid_image(size=size, page=page, zoom=zoom, rotation=rotation, version=version) except UnknownFileFormat: @@ -142,7 +142,7 @@ class Document(models.Model): file_path = get_error_icon_file_path() except: file_path = get_error_icon_file_path() - + if as_base64: image = open(file_path, 'r') out = StringIO() @@ -159,16 +159,16 @@ class Document(models.Model): def add_as_recent_document_for_user(self, user): RecentDocument.objects.add_document_for_user(user, self) - + def delete(self, *args, **kwargs): for version in self.versions.all(): version.delete() return super(Document, self).delete(*args, **kwargs) - + @property def size(self): return self.latest_version.size - + def new_version(self, file, comment=None, version_update=None, release_level=None, serial=None): logger.debug('creating new document version') if version_update: @@ -177,12 +177,12 @@ class Document(models.Model): new_version = DocumentVersion( document=self, file=file, - major = new_version_dict.get('major'), - minor = new_version_dict.get('minor'), - micro = new_version_dict.get('micro'), - release_level = release_level, - serial = serial, - comment = comment, + major=new_version_dict.get('major'), + minor=new_version_dict.get('minor'), + micro=new_version_dict.get('micro'), + release_level=release_level, + serial=serial, + comment=comment, ) new_version.save() else: @@ -198,20 +198,20 @@ class Document(models.Model): # Proxy methods def open(self, *args, **kwargs): - ''' + """ Return a file descriptor to a document's file irrespective of the storage backend - ''' + """ return self.latest_version.open(*args, **kwargs) - + def save_to_file(self, *args, **kwargs): return self.latest_version.save_to_file(*args, **kwargs) def exists(self): - ''' - Returns a boolean value that indicates if the document's + """ + Returns a boolean value that indicates if the document's latest version file exists in storage - ''' + """ return self.latest_version.exists() # Compatibility methods @@ -226,7 +226,7 @@ class Document(models.Model): @property def file_mime_encoding(self): return self.latest_version.encoding - + @property def file_filename(self): return self.latest_version.filename @@ -275,12 +275,12 @@ class Document(models.Model): class DocumentVersion(models.Model): - ''' + """ Model that describes a document version and its properties - ''' + """ _pre_open_hooks = {} _post_save_hooks = {} - + @staticmethod def get_version_update_choices(document_version): return ( @@ -288,7 +288,7 @@ class DocumentVersion(models.Model): (VERSION_UPDATE_MINOR, _(u'Minor %(major)i.%(minor)i, (some updates)') % document_version.get_new_version_dict(VERSION_UPDATE_MINOR)), (VERSION_UPDATE_MICRO, _(u'Micro %(major)i.%(minor)i.%(micro)i, (fixes)') % document_version.get_new_version_dict(VERSION_UPDATE_MICRO)) ) - + @classmethod def register_pre_open_hook(cls, order, func): cls._pre_open_hooks[order] = func @@ -296,7 +296,7 @@ class DocumentVersion(models.Model): @classmethod def register_post_save_hook(cls, order, func): cls._post_save_hooks[order] = func - + document = models.ForeignKey(Document, verbose_name=_(u'document'), editable=False) major = models.PositiveIntegerField(verbose_name=_(u'mayor'), default=1, editable=False) minor = models.PositiveIntegerField(verbose_name=_(u'minor'), default=0, editable=False) @@ -305,7 +305,7 @@ class DocumentVersion(models.Model): serial = models.PositiveIntegerField(verbose_name=_(u'serial'), default=0, editable=False) timestamp = models.DateTimeField(verbose_name=_(u'timestamp'), editable=False) comment = models.TextField(blank=True, verbose_name=_(u'comment')) - + # File related fields file = models.FileField(upload_to=get_filename_from_uuid, storage=STORAGE_BACKEND(), verbose_name=_(u'file')) mimetype = models.CharField(max_length=64, default='', editable=False) @@ -342,11 +342,11 @@ class DocumentVersion(models.Model): 'minor': self.minor, 'micro': self.micro + 1, } - + def get_formated_version(self): - ''' + """ Return the formatted version information - ''' + """ vers = [u'%i.%i' % (self.major, self.minor), ] if self.micro: @@ -360,10 +360,10 @@ class DocumentVersion(models.Model): return self.documentpage_set def save(self, *args, **kwargs): - ''' + """ Overloaded save method that updates the document version's checksum, mimetype, page count and transformation when created - ''' + """ new_document = not self.pk if not self.pk: self.timestamp = datetime.datetime.now() @@ -371,9 +371,9 @@ class DocumentVersion(models.Model): #Only do this for new documents transformations = kwargs.pop('transformations', None) super(DocumentVersion, self).save(*args, **kwargs) - + for key in sorted(DocumentVersion._post_save_hooks): - DocumentVersion._post_save_hooks[key](self) + DocumentVersion._post_save_hooks[key](self) if new_document: #Only do this for new documents @@ -385,10 +385,10 @@ class DocumentVersion(models.Model): self.apply_default_transformations(transformations) def update_checksum(self, save=True): - ''' + """ Open a document version's file and update the checksum field using the user provided checksum function - ''' + """ if self.exists(): source = self.open() self.checksum = unicode(CHECKSUM_FUNCTION(source.read())) @@ -444,17 +444,17 @@ class DocumentVersion(models.Model): page_transformation.save() def revert(self): - ''' + """ Delete the subsequent versions after this one - ''' + """ for version in self.document.versions.filter(timestamp__gt=self.timestamp): version.delete() def update_mimetype(self, save=True): - ''' + """ Read a document verions's file and determine the mimetype by calling the get_mimetype wrapper - ''' + """ if self.exists(): try: self.mimetype, self.encoding = get_mimetype(self.open(), self.filename) @@ -466,35 +466,35 @@ class DocumentVersion(models.Model): self.save() def delete(self, *args, **kwargs): - self.file.storage.delete(self.file.path) + self.file.storage.delete(self.file.path) return super(DocumentVersion, self).delete(*args, **kwargs) def exists(self): - ''' + """ Returns a boolean value that indicates if the document's file exists in storage - ''' + """ return self.file.storage.exists(self.file.path) - + def open(self, raw=False): - ''' + """ Return a file descriptor to a document version's file irrespective of the storage backend - ''' + """ if raw: return self.file.storage.open(self.file.path) else: result = self.file.storage.open(self.file.path) for key in sorted(DocumentVersion._pre_open_hooks): result = DocumentVersion._pre_open_hooks[key](result, self) - + return result def save_to_file(self, filepath, buffer_size=1024 * 1024): - ''' + """ Save a copy of the document from the document storage backend to the local filesystem - ''' + """ input_descriptor = self.open() output_descriptor = open(filepath, 'wb') while True: @@ -507,7 +507,7 @@ class DocumentVersion(models.Model): output_descriptor.close() input_descriptor.close() return filepath - + @property def size(self): if self.exists(): @@ -517,10 +517,10 @@ class DocumentVersion(models.Model): class DocumentTypeFilename(models.Model): - ''' + """ List of filenames available to a specific document type for the quick rename functionality - ''' + """ document_type = models.ForeignKey(DocumentType, verbose_name=_(u'document type')) filename = models.CharField(max_length=128, verbose_name=_(u'filename'), db_index=True) enabled = models.BooleanField(default=True, verbose_name=_(u'enabled')) @@ -535,12 +535,12 @@ class DocumentTypeFilename(models.Model): class DocumentPage(models.Model): - ''' + """ Model that describes a document version page including it's content - ''' + """ # New parent field document_version = models.ForeignKey(DocumentVersion, verbose_name=_(u'document version')) - + # Unchanged fields content = models.TextField(blank=True, null=True, verbose_name=_(u'content')) page_label = models.CharField(max_length=32, blank=True, null=True, verbose_name=_(u'page label')) @@ -568,7 +568,7 @@ class DocumentPage(models.Model): @property def siblings(self): return DocumentPage.objects.filter(document_version=self.document_version) - + # Compatibility methods @property def document(self): diff --git a/apps/documents/tests.py b/apps/documents/tests.py index 8f03074fa6..f8c7164cdb 100644 --- a/apps/documents/tests.py +++ b/apps/documents/tests.py @@ -3,7 +3,6 @@ from __future__ import absolute_import import os from django.utils import unittest -from django.test.client import Client from django.conf import settings from django.core.files.base import File @@ -19,45 +18,45 @@ class DocumentTestCase(unittest.TestCase): self.document_type.save() self.document = Document( - document_type = self.document_type, - description = 'description', + document_type=self.document_type, + description='description', ) self.document.save() #return File(file(self.filepath, 'rb'), name=self.filename) file_object = open(os.path.join(settings.PROJECT_ROOT, 'contrib', 'mayan_11_1.pdf')) new_version = self.document.new_version(file=File(file_object, name='mayan_11_1.pdf')) - file_object.close() + file_object.close() def runTest(self): self.failUnlessEqual(self.document_type.name, 'test doc type') self.failUnlessEqual(self.document.exists(), True) self.failUnlessEqual(self.document.size, 272213) - + self.failUnlessEqual(self.document.file_mimetype, 'application/pdf') self.failUnlessEqual(self.document.file_mime_encoding, 'binary') self.failUnlessEqual(self.document.file_filename, 'mayan_11_1.pdf') self.failUnlessEqual(self.document.checksum, 'c637ffab6b8bb026ed3784afdb07663fddc60099853fae2be93890852a69ecf3') self.failUnlessEqual(self.document.page_count, 47) - + self.failUnlessEqual(self.document.latest_version.get_formated_version(), '1.0') self.failUnlessEqual(self.document.has_detached_signature(), False) - + file_object = open(os.path.join(settings.PROJECT_ROOT, 'contrib', 'mayan_11_1.pdf.gpg')) new_version_data = { 'comment': 'test comment 1', 'version_update': VERSION_UPDATE_MAJOR, 'release_level': RELEASE_LEVEL_FINAL, 'serial': 0, - } - + } + new_version = self.document.new_version(file=File(file_object, name='mayan_11_1.pdf.gpg'), **new_version_data) file_object.close() self.failUnlessEqual(self.document.latest_version.get_formated_version(), '2.0') self.failUnlessEqual(self.document.has_detached_signature(), False) - + self.failUnlessEqual(self.document.verify_signature().status, SIGNATURE_STATE_VALID) new_version_data = { @@ -65,23 +64,22 @@ class DocumentTestCase(unittest.TestCase): 'version_update': VERSION_UPDATE_MAJOR, 'release_level': RELEASE_LEVEL_FINAL, 'serial': 0, - } + } file_object = open(os.path.join(settings.PROJECT_ROOT, 'contrib', 'mayan_11_1.pdf')) new_version = self.document.new_version(file=File(file_object), **new_version_data) file_object.close() self.failUnlessEqual(self.document.latest_version.get_formated_version(), '3.0') - + #GPGVerificationError self.failUnlessEqual(self.document.verify_signature(), None) - + file_object = open(os.path.join(settings.PROJECT_ROOT, 'contrib', 'mayan_11_1.pdf.sig'), 'rb') new_version = self.document.add_detached_signature(File(file_object)) file_object.close() - + self.failUnlessEqual(self.document.has_detached_signature(), True) - self.failUnlessEqual(self.document.verify_signature().status, SIGNATURE_STATE_VALID) - - + self.failUnlessEqual(self.document.verify_signature().status, SIGNATURE_STATE_VALID) + def tearDown(self): self.document.delete() diff --git a/apps/documents/urls.py b/apps/documents/urls.py index 046d274dd8..0303438fdd 100644 --- a/apps/documents/urls.py +++ b/apps/documents/urls.py @@ -33,7 +33,7 @@ urlpatterns = patterns('documents.views', url(r'^(?P\d+)/create/siblings/$', 'document_create_siblings', (), 'document_create_siblings'), url(r'^(?P\d+)/find_duplicates/$', 'document_find_duplicates', (), 'document_find_duplicates'), url(r'^(?P\d+)/clear_transformations/$', 'document_clear_transformations', (), 'document_clear_transformations'), - + url(r'^(?P\d+)/version/all/$', 'document_version_list', (), 'document_version_list'), url(r'^document/version/(?P\d+)/download/$', 'document_download', (), 'document_version_download'), url(r'^document/version/(?P\d+)/revert/$', 'document_version_revert', (), 'document_version_revert'), diff --git a/apps/documents/views.py b/apps/documents/views.py index 2ccecd62bf..c33554edc1 100644 --- a/apps/documents/views.py +++ b/apps/documents/views.py @@ -48,10 +48,10 @@ from .literals import (HISTORY_DOCUMENT_CREATED, HISTORY_DOCUMENT_EDITED, HISTORY_DOCUMENT_DELETED) from .forms import (DocumentTypeSelectForm, DocumentForm_edit, DocumentPropertiesForm, - DocumentPreviewForm, DocumentPageForm, - DocumentPageTransformationForm, DocumentContentForm, - DocumentPageForm_edit, DocumentPageForm_text, PrintForm, - DocumentTypeForm, DocumentTypeFilenameForm, + DocumentPreviewForm, DocumentPageForm, + DocumentPageTransformationForm, DocumentContentForm, + DocumentPageForm_edit, DocumentPageForm_text, PrintForm, + DocumentTypeForm, DocumentTypeFilenameForm, DocumentTypeFilenameForm_create) from .wizards import DocumentCreateWizard from .models import (Document, DocumentType, DocumentPage, @@ -68,12 +68,12 @@ def document_list(request, object_list=None, title=None, extra_context=None): Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW]) except PermissionDenied: # If user doesn't have global permission, get a list of document - # for which he/she does hace access use it to filter the + # for which he/she does hace access use it to filter the # provided object_list final_object_list = AccessEntry.objects.filter_objects_by_access(PERMISSION_DOCUMENT_VIEW, request.user, pre_object_list) else: final_object_list = pre_object_list - + context = { 'object_list': final_object_list, 'title': title if title else _(u'documents'), @@ -190,7 +190,7 @@ def document_delete(request, document_id=None, document_id_list=None): documents = [get_object_or_404(Document, pk=document_id)] post_action_redirect = reverse('document_list') elif document_id_list: - documents = [get_object_or_404(Document, pk=document_id) for document_id in document_id_list.split(',')] + documents = [get_object_or_404(Document, pk=document_id) for document_id in document_id_list.split(',')] else: messages.error(request, _(u'Must provide at least one document.')) return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) @@ -296,12 +296,12 @@ def get_document_image(request, document_id, size=PREVIEW_SIZE, base64_version=F try: Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document) + AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document) page = int(request.GET.get('page', DEFAULT_PAGE_NUMBER)) zoom = int(request.GET.get('zoom', DEFAULT_ZOOM_LEVEL)) - + version = int(request.GET.get('version', document.latest_version.pk)) if zoom < ZOOM_MIN_LEVEL: @@ -317,12 +317,12 @@ def get_document_image(request, document_id, size=PREVIEW_SIZE, base64_version=F else: # TODO: fix hardcoded MIMETYPE return sendfile.sendfile(request, document.get_image(size=size, page=page, zoom=zoom, rotation=rotation, version=version), mimetype=DEFAULT_FILE_FORMAT_MIMETYPE) - + def document_download(request, document_id=None, document_id_list=None, document_version_pk=None): document_version = None documents = [] - + if document_id: documents = [get_object_or_404(Document, pk=document_id)] post_action_redirect = reverse('document_list') @@ -338,7 +338,7 @@ def document_download(request, document_id=None, document_id_list=None, document if len(documents) == 1: document_version = documents[0].latest_version - + if document_version: try: # Test permissions and trigger exception @@ -363,9 +363,9 @@ def document_download(request, document_id=None, document_id_list=None, document descriptor = document.open() compressed_file.add_file(descriptor, arcname=document.filename) descriptor.close() - + compressed_file.close() - + return serve_file( request, compressed_file.as_file('document_bundle.zip'), @@ -386,14 +386,14 @@ def document_multiple_download(request): request, document_id_list=request.GET.get('id_list', []) ) + def document_page_transformation_list(request, document_page_id): document_page = get_object_or_404(DocumentPage, pk=document_page_id) - + try: Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_TRANSFORM]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_DOCUMENT_TRANSFORM, request.user, document_page.document) - + AccessEntry.objects.check_access(PERMISSION_DOCUMENT_TRANSFORM, request.user, document_page.document) return object_list( request, @@ -418,11 +418,11 @@ def document_page_transformation_list(request, document_page_id): def document_page_transformation_create(request, document_page_id): document_page = get_object_or_404(DocumentPage, pk=document_page_id) - + try: Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_TRANSFORM]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_DOCUMENT_TRANSFORM, request.user, document_page.document) + AccessEntry.objects.check_access(PERMISSION_DOCUMENT_TRANSFORM, request.user, document_page.document) if request.method == 'POST': form = DocumentPageTransformationForm(request.POST, initial={'document_page': document_page}) @@ -450,7 +450,7 @@ def document_page_transformation_edit(request, document_page_transformation_id): try: Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_TRANSFORM]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_DOCUMENT_TRANSFORM, request.user, document_page_transformation.document_page.document) + AccessEntry.objects.check_access(PERMISSION_DOCUMENT_TRANSFORM, request.user, document_page_transformation.document_page.document) if request.method == 'POST': form = DocumentPageTransformationForm(request.POST, instance=document_page_transformation) @@ -482,7 +482,7 @@ def document_page_transformation_delete(request, document_page_transformation_id try: Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_TRANSFORM]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_DOCUMENT_TRANSFORM, request.user, document_page_transformation.document_page.document) + AccessEntry.objects.check_access(PERMISSION_DOCUMENT_TRANSFORM, request.user, document_page_transformation.document_page.document) redirect_view = reverse('document_page_transformation_list', args=[document_page_transformation.document_page_id]) previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', redirect_view))) @@ -516,7 +516,7 @@ def document_find_duplicates(request, document_id): try: Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document) + AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document) extra_context = { 'title': _(u'duplicates of: %s') % document, @@ -565,8 +565,8 @@ def document_find_all_duplicates(request): def document_update_page_count(request): - Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_TOOLS]) - + Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_TOOLS]) + office_converter = OfficeConverter() qs = DocumentVersion.objects.exclude(filename__iendswith='dxf').filter(mimetype__in=office_converter.mimetypes()) previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/'))) @@ -580,7 +580,7 @@ def document_update_page_count(request): processed += 1 if old_page_count != document_version.pages.count(): updated += 1 - + messages.success(request, _(u'Page count update complete. Documents processed: %(total)d, documents with changed page count: %(change)d') % { 'total': processed, 'change': updated @@ -673,12 +673,12 @@ def document_missing_list(request): def document_page_view(request, document_page_id): - document_page = get_object_or_404(DocumentPage, pk=document_page_id) + document_page = get_object_or_404(DocumentPage, pk=document_page_id) try: Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document_page.document) + AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document_page.document) zoom = int(request.GET.get('zoom', DEFAULT_ZOOM_LEVEL)) rotation = int(request.GET.get('rotation', DEFAULT_ROTATION)) @@ -717,7 +717,7 @@ def document_page_text(request, document_page_id): try: Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document_page.document) + AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document_page.document) document_page_form = DocumentPageForm_text(instance=document_page) @@ -733,11 +733,11 @@ def document_page_text(request, document_page_id): def document_page_edit(request, document_page_id): document_page = get_object_or_404(DocumentPage, pk=document_page_id) - + try: Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_EDIT]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_DOCUMENT_EDIT, request.user, document_page.document) + AccessEntry.objects.check_access(PERMISSION_DOCUMENT_EDIT, request.user, document_page.document) if request.method == 'POST': form = DocumentPageForm_edit(request.POST, instance=document_page) @@ -766,8 +766,8 @@ def document_page_navigation_next(request, document_page_id): try: Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document_page.document) - + AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document_page.document) + view = resolve_to_name(urlparse.urlparse(request.META.get('HTTP_REFERER', u'/')).path) if document_page.page_number >= document_page.siblings.count(): @@ -784,7 +784,7 @@ def document_page_navigation_previous(request, document_page_id): try: Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document_page.document) + AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document_page.document) view = resolve_to_name(urlparse.urlparse(request.META.get('HTTP_REFERER', u'/')).path) @@ -803,7 +803,7 @@ def document_page_navigation_first(request, document_page_id): try: Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document_page.document) + AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document_page.document) view = resolve_to_name(urlparse.urlparse(request.META.get('HTTP_REFERER', u'/')).path) @@ -812,12 +812,12 @@ def document_page_navigation_first(request, document_page_id): def document_page_navigation_last(request, document_page_id): document_page = get_object_or_404(DocumentPage, pk=document_page_id) - document_page = get_object_or_404(document_page.siblings, page_number=document_page.siblings.count()) + document_page = get_object_or_404(document_page.siblings, page_number=document_page.siblings.count()) try: Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document_page.document) + AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document_page.document) view = resolve_to_name(urlparse.urlparse(request.META.get('HTTP_REFERER', u'/')).path) @@ -841,7 +841,7 @@ def transform_page(request, document_page_id, zoom_function=None, rotation_funct try: Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document_page.document) + AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document_page.document) view = resolve_to_name(urlparse.urlparse(request.META.get('HTTP_REFERER', u'/')).path) @@ -900,11 +900,11 @@ def document_page_rotate_left(request, document_page_id): def document_print(request, document_id): document = get_object_or_404(Document, pk=document_id) - + try: Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document) + AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document) RecentDocument.objects.add_document_for_user(request.user, document) @@ -964,7 +964,7 @@ def document_hard_copy(request, document_id): try: Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document) + AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document) RecentDocument.objects.add_document_for_user(request.user, document) @@ -1056,7 +1056,7 @@ def document_type_edit(request, document_type_id): #'object': document_type, 'object_name': _(u'document type'), 'navigation_object_name': 'document_type', - 'document_type': document_type, + 'document_type': document_type, 'next': next }, context_instance=RequestContext(request)) @@ -1253,8 +1253,8 @@ def document_type_filename_create(request, document_type_id): 'document_type': document_type, }, context_instance=RequestContext(request)) - - + + def document_clear_image_cache(request): Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_TOOLS]) @@ -1266,23 +1266,23 @@ def document_clear_image_cache(request): messages.success(request, _(u'Document image cache cleared successfully')) except Exception, msg: messages.error(request, _(u'Error clearing document image cache; %s') % msg) - + return HttpResponseRedirect(previous) return render_to_response('generic_confirm.html', { 'previous': previous, 'title': _(u'Are you sure you wish to clear the document image cache?'), 'form_icon': u'camera_delete.png', - }, context_instance=RequestContext(request)) + }, context_instance=RequestContext(request)) def document_version_list(request, document_pk): document = get_object_or_404(Document, pk=document_pk) - + try: Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document) + AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document) RecentDocument.objects.add_document_for_user(request.user, document) @@ -1330,7 +1330,7 @@ def document_version_revert(request, document_version_pk): try: Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VERSION_REVERT]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VERSION_REVERT, request.user, document_version.document) + AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VERSION_REVERT, request.user, document_version.document) previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/'))) @@ -1340,7 +1340,7 @@ def document_version_revert(request, document_version_pk): messages.success(request, _(u'Document version reverted successfully')) except Exception, msg: messages.error(request, _(u'Error reverting document version; %s') % msg) - + return HttpResponseRedirect(previous) return render_to_response('generic_confirm.html', { @@ -1349,4 +1349,4 @@ def document_version_revert(request, document_version_pk): 'title': _(u'Are you sure you wish to revert to this version?'), 'message': _(u'All later version after this one will be deleted too.'), 'form_icon': u'page_refresh.png', - }, context_instance=RequestContext(request)) + }, context_instance=RequestContext(request)) diff --git a/apps/documents/widgets.py b/apps/documents/widgets.py index 0bd9ce473e..bdc963ed94 100644 --- a/apps/documents/widgets.py +++ b/apps/documents/widgets.py @@ -6,12 +6,9 @@ from django.utils.translation import ugettext_lazy as _ from django.core.urlresolvers import reverse from django.utils.http import urlencode -from converter.literals import DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION, \ - DEFAULT_PAGE_NUMBER -from converter.exceptions import UnknownFileFormat, UnkownConvertError +from converter.literals import (DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION, + DEFAULT_PAGE_NUMBER) from mimetype.api import get_error_icon_url - -from .conf.settings import DISPLAY_SIZE def document_thumbnail(document): @@ -24,7 +21,7 @@ def document_link(document): def document_html_widget(document, view='document_thumbnail', click_view=None, page=DEFAULT_PAGE_NUMBER, zoom=DEFAULT_ZOOM_LEVEL, rotation=DEFAULT_ROTATION, gallery_name=None, fancybox_class='fancybox', version=None): result = [] - + alt_text = _(u'document page image') if not version: @@ -41,13 +38,13 @@ def document_html_widget(document, view='document_thumbnail', click_view=None, p gallery_template = u'rel="%s"' % gallery_name else: gallery_template = u'' - + query_string = urlencode(query_dict) preview_view = u'%s?%s' % (reverse(view, args=[document.pk]), query_string) - + plain_template = [] plain_template.append(u'%s' % (preview_view, alt_text)) - + result.append(u'
' % (document.pk, page if page else 1)) if click_view: @@ -55,7 +52,7 @@ def document_html_widget(document, view='document_thumbnail', click_view=None, p result.append(u'%s' % (preview_view, settings.STATIC_URL, alt_text)) result.append(u'' % (preview_view, alt_text)) - if click_view: + if click_view: result.append(u'') result.append(u'
') diff --git a/apps/exporter/__init__.py b/apps/exporter/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/apps/exporter/models.py b/apps/exporter/models.py deleted file mode 100644 index 71a8362390..0000000000 --- a/apps/exporter/models.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.db import models - -# Create your models here. diff --git a/apps/exporter/tests.py b/apps/exporter/tests.py deleted file mode 100644 index 501deb776c..0000000000 --- a/apps/exporter/tests.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -This file demonstrates writing tests using the unittest module. These will pass -when you run "manage.py test". - -Replace this 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.assertEqual(1 + 1, 2) diff --git a/apps/exporter/urls.py b/apps/exporter/urls.py deleted file mode 100644 index 73fda937a8..0000000000 --- a/apps/exporter/urls.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.conf.urls.defaults import patterns, url - -urlpatterns = patterns('exporter.views', - url(r'^export_test/$', 'export_test', (), 'export_test'), -) diff --git a/apps/exporter/views.py b/apps/exporter/views.py deleted file mode 100644 index 407f3ffcc8..0000000000 --- a/apps/exporter/views.py +++ /dev/null @@ -1,150 +0,0 @@ -import os -import hashlib - -from django.utils import simplejson -from django.http import HttpResponse -from django.template.defaultfilters import slugify - -from documents.models import Document, DocumentType -from metadata.models import MetadataType, MetadataSet - -FORMAT_VERSION = 1.0 -HASH_FUNCTION = lambda x: hashlib.sha256(x).hexdigest() - - -def get_hash(obj): - if obj: - return u'%s_%s' % (HASH_FUNCTION(unicode(obj)), slugify(unicode(obj))) - else: - return None - - -''' - - -comments -tags -folders - -pages -pages transformation -metadata -doc_type metadata - -sources -sources transform - -users - -class DocumentTypeDefaults(models.Model): - """ - Default preselected metadata types and metadata set per document - type - """ - document_type = models.ForeignKey(DocumentType, verbose_name=_(u'document type')) - default_metadata_sets = models.ManyToManyField(MetadataSet, blank=True, verbose_name=_(u'default metadata sets')) - default_metadata = models.ManyToManyField(MetadataType, blank=True, verbose_name=_(u'default metadata')) - - -''' - -def export_test(request): - big_list = [] - big_list.append({'version': FORMAT_VERSION}) - - for metadata_type in MetadataType.objects.all(): - big_list.append( - { - 'metadata_types': [ - { - 'id': get_hash(metadata_type.name), - 'name': metadata_type.name, - 'title': metadata_type.title, - 'default': metadata_type.default, - 'lookup': metadata_type.lookup, - } - ] - } - ) - - for metadata_set in MetadataSet.objects.all(): - big_list.append( - { - 'metadata_sets': [ - { - 'id': get_hash(metadata_set.title), - 'name': metadata_set.title, - 'metadata_types': [ - { - 'id': get_hash(metadata_type), - } - for metadata_type in metadata_set.metadatasetitem_set.all() - ] - } - ] - } - ) - - - for document_type in DocumentType.objects.all(): - big_list.append( - { - 'document_types': [ - { - 'id': get_hash(document_type.name), - 'name': document_type.name, - 'filenames': [ - { - 'filename': doc_type_filename.filename, - 'enabled': doc_type_filename.enabled, - } - for doc_type_filename in document_type.documenttypefilename_set.all() - ], - 'metadata_defaults': [ - { - 'default_metadata': [get_hash(metadata_type.name) for metadata_type in doc_type_defaults.default_metadata.all()], - 'default_metadata_sets': [get_hash(metadata_set.title) for metadata_set in doc_type_defaults.default_metadata_sets.all()], - } - for doc_type_defaults in document_type.documenttypedefaults_set.all() - ] - } - ] - } - ) - - for document in Document.objects.all()[:10]: - big_list.append( - { - 'documents': [ - { - 'document_type': get_hash(document.document_type), - 'filename': os.extsep.join([document.file_filename, document.file_extension]), - #'date_added' - 'uuid': document.uuid, - 'description': unicode(document.description) if document.description else None, - 'tags': [get_hash(tag) for tag in document.tags.all()], - 'folders': [get_hash(folder_document.folder) for folder_document in document.folderdocument_set.all()], - 'comments': [ - { - 'comment': comment.comment, - 'user': unicode(comment.user), - 'submit_date': unicode(comment.submit_date), - } - for comment in document.comments.all() - ], - 'versions': [ - { - 1.0: { - 'mimetype': document.file_mimetype, - 'encoding': document.file_mime_encoding, - #'date_updated' - 'checksum': document.checksum, - } - } - ] - } - ] - } - ) - - return HttpResponse(simplejson.dumps(big_list, indent=4, ensure_ascii=True), mimetype='application/json') diff --git a/apps/folders/forms.py b/apps/folders/forms.py index a17c3a3d27..d76da47f3d 100644 --- a/apps/folders/forms.py +++ b/apps/folders/forms.py @@ -32,7 +32,7 @@ class FolderListForm(forms.Form): Permission.objects.check_permissions(user, [PERMISSION_FOLDER_VIEW]) except PermissionDenied: queryset = AccessEntry.objects.filter_objects_by_access(PERMISSION_FOLDER_VIEW, user, queryset) - + self.fields['folder'] = forms.ModelChoiceField( queryset=queryset, label=_(u'Folder')) diff --git a/apps/folders/models.py b/apps/folders/models.py index 20c2eda7a7..e58db8ab91 100644 --- a/apps/folders/models.py +++ b/apps/folders/models.py @@ -23,15 +23,15 @@ class Folder(models.Model): @models.permalink def get_absolute_url(self): return ('folder_view', [self.pk]) - + @property def documents(self): return [folder_document.document for folder_document in self.folderdocument_set.all()] - + def remove_document(self, document): folder_document = self.folderdocument_set.get(document=document) folder_document.delete() - + def add_document(self, document): folder_document, created = FolderDocument.objects.get_or_create(folder=self, document=document) return created diff --git a/apps/folders/permissions.py b/apps/folders/permissions.py index 6077438f42..5538a70214 100644 --- a/apps/folders/permissions.py +++ b/apps/folders/permissions.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import +from __future__ import absolute_import from django.utils.translation import ugettext_lazy as _ diff --git a/apps/folders/tests.py b/apps/folders/tests.py deleted file mode 100644 index 2247054b35..0000000000 --- a/apps/folders/tests.py +++ /dev/null @@ -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 -"""} - diff --git a/apps/folders/urls.py b/apps/folders/urls.py index 0e0cf0d5ad..9f35d24c69 100644 --- a/apps/folders/urls.py +++ b/apps/folders/urls.py @@ -11,6 +11,6 @@ urlpatterns = patterns('folders.views', url(r'^document/(?P\d+)/folder/add/$', 'folder_add_document', (), 'folder_add_document'), url(r'^document/(?P\d+)/folder/list/$', 'document_folder_list', (), 'document_folder_list'), - + url(r'^(?P\d+)/acl/list/$', 'folder_acl_list', (), 'folder_acl_list'), ) diff --git a/apps/folders/views.py b/apps/folders/views.py index de1dcc4ca4..0bd85d2790 100644 --- a/apps/folders/views.py +++ b/apps/folders/views.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import +from __future__ import absolute_import import logging @@ -7,7 +7,6 @@ from django.http import HttpResponseRedirect from django.shortcuts import render_to_response, get_object_or_404 from django.template import RequestContext from django.contrib import messages -from django.views.generic.list_detail import object_list from django.core.urlresolvers import reverse from django.core.exceptions import PermissionDenied @@ -19,7 +18,7 @@ from common.utils import encapsulate from acls.models import AccessEntry from acls.views import acl_list_for -from .models import Folder, FolderDocument +from .models import Folder from .forms import FolderForm, FolderListForm from .permissions import (PERMISSION_FOLDER_CREATE, PERMISSION_FOLDER_EDIT, PERMISSION_FOLDER_DELETE, @@ -50,8 +49,8 @@ def folder_list(request, queryset=None, extra_context=None): queryset = AccessEntry.objects.filter_objects_by_access(PERMISSION_FOLDER_VIEW, request.user, queryset) context['object_list'] = queryset - - return render_to_response('generic_list.html', + + return render_to_response('generic_list.html', context, context_instance=RequestContext(request) ) @@ -59,7 +58,7 @@ def folder_list(request, queryset=None, extra_context=None): def folder_create(request): Permission.objects.check_permissions(request.user, [PERMISSION_FOLDER_CREATE]) - + if request.method == 'POST': form = FolderForm(request.POST) if form.is_valid(): @@ -158,9 +157,9 @@ def folder_view(request, folder_id): 'hide_links': True, 'multi_select_as_buttons': True, 'object': folder, - 'object_name': _(u'folder'), + 'object_name': _(u'folder'), } - + return document_list( request, object_list=folder.documents, @@ -194,14 +193,13 @@ def folder_add_document(request, document_id): else: form = FolderListForm(user=request.user) - return render_to_response('generic_form.html', { 'title': _(u'add document "%s" to a folder') % document, 'form': form, 'object': document, 'next': next, }, - context_instance=RequestContext(request)) + context_instance=RequestContext(request)) def document_folder_list(request, document_id): diff --git a/apps/linking/__init__.py b/apps/linking/__init__.py index 0d827f3e48..e45e80a496 100644 --- a/apps/linking/__init__.py +++ b/apps/linking/__init__.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import +from __future__ import absolute_import from django.utils.translation import ugettext_lazy as _ diff --git a/apps/linking/admin.py b/apps/linking/admin.py index 84f13692f5..2116114693 100644 --- a/apps/linking/admin.py +++ b/apps/linking/admin.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import +from __future__ import absolute_import from django.contrib import admin diff --git a/apps/linking/forms.py b/apps/linking/forms.py index 5cdb6be1f9..53c9639f53 100644 --- a/apps/linking/forms.py +++ b/apps/linking/forms.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import +from __future__ import absolute_import from django import forms from django.utils.translation import ugettext_lazy as _ @@ -18,7 +18,7 @@ class SmartLinkForm(forms.ModelForm): class Meta: model = SmartLink - + class SmartLinkConditionForm(forms.ModelForm): class Meta: model = SmartLinkCondition @@ -56,7 +56,7 @@ class SmartLinkImageWidget(forms.widgets.Widget): output.append(u'%s' % (reverse('document_view_simple', args=[document.pk]), ugettext(u'Select'))) output.append(u'
') output.append(u'
') - + output.append(u'') output.append( u'
%s' % @@ -70,9 +70,9 @@ class SmartLinkInstanceForm(forms.Form): smart_link_instances = kwargs.pop('smart_link_instances', None) links = kwargs.pop('links', None) current_document = kwargs.pop('current_document', None) - + super(SmartLinkInstanceForm, self).__init__(*args, **kwargs) - + for smart_link_instance, data in smart_link_instances.items(): self.fields['preview-%s' % smart_link_instance] = forms.CharField( widget=SmartLinkImageWidget(), diff --git a/apps/linking/managers.py b/apps/linking/managers.py index bb6dcba1c5..4583b646ad 100644 --- a/apps/linking/managers.py +++ b/apps/linking/managers.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import +from __future__ import absolute_import from django.db import models from django.db.models import Q diff --git a/apps/linking/models.py b/apps/linking/models.py index 2c75642c9e..0af9522e77 100644 --- a/apps/linking/models.py +++ b/apps/linking/models.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import +from __future__ import absolute_import from django.db import models from django.utils.translation import ugettext_lazy as _ diff --git a/apps/linking/permissions.py b/apps/linking/permissions.py index c9b889b084..f5e7cc30b7 100644 --- a/apps/linking/permissions.py +++ b/apps/linking/permissions.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import +from __future__ import absolute_import from django.utils.translation import ugettext_lazy as _ diff --git a/apps/linking/urls.py b/apps/linking/urls.py index cf47c7ca7e..7cb2749d6e 100644 --- a/apps/linking/urls.py +++ b/apps/linking/urls.py @@ -4,12 +4,12 @@ urlpatterns = patterns('linking.views', url(r'^action/$', 'smart_link_action', (), 'smart_link_action'), url(r'^document/(?P\d+)/smart_link/(?P\d+)/$', 'smart_link_instance_view', (), 'smart_link_instance_view'), url(r'^smart/for_document/(?P\d+)/$', 'smart_link_instances_for_document', (), 'smart_link_instances_for_document'), - + url(r'^setup/list/$', 'smart_link_list', (), 'smart_link_list'), url(r'^setup/create/$', 'smart_link_create', (), 'smart_link_create'), url(r'^setup/(?P\d+)/delete/$', 'smart_link_delete', (), 'smart_link_delete'), url(r'^setup/(?P\d+)/edit/$', 'smart_link_edit', (), 'smart_link_edit'), - + url(r'^setup/(?P\d+)/condition/list/$', 'smart_link_condition_list', (), 'smart_link_condition_list'), url(r'^setup/(?P\d+)/condition/create/$', 'smart_link_condition_create', (), 'smart_link_condition_create'), url(r'^setup/smart_link/condition/(?P\d+)/edit/$', 'smart_link_condition_edit', (), 'smart_link_condition_edit'), diff --git a/apps/linking/views.py b/apps/linking/views.py index 58a1c8451c..07e1d42351 100644 --- a/apps/linking/views.py +++ b/apps/linking/views.py @@ -9,7 +9,7 @@ from django.shortcuts import get_object_or_404, render_to_response from django.core.urlresolvers import reverse from django.template import RequestContext -from common.utils import generate_choices_w_labels, encapsulate +from common.utils import encapsulate from common.widgets import two_state_template from documents.models import Document from documents.views import document_list @@ -32,7 +32,7 @@ logger = logging.getLogger(__name__) def smart_link_action(request): #Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_VIEW]) - + action = request.GET.get('action', None) if not action: @@ -45,12 +45,12 @@ def smart_link_action(request): def smart_link_instance_view(request, document_id, smart_link_pk): document = get_object_or_404(Document, pk=document_id) smart_link = get_object_or_404(SmartLink, pk=smart_link_pk) - + try: Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_VIEW]) except PermissionDenied: AccessEntry.objects.check_access(PERMISSION_SMART_LINK_VIEW, request.user, smart_link) - + object_list, errors = SmartLink.objects.get_smart_link_instances_for(document, smart_link) return document_list( @@ -86,7 +86,7 @@ def smart_link_instances_for_document(request, document_id): for key, value in smart_link_instances.items(): if key not in smart_link_instances_keys_filtered: smart_link_instances.pop(key) - + value['documents'] = AccessEntry.objects.filter_objects_by_access(PERMISSION_DOCUMENT_VIEW, request.user, value['documents']) if smart_link_instances: @@ -116,30 +116,30 @@ def smart_link_instances_for_document(request, document_id): 'document': document, 'subtemplates_list': subtemplates_list, }, context_instance=RequestContext(request)) - - + + def smart_link_list(request): qs = SmartLink.objects.all() - + try: Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_VIEW]) except PermissionDenied: qs = AccessEntry.objects.filter_objects_by_access(PERMISSION_SMART_LINK_VIEW, request.user, qs) - - + + return render_to_response('generic_list.html', { 'title': _(u'smart links'), 'object_list': qs, 'extra_columns': [ {'name': _(u'dynamic title'), 'attribute': 'dynamic_title'}, {'name': _(u'enabled'), 'attribute': encapsulate(lambda x: two_state_template(x.enabled))}, - ], + ], 'hide_link': True, 'list_object_variable_name': 'smart_link', }, context_instance=RequestContext(request)) - - + + def smart_link_create(request): Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_CREATE]) @@ -155,9 +155,9 @@ def smart_link_create(request): return render_to_response('generic_form.html', { 'form': form, 'title': _(u'Create new smart link') - }, context_instance=RequestContext(request)) - - + }, context_instance=RequestContext(request)) + + def smart_link_edit(request, smart_link_pk): smart_link = get_object_or_404(SmartLink, pk=smart_link_pk) @@ -180,16 +180,16 @@ def smart_link_edit(request, smart_link_pk): 'object': smart_link, 'form': form, 'title': _(u'Edit smart link: %s') % smart_link - }, context_instance=RequestContext(request)) - - + }, context_instance=RequestContext(request)) + + def smart_link_delete(request, smart_link_pk): smart_link = get_object_or_404(SmartLink, pk=smart_link_pk) try: Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_DELETE]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_SMART_LINK_DELETE, request.user, smart_link) + AccessEntry.objects.check_access(PERMISSION_SMART_LINK_DELETE, request.user, smart_link) next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', '/'))) previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/'))) @@ -212,26 +212,26 @@ def smart_link_delete(request, smart_link_pk): 'next': next, 'previous': previous, 'form_icon': u'link_delete.png', - }, context_instance=RequestContext(request)) - + }, context_instance=RequestContext(request)) + def smart_link_condition_list(request, smart_link_pk): smart_link = get_object_or_404(SmartLink, pk=smart_link_pk) - + try: Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT]) except PermissionDenied: - AccessEntry.objects.check_accesses([PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT], request.user, smart_link) - + AccessEntry.objects.check_accesses([PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT], request.user, smart_link) + return render_to_response('generic_list.html', { 'title': _(u'conditions for smart link: %s') % smart_link, 'object_list': smart_link.smartlinkcondition_set.all(), 'extra_columns': [ {'name': _(u'enabled'), 'attribute': encapsulate(lambda x: two_state_template(x.enabled))}, - ], + ], 'hide_link': True, 'object': smart_link, - 'list_object_variable_name': 'condition', + 'list_object_variable_name': 'condition', }, context_instance=RequestContext(request)) @@ -241,14 +241,14 @@ def smart_link_condition_create(request, smart_link_pk): try: Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT]) except PermissionDenied: - AccessEntry.objects.check_accesses([PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT], request.user, smart_link) + AccessEntry.objects.check_accesses([PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT], request.user, smart_link) if request.method == 'POST': form = SmartLinkConditionForm(request.POST) if form.is_valid(): new_smart_link_condition = form.save(commit=False) new_smart_link_condition.smart_link = smart_link - new_smart_link_condition.save() + new_smart_link_condition.save() messages.success(request, _(u'Smart link condition: "%s" created successfully.') % new_smart_link_condition) return HttpResponseRedirect(reverse('smart_link_condition_list', args=[smart_link.pk])) else: @@ -257,8 +257,8 @@ def smart_link_condition_create(request, smart_link_pk): return render_to_response('generic_form.html', { 'form': form, 'title': _(u'Add new conditions to smart link: "%s"') % smart_link, - 'object': smart_link, - }, context_instance=RequestContext(request)) + 'object': smart_link, + }, context_instance=RequestContext(request)) def smart_link_condition_edit(request, smart_link_condition_pk): @@ -267,7 +267,7 @@ def smart_link_condition_edit(request, smart_link_condition_pk): try: Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT]) except PermissionDenied: - AccessEntry.objects.check_accesses([PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT], request.user, smart_link_condition.smart_link) + AccessEntry.objects.check_accesses([PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT], request.user, smart_link_condition.smart_link) next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', '/'))) previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/'))) @@ -294,8 +294,8 @@ def smart_link_condition_edit(request, smart_link_condition_pk): {'object': 'object', 'name': _(u'smart link')}, {'object': 'condition', 'name': _(u'condition')} ], - - }, context_instance=RequestContext(request)) + + }, context_instance=RequestContext(request)) def smart_link_condition_delete(request, smart_link_condition_pk): @@ -304,7 +304,7 @@ def smart_link_condition_delete(request, smart_link_condition_pk): try: Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT]) except PermissionDenied: - AccessEntry.objects.check_accesses([PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT], request.user, smart_link_condition.smart_link) + AccessEntry.objects.check_accesses([PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT], request.user, smart_link_condition.smart_link) next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', '/'))) previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/'))) @@ -332,7 +332,7 @@ def smart_link_condition_delete(request, smart_link_condition_pk): 'next': next, 'previous': previous, 'form_icon': u'cog_delete.png', - }, context_instance=RequestContext(request)) + }, context_instance=RequestContext(request)) def smart_link_acl_list(request, smart_link_pk): diff --git a/apps/lock_manager/managers.py b/apps/lock_manager/managers.py index f5613110f4..603a36c575 100644 --- a/apps/lock_manager/managers.py +++ b/apps/lock_manager/managers.py @@ -3,7 +3,6 @@ from __future__ import absolute_import import logging import datetime -from django.db.utils import DatabaseError from django.db.utils import IntegrityError from django.db import transaction from django.db import models diff --git a/apps/lock_manager/models.py b/apps/lock_manager/models.py index 25188380c7..a70af8230c 100644 --- a/apps/lock_manager/models.py +++ b/apps/lock_manager/models.py @@ -21,7 +21,7 @@ class Lock(models.Model): def save(self, *args, **kwargs): self.creation_datetime = datetime.datetime.now() - if not self.timeout and not kwarget.get('timeout'): + if not self.timeout and not kwargs.get('timeout'): self.timeout = DEFAULT_LOCK_TIMEOUT super(Lock, self).save(*args, **kwargs) diff --git a/apps/main/__init__.py b/apps/main/__init__.py index 8a502f30f9..80d503ca7e 100644 --- a/apps/main/__init__.py +++ b/apps/main/__init__.py @@ -12,7 +12,7 @@ from .conf.settings import SIDE_BAR_SEARCH, DISABLE_HOME_VIEW __author__ = 'Roberto Rosario' __copyright__ = 'Copyright 2011 Roberto Rosario' -__credits__ = ['Roberto Rosario',] +__credits__ = ['Roberto Rosario',] __license__ = 'GPL' __maintainer__ = 'Roberto Rosario' __email__ = 'roberto.rosario.gonzalez@gmail.com' @@ -58,7 +58,7 @@ __version__ = get_version() if 'django.contrib.admin' in settings.INSTALLED_APPS: register_setup(admin_site) - + register_tool(maintenance_menu) register_tool(statistics) register_tool(diagnostics) diff --git a/apps/main/tests.py b/apps/main/tests.py index 2247054b35..3b31148896 100644 --- a/apps/main/tests.py +++ b/apps/main/tests.py @@ -20,4 +20,3 @@ Another way to test that 1 + 1 is equal to 2. >>> 1 + 1 == 2 True """} - diff --git a/apps/metadata/__init__.py b/apps/metadata/__init__.py index 099b908216..f52465d568 100644 --- a/apps/metadata/__init__.py +++ b/apps/metadata/__init__.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import +from __future__ import absolute_import from django.utils.translation import ugettext_lazy as _ diff --git a/apps/metadata/admin.py b/apps/metadata/admin.py index 53ca6f69cd..058d5d0544 100644 --- a/apps/metadata/admin.py +++ b/apps/metadata/admin.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import +from __future__ import absolute_import from django.contrib import admin diff --git a/apps/metadata/api.py b/apps/metadata/api.py index 3473cf5bd0..60e611e5f6 100644 --- a/apps/metadata/api.py +++ b/apps/metadata/api.py @@ -1,5 +1,5 @@ -'''Metadata handling commonalities''' -from __future__ import absolute_import +"""Metadata handling commonalities""" +from __future__ import absolute_import from urllib import unquote_plus @@ -9,9 +9,9 @@ from .models import DocumentMetadata, MetadataType def decode_metadata_from_url(url_dict): - ''' + """ Parse a URL query string to a list of metadata - ''' + """ metadata_dict = { 'id': {}, 'value': {} @@ -35,19 +35,19 @@ def decode_metadata_from_url(url_dict): def save_metadata_list(metadata_list, document, create=False): - ''' + """ Take a list of metadata dictionaries and associate them to a document - ''' + """ for item in metadata_list: save_metadata(item, document, create) def save_metadata(metadata_dict, document, create=False): - ''' + """ Take a dictionary of metadata type & value and associate it to a document - ''' + """ if create: # Use matched metadata now to create document metadata document_metadata, created = DocumentMetadata.objects.get_or_create( @@ -81,16 +81,16 @@ def save_metadata(metadata_dict, document, create=False): def metadata_repr(metadata_list): - ''' + """ Return a printable representation of a metadata list - ''' + """ return u', '.join(metadata_repr_as_list(metadata_list)) def metadata_repr_as_list(metadata_list): - ''' + """ Turn a list of metadata into a list of printable representations - ''' + """ output = [] for metadata_dict in metadata_list: try: @@ -103,7 +103,7 @@ def metadata_repr_as_list(metadata_list): def get_metadata_string(document): - ''' + """ Return a formated representation of a document's metadata values - ''' + """ return u', '.join([u'%s - %s' % (metadata.metadata_type, metadata.value) for metadata in DocumentMetadata.objects.filter(document=document).select_related('metadata_type')]) diff --git a/apps/metadata/forms.py b/apps/metadata/forms.py index e319ff3f92..c2e281242c 100644 --- a/apps/metadata/forms.py +++ b/apps/metadata/forms.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import +from __future__ import absolute_import from django import forms from django.utils.translation import ugettext_lazy as _ diff --git a/apps/metadata/models.py b/apps/metadata/models.py index 1c7fda9249..5e13f65c48 100644 --- a/apps/metadata/models.py +++ b/apps/metadata/models.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import +from __future__ import absolute_import from django.db import models from django.utils.translation import ugettext_lazy as _ @@ -12,9 +12,9 @@ available_functions_string = (_(u' Available functions: %s') % u','.join([u'%s() class MetadataType(models.Model): - ''' + """ Define a type of metadata - ''' + """ name = models.CharField(unique=True, max_length=48, verbose_name=_(u'name'), help_text=_(u'Do not use python reserved words, or spaces.')) title = models.CharField(max_length=48, verbose_name=_(u'title'), blank=True, null=True) default = models.CharField(max_length=128, blank=True, null=True, @@ -35,9 +35,9 @@ class MetadataType(models.Model): class MetadataSet(models.Model): - ''' + """ Define a group of metadata types - ''' + """ title = models.CharField(max_length=48, verbose_name=_(u'title')) def __unicode__(self): @@ -50,10 +50,10 @@ class MetadataSet(models.Model): class MetadataSetItem(models.Model): - ''' + """ Define the set of metadata that relates to a set or group of metadata fields - ''' + """ metadata_set = models.ForeignKey(MetadataSet, verbose_name=_(u'metadata set')) metadata_type = models.ForeignKey(MetadataType, verbose_name=_(u'metadata type')) #required = models.BooleanField(default=True, verbose_name=_(u'required')) @@ -67,10 +67,10 @@ class MetadataSetItem(models.Model): class DocumentMetadata(models.Model): - ''' + """ Link a document to a specific instance of a metadata type with it's current value - ''' + """ document = models.ForeignKey(Document, verbose_name=_(u'document')) metadata_type = models.ForeignKey(MetadataType, verbose_name=_(u'type')) value = models.CharField(max_length=256, blank=True, verbose_name=_(u'value'), db_index=True) @@ -84,10 +84,10 @@ class DocumentMetadata(models.Model): class DocumentTypeDefaults(models.Model): - ''' + """ Default preselected metadata types and metadata set per document type - ''' + """ document_type = models.ForeignKey(DocumentType, verbose_name=_(u'document type')) default_metadata_sets = models.ManyToManyField(MetadataSet, blank=True, verbose_name=_(u'default metadata sets')) default_metadata = models.ManyToManyField(MetadataType, blank=True, verbose_name=_(u'default metadata')) diff --git a/apps/metadata/permissions.py b/apps/metadata/permissions.py index 5ed8f9cb43..9f6ff38a76 100644 --- a/apps/metadata/permissions.py +++ b/apps/metadata/permissions.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import +from __future__ import absolute_import from django.utils.translation import ugettext_lazy as _ diff --git a/apps/metadata/tests.py b/apps/metadata/tests.py index 2247054b35..3b31148896 100644 --- a/apps/metadata/tests.py +++ b/apps/metadata/tests.py @@ -20,4 +20,3 @@ Another way to test that 1 + 1 is equal to 2. >>> 1 + 1 == 2 True """} - diff --git a/apps/metadata/views.py b/apps/metadata/views.py index 6f570beed8..6c66baaf4d 100644 --- a/apps/metadata/views.py +++ b/apps/metadata/views.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import +from __future__ import absolute_import from django.shortcuts import render_to_response from django.template import RequestContext @@ -46,10 +46,10 @@ def metadata_edit(request, document_id=None, document_id_list=None): Permission.objects.check_permissions(request.user, [PERMISSION_METADATA_DOCUMENT_EDIT]) except PermissionDenied: documents = AccessEntry.objects.filter_objects_by_access(PERMISSION_METADATA_DOCUMENT_EDIT, request.user, documents) - + if not documents: messages.error(request, _(u'Must provide at least one document.')) - return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) + return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) post_action_redirect = reverse('document_list_recent') @@ -141,7 +141,7 @@ def metadata_add(request, document_id=None, document_id_list=None): if not documents: messages.error(request, _(u'Must provide at least one document.')) - return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) + return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) for document in documents: RecentDocument.objects.add_document_for_user(request.user, document) @@ -205,12 +205,12 @@ def metadata_remove(request, document_id=None, document_id_list=None): elif document_id_list: documents = [get_object_or_404(Document, pk=document_id) for document_id in document_id_list.split(',')] - + try: Permission.objects.check_permissions(request.user, [PERMISSION_METADATA_DOCUMENT_REMOVE]) except PermissionDenied: documents = AccessEntry.objects.filter_objects_by_access(PERMISSION_METADATA_DOCUMENT_REMOVE, request.user, documents) - + if not documents: messages.error(request, _(u'Must provide at least one document.')) return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) @@ -304,7 +304,7 @@ def metadata_view(request, document_id): 'hide_link': True, 'object': document, }, context_instance=RequestContext(request)) - + # Setup views def setup_metadata_type_list(request): @@ -323,12 +323,12 @@ def setup_metadata_type_list(request): } return render_to_response('generic_list.html', context, - context_instance=RequestContext(request)) + context_instance=RequestContext(request)) def setup_metadata_type_edit(request, metadatatype_id): Permission.objects.check_permissions(request.user, [PERMISSION_METADATA_TYPE_EDIT]) - + metadata_type = get_object_or_404(MetadataType, pk=metadatatype_id) if request.method == 'POST': @@ -351,12 +351,12 @@ def setup_metadata_type_edit(request, metadatatype_id): 'object': metadata_type, 'object_name': _(u'metadata type'), }, - context_instance=RequestContext(request)) - - + context_instance=RequestContext(request)) + + def setup_metadata_type_create(request): Permission.objects.check_permissions(request.user, [PERMISSION_METADATA_TYPE_CREATE]) - + if request.method == 'POST': form = MetadataTypeForm(request.POST) if form.is_valid(): @@ -375,7 +375,7 @@ def setup_metadata_type_create(request): def setup_metadata_type_delete(request, metadatatype_id): Permission.objects.check_permissions(request.user, [PERMISSION_METADATA_TYPE_DELETE]) - + metadata_type = get_object_or_404(MetadataType, pk=metadatatype_id) post_action_redirect = reverse('setup_metadata_type_list') @@ -423,7 +423,7 @@ def setup_metadata_set_list(request): } return render_to_response('generic_list.html', context, - context_instance=RequestContext(request)) + context_instance=RequestContext(request)) def get_set_members(metadata_set): @@ -471,7 +471,7 @@ def setup_metadata_set_edit(request, metadata_set_id): def setup_metadata_set_create(request): Permission.objects.check_permissions(request.user, [PERMISSION_METADATA_SET_CREATE]) - + if request.method == 'POST': form = MetadataSetForm(request.POST) if form.is_valid(): @@ -490,7 +490,7 @@ def setup_metadata_set_create(request): def setup_metadata_set_delete(request, metadata_set_id): Permission.objects.check_permissions(request.user, [PERMISSION_METADATA_SET_DELETE]) - + metadata_set = get_object_or_404(MetadataSet, pk=metadata_set_id) post_action_redirect = reverse('setup_metadata_set_list') @@ -566,7 +566,7 @@ def setup_document_type_metadata(request, document_type_id): # Initialize defaults DocumentTypeDefaults.objects.get_or_create(document_type=document_type) - + return assign_remove( request, left_list=lambda: generate_choices_w_labels(get_document_type_metadata_non_members(document_type)), diff --git a/apps/navigation/api.py b/apps/navigation/api.py index 8939370cb9..a0ccc9f32e 100644 --- a/apps/navigation/api.py +++ b/apps/navigation/api.py @@ -1,5 +1,3 @@ -import copy - object_navigation = {} multi_object_navigation = {} model_list_columns = {} @@ -46,7 +44,7 @@ def register_links(src, links, menu_name=None, position=None): object_navigation[menu_name][src]['links'].extend(links) -def register_top_menu(name, link, children_views=None, +def register_top_menu(name, link, children_views=None, children_path_regex=None, children_view_regex=None, position=None): """ diff --git a/apps/navigation/widgets.py b/apps/navigation/widgets.py index 78c6923e43..f587fc6ebb 100644 --- a/apps/navigation/widgets.py +++ b/apps/navigation/widgets.py @@ -8,13 +8,11 @@ from django.utils.translation import ugettext_lazy as _ from django.core.urlresolvers import reverse from django.template.defaultfilters import capfirst from django.core.exceptions import PermissionDenied -from django.template import RequestContext -from django.template import (TemplateSyntaxError, Library, - VariableDoesNotExist, Node, Variable) - +from django.template import RequestContext, Variable + from permissions.models import Permission -from .templatetags.navigation_tags import resolve_links, _get_object_navigation_links +from .templatetags.navigation_tags import resolve_links from .utils import resolve_to_name @@ -27,7 +25,8 @@ def button_navigation_widget(request, link): return u'' else: return render_widget(request, link) - + + def render_widget(request, link): context = RequestContext(request) @@ -37,7 +36,7 @@ def render_widget(request, link): query_string = urlparse.urlparse(request.get_full_path()).query or urlparse.urlparse(request.META.get('HTTP_REFERER', u'/')).query parsed_query_string = urlparse.parse_qs(query_string) - + links = resolve_links(context, [link], current_view, current_path, parsed_query_string) if links: link = links[0] diff --git a/apps/ocr/__init__.py b/apps/ocr/__init__.py index 78f3f297c2..f228843100 100644 --- a/apps/ocr/__init__.py +++ b/apps/ocr/__init__.py @@ -1,15 +1,14 @@ from __future__ import absolute_import import logging - + from django.db import transaction from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext from django.db.models.signals import post_save from django.dispatch import receiver -from navigation.api import register_links, register_top_menu, register_multi_item_links -from permissions.models import Permission, PermissionNamespace +from navigation.api import register_links, register_multi_item_links from documents.models import Document, DocumentVersion from main.api import register_maintenance_links from project_tools.api import register_tool @@ -18,11 +17,12 @@ from acls.api import class_permissions from scheduler.api import register_interval_job from .conf.settings import (AUTOMATIC_OCR, QUEUE_PROCESSING_INTERVAL) -from .models import DocumentQueue, QueueTransformation, QueueDocument +from .models import DocumentQueue, QueueTransformation from .tasks import task_process_document_queues from .permissions import (PERMISSION_OCR_DOCUMENT, PERMISSION_OCR_DOCUMENT_DELETE, PERMISSION_OCR_QUEUE_ENABLE_DISABLE, - PERMISSION_OCR_CLEAN_ALL_PAGES, PERMISSION_OCR_QUEUE_EDIT) + PERMISSION_OCR_CLEAN_ALL_PAGES) +from .exceptions import AlreadyQueued logger = logging.getLogger(__name__) @@ -77,7 +77,10 @@ def document_post_save(sender, instance, **kwargs): logger.debug('instance: %s' % instance) if kwargs.get('created', False): if AUTOMATIC_OCR: - DocumentQueue.objects.queue_document(instance.document) + try: + DocumentQueue.objects.queue_document(instance.document) + except AlreadyQueued: + pass # Disabled because it appears Django execute signals using the same @@ -85,7 +88,7 @@ def document_post_save(sender, instance, **kwargs): # the OCR process completes which could take several minutes :/ #@receiver(post_save, dispatch_uid='call_queue', sender=QueueDocument) #def call_queue(sender, **kwargs): -# if kwargs.get('created', False): +# if kwargs.get('created', False): # logger.debug('got call_queue signal: %s' % kwargs) # task_process_document_queues() diff --git a/apps/ocr/conf/settings.py b/apps/ocr/conf/settings.py index ff2f7ca04d..31e2c908b8 100644 --- a/apps/ocr/conf/settings.py +++ b/apps/ocr/conf/settings.py @@ -14,7 +14,6 @@ register_settings( {'name': u'NODE_CONCURRENT_EXECUTION', 'global_name': u'OCR_NODE_CONCURRENT_EXECUTION', 'default': 1, 'description': _(u'Maximum amount of concurrent document OCRs a node can perform.')}, {'name': u'AUTOMATIC_OCR', 'global_name': u'OCR_AUTOMATIC_OCR', 'default': False, 'description': _(u'Automatically queue newly created documents for OCR.')}, {'name': u'QUEUE_PROCESSING_INTERVAL', 'global_name': u'OCR_QUEUE_PROCESSING_INTERVAL', 'default': 10}, - {'name': u'CACHE_URI', 'global_name': u'OCR_CACHE_URI', 'default': None, 'description': _(u'URI in the form: "memcached://127.0.0.1:11211/" to specify a cache backend to use for locking. Multiple hosts can be specified separated by a semicolon.')}, {'name': u'UNPAPER_PATH', 'global_name': u'OCR_UNPAPER_PATH', 'default': u'/usr/bin/unpaper', 'description': _(u'File path to unpaper program.'), 'exists': True}, ] ) diff --git a/apps/ocr/exceptions.py b/apps/ocr/exceptions.py index 0b6f4a129a..32ec4c4c07 100644 --- a/apps/ocr/exceptions.py +++ b/apps/ocr/exceptions.py @@ -1,21 +1,21 @@ class AlreadyQueued(Exception): - ''' + """ Raised when a trying to queue document already in the queue - ''' + """ pass class TesseractError(Exception): - ''' + """ Raised by tesseract - ''' + """ pass class UnpaperError(Exception): - ''' + """ Raised by unpaper - ''' + """ pass diff --git a/apps/ocr/parsers/__init__.py b/apps/ocr/parsers/__init__.py index 3d5a39635e..6a91d392d4 100644 --- a/apps/ocr/parsers/__init__.py +++ b/apps/ocr/parsers/__init__.py @@ -3,10 +3,9 @@ import logging from django.utils.translation import ugettext as _ -from converter import office_converter from converter import office_converter from converter.office_converter import OfficeConverter -from converter.exceptions import OfficeBackendError, OfficeConversionError +from converter.exceptions import OfficeConversionError from documents.utils import document_save_to_temp_dir from ocr.parsers.exceptions import ParserError, ParserUnknownFile @@ -27,7 +26,7 @@ def register_parser(function, mimetype=None, mimetypes=None): def pdf_parser(document_page, descriptor=None): if not descriptor: descriptor = document_page.document_version.open() - + pdf_pages = slate.PDF(descriptor) descriptor.close() @@ -45,7 +44,7 @@ def office_parser(document_page): office_converter = OfficeConverter() document_file = document_save_to_temp_dir(document_page.document, document_page.document.checksum) logger.debug('document_file: %s', document_file) - + office_converter.convert(document_file, mimetype=document_page.document.file_mimetype) if office_converter.exists: input_filepath = office_converter.output_filepath @@ -58,7 +57,7 @@ def office_parser(document_page): except OfficeConversionError, msg: print msg raise ParserError - + def parse_document_page(document_page): logger.debug('executing') diff --git a/apps/ocr/tasks.py b/apps/ocr/tasks.py index 14c0ce5152..800d0623d2 100644 --- a/apps/ocr/tasks.py +++ b/apps/ocr/tasks.py @@ -2,8 +2,6 @@ from __future__ import absolute_import from datetime import timedelta, datetime import platform -from time import sleep -from random import random import logging from django.db.models import Q @@ -17,7 +15,7 @@ from .literals import (QUEUEDOCUMENT_STATE_PENDING, QUEUEDOCUMENT_STATE_ERROR) from .models import QueueDocument, DocumentQueue from .conf.settings import (NODE_CONCURRENT_EXECUTION, REPLICATION_DELAY, - CACHE_URI, QUEUE_PROCESSING_INTERVAL) + QUEUE_PROCESSING_INTERVAL) LOCK_EXPIRE = 60 * 10 # Lock expires in 10 minutes # TODO: Tie LOCK_EXPIRATION with hard task timeout @@ -42,44 +40,16 @@ def task_process_queue_document(queue_document_id): queue_document.state = QUEUEDOCUMENT_STATE_ERROR queue_document.result = e queue_document.save() - + lock.release() except LockError: logger.debug('unable to obtain lock') pass -def reset_orphans(): - pass - ''' - i = inspect().active() - active_tasks = [] - orphans = [] - - if i: - for host, instances in i.items(): - for instance in instances: - active_tasks.append(instance['id']) - - for document_queue in DocumentQueue.objects.filter(state=DOCUMENTQUEUE_STATE_ACTIVE): - orphans = document_queue.queuedocument_set.\ - filter(state=QUEUEDOCUMENT_STATE_PROCESSING).\ - exclude(result__in=active_tasks) - - for orphan in orphans: - orphan.result = _(u'Orphaned') - orphan.state = QUEUEDOCUMENT_STATE_PENDING - orphan.delay = False - orphan.node_name = None - orphan.save() - ''' - - def task_process_document_queues(): logger.debug('executed') - # reset_orphans() - # Causes problems with big clusters increased latency - # Disabled until better solution + # TODO: reset_orphans() q_pending = Q(state=QUEUEDOCUMENT_STATE_PENDING) q_delayed = Q(delay=True) q_delay_interval = Q(datetime_submitted__lt=datetime.now() - timedelta(seconds=REPLICATION_DELAY)) @@ -100,7 +70,7 @@ def task_process_document_queues(): #print 'DocumentQueueWatcher exception: %s' % e finally: # Don't process anymore from this queryset, might be stale - break; + break else: logger.debug('already processing maximun') else: diff --git a/apps/ocr/tests.py b/apps/ocr/tests.py index 2247054b35..3b31148896 100644 --- a/apps/ocr/tests.py +++ b/apps/ocr/tests.py @@ -20,4 +20,3 @@ Another way to test that 1 + 1 is equal to 2. >>> 1 + 1 == 2 True """} - diff --git a/apps/ocr/views.py b/apps/ocr/views.py index be640952b4..52e0fc9eb4 100644 --- a/apps/ocr/views.py +++ b/apps/ocr/views.py @@ -123,9 +123,9 @@ def queue_document_multiple_delete(request): def submit_document_multiple(request): for item_id in request.GET.get('id_list', '').split(','): submit_document(request, item_id) - + return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) - + def submit_document(request, document_id): document = get_object_or_404(Document, pk=document_id) @@ -134,7 +134,7 @@ def submit_document(request, document_id): Permission.objects.check_permissions(request.user, [PERMISSION_OCR_DOCUMENT]) except PermissionDenied: AccessEntry.objects.check_access(PERMISSION_OCR_DOCUMENT, request.user, document) - + return submit_document_to_queue(request, document=document, post_submit_redirect=request.META.get('HTTP_REFERER', '/')) diff --git a/apps/permissions/api.py b/apps/permissions/api.py index 8b13789179..e69de29bb2 100644 --- a/apps/permissions/api.py +++ b/apps/permissions/api.py @@ -1 +0,0 @@ - diff --git a/apps/permissions/models.py b/apps/permissions/models.py index b21cdbf7ae..ff7dfd957f 100644 --- a/apps/permissions/models.py +++ b/apps/permissions/models.py @@ -13,7 +13,7 @@ from django.core.exceptions import PermissionDenied from common.models import AnonymousUserSingleton from .managers import (RoleMemberManager, StoredPermissionManager) - + logger = logging.getLogger(__name__) @@ -21,7 +21,7 @@ class PermissionNamespace(object): def __init__(self, name, label): self.name = name self.label = label - + def __unicode__(self): return unicode(self.label) @@ -29,17 +29,17 @@ class PermissionNamespace(object): class PermissionDoesNotExists(Exception): pass - + class PermissionManager(object): _permissions = {} DoesNotExist = PermissionDoesNotExists() - + @classmethod def register(cls, namespace, name, label): permission = Permission(namespace, name, label) cls._permissions[permission.uuid] = permission return permission - + @classmethod def check_permissions(cls, requester, permission_list): for permission in permission_list: @@ -49,11 +49,11 @@ class PermissionManager(object): logger.debug('no permission') raise PermissionDenied(ugettext(u'Insufficient permissions.')) - + @classmethod def get_for_holder(cls, holder): return StoredPermission.objects.get_for_holder(holder) - + @classmethod def all(cls): # Return sorted permisions by namespace.name @@ -69,21 +69,21 @@ class PermissionManager(object): return cls._permissions[get_dict['pk']].get_stored_permission() except KeyError: raise Permission.DoesNotExist - - + + def __init__(self, model): self.model = model - + class Permission(object): DoesNotExist = PermissionDoesNotExists - + def __init__(self, namespace, name, label): self.namespace = namespace self.name = name self.label = label self.pk = self.uuid - + def __unicode__(self): return unicode(self.label) @@ -93,7 +93,7 @@ class Permission(object): @property def uuid(self): return u'%s.%s' % (self.namespace.name, self.name) - + @property def stored_permission(self): return self.get_stored_permission() @@ -107,17 +107,17 @@ class Permission(object): stored_permission.save() stored_permission.volatile_permission = self return stored_permission - + def requester_has_this(self, requester): stored_permission = self.get_stored_permission() return stored_permission.requester_has_this(requester) def save(self, *args, **kwargs): return self.get_stored_permission() - + Permission.objects = PermissionManager(Permission) Permission._default_manager = Permission.objects - + class StoredPermission(models.Model): namespace = models.CharField(max_length=64, verbose_name=_(u'namespace')) @@ -126,62 +126,62 @@ class StoredPermission(models.Model): objects = StoredPermissionManager() class Meta: - ordering = ('namespace', ) + ordering = ('namespace', ) unique_together = ('namespace', 'name') verbose_name = _(u'permission') verbose_name_plural = _(u'permissions') - + def __init__(self, *args, **kwargs): super(StoredPermission, self).__init__(*args, **kwargs) self.volatile_permission = Permission.objects.get({'pk': '%s.%s' % (self.namespace, self.name)}, proxy_only=True) - + def __unicode__(self): return unicode(getattr(self, 'volatile_permission', self.name)) def get_holders(self): return [holder.holder_object for holder in self.permissionholder_set.all()] - def requester_has_this(self, requester): - requester = AnonymousUserSingleton.objects.passthru_check(requester) - logger.debug('requester: %s' % requester) - if isinstance(requester, User): - if requester.is_superuser or requester.is_staff: + def requester_has_this(self, actor): + actor = AnonymousUserSingleton.objects.passthru_check(actor) + logger.debug('actor: %s' % actor) + if isinstance(actor, User): + if actor.is_superuser or actor.is_staff: return True # Request is one of the permission's holders? - if requester in self.get_holders(): + if actor in self.get_holders(): return True # If not check if the requesters memberships objects is one of # the permission's holder? - roles = RoleMember.objects.get_roles_for_member(requester) + roles = RoleMember.objects.get_roles_for_member(actor) - if isinstance(requester, User): - groups = requester.groups.all() + if isinstance(actor, User): + groups = actor.groups.all() else: groups = [] for membership in list(set(roles) | set(groups)): if self.requester_has_this(membership): return True - + logger.debug('Fallthru') return False - def grant_to(self, requester): - requester = AnonymousUserSingleton.objects.passthru_check(requester) - permission_holder, created = PermissionHolder.objects.get_or_create(permission=self, holder_type=ContentType.objects.get_for_model(requester), holder_id=requester.pk) + def grant_to(self, actor): + actor = AnonymousUserSingleton.objects.passthru_check(actor) + permission_holder, created = PermissionHolder.objects.get_or_create(permission=self, holder_type=ContentType.objects.get_for_model(actor), holder_id=actor.pk) return created - def revoke_from(self, holder): - requester = AnonymousUserSingleton.objects.passthru_check(requester) + def revoke_from(self, actor): + actor = AnonymousUserSingleton.objects.passthru_check(actor) try: - permission_holder = PermissionHolder.objects.get(permission=self, holder_type=ContentType.objects.get_for_model(holder), holder_id=holder.pk) + permission_holder = PermissionHolder.objects.get(permission=self, holder_type=ContentType.objects.get_for_model(actor), holder_id=actor.pk) permission_holder.delete() return True except PermissionHolder.DoesNotExist: return False - + class PermissionHolder(models.Model): permission = models.ForeignKey(StoredPermission, verbose_name=_(u'permission')) @@ -228,7 +228,7 @@ class Role(models.Model): member = AnonymousUserSingleton.objects.passthru_check(member) member_type=ContentType.objects.get_for_model(member) role_member = RoleMember.objects.get(role=self, member_type=member_type, member_id=member.pk) - role_member.delete() + role_member.delete() def members(self, filter_dict=None): filter_dict = filter_dict or {} diff --git a/apps/permissions/runtime.py b/apps/permissions/runtime.py index 8b13789179..e69de29bb2 100644 --- a/apps/permissions/runtime.py +++ b/apps/permissions/runtime.py @@ -1 +0,0 @@ - diff --git a/apps/permissions/tests.py b/apps/permissions/tests.py index 2247054b35..3b31148896 100644 --- a/apps/permissions/tests.py +++ b/apps/permissions/tests.py @@ -20,4 +20,3 @@ Another way to test that 1 + 1 is equal to 2. >>> 1 + 1 == 2 True """} - diff --git a/apps/permissions/urls.py b/apps/permissions/urls.py index ed85c44527..a052f1471b 100644 --- a/apps/permissions/urls.py +++ b/apps/permissions/urls.py @@ -7,7 +7,7 @@ urlpatterns = patterns('permissions.views', url(r'^role/(?P\d+)/edit/$', 'role_edit', (), 'role_edit'), url(r'^role/(?P\d+)/delete/$', 'role_delete', (), 'role_delete'), url(r'^role/(?P\d+)/members/$', 'role_members', (), 'role_members'), - + url(r'^permissions/multiple/grant/$', 'permission_grant', (), 'permission_multiple_grant'), url(r'^permissions/multiple/revoke/$', 'permission_revoke', (), 'permission_multiple_revoke'), ) diff --git a/apps/permissions/views.py b/apps/permissions/views.py index a7e2df41fb..4d2230dbb2 100644 --- a/apps/permissions/views.py +++ b/apps/permissions/views.py @@ -24,7 +24,7 @@ from .models import Role, Permission, PermissionHolder, RoleMember from .forms import RoleForm, RoleForm_view from .permissions import (PERMISSION_ROLE_VIEW, PERMISSION_ROLE_EDIT, PERMISSION_ROLE_CREATE, PERMISSION_ROLE_DELETE, - PERMISSION_PERMISSION_GRANT, PERMISSION_PERMISSION_REVOKE) + PERMISSION_PERMISSION_GRANT, PERMISSION_PERMISSION_REVOKE) from .widgets import role_permission_link @@ -133,20 +133,20 @@ def permission_grant(request): permission = Permission.objects.get({'pk': item_properties['permission_id']}) except Permission.DoesNotExist: raise Http404 - + ct = get_object_or_404(ContentType, app_label=item_properties['requester_app_label'], model=item_properties['requester_model']) requester_model = ct.model_class() requester = get_object_or_404(requester_model, pk=item_properties['requester_id']) items.append({'requester': requester, 'permission': permission}) - + sorted_items = sorted(items, key=operator.itemgetter('requester')) # Group items by requester groups = itertools.groupby(sorted_items, key=operator.itemgetter('requester')) grouped_items = [(grouper, [permission['permission'] for permission in group_data]) for grouper, group_data in groups] - + # Warning: trial and error black magic ahead title_suffix = _(u' and ').join([_(u'%(permissions)s to %(requester)s') % {'permissions': ', '.join(['"%s"' % unicode(ps) for ps in p]), 'requester': unicode(r)} for r, p in grouped_items]) - + if len(grouped_items) == 1 and len(grouped_items[0][1]) == 1: permissions_label = _(u'permission') else: @@ -174,13 +174,13 @@ def permission_grant(request): 'permissions_label': permissions_label, 'title_suffix': title_suffix, } - + if len(grouped_items) == 1: context['object'] = grouped_items[0][0] return render_to_response('generic_confirm.html', context, context_instance=RequestContext(request)) - + def permission_revoke(request): Permission.objects.check_permissions(request.user, [PERMISSION_PERMISSION_REVOKE]) @@ -197,20 +197,20 @@ def permission_revoke(request): permission = Permission.objects.get({'pk': item_properties['permission_id']}) except Permission.DoesNotExist: raise Http404 - + ct = get_object_or_404(ContentType, app_label=item_properties['requester_app_label'], model=item_properties['requester_model']) requester_model = ct.model_class() requester = get_object_or_404(requester_model, pk=item_properties['requester_id']) items.append({'requester': requester, 'permission': permission}) - + sorted_items = sorted(items, key=operator.itemgetter('requester')) # Group items by requester groups = itertools.groupby(sorted_items, key=operator.itemgetter('requester')) grouped_items = [(grouper, [permission['permission'] for permission in group_data]) for grouper, group_data in groups] - + # Warning: trial and error black magic ahead title_suffix = _(u' and ').join([_(u'%(permissions)s to %(requester)s') % {'permissions': ', '.join(['"%s"' % unicode(ps) for ps in p]), 'requester': unicode(r)} for r, p in grouped_items]) - + if len(grouped_items) == 1 and len(grouped_items[0][1]) == 1: permissions_label = _(u'permission') else: @@ -238,7 +238,7 @@ def permission_revoke(request): 'permissions_label': permissions_label, 'title_suffix': title_suffix, } - + if len(grouped_items) == 1: context['object'] = grouped_items[0][0] @@ -259,7 +259,7 @@ def get_role_members(role, separate=False): user_ct = ContentType.objects.get(model='user') group_ct = ContentType.objects.get(model='group') anonymous = ContentType.objects.get(model='anonymoususersingleton') - + users = role.members(filter_dict={'member_type': user_ct}) groups = role.members(filter_dict={'member_type': group_ct}) anonymous = role.members(filter_dict={'member_type': anonymous}) @@ -268,34 +268,34 @@ def get_role_members(role, separate=False): return users, groups, anonymous else: members = [] - + if users: members.append((_(u'Users'), _as_choice_list(list(users)))) - + if groups: members.append((_(u'Groups'), _as_choice_list(list(groups)))) if anonymous: members.append((_(u'Special'), _as_choice_list(list(anonymous)))) - return members + return members def get_non_role_members(role): #non members = all users - members - staff - super users member_users, member_groups, member_anonymous = get_role_members(role, separate=True) - + staff_users = User.objects.filter(is_staff=True) super_users = User.objects.filter(is_superuser=True) - + users = set(User.objects.all()) - set(member_users) - set(staff_users) - set(super_users) groups = set(Group.objects.all()) - set(member_groups) anonymous = set([AnonymousUserSingleton.objects.get()]) - set(member_anonymous) - + non_members = [] if users: non_members.append((_(u'Users'), _as_choice_list(list(users)))) - + if groups: non_members.append((_(u'Groups'), _as_choice_list(list(groups)))) @@ -303,7 +303,7 @@ def get_non_role_members(role): non_members.append((_(u'Special'), _as_choice_list(list(anonymous)))) #non_holder_list.append((_(u'Special'), _as_choice_list([AnonymousUserSingleton.objects.get()]))) - + return non_members diff --git a/apps/smart_settings/__init__.py b/apps/smart_settings/__init__.py index 5926e68754..e28aa67add 100644 --- a/apps/smart_settings/__init__.py +++ b/apps/smart_settings/__init__.py @@ -2,6 +2,7 @@ from django.utils.translation import ugettext_lazy as _ from project_setup.api import register_setup + def is_superuser(context): return context['request'].user.is_staff or context['request'].user.is_superuser diff --git a/apps/smart_settings/tests.py b/apps/smart_settings/tests.py index 2247054b35..3b31148896 100644 --- a/apps/smart_settings/tests.py +++ b/apps/smart_settings/tests.py @@ -20,4 +20,3 @@ Another way to test that 1 + 1 is equal to 2. >>> 1 + 1 == 2 True """} - diff --git a/apps/sources/__init__.py b/apps/sources/__init__.py index 62027a4734..707b09ef67 100644 --- a/apps/sources/__init__.py +++ b/apps/sources/__init__.py @@ -2,15 +2,11 @@ from __future__ import absolute_import from django.utils.translation import ugettext_lazy as _ -from navigation.api import register_links, \ - register_model_list_columns -from permissions.models import Permission, PermissionNamespace +from navigation.api import (register_links, + register_model_list_columns) from common.utils import encapsulate from project_setup.api import register_setup -from documents.models import Document -from documents.permissions import (PERMISSION_DOCUMENT_CREATE, - PERMISSION_DOCUMENT_NEW_VERSION) -from acls.api import class_permissions +from documents.permissions import PERMISSION_DOCUMENT_NEW_VERSION from .staging import StagingFile from .models import (WebForm, StagingFolder, SourceTransformation, diff --git a/apps/sources/forms.py b/apps/sources/forms.py index 259f900062..714343530b 100644 --- a/apps/sources/forms.py +++ b/apps/sources/forms.py @@ -39,7 +39,7 @@ class StagingDocumentForm(DocumentForm): staging_list_index = self.fields.keyOrder.index('staging_file_id') staging_list = self.fields.keyOrder.pop(staging_list_index) self.fields.keyOrder.insert(0, staging_list) - + staging_file_id = forms.ChoiceField(label=_(u'Staging file')) class Meta(DocumentForm.Meta): @@ -63,7 +63,7 @@ class WebFormForm(DocumentForm): # Move the file filed to the top self.fields.keyOrder.remove('file') self.fields.keyOrder.insert(0, 'file') - + def clean_file(self): data = self.cleaned_data['file'] validate_whitelist_blacklist(data.name, self.source.whitelist.split(','), self.source.blacklist.split(',')) diff --git a/apps/sources/managers.py b/apps/sources/managers.py index 53aa143d5b..4e74ec7d4f 100644 --- a/apps/sources/managers.py +++ b/apps/sources/managers.py @@ -22,5 +22,5 @@ class SourceTransformationManager(models.Manager): ) except (ValueError, SyntaxError), e: warnings.append(e) - + return transformations, warnings diff --git a/apps/sources/models.py b/apps/sources/models.py index 8bf86d7a0c..52e828a4fe 100644 --- a/apps/sources/models.py +++ b/apps/sources/models.py @@ -9,7 +9,7 @@ from django.contrib.contenttypes import generic from django.core.exceptions import ValidationError from converter.api import get_available_transformations_choices -from converter.literals import DIMENSION_SEPARATOR +from converter.literals import DIMENSION_SEPARATOR from documents.models import DocumentType, Document from documents.literals import HISTORY_DOCUMENT_CREATED from document_indexing.api import update_indexes @@ -33,7 +33,7 @@ class BaseModel(models.Model): whitelist = models.TextField(blank=True, verbose_name=_(u'whitelist'), editable=False) blacklist = models.TextField(blank=True, verbose_name=_(u'blacklist'), editable=False) #document_type = models.ForeignKey(DocumentType, blank=True, null=True, verbose_name=_(u'document type'), help_text=(u'Optional document type to be applied to documents uploaded from this source.')) - + @classmethod def class_fullname(cls): return unicode(dict(SOURCE_CHOICES).get(cls.source_type)) @@ -44,10 +44,10 @@ class BaseModel(models.Model): def __unicode__(self): return u'%s' % self.title - + def fullname(self): return u' '.join([self.class_fullname(), '"%s"' % self.title]) - + def internal_name(self): return u'%s_%d' % (self.source_type, self.pk) @@ -66,15 +66,15 @@ class BaseModel(models.Model): self.upload_single_file(file_object, filename, document_type, metadata_dict_list, user) else: self.upload_single_file(file_object, filename, use_file_name, document_type, metadata_dict_list, user, document, new_version_data) - + file_object.close() - + def upload_single_file(self, file_object, filename=None, use_file_name=False, document_type=None, metadata_dict_list=None, user=None, document=None, new_version_data=None): if not document: document = Document() if document_type: document.document_type = document_type - document.save() + document.save() if metadata_dict_list: save_metadata_list(metadata_dict_list, document, create=True) @@ -93,7 +93,7 @@ class BaseModel(models.Model): if not new_version_data: new_version_data = {} - + new_version = document.new_version(file=file_object, **new_version_data) if filename: new_version.filename = filename @@ -103,7 +103,7 @@ class BaseModel(models.Model): new_version.apply_default_transformations(transformations) #TODO: new HISTORY for version updates - + class Meta: ordering = ('title',) abstract = True @@ -120,12 +120,12 @@ class InteractiveBaseModel(BaseModel): class Meta(BaseModel.Meta): abstract = True - + class StagingFolder(InteractiveBaseModel): is_interactive = True source_type = SOURCE_CHOICE_STAGING default_icon = SOURCE_ICON_DRIVE - + folder_path = models.CharField(max_length=255, verbose_name=_(u'folder path'), help_text=_(u'Server side filesystem path.')) preview_width = models.IntegerField(blank=True, null=True, verbose_name=_(u'preview width'), help_text=_(u'Width value to be passed to the converter backend.')) preview_height = models.IntegerField(blank=True, null=True, verbose_name=_(u'preview height'), help_text=_(u'Height value to be passed to the converter backend.')) @@ -173,16 +173,16 @@ class WebForm(InteractiveBaseModel): verbose_name = _(u'web form') verbose_name_plural = _(u'web forms') - + class WatchFolder(BaseModel): is_interactive = False source_type = SOURCE_CHOICE_WATCH - + folder_path = models.CharField(max_length=255, verbose_name=_(u'folder path'), help_text=_(u'Server side filesystem path.')) uncompress = models.CharField(max_length=1, choices=SOURCE_UNCOMPRESS_CHOICES, verbose_name=_(u'uncompress'), help_text=_(u'Whether to expand or not compressed archives.')) delete_after_upload = models.BooleanField(default=True, verbose_name=_(u'delete after upload'), help_text=_(u'Delete the file after is has been successfully uploaded.')) interval = models.PositiveIntegerField(verbose_name=_(u'interval'), help_text=_(u'Inverval in seconds where the watch folder path is checked for new documents.')) - + def save(self, *args, **kwargs): if self.pk: remove_job(self.internal_name()) @@ -191,11 +191,11 @@ class WatchFolder(BaseModel): def schedule(self): if self.enabled: - register_interval_job(self.internal_name(), - title=self.fullname(), func=self.execute, + register_interval_job(self.internal_name(), + title=self.fullname(), func=self.execute, kwargs={'source_id': self.pk}, seconds=self.interval ) - + def execute(self, source_id): source = WatchFolder.objects.get(pk=source_id) if source.uncompress == SOURCE_UNCOMPRESS_CHOICE_Y: @@ -203,11 +203,11 @@ class WatchFolder(BaseModel): else: expand = False print 'execute: %s' % self.internal_name() - + class Meta(BaseModel.Meta): verbose_name = _(u'watch folder') verbose_name_plural = _(u'watch folders') - + class ArgumentsValidator(object): message = _(u'Enter a valid value.') diff --git a/apps/sources/tests.py b/apps/sources/tests.py index 2247054b35..3b31148896 100644 --- a/apps/sources/tests.py +++ b/apps/sources/tests.py @@ -20,4 +20,3 @@ Another way to test that 1 + 1 is equal to 2. >>> 1 + 1 == 2 True """} - diff --git a/apps/sources/utils.py b/apps/sources/utils.py index 6d61ad9ebb..79a2c80fc4 100644 --- a/apps/sources/utils.py +++ b/apps/sources/utils.py @@ -9,28 +9,28 @@ def accept_item(value, whitelist, blacklist, default_accept=True): """ return true if this item is either whitelisted or not blacklisted - """ + """ if not whitelist: whitelist = [] - + if not blacklist: blacklist = [] - # note the order - for reject, item_list in ([False, whitelist], [True, blacklist]): + # note the order + for reject, item_list in ([False, whitelist], [True, blacklist]): #print 'item_list: %s' % item_list #print 'reject: %s' % reject for okpattern in item_list: #print 'okpattern: %s' % okpattern - if re.findall(okpattern.replace('*', '\S+'), value, re.I): - # match! + if re.findall(okpattern.replace('*', '\S+'), value, re.I): + # match! #print 'MATCH' - if reject: - return False - else: + if reject: + return False + else: return True - # default is to accept all + # default is to accept all return default_accept diff --git a/apps/sources/views.py b/apps/sources/views.py index 1f98826d2c..f116dfad64 100644 --- a/apps/sources/views.py +++ b/apps/sources/views.py @@ -26,7 +26,7 @@ from sources.literals import (SOURCE_CHOICE_WEB_FORM, SOURCE_CHOICE_STAGING, SOURCE_CHOICE_WATCH) from sources.literals import (SOURCE_UNCOMPRESS_CHOICE_Y, SOURCE_UNCOMPRESS_CHOICE_ASK) -from sources.staging import create_staging_file_class, StagingFile +from sources.staging import create_staging_file_class from sources.forms import (StagingDocumentForm, WebFormForm, WatchFolderSetupForm) from sources.forms import WebFormSetupForm, StagingFolderSetupForm @@ -47,7 +47,7 @@ def get_tab_link_for_source(source, document=None): else: view = u'upload_interactive' args = [u'"%s"' % source.source_type, source.pk] - + return { 'text': source.title, 'view': view, @@ -55,19 +55,19 @@ def get_tab_link_for_source(source, document=None): 'famfam': source.icon, 'keep_query': True, 'conditional_highlight': return_function(source), - } + } def get_active_tab_links(document=None): tab_links = [] - + web_forms = WebForm.objects.filter(enabled=True) for web_form in web_forms: tab_links.append(get_tab_link_for_source(web_form, document)) staging_folders = StagingFolder.objects.filter(enabled=True) for staging_folder in staging_folders: - tab_links.append(get_tab_link_for_source(staging_folder, document)) + tab_links.append(get_tab_link_for_source(staging_folder, document)) return { 'tab_links': tab_links, @@ -75,6 +75,7 @@ def get_active_tab_links(document=None): SOURCE_CHOICE_STAGING: staging_folders } + def upload_interactive(request, source_type=None, source_id=None, document_pk=None): subtemplates_list = [] @@ -84,7 +85,7 @@ def upload_interactive(request, source_type=None, source_id=None, document_pk=No Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_NEW_VERSION]) except PermissionDenied: AccessEntry.objects.check_access(PERMISSION_DOCUMENT_NEW_VERSION, request.user, document) - + results = get_active_tab_links(document) else: Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_CREATE]) @@ -148,7 +149,7 @@ def upload_interactive(request, source_type=None, source_id=None, document_pk=No expand = False new_filename = get_form_filename(form) - + web_form.upload_file(request.FILES['file'], new_filename, use_file_name=form.cleaned_data.get('use_file_name', False), document_type=document_type, @@ -156,7 +157,7 @@ def upload_interactive(request, source_type=None, source_id=None, document_pk=No metadata_dict_list=decode_metadata_from_url(request.GET), user=request.user, document=document, - new_version_data=form.cleaned_data.get('new_version_data') + new_version_data=form.cleaned_data.get('new_version_data') ) if document: messages.success(request, _(u'Document version uploaded successfully.')) @@ -179,7 +180,7 @@ def upload_interactive(request, source_type=None, source_id=None, document_pk=No title = _(u'upload a new version from source: %s') % web_form.title else: title = _(u'upload a local document from source: %s') % web_form.title - + subtemplates_list.append({ 'name': 'generic_form_subtemplate.html', 'context': { @@ -213,7 +214,7 @@ def upload_interactive(request, source_type=None, source_id=None, document_pk=No expand = False new_filename = get_form_filename(form) - + staging_folder.upload_file(staging_file.upload(), new_filename, use_file_name=form.cleaned_data.get('use_file_name', False), document_type=document_type, @@ -221,7 +222,7 @@ def upload_interactive(request, source_type=None, source_id=None, document_pk=No metadata_dict_list=decode_metadata_from_url(request.GET), user=request.user, document=document, - new_version_data=form.cleaned_data.get('new_version_data') + new_version_data=form.cleaned_data.get('new_version_data') ) if document: messages.success(request, _(u'Document version from staging file: %s, uploaded successfully.') % staging_file.filename) @@ -257,7 +258,7 @@ def upload_interactive(request, source_type=None, source_id=None, document_pk=No title = _(u'upload a new version from staging source: %s') % staging_folder.title else: title = _(u'upload a document from staging source: %s') % staging_folder.title - + subtemplates_list = [ { 'name': 'generic_form_subtemplate.html', @@ -274,7 +275,7 @@ def upload_interactive(request, source_type=None, source_id=None, document_pk=No 'hide_link': True, } }, - ] + ] if document: context['object'] = document @@ -289,11 +290,11 @@ def upload_interactive(request, source_type=None, source_id=None, document_pk=No }, 'upload_interactive': { 'links': results['tab_links'] - } + } } }, }) - + if not document: context.update( { @@ -309,7 +310,7 @@ def upload_interactive(request, source_type=None, source_id=None, document_pk=No ], } ) - + return render_to_response('generic_form.html', context, context_instance=RequestContext(request)) @@ -419,12 +420,12 @@ def setup_source_list(request, source_type): } return render_to_response('generic_list.html', context, - context_instance=RequestContext(request)) + context_instance=RequestContext(request)) def setup_source_edit(request, source_type, source_id): Permission.objects.check_permissions(request.user, [PERMISSION_SOURCES_SETUP_EDIT]) - + if source_type == SOURCE_CHOICE_WEB_FORM: cls = WebForm form_class = WebFormSetupForm @@ -434,7 +435,7 @@ def setup_source_edit(request, source_type, source_id): elif source_type == SOURCE_CHOICE_WATCH: cls = WatchFolder form_class = WatchFolderSetupForm - + source = get_object_or_404(cls, pk=source_id) next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', '/'))) @@ -476,12 +477,12 @@ def setup_source_delete(request, source_type, source_id): cls = WatchFolder form_icon = u'folder_delete.png' redirect_view = 'setup_watch_folder_list' - + redirect_view = reverse('setup_source_list', args=[source_type]) previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', redirect_view))) source = get_object_or_404(cls, pk=source_id) - + if request.method == 'POST': try: source.delete() @@ -510,7 +511,7 @@ def setup_source_delete(request, source_type, source_id): def setup_source_create(request, source_type): Permission.objects.check_permissions(request.user, [PERMISSION_SOURCES_SETUP_CREATE]) - + if source_type == SOURCE_CHOICE_WEB_FORM: cls = WebForm form_class = WebFormSetupForm @@ -520,7 +521,7 @@ def setup_source_create(request, source_type): elif source_type == SOURCE_CHOICE_WATCH: cls = WatchFolder form_class = WatchFolderSetupForm - + if request.method == 'POST': form = form_class(data=request.POST) if form.is_valid(): @@ -544,7 +545,7 @@ def setup_source_create(request, source_type): def setup_source_transformation_list(request, source_type, source_id): Permission.objects.check_permissions(request.user, [PERMISSION_SOURCES_SETUP_EDIT]) - + if source_type == SOURCE_CHOICE_WEB_FORM: cls = WebForm elif source_type == SOURCE_CHOICE_STAGING: @@ -571,12 +572,12 @@ def setup_source_transformation_list(request, source_type, source_id): } return render_to_response('generic_list.html', context, - context_instance=RequestContext(request)) + context_instance=RequestContext(request)) def setup_source_transformation_edit(request, transformation_id): Permission.objects.check_permissions(request.user, [PERMISSION_SOURCES_SETUP_EDIT]) - + source_transformation = get_object_or_404(SourceTransformation, pk=transformation_id) redirect_view = reverse('setup_source_transformation_list', args=[source_transformation.content_object.source_type, source_transformation.content_object.pk]) next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', redirect_view))) @@ -604,7 +605,7 @@ def setup_source_transformation_edit(request, transformation_id): ], 'next': next, }, - context_instance=RequestContext(request)) + context_instance=RequestContext(request)) def setup_source_transformation_delete(request, transformation_id): @@ -631,14 +632,14 @@ def setup_source_transformation_delete(request, transformation_id): 'navigation_object_list': [ {'object': 'source', 'name': _(u'source')}, {'object': 'transformation', 'name': _(u'transformation')} - ], + ], 'title': _(u'Are you sure you wish to delete source transformation "%(transformation)s"') % { 'transformation': source_transformation.get_transformation_display(), }, 'previous': previous, 'form_icon': u'shape_square_delete.png', }, - context_instance=RequestContext(request)) + context_instance=RequestContext(request)) def setup_source_transformation_create(request, source_type, source_id): @@ -650,11 +651,11 @@ def setup_source_transformation_create(request, source_type, source_id): cls = StagingFolder elif source_type == SOURCE_CHOICE_WATCH: cls = WatchFolder - + source = get_object_or_404(cls, pk=source_id) - + redirect_view = reverse('setup_source_transformation_list', args=[source.source_type, source.pk]) - + if request.method == 'POST': form = SourceTransformationForm_create(request.POST) if form.is_valid(): @@ -668,7 +669,7 @@ def setup_source_transformation_create(request, source_type, source_id): messages.error(request, _(u'Error creating source transformation; %s') % e) else: form = SourceTransformationForm_create() - + return render_to_response('generic_form.html', { 'form': form, 'source': source, diff --git a/apps/tags/forms.py b/apps/tags/forms.py index cd2bead2c2..b10ac68679 100644 --- a/apps/tags/forms.py +++ b/apps/tags/forms.py @@ -18,9 +18,9 @@ logger = logging.getLogger(__name__) class TagForm(forms.Form): - ''' + """ Form to edit an existing tag's properties - ''' + """ name = forms.CharField(label=_(u'Name')) color = forms.ChoiceField(choices=COLOR_CHOICES, label=_(u'Color')) @@ -36,7 +36,7 @@ class TagListForm(forms.Form): Permission.objects.check_permissions(user, [PERMISSION_TAG_VIEW]) except PermissionDenied: queryset = AccessEntry.objects.filter_objects_by_access(PERMISSION_TAG_VIEW, user, queryset) - + self.fields['tag'] = forms.ModelChoiceField( queryset=queryset, label=_(u'Tags')) diff --git a/apps/tags/urls.py b/apps/tags/urls.py index fff26800a8..14c9902303 100644 --- a/apps/tags/urls.py +++ b/apps/tags/urls.py @@ -12,6 +12,6 @@ urlpatterns = patterns('tags.views', url(r'^multiple/remove_from_document/(?P\d+)/$', 'tag_multiple_remove', (), 'tag_multiple_remove'), url(r'^document/(?P\d+)/add/$', 'tag_attach', (), 'tag_attach'), url(r'^document/(?P\d+)/list/$', 'document_tags', (), 'document_tags'), - + url(r'^(?P\d+)/acl/list/$', 'tag_acl_list', (), 'tag_acl_list'), ) diff --git a/apps/tags/views.py b/apps/tags/views.py index 50e8929c10..615c248829 100644 --- a/apps/tags/views.py +++ b/apps/tags/views.py @@ -40,11 +40,11 @@ def tag_create(request): if tag_name in Tag.objects.values_list('name', flat=True): messages.error(request, _(u'Tag already exists.')) return HttpResponseRedirect(previous) - + tag = Tag(name=tag_name) tag.save() TagProperties(tag=tag, color=form.cleaned_data['color']).save() - + messages.success(request, _(u'Tag created succesfully.')) return HttpResponseRedirect(redirect_url) else: @@ -54,7 +54,7 @@ def tag_create(request): 'title': _(u'create tag'), 'form': form, }, - context_instance=RequestContext(request)) + context_instance=RequestContext(request)) def tag_attach(request, document_id): @@ -63,7 +63,7 @@ def tag_attach(request, document_id): try: Permission.objects.check_permissions(request.user, [PERMISSION_TAG_ATTACH]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_TAG_ATTACH, request.user, document) + AccessEntry.objects.check_access(PERMISSION_TAG_ATTACH, request.user, document) next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', reverse('document_tags', args=[document.pk])))) @@ -108,7 +108,7 @@ def tag_list(request, queryset=None, extra_context=None): queryset = AccessEntry.objects.filter_objects_by_access(PERMISSION_TAG_VIEW, request.user, queryset) context['object_list'] = queryset - + return render_to_response('generic_list.html', context, context_instance=RequestContext(request) @@ -126,11 +126,11 @@ def tag_delete(request, tag_id=None, tag_id_list=None): else: messages.error(request, _(u'Must provide at least one tag.')) return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) - + try: Permission.objects.check_permissions(request.user, [PERMISSION_TAG_DELETE]) except PermissionDenied: - tags = AccessEntry.objects.filter_objects_by_access(PERMISSION_TAG_DELETE, request.user, tags) + tags = AccessEntry.objects.filter_objects_by_access(PERMISSION_TAG_DELETE, request.user, tags) 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', '/'))) @@ -178,7 +178,7 @@ def tag_edit(request, tag_id): try: Permission.objects.check_permissions(request.user, [PERMISSION_TAG_EDIT]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_TAG_EDIT, request.user, tag) + AccessEntry.objects.check_access(PERMISSION_TAG_EDIT, request.user, tag) if request.method == 'POST': form = TagForm(request.POST) @@ -227,13 +227,13 @@ def document_tags(request, document_id): Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW]) except PermissionDenied: AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document) - + context = { 'object': document, 'document': document, 'title': _(u'tags for: %s') % document, } - + return tag_list(request, queryset=document.tags.all(), extra_context=context) @@ -243,7 +243,7 @@ def tag_remove(request, document_id, tag_id=None, tag_id_list=None): try: Permission.objects.check_permissions(request.user, [PERMISSION_TAG_REMOVE]) except PermissionDenied: - AccessEntry.objects.check_access(PERMISSION_TAG_REMOVE, request.user, document) + AccessEntry.objects.check_access(PERMISSION_TAG_REMOVE, request.user, document) post_action_redirect = None diff --git a/apps/tags/widgets.py b/apps/tags/widgets.py index b9dcb0266b..521ad6a1b2 100644 --- a/apps/tags/widgets.py +++ b/apps/tags/widgets.py @@ -3,9 +3,9 @@ from django.utils.safestring import mark_safe def get_tags_inline_widget(document): - ''' + """ A tag widget that includes the total tag count for a given document - ''' + """ tags_template = [] tag_count = document.tags.count() if tag_count: @@ -13,17 +13,17 @@ def get_tags_inline_widget(document): for tag in document.tags.all(): tags_template.append(u'
  • %s
' % (tag.tagproperties_set.get().get_color_code(), tag.name)) - + tags_template.append(u'
') tags_template.append(u'') return mark_safe(u''.join(tags_template)) def get_tags_inline_widget_simple(document): - ''' + """ A tag widget that only displayes the rectangular colored boxes for a given document - ''' + """ tags_template = [] tag_count = document.tags.count() diff --git a/docs/changelog.rst b/docs/changelog.rst index 572225bb14..4a37902165 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,5 +1,6 @@ Version 0.12 ------------ +* Removal of the OCR_CACHE_URI configuration option * Upgrade commands: * ./manage.py syncdb diff --git a/docs/settings.rst b/docs/settings.rst index 8d9b0237be..d27a0bb0ac 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -270,14 +270,6 @@ OCR Default: ``10`` -.. data:: OCR_CACHE_URI - - Default: ``None`` - - URI in the form: ``"memcached://127.0.0.1:11211/"`` to specify a cache - backend to use for locking. Multiple hosts can be specified separated - by a semicolon. - .. data:: OCR_UNPAPER_PATH