-
Notifications
You must be signed in to change notification settings - Fork 20
Subscriptions Management & Implementation
A user can subscribe to various types of streams through Councilmatic:
- new legislation
- newly scheduled meetings/agenda items
If a user wants to receive updates (new actions, or comments) to content they can "bookmark" the content. A user is subscribed to any updates to their bookmarked content. They can bookmark or unbookmark content at any point in the content's life.
A few tasks must be regularly carried out to ensure up-to-date information: updating the cache of legislation content, updating the search index, updating the feeds, and sending off new content notifications. These are made accessible through Django management commands.
To send off emails to subscribers, use the command:
python manage.py sendfeedupdates
This command will get run once daily. A feed will only be sent to a subscriber if there have been changes to the content, and only changed content will be sent. The process that Councilmatic goes through is:
- Update all the site data.
- Update the newest data datetime on each feed.
- Go through each subscription and compare the last sent date to the latest updated date in the subscription feed.
- For each user, collect subscriptions that do have new content.
- Send the collection of new content to the user through the appropriate channel.
- Update the last sent date for the subscriber
The subscriptions.ContentFeed
model stores information necessary for retrieving a queryset of content. The subscriptions.Subscription
model associates a User
with a ContentFeed
, and stores information about the last time the user was sent the feed, etc.
subscriptions/models.py
:
class ContentFeed (models.Model): queryset = models.TextField() last_updated_calc = models.TextField() last_updated = models.DateTimeField(default=datetime(1970,1,1,0,0,0)) def get_content(self): ... def get_last_updated(self, results): ... @classmethod def factory(cls, queryset, last_updated_calc): ...
The query for the ContentFeed
is stored as a pickled iterable object. Don't judge me!!! Calling get_content
on a ContentFeed
will return you the results of the query. Calling get_last_updated
will return you the last time the given set of content was updated.
To create a ContentFeed
object, use the factory
method. This will take your parameters and pickle them for you, returning a valid ContentFeed
object. you must specify a last_updated_calc callable, because each set of content may have a different way of determining when it was last updated.
subscriptions/models.py
:
import django.contrib.auth.models as auth class Subscriber (auth.User): def subscribe(self, feed): ... class Subscription (models.Model): user = models.ForeignKey('Subscriber', related_name='subscriptions') feed = models.ForeignKey('ContentFeed') last_sent = models.DateTimeField()
A subscriber is a normal user. To subscribe a user to a content feed, simply call subscribe
on the Subscriber
. Note, if you just have an auth.User
object (say, from the request
or in a template), you get the subscriber version of the user with user.subscriber
. If the User
is not a Subscriber
(which it normally will be), this will raise a Subscriber.DoesNotExist
error.
When a Subscription
is first saved, the last_sent
time is set to the current time. This prevents subscribers from being bothered with content that was posted to a feed before the user subscribed to the feed.