diff --git a/abilian/services/activity/__init__.py b/abilian/services/activity/__init__.py new file mode 100644 index 00000000..d8f183cc --- /dev/null +++ b/abilian/services/activity/__init__.py @@ -0,0 +1,2 @@ +from .service import ActivityService +from .models import ActivityEntry \ No newline at end of file diff --git a/abilian/services/activity.py b/abilian/services/activity/models.py similarity index 59% rename from abilian/services/activity.py rename to abilian/services/activity/models.py index 80f1b6ef..f340e108 100644 --- a/abilian/services/activity.py +++ b/abilian/services/activity/models.py @@ -16,9 +16,10 @@ from sqlalchemy.types import Integer, DateTime, Text from abilian.core.entities import db, all_entity_classes -from abilian.core.signals import activity from abilian.core.subjects import User +__all__ = ['ActivityEntry'] + # TODO: review the design as it hits the DB with too many requests. class ActivityEntry(db.Model): @@ -48,41 +49,3 @@ def object(self): if cls.__name__ == self.object_class: return cls.query.get(self.object_id) raise Exception("Unknown class: %s" % self.object_class) - - -class ActivityService(object): - - def __init__(self, app=None): - self.running = False - if app: - self.init_app(app) - - def init_app(self, app): - self.app = app - - def start(self): - assert not self.running - activity.connect(self.log_activity) - self.running = True - - def stop(self): - assert self.running - activity.disconnect(self.log_activity) - self.running = False - - def log_activity(self, sender, actor, verb, object, subject=None): - assert self.running - entry = ActivityEntry() - entry.actor = actor - entry.verb = verb - entry.object_id = object.id - entry.object_class = object.__class__.__name__ - if subject: - entry.subject_id = subject.id - entry.subject_class = subject.__class__.__name__ - - db.session.add(entry) - - @staticmethod - def entries_for_actor(actor, limit=50): - return ActivityEntry.query.filter(ActivityEntry.actor_id == actor.id).limit(limit).all() diff --git a/abilian/services/activity/service.py b/abilian/services/activity/service.py new file mode 100644 index 00000000..0dfb4a0a --- /dev/null +++ b/abilian/services/activity/service.py @@ -0,0 +1,45 @@ +from abilian.core.extensions import db +from abilian.core.signals import activity + +from .models import ActivityEntry + + +__all__ = ['ActivityService'] + + +class ActivityService(object): + + def __init__(self, app=None): + self.running = False + if app: + self.init_app(app) + + def init_app(self, app): + self.app = app + + def start(self): + assert not self.running + activity.connect(self.log_activity) + self.running = True + + def stop(self): + assert self.running + activity.disconnect(self.log_activity) + self.running = False + + def log_activity(self, sender, actor, verb, object, subject=None): + assert self.running + entry = ActivityEntry() + entry.actor = actor + entry.verb = verb + entry.object_id = object.id + entry.object_class = object.__class__.__name__ + if subject: + entry.subject_id = subject.id + entry.subject_class = subject.__class__.__name__ + + db.session.add(entry) + + @staticmethod + def entries_for_actor(actor, limit=50): + return ActivityEntry.query.filter(ActivityEntry.actor_id == actor.id).limit(limit).all() diff --git a/abilian/services/activity/tests.py b/abilian/services/activity/tests.py new file mode 100644 index 00000000..ba7086d3 --- /dev/null +++ b/abilian/services/activity/tests.py @@ -0,0 +1,37 @@ +from abilian.core.entities import Entity +from abilian.core.extensions import db +from abilian.core.subjects import User +from abilian.testing import BaseTestCase + +from .service import ActivityService + + +class Message1(Entity): + pass + +class ActivityTestCase(BaseTestCase): + + def setUp(self): + BaseTestCase.setUp(self) + self.activity_service = ActivityService() + self.activity_service.start() + + def test(self): + service = self.activity_service + user = User(email=u'test@example.com') + message = Message1() + + db.session.add(user) + db.session.add(message) + db.session.flush() + + service.log_activity(None, user, "post", message) + db.session.flush() + + entries = service.entries_for_actor(user, 10) + self.assertEquals(len(entries), 1) + entry = entries[0] + self.assertEquals(entry.actor, user) + self.assertEquals(entry.object, message) + + diff --git a/abilian/services/tagging/service.py b/abilian/services/tagging/service.py index b8a247f2..08866a44 100644 --- a/abilian/services/tagging/service.py +++ b/abilian/services/tagging/service.py @@ -1,6 +1,10 @@ +""" + +""" class Taggable(object): - """Mixin trait for taggable objects. + """ + Mixin trait for taggable objects. Currently not used. """ @@ -8,7 +12,8 @@ class Taggable(object): class TagService(object): - """The tag service. + """ + The tag service. """ def tag(self, object, term, user=None): @@ -22,7 +27,9 @@ def untag(self, object, term, user=None): """ def get_objects_tagged_with(self, term): - """Returns a list of objects tagged with a given term.""" + """Returns a list of objects tagged with a given term. + """ def get_tags_applied_on(self, object): - """Return a list of tags applied on a given document.""" + """Returns a list of tags applied on a given document. + """ diff --git a/abilian/testing/__init__.py b/abilian/testing/__init__.py index d0d63115..9e6b0e4f 100644 --- a/abilian/testing/__init__.py +++ b/abilian/testing/__init__.py @@ -11,6 +11,7 @@ class TestConfig(object): SQLALCHEMY_DATABASE_URI = "sqlite://" SQLALCHEMY_ECHO = False TESTING = True + SECRET = "" class BaseTestCase(TestCase):