Finish the move to the new events app
This commit is contained in:
@@ -5,36 +5,6 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from events.classes import Event
|
||||
|
||||
event_document_check_out = Event(name='checkouts_document_check_out', label=_('Document checked out'))
|
||||
|
||||
HISTORY_DOCUMENT_CHECKED_OUT = {
|
||||
'namespace': 'checkouts', 'name': 'document_checked_out',
|
||||
'label': _(u'Document checked out'),
|
||||
'summary': _(u'Document "%(document)s" checked out by %(fullname)s.'),
|
||||
'expressions': {'fullname': 'user.get_full_name() if user.get_full_name() else user'}
|
||||
}
|
||||
|
||||
event_document_check_in = Event(name='checkouts_document_check_in', label=_('Document checked in'))
|
||||
|
||||
HISTORY_DOCUMENT_CHECKED_IN = {
|
||||
'namespace': 'checkouts', 'name': 'document_checked_in',
|
||||
'label': _(u'Document checked in'),
|
||||
'summary': _(u'Document "%(document)s" checked in by %(fullname)s.'),
|
||||
'expressions': {'fullname': 'user.get_full_name() if user.get_full_name() else user'}
|
||||
}
|
||||
|
||||
event_document_auto_check_in = Event(name='checkouts_document_auto_check_in', label=_('Document automatically checked in'))
|
||||
|
||||
HISTORY_DOCUMENT_AUTO_CHECKED_IN = {
|
||||
'namespace': 'checkouts', 'name': 'document_auto_checked_in',
|
||||
'label': _(u'Document automatically checked in'),
|
||||
'summary': _(u'Document "%(document)s" automatically checked in.'),
|
||||
}
|
||||
|
||||
event_document_forceful_check_in = Event(name='checkouts_document_forceful_check_in', label=_('Document forcefully checked in'))
|
||||
|
||||
HISTORY_DOCUMENT_FORCEFUL_CHECK_IN = {
|
||||
'namespace': 'checkouts', 'name': 'document_forefull_check_in',
|
||||
'label': _(u'Document forcefully checked in'),
|
||||
'summary': _(u'Document "%(document)s" forcefully checked in by %(fullname)s.'),
|
||||
'expressions': {'fullname': 'user.get_full_name() if user.get_full_name() else user'}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ from acls.api import class_permissions
|
||||
from common.classes import ModelAttribute
|
||||
from common.utils import encapsulate, validate_path
|
||||
from dynamic_search.classes import SearchModel
|
||||
from history.permissions import PERMISSION_HISTORY_VIEW
|
||||
from events.permissions import PERMISSION_EVENTS_VIEW
|
||||
from main.api import register_maintenance_links
|
||||
from navigation.api import (register_links, register_model_list_columns)
|
||||
from navigation.links import link_spacer
|
||||
@@ -21,8 +21,9 @@ from .links import (document_clear_image_cache,
|
||||
document_clear_transformations, document_content,
|
||||
document_delete,
|
||||
document_document_type_edit,
|
||||
document_events_view,
|
||||
document_multiple_document_type_edit, document_download,
|
||||
document_edit, document_history_view, document_list,
|
||||
document_edit, document_list,
|
||||
document_list_recent, document_multiple_delete,
|
||||
document_multiple_clear_transformations,
|
||||
document_multiple_download,
|
||||
@@ -72,8 +73,7 @@ register_links([Document], [document_multiple_clear_transformations, document_mu
|
||||
register_links(Document, [document_preview], menu_name='form_header', position=0)
|
||||
register_links(Document, [document_content], menu_name='form_header', position=1)
|
||||
register_links(Document, [document_properties], menu_name='form_header', position=2)
|
||||
register_links(Document, [document_history_view], menu_name='form_header')
|
||||
register_links(Document, [document_version_list], menu_name='form_header')
|
||||
register_links(Document, [document_events_view, document_version_list], menu_name='form_header')
|
||||
|
||||
# Document Version links
|
||||
register_links(DocumentVersion, [document_version_revert, document_version_download])
|
||||
@@ -124,7 +124,7 @@ class_permissions(Document, [PERMISSION_DOCUMENT_DELETE,
|
||||
PERMISSION_DOCUMENT_TRANSFORM,
|
||||
PERMISSION_DOCUMENT_VERSION_REVERT,
|
||||
PERMISSION_DOCUMENT_VIEW,
|
||||
PERMISSION_HISTORY_VIEW])
|
||||
PERMISSION_EVENTS_VIEW])
|
||||
|
||||
document_search = SearchModel('documents', 'Document', permission=PERMISSION_DOCUMENT_VIEW, serializer_string='documents.serializers.DocumentSerializer')
|
||||
|
||||
|
||||
@@ -5,23 +5,4 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from events.classes import Event
|
||||
|
||||
event_document_create = Event(name='documents_document_create', label=_('Document created'))
|
||||
|
||||
HISTORY_DOCUMENT_CREATED = {
|
||||
'namespace': 'documents', 'name': 'document_created',
|
||||
'label': _(u'Document creation'),
|
||||
'summary': _(u'Document "%(content_object)s" created by %(fullname)s.'),
|
||||
'details': _(u'Document "%(content_object)s" created on %(datetime)s by %(fullname)s.'),
|
||||
'expressions': {'fullname': 'user[0]["fields"]["username"] if isinstance(user, list) else user.get_full_name() if user.get_full_name() else user.username'}
|
||||
}
|
||||
|
||||
event_document_edited = Event(name='documents_document_edit', label=_('Document edited'))
|
||||
|
||||
HISTORY_DOCUMENT_EDITED = {
|
||||
'namespace': 'documents', 'name': 'document_edited',
|
||||
'label': _(u'Document edited'),
|
||||
'summary': _(u'Document "%(content_object)s" edited by %(fullname)s.'),
|
||||
'details': _(u'Document "%(content_object)s" was edited on %(datetime)s by %(fullname)s.'),
|
||||
'expressions': {
|
||||
'fullname': 'user[0]["fields"]["username"] if isinstance(user, list) else user.get_full_name() if user.get_full_name() else user.username',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ from __future__ import absolute_import
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from history.permissions import PERMISSION_HISTORY_VIEW
|
||||
from events.permissions import PERMISSION_EVENTS_VIEW
|
||||
|
||||
from .permissions import (PERMISSION_DOCUMENT_PROPERTIES_EDIT,
|
||||
PERMISSION_DOCUMENT_VIEW, PERMISSION_DOCUMENT_DELETE,
|
||||
@@ -54,7 +54,7 @@ document_multiple_update_page_count = {'text': _(u'Reset page count'), 'view': '
|
||||
document_clear_transformations = {'text': _(u'Clear transformations'), 'view': 'documents:document_clear_transformations', 'args': 'object.id', 'famfam': 'page_paintbrush', 'permissions': [PERMISSION_DOCUMENT_TRANSFORM]}
|
||||
document_multiple_clear_transformations = {'text': _(u'Clear transformations'), 'view': 'documents:document_multiple_clear_transformations', 'famfam': 'page_paintbrush', 'permissions': [PERMISSION_DOCUMENT_TRANSFORM]}
|
||||
document_print = {'text': _(u'Print'), 'view': 'documents:document_print', 'args': 'object.id', 'famfam': 'printer', 'permissions': [PERMISSION_DOCUMENT_VIEW]}
|
||||
document_history_view = {'text': _(u'History'), 'view': 'history:history_for_object', 'args': ['"documents"', '"document"', 'object.id'], 'famfam': 'book_go', 'permissions': [PERMISSION_HISTORY_VIEW]}
|
||||
document_events_view = {'text': _(u'Events'), 'view': 'events:events_for_object', 'args': ['"documents"', '"document"', 'object.id'], 'famfam': 'book_go', 'permissions': [PERMISSION_EVENTS_VIEW]}
|
||||
|
||||
# Tools
|
||||
document_clear_image_cache = {'text': _(u'Clear the document image cache'), 'view': 'documents:document_clear_image_cache', 'famfam': 'camera_delete', 'permissions': [PERMISSION_DOCUMENT_TOOLS], 'description': _(u'Clear the graphics representations used to speed up the documents\' display and interactive transformations results.')}
|
||||
|
||||
@@ -237,7 +237,7 @@ def document_edit(request, document_id):
|
||||
document.label = form.cleaned_data['document_type_available_filenames'].filename
|
||||
|
||||
document.save()
|
||||
event_document_edited.commit(actor=request.user)
|
||||
event_document_edited.commit(actor=request.user, target=document)
|
||||
document.add_as_recent_document_for_user(request.user)
|
||||
|
||||
messages.success(request, _(u'Document "%s" edited successfully.') % document)
|
||||
@@ -279,7 +279,7 @@ def document_document_type_edit(request, document_id=None, document_id_list=None
|
||||
|
||||
for document in documents:
|
||||
document.set_document_type(form.cleaned_data['document_type'])
|
||||
event_document_edited.commit(actor=request.user)
|
||||
event_document_edited.commit(actor=request.user, target=document)
|
||||
document.add_as_recent_document_for_user(request.user)
|
||||
|
||||
messages.success(request, _(u'Document type changed successfully.'))
|
||||
|
||||
@@ -1 +1,8 @@
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from project_tools.api import register_tool
|
||||
|
||||
from .classes import Event # NOQA
|
||||
from .links import events_list
|
||||
|
||||
register_tool(events_list)
|
||||
|
||||
@@ -2,8 +2,9 @@ from django.contrib import admin
|
||||
|
||||
from .models import EventType
|
||||
|
||||
|
||||
class EventTypeAdmin(admin.ModelAdmin):
|
||||
readonly_fields = ('name', 'get_label')
|
||||
readonly_fields = ('name', '__str__')
|
||||
|
||||
|
||||
admin.site.register(EventType, EventTypeAdmin)
|
||||
|
||||
@@ -1,22 +1,31 @@
|
||||
from __future__ import absolute_import
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from django.core import serializers
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from actstream import action
|
||||
|
||||
|
||||
class Event(object):
|
||||
_labels = {}
|
||||
|
||||
@classmethod
|
||||
def get_label(cls, name):
|
||||
try:
|
||||
return cls._labels[name]
|
||||
except KeyError:
|
||||
return _('Unknown or obsolete event type: {0}'.format(name))
|
||||
|
||||
def __init__(self, name, label):
|
||||
self.name = name
|
||||
self.label = label
|
||||
self.event_type = None
|
||||
self.__class__._labels[name] = label
|
||||
|
||||
def commit(self, actor=None, action_object=None, target=None):
|
||||
model = models.get_model('events', 'EventType')
|
||||
|
||||
if not self.event_type:
|
||||
self.event_type, created = model.objects.get_or_create(
|
||||
label=self.label, name=self.name)
|
||||
self.event_type, created = model.objects.get_or_create(name=self.name)
|
||||
|
||||
action.send(actor or target, actor=actor, verb=self.name, action_object=action_object, target=target)
|
||||
|
||||
5
mayan/apps/events/links.py
Normal file
5
mayan/apps/events/links.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
events_list = {'text': _('Events'), 'view': 'events:events_list', 'famfam': 'book', 'icon': 'book.png'}
|
||||
@@ -1,23 +0,0 @@
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.db import models
|
||||
|
||||
|
||||
class EventTypeManager(models.Manager):
|
||||
def create(self, *args, **kwargs):
|
||||
label = kwargs.pop('label')
|
||||
|
||||
instance = super(EventTypeManager, self).create(*args, **kwargs)
|
||||
self.model._labels[instance.name] = label
|
||||
return instance
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
instance = super(EventTypeManager, self).get(*args, **kwargs)
|
||||
instance.label = self.model._labels[instance.name]
|
||||
return instance
|
||||
|
||||
def get_or_create(self, *args, **kwargs):
|
||||
label = kwargs.pop('label')
|
||||
|
||||
instance, boolean = super(EventTypeManager, self).get_or_create(*args, **kwargs)
|
||||
self.model._labels[instance.name] = label
|
||||
return instance, boolean
|
||||
@@ -4,30 +4,38 @@ from django.db import models
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from .managers import EventTypeManager
|
||||
from actstream.models import Action
|
||||
|
||||
from common.utils import encapsulate
|
||||
from navigation.api import register_model_list_columns
|
||||
|
||||
from .classes import Event
|
||||
from .widgets import event_type_link
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class EventType(models.Model):
|
||||
_labels = {}
|
||||
|
||||
name = models.CharField(max_length=64, unique=True, verbose_name=_('Name'))
|
||||
|
||||
objects = EventTypeManager()
|
||||
|
||||
def __str__(self):
|
||||
return unicode(self.get_label())
|
||||
|
||||
def get_label(self):
|
||||
try:
|
||||
return self.__class__._labels[self.name]
|
||||
except KeyError:
|
||||
return _('Unknown or obsolete event type: {0}'.format(self.name))
|
||||
|
||||
#@models.permalink
|
||||
#def get_absolute_url(self):
|
||||
# return ('history_type_list', [self.pk])
|
||||
return unicode(Event.get_label(self.name))
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Event type')
|
||||
verbose_name_plural = _('Event types')
|
||||
|
||||
|
||||
register_model_list_columns(Action, [
|
||||
{
|
||||
'name': _('Timestamp'),
|
||||
'attribute': 'timestamp'
|
||||
},
|
||||
{
|
||||
'name': _('Actor'),
|
||||
'attribute': 'actor',
|
||||
},
|
||||
{
|
||||
'name': _(u'Verb'),
|
||||
'attribute': encapsulate(lambda entry: event_type_link(entry))
|
||||
},
|
||||
])
|
||||
|
||||
8
mayan/apps/events/permissions.py
Normal file
8
mayan/apps/events/permissions.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from permissions.models import PermissionNamespace, Permission
|
||||
|
||||
events_namespace = PermissionNamespace('events', _('Events'))
|
||||
PERMISSION_EVENTS_VIEW = Permission.objects.register(events_namespace, 'events_view', _('Access the events of an object'))
|
||||
200
mayan/apps/events/south_migrations/0002_migrate_history_data.py
Normal file
200
mayan/apps/events/south_migrations/0002_migrate_history_data.py
Normal file
@@ -0,0 +1,200 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import json
|
||||
|
||||
from south.utils import datetime_utils as datetime
|
||||
from south.db import db
|
||||
from south.v2 import DataMigration
|
||||
from django.db import models
|
||||
|
||||
type_equivalence = {
|
||||
'documents.document_created': 'documents_document_create',
|
||||
'documents.document_edited': 'documents_document_edit',
|
||||
'checkouts.document_checked_out': 'checkouts_document_check_out',
|
||||
'checkouts.document_checked_in': 'checkouts_document_check_in',
|
||||
'checkouts.document_auto_checked_in': 'checkouts_document_auto_check_in',
|
||||
'checkouts.document_forefull_check_in': 'checkouts_document_forceful_check_in',
|
||||
}
|
||||
|
||||
|
||||
class Migration(DataMigration):
|
||||
|
||||
depends_on = (
|
||||
('actstream', '0001_initial'),
|
||||
('history', '0002_auto__chg_field_history_datetime'),
|
||||
)
|
||||
|
||||
def forwards(self, orm):
|
||||
"Write your forwards methods here."
|
||||
# Note: Don't use "from appname.models import ModelName".
|
||||
# Use orm.ModelName to refer to models in this application,
|
||||
# and orm['appname.ModelName'] for models in other applications.
|
||||
|
||||
user_content_type = orm['contenttypes.contenttype'].objects.get(app_label='auth', model='user')
|
||||
|
||||
for history_event in orm['history.history'].objects.all():
|
||||
user_pk = None
|
||||
if history_event.dictionary:
|
||||
loaded_dictionary = json.loads(history_event.dictionary)
|
||||
if 'user' in loaded_dictionary:
|
||||
user_pk = json.loads(loaded_dictionary['user']['value'])[0]['pk']
|
||||
|
||||
try:
|
||||
orm['documents.document'].objects.get(pk=history_event.object_id)
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
if user_pk and history_event.object_id:
|
||||
action = orm['actstream.action'](
|
||||
timestamp=history_event.datetime,
|
||||
actor_content_type=user_content_type,
|
||||
actor_object_id=user_pk,
|
||||
verb=type_equivalence['{0}.{1}'.format(history_event.history_type.namespace, history_event.history_type.name)],
|
||||
target_content_type=history_event.content_type,
|
||||
target_object_id=history_event.object_id
|
||||
)
|
||||
action.save()
|
||||
|
||||
def backwards(self, orm):
|
||||
"Write your backwards methods here."
|
||||
|
||||
models = {
|
||||
u'actstream.action': {
|
||||
'Meta': {'ordering': "('-timestamp',)", 'object_name': 'Action'},
|
||||
'action_object_content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'action_object'", 'null': 'True', 'to': u"orm['contenttypes.ContentType']"}),
|
||||
'action_object_object_id': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||
'actor_content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'actor'", 'to': u"orm['contenttypes.ContentType']"}),
|
||||
'actor_object_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'target_content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'target'", 'null': 'True', 'to': u"orm['contenttypes.ContentType']"}),
|
||||
'target_object_id': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||
'timestamp': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'verb': ('django.db.models.fields.CharField', [], {'max_length': '255'})
|
||||
},
|
||||
u'actstream.follow': {
|
||||
'Meta': {'unique_together': "(('user', 'content_type', 'object_id'),)", 'object_name': 'Follow'},
|
||||
'actor_only': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'object_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'started': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
|
||||
},
|
||||
u'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
u'auth.permission': {
|
||||
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
u'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
u'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
u'documents.document': {
|
||||
'Meta': {'ordering': "['-date_added']", 'object_name': 'Document'},
|
||||
'date_added': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'document_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'documents'", 'to': u"orm['documents.DocumentType']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'label': ('django.db.models.fields.CharField', [], {'default': "u'Uninitialized document'", 'max_length': '255', 'db_index': 'True'}),
|
||||
'language': ('django.db.models.fields.CharField', [], {'default': "u'eng'", 'max_length': '8'}),
|
||||
'uuid': ('django.db.models.fields.CharField', [], {'default': "u'bbce0d8c-5707-4b0d-a996-4f4780787b53'", 'max_length': '48'})
|
||||
},
|
||||
u'documents.documentpage': {
|
||||
'Meta': {'ordering': "['page_number']", 'object_name': 'DocumentPage'},
|
||||
'content': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'document_version': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'pages'", 'to': u"orm['documents.DocumentVersion']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'page_label': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
|
||||
'page_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'db_index': 'True'})
|
||||
},
|
||||
u'documents.documentpagetransformation': {
|
||||
'Meta': {'ordering': "('order',)", 'object_name': 'DocumentPageTransformation'},
|
||||
'arguments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'document_page': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['documents.DocumentPage']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'null': 'True', 'db_index': 'True', 'blank': 'True'}),
|
||||
'transformation': ('django.db.models.fields.CharField', [], {'max_length': '128'})
|
||||
},
|
||||
u'documents.documenttype': {
|
||||
'Meta': {'ordering': "['name']", 'object_name': 'DocumentType'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'}),
|
||||
'ocr': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
u'documents.documenttypefilename': {
|
||||
'Meta': {'ordering': "['filename']", 'unique_together': "(('document_type', 'filename'),)", 'object_name': 'DocumentTypeFilename'},
|
||||
'document_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'filenames'", 'to': u"orm['documents.DocumentType']"}),
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'filename': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||
},
|
||||
u'documents.documentversion': {
|
||||
'Meta': {'object_name': 'DocumentVersion'},
|
||||
'checksum': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'document': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'versions'", 'to': u"orm['documents.Document']"}),
|
||||
'encoding': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}),
|
||||
'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'mimetype': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||
'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
|
||||
},
|
||||
u'documents.recentdocument': {
|
||||
'Meta': {'ordering': "('-datetime_accessed',)", 'object_name': 'RecentDocument'},
|
||||
'datetime_accessed': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}),
|
||||
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['documents.Document']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
|
||||
},
|
||||
u'events.eventtype': {
|
||||
'Meta': {'object_name': 'EventType'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
|
||||
},
|
||||
u'history.history': {
|
||||
'Meta': {'ordering': "('-datetime',)", 'object_name': 'History'},
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}),
|
||||
'datetime': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'dictionary': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'history_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['history.HistoryType']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'object_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
u'history.historytype': {
|
||||
'Meta': {'ordering': "('namespace', 'name')", 'unique_together': "(('namespace', 'name'),)", 'object_name': 'HistoryType'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'namespace': ('django.db.models.fields.CharField', [], {'max_length': '64'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['history', 'auth', 'actstream', 'documents', 'events']
|
||||
symmetrical = True
|
||||
7
mayan/apps/events/urls.py
Normal file
7
mayan/apps/events/urls.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from django.conf.urls import patterns, url
|
||||
|
||||
urlpatterns = patterns('events.views',
|
||||
url(r'^all/$', 'events_list', (), 'events_list'),
|
||||
url(r'^for_object/(?P<app_label>[\w\-]+)/(?P<module_name>[\w\-]+)/(?P<object_id>\d+)/$', 'events_list', (), 'events_for_object'),
|
||||
url(r'^by_verb/(?P<verb>[\w\-]+)/$', 'events_list', (), 'events_by_verb'),
|
||||
)
|
||||
@@ -1,3 +1,88 @@
|
||||
from django.shortcuts import render
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
# Create your views here.
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.db.models.loading import get_model
|
||||
from django.http import Http404
|
||||
from django.shortcuts import get_object_or_404, render_to_response
|
||||
from django.template import RequestContext
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from actstream.models import Action, any_stream
|
||||
|
||||
from acls.models import AccessEntry
|
||||
from common.utils import encapsulate
|
||||
from permissions.models import Permission
|
||||
|
||||
from .classes import Event
|
||||
from .permissions import PERMISSION_EVENTS_VIEW
|
||||
from .widgets import event_object_link
|
||||
|
||||
|
||||
def events_list(request, app_label=None, module_name=None, object_id=None, verb=None):
|
||||
extra_columns = []
|
||||
|
||||
context = {
|
||||
'extra_columns': extra_columns,
|
||||
'hide_object': True,
|
||||
}
|
||||
|
||||
if app_label and module_name and object_id:
|
||||
model = get_model(app_label, module_name)
|
||||
if not model:
|
||||
raise Http404
|
||||
content_object = get_object_or_404(model, pk=object_id)
|
||||
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_EVENTS_VIEW])
|
||||
except PermissionDenied:
|
||||
AccessEntry.objects.check_access(PERMISSION_EVENTS_VIEW, request.user, content_object)
|
||||
|
||||
context.update({
|
||||
'object_list': any_stream(content_object),
|
||||
'title': _('Events for: %s') % content_object,
|
||||
'object': content_object
|
||||
})
|
||||
elif verb:
|
||||
pre_object_list = Action.objects.filter(verb=verb)
|
||||
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_EVENTS_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
|
||||
# provided object_list
|
||||
object_list = AccessEntry.objects.filter_objects_by_access(PERMISSION_EVENTS_VIEW, request.user, pre_object_list, related='content_object')
|
||||
else:
|
||||
object_list = pre_object_list
|
||||
|
||||
context.update({
|
||||
'title': _('Events of type: %s') % Event.get_label(verb),
|
||||
'object_list': object_list
|
||||
})
|
||||
else:
|
||||
pre_object_list = Action.objects.all()
|
||||
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_EVENTS_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
|
||||
# provided object_list
|
||||
object_list = AccessEntry.objects.filter_objects_by_access(PERMISSION_EVENTS_VIEW, request.user, pre_object_list, related='content_object')
|
||||
else:
|
||||
object_list = pre_object_list
|
||||
|
||||
context.update({
|
||||
'title': _('Events'),
|
||||
'object_list': object_list
|
||||
})
|
||||
|
||||
if not (app_label and module_name and object_id):
|
||||
extra_columns.append(
|
||||
{
|
||||
'name': _('Target'),
|
||||
'attribute': encapsulate(lambda entry: event_object_link(entry))
|
||||
}
|
||||
)
|
||||
return render_to_response('main/generic_list.html', context,
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
20
mayan/apps/events/widgets.py
Normal file
20
mayan/apps/events/widgets.py
Normal file
@@ -0,0 +1,20 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
from .classes import Event
|
||||
|
||||
|
||||
def event_object_link(entry):
|
||||
return mark_safe('<a href="%(url)s">%(label)s</a>' % {
|
||||
'url': entry.target.get_absolute_url() if entry.target else '#',
|
||||
'label': entry.target}
|
||||
)
|
||||
|
||||
|
||||
def event_type_link(entry):
|
||||
return mark_safe('<a href="%(url)s">%(label)s</a>' % {
|
||||
'url': reverse('events:events_by_verb', kwargs={'verb': entry.verb}),
|
||||
'label': Event.get_label(entry.verb)}
|
||||
)
|
||||
@@ -1,30 +1 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from project_tools.api import register_tool
|
||||
from navigation.api import register_model_list_columns, register_links
|
||||
from common.utils import encapsulate
|
||||
|
||||
from .models import History
|
||||
from .widgets import history_entry_type_link
|
||||
from .links import history_list, history_details
|
||||
|
||||
register_tool(history_list)
|
||||
|
||||
register_model_list_columns(History, [
|
||||
{
|
||||
'name': _(u'Date and time'),
|
||||
'attribute': 'datetime'
|
||||
},
|
||||
{
|
||||
'name': _(u'Type'),
|
||||
'attribute': encapsulate(lambda entry: history_entry_type_link(entry))
|
||||
},
|
||||
{
|
||||
'name': _(u'Summary'),
|
||||
'attribute': encapsulate(lambda entry: unicode(entry.get_processed_summary()))
|
||||
}
|
||||
])
|
||||
|
||||
register_links(History, [history_details])
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from common.forms import DetailForm
|
||||
|
||||
from .models import History
|
||||
|
||||
|
||||
class HistoryDetailForm(DetailForm):
|
||||
class Meta:
|
||||
model = History
|
||||
exclude = ('datetime', 'content_type', 'object_id', 'history_type', 'dictionary')
|
||||
@@ -1,8 +0,0 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from .permissions import PERMISSION_HISTORY_VIEW
|
||||
|
||||
history_list = {'text': _(u'History'), 'view': 'history:history_list', 'famfam': 'book', 'icon': 'book.png'}
|
||||
history_details = {'text': _(u'Details'), 'view': 'history:history_view', 'famfam': 'book_open', 'args': 'object.pk', 'permissions': [PERMISSION_HISTORY_VIEW]}
|
||||
@@ -1,9 +0,0 @@
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db import models
|
||||
|
||||
|
||||
class ObjectHistoryManager(models.Manager):
|
||||
def get_url_for_object(self):
|
||||
ct = ContentType.objects.get_for_model(self.instance)
|
||||
return reverse('history_for_object', args=[ct, self.instance.pk])
|
||||
@@ -1,108 +1,3 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import json
|
||||
import pickle
|
||||
|
||||
from django.contrib.contenttypes import generic
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core import serializers
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
#from .runtime_data import history_types_dict
|
||||
|
||||
|
||||
class HistoryType(models.Model):
|
||||
namespace = models.CharField(max_length=64, verbose_name=_(u'Namespace'))
|
||||
name = models.CharField(max_length=64, verbose_name=_(u'Name'))
|
||||
|
||||
def __unicode__(self):
|
||||
return '{0}.{1}'.format(self.namespace, self.name)
|
||||
# try:
|
||||
# return unicode(history_types_dict[self.namespace][self.name]['label'])
|
||||
# except KeyError:
|
||||
# return u'Obsolete history type: %s - %s' % (self.namespace, self.name)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('history:history_type_list', args=[self.pk])
|
||||
|
||||
class Meta:
|
||||
ordering = ('namespace', 'name')
|
||||
unique_together = ('namespace', 'name')
|
||||
verbose_name = _(u'History type')
|
||||
verbose_name_plural = _(u'History types')
|
||||
|
||||
|
||||
class History(models.Model):
|
||||
datetime = models.DateTimeField(verbose_name=_(u'Date time'), auto_now_add=True)
|
||||
content_type = models.ForeignKey(ContentType, blank=True, null=True)
|
||||
object_id = models.PositiveIntegerField(blank=True, null=True)
|
||||
content_object = generic.GenericForeignKey('content_type', 'object_id')
|
||||
history_type = models.ForeignKey(HistoryType, verbose_name=_(u'History type'))
|
||||
dictionary = models.TextField(verbose_name=_(u'Dictionary'), blank=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return u'%s - %s - %s' % (self.datetime, self.content_object, self.history_type)
|
||||
|
||||
def get_label(self):
|
||||
return history_types_dict[self.history_type.namespace][self.history_type.name]['label']
|
||||
|
||||
def get_summary(self):
|
||||
return history_types_dict[self.history_type.namespace][self.history_type.name].get('summary', u'')
|
||||
|
||||
def get_details(self):
|
||||
return history_types_dict[self.history_type.namespace][self.history_type.name].get('details', u'')
|
||||
|
||||
def get_expressions(self):
|
||||
return history_types_dict[self.history_type.namespace][self.history_type.name].get('expressions', {})
|
||||
|
||||
def get_processed_summary(self):
|
||||
return _process_history_text(self, self.get_summary())
|
||||
|
||||
def get_processed_details(self):
|
||||
return _process_history_text(self, self.get_details())
|
||||
|
||||
@models.permalink
|
||||
def get_absolute_url(self):
|
||||
return ('history_view', [self.pk])
|
||||
|
||||
class Meta:
|
||||
ordering = ('-datetime',)
|
||||
verbose_name = _(u'History')
|
||||
verbose_name_plural = _(u'Histories')
|
||||
|
||||
|
||||
def _process_history_text(history, text):
|
||||
key_values = {
|
||||
'content_object': history.content_object,
|
||||
'datetime': history.datetime
|
||||
}
|
||||
|
||||
loaded_dictionary = json.loads(history.dictionary)
|
||||
|
||||
new_dict = {}
|
||||
for key, values in loaded_dictionary.items():
|
||||
value_type = pickle.loads(str(values['type']))
|
||||
if isinstance(value_type, models.base.ModelBase):
|
||||
for deserialized in serializers.deserialize('json', values['value']):
|
||||
new_dict[key] = deserialized.object
|
||||
elif isinstance(value_type, models.query.QuerySet):
|
||||
qs = []
|
||||
for deserialized in serializers.deserialize('json', values['value']):
|
||||
qs.append(deserialized.object)
|
||||
new_dict[key] = qs
|
||||
else:
|
||||
new_dict[key] = json.loads(values['value'])
|
||||
|
||||
key_values.update(new_dict)
|
||||
expressions_dict = {}
|
||||
|
||||
for key, value in history.get_expressions().items():
|
||||
try:
|
||||
expressions_dict[key] = eval(value, key_values.copy())
|
||||
except Exception as exception:
|
||||
expressions_dict[key] = exception
|
||||
|
||||
key_values.update(expressions_dict)
|
||||
return text % key_values
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from permissions.models import PermissionNamespace, Permission
|
||||
|
||||
history_namespace = PermissionNamespace('history', _(u'History'))
|
||||
PERMISSION_HISTORY_VIEW = Permission.objects.register(history_namespace, 'history_view', _(u'Access the history of an object'))
|
||||
@@ -0,0 +1,52 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from south.utils import datetime_utils as datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
depends_on = (
|
||||
('events', '0002_migrate_history_data'),
|
||||
)
|
||||
|
||||
def forwards(self, orm):
|
||||
# Removing unique constraint on 'HistoryType', fields ['namespace', 'name']
|
||||
db.delete_unique(u'history_historytype', ['namespace', 'name'])
|
||||
|
||||
# Deleting model 'History'
|
||||
db.delete_table(u'history_history')
|
||||
|
||||
# Deleting model 'HistoryType'
|
||||
db.delete_table(u'history_historytype')
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Adding model 'History'
|
||||
db.create_table(u'history_history', (
|
||||
('history_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['history.HistoryType'])),
|
||||
('dictionary', self.gf('django.db.models.fields.TextField')(blank=True)),
|
||||
('object_id', self.gf('django.db.models.fields.PositiveIntegerField')(null=True, blank=True)),
|
||||
('datetime', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
|
||||
('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True, blank=True)),
|
||||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
))
|
||||
db.send_create_signal(u'history', ['History'])
|
||||
|
||||
# Adding model 'HistoryType'
|
||||
db.create_table(u'history_historytype', (
|
||||
('namespace', self.gf('django.db.models.fields.CharField')(max_length=64)),
|
||||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('name', self.gf('django.db.models.fields.CharField')(max_length=64)),
|
||||
))
|
||||
db.send_create_signal(u'history', ['HistoryType'])
|
||||
|
||||
# Adding unique constraint on 'HistoryType', fields ['namespace', 'name']
|
||||
db.create_unique(u'history_historytype', ['namespace', 'name'])
|
||||
|
||||
|
||||
models = {
|
||||
|
||||
}
|
||||
|
||||
complete_apps = ['history']
|
||||
@@ -1,8 +0,0 @@
|
||||
from django.conf.urls import patterns, url
|
||||
|
||||
urlpatterns = patterns('history.views',
|
||||
url(r'^list/$', 'history_list', (), 'history_list'),
|
||||
url(r'^list/for_object/(?P<app_label>[\w\-]+)/(?P<module_name>[\w\-]+)/(?P<object_id>\d+)/$', 'history_for_object', (), 'history_for_object'),
|
||||
url(r'^(?P<object_id>\d+)/$', 'history_view', (), 'history_view'),
|
||||
url(r'^type/(?P<history_type_pk>\d+)/list/$', 'history_type_list', (), 'history_type_list'),
|
||||
)
|
||||
@@ -1,105 +0,0 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.db.models.loading import get_model
|
||||
from django.http import Http404
|
||||
from django.shortcuts import get_object_or_404, render_to_response
|
||||
from django.template import RequestContext
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from acls.models import AccessEntry
|
||||
from common.utils import encapsulate
|
||||
from permissions.models import Permission
|
||||
|
||||
from .forms import HistoryDetailForm
|
||||
from .models import History, HistoryType
|
||||
from .permissions import PERMISSION_HISTORY_VIEW
|
||||
from .widgets import history_entry_object_link
|
||||
|
||||
|
||||
def history_list(request, object_list=None, title=None, extra_context=None):
|
||||
pre_object_list = object_list if not (object_list is None) else History.objects.all()
|
||||
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_HISTORY_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
|
||||
# provided object_list
|
||||
final_object_list = AccessEntry.objects.filter_objects_by_access(PERMISSION_HISTORY_VIEW, request.user, pre_object_list, related='content_object')
|
||||
else:
|
||||
final_object_list = pre_object_list
|
||||
|
||||
context = {
|
||||
'object_list': final_object_list,
|
||||
'title': title if title else _(u'History events'),
|
||||
'extra_columns': [
|
||||
{
|
||||
'name': _(u'Object link'),
|
||||
'attribute': encapsulate(lambda x: history_entry_object_link(x))
|
||||
},
|
||||
],
|
||||
'hide_object': True,
|
||||
}
|
||||
|
||||
if extra_context:
|
||||
context.update(extra_context)
|
||||
|
||||
return render_to_response('main/generic_list.html', context,
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def history_for_object(request, app_label, module_name, object_id):
|
||||
model = get_model(app_label, module_name)
|
||||
if not model:
|
||||
raise Http404
|
||||
content_object = get_object_or_404(model, pk=object_id)
|
||||
content_type = ContentType.objects.get_for_model(model)
|
||||
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_HISTORY_VIEW])
|
||||
except PermissionDenied:
|
||||
AccessEntry.objects.check_access(PERMISSION_HISTORY_VIEW, request.user, content_object)
|
||||
|
||||
context = {
|
||||
'object_list': History.objects.filter(content_type=content_type, object_id=object_id),
|
||||
'title': _(u'History events for: %s') % content_object,
|
||||
'object': content_object,
|
||||
'hide_object': True,
|
||||
}
|
||||
|
||||
return render_to_response('main/generic_list.html', context,
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def history_view(request, object_id):
|
||||
history = get_object_or_404(History, pk=object_id)
|
||||
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_HISTORY_VIEW])
|
||||
except PermissionDenied:
|
||||
AccessEntry.objects.check_access(PERMISSION_HISTORY_VIEW, request.user, history.content_object)
|
||||
|
||||
form = HistoryDetailForm(instance=history, extra_fields=[
|
||||
{'label': _(u'Date'), 'field': lambda x: x.datetime.date()},
|
||||
{'label': _(u'Time'), 'field': lambda x: unicode(x.datetime.time()).split('.')[0]},
|
||||
{'label': _(u'Object'), 'field': 'content_object'},
|
||||
{'label': _(u'Event type'), 'field': lambda x: x.get_label()},
|
||||
{'label': _(u'Additional details'), 'field': lambda x: x.get_processed_details() or _(u'None')},
|
||||
])
|
||||
|
||||
return render_to_response('main/generic_detail.html', {
|
||||
'title': _(u'Details for: %s') % history.get_processed_summary(),
|
||||
'form': form,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def history_type_list(request, history_type_pk):
|
||||
history_type = get_object_or_404(HistoryType, pk=history_type_pk)
|
||||
|
||||
return history_list(
|
||||
request,
|
||||
object_list=History.objects.filter(history_type=history_type),
|
||||
title=_(u'History events of type: %s') % history_type,
|
||||
)
|
||||
@@ -1,23 +0,0 @@
|
||||
from django.utils.html import escape
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
|
||||
def history_entry_object_link(entry):
|
||||
return mark_safe(u'<a href="%(url)s">%(label)s</a>' % {
|
||||
'url': entry.content_object.get_absolute_url() if entry.content_object else u'#',
|
||||
'label': escape(unicode(entry.content_object)) if entry.content_object else u''}
|
||||
)
|
||||
|
||||
|
||||
def history_entry_summary(entry):
|
||||
return mark_safe(u'<a href="%(url)s">%(label)s</a>' % {
|
||||
'url': entry.get_absolute_url(),
|
||||
'label': unicode(entry.get_processed_summary())}
|
||||
)
|
||||
|
||||
|
||||
def history_entry_type_link(entry):
|
||||
return mark_safe(u'<a href="%(url)s">%(label)s</a>' % {
|
||||
'url': entry.history_type.get_absolute_url(),
|
||||
'label': unicode(entry.history_type)}
|
||||
)
|
||||
@@ -2,7 +2,6 @@ from __future__ import absolute_import
|
||||
|
||||
from django.contrib.auth.models import User, Group
|
||||
|
||||
from actstream import registry
|
||||
|
||||
from navigation.api import register_links
|
||||
from navigation.links import link_spacer
|
||||
@@ -28,5 +27,4 @@ register_setup(group_setup)
|
||||
|
||||
APIEndPoint('users', app_name='user_management')
|
||||
|
||||
registry.register(User)
|
||||
registry.register(Group)
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User, Group
|
||||
|
||||
# Create your models here.
|
||||
from actstream import registry
|
||||
|
||||
registry.register(User)
|
||||
registry.register(Group)
|
||||
|
||||
@@ -8,7 +8,6 @@ urlpatterns = patterns('',
|
||||
url(r'^', include('common.urls', namespace='common')),
|
||||
url(r'^', include('main.urls', namespace='main')),
|
||||
url(r'^acls/', include('acls.urls', namespace='acls')),
|
||||
url(r'^activity/', include('actstream.urls')),
|
||||
url(r'^admin/', include(admin.site.urls)),
|
||||
url(r'^api/', include('rest_api.urls')),
|
||||
url(r'^checkouts/', include('checkouts.urls', namespace='checkouts')),
|
||||
@@ -18,9 +17,9 @@ urlpatterns = patterns('',
|
||||
url(r'^documents/', include('documents.urls', namespace='documents')),
|
||||
url(r'^documents/signatures/', include('document_signatures.urls', namespace='signatures')),
|
||||
url(r'^docs/', include('rest_framework_swagger.urls')),
|
||||
url(r'^events/', include('events.urls', namespace='events')),
|
||||
url(r'^folders/', include('folders.urls', namespace='folders')),
|
||||
url(r'^gpg/', include('django_gpg.urls', namespace='django_gpg')),
|
||||
url(r'^history/', include('history.urls', namespace='history')),
|
||||
url(r'^installation/', include('installation.urls', namespace='installation')),
|
||||
url(r'^linking/', include('linking.urls', namespace='linking')),
|
||||
url(r'^mailer/', include('mailer.urls', namespace='mailer')),
|
||||
|
||||
Reference in New Issue
Block a user