Skip to content

axant/tgapp-activitystream

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

About activitystream

activitystream is a Pluggable application for TurboGears2 for create a simple activity stream.

The activity stream is intended to be used as base layer for a notification system

Currently this pluggable works only with ming fell free to submit a pull request with sqlalchemy support

Installing

activitystream can be installed both from pypi or from github:

pip install activitystream

should just work for most of the users

Plugging activitystream

In your application config/app_cfg.py import plug:

from tgext.pluggable import plug

Then at the end of the file call plug with activitystream:

plug(base_config, 'activitystream')

ActionManager

When you want to create an activity you should do something like:

from activitystream import ActionManager
am = ActionManager()

activity = am.create(
    actor=model.User.query.find().all()[0],
    verb='created',
    target=model.Post.query.find().all()[0],
    recipients=model.User.query.find().all()[1:3],
)

Then you may want to notify the activity to the recipients. It's up to you to choose how to dispatch them.

Fields Explanation

  • actor: reference to who is creating the activity
  • verb: a string describing the action itself, for example 'created' or 'updated'
  • action_obj: reference to ... I don't know
  • target: reference to the subject of the activity
  • timestamp: datetime of the creation of the activity
  • description: string with a description of the activity
  • extra: string that you can use for example to store a json with extra informations
  • recipients: list of references to who is expected to receive a notification from this activity. references can be of different entities.

Not Seen (counter of unread notifications)

Add in your recipient model (probably your User model):

from datetime import datetime
last_activity_seen = FieldProperty(s.DateTime, if_missing=datetime.utcnow())

then you can get the latest 10 notifications of a recipient with:

recipient = model.User.query.find().all()[1]
actions = am.get_by_recipient(recipient).limit(10).all()
# and if you want a counter of unread notifications call
count = am.count_not_seen_by_recipient(recipient)
# you can check if the recipient have seen a notification with
not_seen = actions[0].timestamp > recipient.last_activity_seen
# don't forget to update your recipient when him reads his notifications
recipient.last_activity_seen = datetime.utcnow()

Exposed Controllers

if you don't like your urls to start with activitystream just plug with a new app_id

  • /activitystream/ajax_update_last_seen_of_a_recipient: call this through ajax with _type and _id of the recipient to update last_activity_seen. should return a json with the last_activity_seen before the update
  • /activitystream/see: updates last_activity_seen of the logged in user and redirects to the given target_link

Notifications Rendering

This is up to you. I suggest to use tg.render_template with tg_cache

adding in myproject.lib.helpers:

from activitystream import am
from tg import render_template
def notification_cache(n):
    return {
        'cache_key': n._id,  # this is really important
        'cache_expire': 604800,  # a week
        'cache_type': 'memory',
    }

and in the template where you want your notifications to being displayed:

<py:for each="n in h.am.get_by_recipient(request.identity['user']).limit(10)">
  <li>${h.render_template(
    {'n': n, 'tg_cache': h.notification_cache(n)},
    'kajiki',
    'myproject.templates.notification'
  )}<hr/></li>
</py:for>

meanwhile your myproject.templates.notification may look like:

<a href="${h.plug_url('activitystream', '/see', params={'target_link': n.target_link})}">
  <img src="${n.actor.avatar_url}"/>
  <div class="content">
    <b>${n.actor.display_name}</b> ${_(n.verb)} <i>${n.target}</i>
    <div>${n.timestamp_since}</div>
  </div>
</a>

if your notification needs to be rendered differently based on the recipient then you have to use another caching strategy

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •