Converted NewsfeedModule.md
diff --git a/NewsfeedModule.wiki b/NewsfeedModule.md similarity index 60% rename from NewsfeedModule.wiki rename to NewsfeedModule.md index 68d3e12..1c253b5 100644 --- a/NewsfeedModule.wiki +++ b/NewsfeedModule.md
@@ -1,44 +1,41 @@ -#summary 'Sandworm' Newsfeed Module -#labels Importance-Useful,Phase-Requirements,Contents-Draft +[Source Code Repository](http://github.com/jamslevy/Melange/tree/master) -[http://github.com/jamslevy/Melange/tree/master Source Code Repository] -<wiki:toc max_depth="3" /> -= Introduction = +# Introduction - A framework for customizable news feeds for various entity kinds that can be formatted on various site pages. Each newsfeed includes a subscription link, and through a 'subscribe' url pattern is used to render XML feeds. +> A framework for customizable news feeds for various entity kinds that can be formatted on various site pages. Each newsfeed includes a subscription link, and through a 'subscribe' url pattern is used to render XML feeds. -Because of the relatively simple nature of the initial project, some of the post-midterm development will include an auxiliary open source pubsub component meant to be deployed separately, and act as a hub allowing Melange instances to host chat, Google Wave updates, and other real-time activity. +Because of the relatively simple nature of the initial project, some of the post-midterm development will include an auxiliary open source pubsub component meant to be deployed separately, and act as a hub allowing Melange instances to host chat, Google Wave updates, and other real-time activity. -= Newsfeed Model = +# Newsfeed Model An individual FeedItem entity is created for each news feed update. A garbage collection task will delete old feed items, so they don't take over the datastore. The FeedItem model contains the following properties: - * *sender* (db.Key) - The sender is the entity that was updated + * **sender** (db.Key) - The sender is the entity that was updated - * *receivers* (db.Key) - A list of entities whose news feed is being updated. + * **receivers** (db.Key) - A list of entities whose news feed is being updated. - * *update_type* (created, deleted, modified) + * **update\_type** (created, deleted, modified) - * *created* (datetime) + * **created** (datetime) -A FeedItem is created for each sender-receiver pair. For instance, if a document is created and saved, it is the sender while its associated project and program and user could all be receivers. +A FeedItem is created for each sender-receiver pair. For instance, if a document is created and saved, it is the sender while its associated project and program and user could all be receivers. -= Access Protection = +# Access Protection Very basic entity information (a title/name and a link) is shown in the Recent Updates box and the ATOM feed. This may violate access protection, and the alternative is to just show the name of the entity kind, or a truncated title. Because the mail subscriptions are privately sent on a per-user basis, they contain more detailed information about the updated entity. -= Logic = +# Logic Newsfeed logic consists of two public methods: - - * *addToFeed* takes a sender entity, a list of receiver entities, an update type, and an optional payload (like a text preview of a document). It adds all the receivers to a FeedItem with the specified payload: -{{{ + + * **addToFeed** takes a sender entity, a list of receiver entities, an update type, and an optional payload (like a text preview of a document). It adds all the receivers to a FeedItem with the specified payload: +``` for receiver in receivers: new_feed_item = soc.models.news_feed.FeedItem( sender_key= str(sender.key()), @@ -46,94 +43,96 @@ user = user, update_type = update_type ) -}}} +``` - * *retrieveFeed* takes a receiever entity, and retrieves it's latest news feed updates, with an optional count kwarg. This method is cached, with a cache handler in the /cache folder. + * **retrieveFeed** takes a receiever entity, and retrieves it's latest news feed updates, with an optional count kwarg. This method is cached, with a cache handler in the /cache folder. -{{{ +``` def retrieveFeed(self, entity, count=10): """ Retrieves feed for a given entity """ feed_items = soc.models.news_feed.FeedItem.all().filter( "receiver_key =", str(entity.key())).fetch(1000) return feed_items[:count] -}}} +``` -= Views = +# Views -The newsfeed template itself is simply a table modeled after the blog template that lists each news feed update, which is added to the context dict through the retrieveFeed method. +The newsfeed template itself is simply a table modeled after the blog template that lists each news feed update, which is added to the context dict through the retrieveFeed method. -= Subscribe via RSS = +# Subscribe via RSS -I've added a new url_path 'subscribe', so that a URL for requesting an ATOM feed would look like this: +I've added a new url\_path 'subscribe', so that a URL for requesting an ATOM feed would look like this: http://melange.appspot.com/site/subscribe/somesite The new URL pattern is configured in soc.views.helper.params: -{{{ +``` if params.get('subscribe'): new_params['django_patterns_defaults'] += [ (r'^%(url_name)s/(?P<access_type>subscribe)/%(key_fields)s$', '%(module_package)s.%(module_name)s.subscribe', 'Subscribe to %(name_plural)s')] -}}} +``` This address is added to pages with a meta tag: - <link rel="alternate" type="application/rss+xml" title="RSS" href="{{ feed_url }}"/> +> -There is also a graphic subscribe icon on the corner of the newsfeed GUI module. - -The 'subscribe' path will also be the interface for any PubSub interactions, but those will only be activated on POST requests with a callback URL, otherwise the ATOM feed will be returned as normal. +<link rel="alternate" type="application/rss+xml" title="RSS" href="{{ feed\_url }}"/> -= Notification Integration = + +There is also a graphic subscribe icon on the corner of the newsfeed GUI module. + +The 'subscribe' path will also be the interface for any PubSub interactions, but those will only be activated on POST requests with a callback URL, otherwise the ATOM feed will be returned as normal. + + +# Notification Integration The notifications module has been in need of work, and I've refactored it so that it has two new beneficial features: - * Deploy to multiple contexts (the newsfeed widget, an ATOM feed for the user w/ pubsub support, and information-enriched private e-mails). - - * Any entity with a newsfeed can now be referenced in the notification so that that entity's newsfeed will be updated, etc. + * Deploy to multiple contexts (the newsfeed widget, an ATOM feed for the user w/ pubsub support, and information-enriched private e-mails). + + * Any entity with a newsfeed can now be referenced in the notification so that that entity's newsfeed will be updated, etc. -== Notification TODO == +## Notification TODO -* Refactor access handler to be able to perform reflective rights-based queries. -* Improve notifications front-end -* Licensing issues for images? -* Improve e-mail format to take better advantage of entity-tagging in notes. -* Tag multiple entities in notification. +**Refactor access handler to be able to perform reflective rights-based queries.** Improve notifications front-end +**Licensing issues for images?** Improve e-mail format to take better advantage of entity-tagging in notes. +**Tag multiple entities in notification.** -= E-mail Tasks = +# E-mail Tasks When a feed item is created, it schedules a handler to send out e-mail notification. This handler calls the sendFeedItemEmailNotifications method that fetches a list of users who are subscribed to the sender entity and e-mails them. -E-mails are now each sent via the mail_dispatcher task. Since it is very common to get OverQuotaErrors, this task API should always be used for sending e-mails. +E-mails are now each sent via the mail\_dispatcher task. Since it is very common to get OverQuotaErrors, this task API should always be used for sending e-mails. -= User Subscriptions = +# User Subscriptions -The subscriptions model contains a relational index entity for the user, containing a list of entity keys that the user is subscribed to. From their edit_profile page, the user can set a global preference for whether they are accepting e-mail notifications, and the user can also configure individual entity preferences from those pages using the subscribe-by-star UI pattern. +The subscriptions model contains a relational index entity for the user, containing a list of entity keys that the user is subscribed to. From their edit\_profile page, the user can set a global preference for whether they are accepting e-mail notifications, and the user can also configure individual entity preferences from those pages using the subscribe-by-star UI pattern. -= PubSubHubbub Support = +# PubSubHubbub Support -<wiki:video url="http://www.youtube.com/watch?v=ewQBgbysSOQ"/> +<a href='http://www.youtube.com/watch?feature=player_embedded&v=ewQBgbysSOQ' target='_blank'><img src='http://img.youtube.com/vi/ewQBgbysSOQ/0.jpg' width='425' height=344 /></a> This demo demonstrates Google Reader updating in seconds after a blog is updated. -It should be fairly trivial to integrate push notification support, and abstract it so that it could also be accessed by other Melange features. +It should be fairly trivial to integrate push notification support, and abstract it so that it could also be accessed by other Melange features. -== TODO == +## TODO -== Subscription Handler == +## Subscription Handler The subscriptions logic contains an UpdateLogic class that is meant to automatically compile a list of users with read-access to an arbitrary entity. Unfortunately, setting subscriptions manually is the only option right now, since the automatic subscription handler is not nearly where I hoped it would be by now. The idea is very simple - just subscribe users to the entities where they have read-access. But the reality @@ -142,12 +141,12 @@ interface (subscribe-by-star). The takeaway from this is that perhaps the access component should be abstracted to a high-level API, because it appears to have gained dependencies and complexities that prevent it from -being useful to the news feed logic. +being useful to the news feed logic. -== Post Commit Hooks == +## Post Commit Hooks Since most soc projects involve a code repository, it would be useful to allow repository commits to enter the news feed. This is already possible through using an RSS feed, but real-time updates could be generated by using the Google Code Post Commit Hook Support: http://code.google.com/p/support/wiki/PostCommitWebHooks -This would require project owners to change a setting on their projects, and would be fairly easy to implement. \ No newline at end of file +This would require project owners to change a setting on their projects, and would be fairly easy to implement. \ No newline at end of file