# coding=utf-8
"""
"""
from __future__ import absolute_import
import sqlalchemy as sa
from sqlalchemy.orm import object_session
from abilian.services import Service
from abilian.core.signals import activity
from abilian.core.entities import Entity
from .models import ActivityEntry
__all__ = ['ActivityService']
[docs]class ActivityService(Service):
name = 'activity'
[docs] def init_app(self, app):
Service.init_app(self, app)
[docs] def start(self):
Service.start(self)
activity.connect(self.log_activity)
[docs] def stop(self):
Service.stop(self)
activity.disconnect(self.log_activity)
[docs] def log_activity(self, sender, actor, verb, object, target=None):
assert self.running
if not isinstance(object, Entity):
# generic forms may send signals inconditionnaly. For now we have activity
# only for Entities
return
session = object_session(object)
kwargs = dict(actor=actor, verb=verb, object_type=object.entity_type)
if sa.inspect(object).deleted:
# object is in deleted state: flush has occurred, don't reference it or
# we'll have an error when adding entry to session
kwargs['object_id'] = object.id
else:
kwargs['object'] = object
if target is not None:
kwargs['target_type'] = target.entity_type
if sa.inspect(target).deleted:
kwargs['target_id'] = target.id
else:
kwargs['target'] = target
entry = ActivityEntry(**kwargs)
entry.object_type = object.entity_type
session.add(entry)
@staticmethod
[docs] def entries_for_actor(actor, limit=50):
return ActivityEntry.query.filter(ActivityEntry.actor == actor).limit(limit).all()