abilian.services.activity.service — Abilian 0.1 documentation

# Source code for abilian.services.activity.service

    # coding=utf-8
    """
    """
    from __future__ import absolute_import, print_function, division

    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']

    class ActivityService(Service):
      name = 'activity'

      def init_app(self, app):
        Service.init_app(self, app)

      def start(self):
        Service.start(self)
        activity.connect(self.log_activity)

      def stop(self):
        Service.stop(self)
        activity.disconnect(self.log_activity)

      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
      def entries_for_actor(actor, limit=50):
        return ActivityEntry.query.filter(ActivityEntry.actor == actor).limit(limit).all()