Hildon Event Feed
Hildon Event Feed is an event feed application and widget for Maemo5, with the purpose of display events posted by third-party applications and scripts. The event feed provides several DBus methods that can be used for posting events, removing events and adding refresh actions, which can be called using dbus-send or via one of the higher-level DBus APIs using Python, Qt etc.
The Hildon Event Feed DBus object is located at:
- Service: com.maemo.eventFeed
- Path: /
- Interface: com.maemo.eventFeed
[edit] DBus Methods
addEvent
Adds an event to the event feed.
Takes the following arguments:
sourceName (string): The name used to identify the source of the event. Must be unique to the source.
sourceDisplayName (string): The name representing the source for display purposes in the event feed UI.
icon (string): The path to the icon for the source. Can be a path to a local file, or a link to a file on a remote server.
title (string): The title of the event.
body (string): The description/details of the event.
images (array of strings): Images for the event (e.g video thumbnails). Only the first two images will be displayed. As with the icon, HTTP links can be used.
footer (string): Useful for indicating the original source of the event (e.g twitter username).
timestamp (string): The date and time of the event.
Accepted formats for timestamp:
- Timestamp in msecs since epoch, e.g '1349044868990'
- String in ISO format, e.g '2012-09-30T23:41:08.000Z'
- String in Qt::TextDate format, e.g 'Sun Sep 30 23:41:08 2012'
- String format 'Sun, 30 Sep 2012 23:41:08'
action (string): The action to be called when the user taps on the event in the event feed UI.
Accepted formats for action:
- dbus:session [service] [path] [interface] [method] [argument(s)] For DBus calls on session bus.
- dbus:system [service] [path] [interface] [method] [argument(s)] For DBus calls on system bus.
- exec [command] [argument(s)] For calling an application/script directly.
Returns:
eventId (long) if successful, else -1
removeEvent
Removes the specified event from the event feed.
Takes the following arguments:
eventId (long)
Returns:
success (boolean)
removeEventsBySourceName
Removes all events with sourceName equal to that specified.
Takes the following arguments:
sourceName (string)
Returns:
success (boolean)
addRefreshAction
Adds a refresh action for the specified source. This will be called when the user chooses to refresh the event feed.
Takes the following arguments:
sourceName (string)
refreshAction (string): Accepted formats are the same as for event action.
Returns:
success (boolean)
removeRefreshAction
Removes the refresh action for the specified source, if it exists.
Takes the following arguments:
sourceName (string)
Returns:
success (boolean)
getRefreshAction
Retrieves the refresh action for the specified source, if it exists.
Takes the following arguments:
sourceName (string)
Returns:
action (string) if it exists, else an empty string.
[edit] Examples
Adding an event
dbus-send
dbus-send --print-reply --type=method_call --dest=com.maemo.eventFeed / com.maemo.eventFeed.addEvent string:'my_source' string:'My Source' string:'/path/to/my/icon.png' string:'My Event' string:'This is an event' array:string:'/path/to/image/one.png', '/path/to/image/two.png' string:'Event footer' string:'2012-10-01T16:00:08.000Z' string:'exec /path/to/my/script argument'
Python
import dbus import datetime current_date_time = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S") bus = dbus.SessionBus() iface = dbus.Interface(bus.get_object("com.maemo.eventFeed", "/"), "com.maemo.eventFeed") event_id = iface.addEvent('my_source', 'My Source', '/path/to/my/icon.png', 'My Event', 'This is an event', ['/path/to/image/one.png', '/path/to/image/two.png'], 'Event footer', current_date_time, 'exec python /path/to/my/script argument') if event_id > 0: print event_id else: print 'Error adding event'
Example Python script to retrieve YouTube videos and add them to the event feed
#!/usr/bin/env python from __future__ import with_statement import urllib2 import simplejson import dbus import datetime import sys LAST_RUN_DATE_TIME_FILE = '/home/user/Event Feed/examples/YouTube/last_run.txt' # File to read/write serialized date/time when script was last run. SCRIPT_FILE = '/home/user/Event\ Feed/examples/YouTube/get_youtube_videos' # Path to the script. def get_youtube_videos(query): """ Retrieve YouTube videos and populate the Hildon Event Feed Usage: get_youtube_videos [query] """ query = query.strip().replace(' ', '+') video_feed = 'http://gdata.youtube.com/feeds/api/videos?v=2.1&max-results=20&alt=json&orderby=published&q=' video_fields = 'entry(media:group(media:title,media:thumbnail,media:description,media:credit,yt:uploaded,yt:videoid))' source_name = 'youtube_example' # Identifies the source of the events. Must be unique to the source. source_display_name = 'YouTube' # Display name for the source in the event feed UI. icon = '/home/user/Event Feed/examples/YouTube/youtube_icon.png' # Icon to be displayed in the event feed UI. action = 'dbus:system com.nokia.osso_browser /com/nokia/osso_browser/request com.nokia.osso_browser load_url' # This will be called when the user taps on an item in the event feed. In this example, the video url is opened in the browser. refresh_action = 'exec python %s %s' % (SCRIPT_FILE, query) # This will be called when the user presses the 'Refresh' button in the event feed UI. bus = dbus.SessionBus() iface = dbus.Interface(bus.get_object('com.maemo.eventFeed', '/'), 'com.maemo.eventFeed') # Connect to event feed dbus object iface.addRefreshAction(source_name, refresh_action) # Add a refresh action to the event feed. last_run = script_last_run() # Time when script was last run. Will be used to check against the date/time of each video in the feed. result = urllib2.urlopen('%s%s&fields=%s' % (video_feed, query, video_fields)).read() json_result = simplejson.loads(result) try: result = json_result['feed'] videos = result['entry'] except: videos = [] print 'Error retrieving video feed' for video in videos: try: group = video['media$group'] video_id = group['yt$videoid']['$t'] title = group['media$title']['$t'] description = group['media$description']['$t'] thumbnail = group['media$thumbnail'][3]['url'] thumbnail2 = group['media$thumbnail'][4]['url'] uploader = group['media$credit'][0]['$t'] upload_date = group['yt$uploaded']['$t'] try: item_date_time = datetime.datetime.strptime(upload_date[0: upload_date.find('.')], '%Y-%m-%dT%H:%M:%S') except: print 'Cannot parse item date/time. Using default' item_date_time = datetime.datetime.min if item_date_time > last_run: print iface.addEvent(source_name, source_display_name, icon, title, description, [thumbnail, thumbnail2], uploader, upload_date, '%s http://www.youtube.com/watch?v=%s' % (action, video_id)) except: print 'Error processing video item' set_script_last_run(datetime.datetime.now().strftime('%Y, %m, %d, %H, %M, %S')) def script_last_run(): """ Read serialized date/time from last_run.txt. """ date_time_string = last_run = datetime.datetime.min try: with open(LAST_RUN_DATE_TIME_FILE, 'r') as file: date_time_string = file.read() file.close() if date_time_string != : try: last_run = datetime.datetime.strptime(date_time_string, '%Y, %m, %d, %H, %M, %S') except: print 'Saved date/time in incorrect format. Using default' except IOError: print 'Cannot read date/time from file. Using default.' return last_run def set_script_last_run(date_time_string): """ Serialize the date/time the script was last run to last_run.txt. """ try: with open(LAST_RUN_DATE_TIME_FILE, 'w') as file: file.write(unicode(date_time_string)) file.close() except IOError: print 'Cannot write date/time to file' if __name__ == '__main__': if len(sys.argv) == 2: sys.exit(get_youtube_videos(sys.argv[1])) else: print 'Usage: get_youtube_videos [query]'
Example Python script to retrieve an RSS feed (default is latest TMO threads) and post new items to the event feed.
#!/usr/bin/env python from __future__ import with_statement import xml.dom.minidom as DOM import urllib2 import dbus import re import datetime import sys LAST_RUN_DATE_TIME_FILE = '/home/user/Event Feed/examples/RSS Feed/last_run.txt' # File to read/write serialized date/time when script was last run. SCRIPT_FILE = '/home/user/Event\ Feed/examples/RSS\ Feed/get_rss_feed' # Path to the script. def get_rss_feed(feed = 'http://talk.maemo.org/external.php?type=RSS2'): """ Retrieve the RSS feed (default is latest TMO threads) and post events to the Hildon Event Feed. """ source_name = 'rss_feed_example' # Source of the events display_name = 'RSS Feed' # Source name displayed in the event feed UI icon = '/usr/share/icons/hicolor/64x64/hildon/general_rss.png' # Icon for the events in the UI action = 'dbus:system com.nokia.osso_browser /com/nokia/osso_browser/request com.nokia.osso_browser load_url' # This will be called when the user taps on an item in the event feed. In this example, the link is opened in the browser. refresh_action = 'exec python %s %s' % (SCRIPT_FILE, feed) # When this refresh action is added, the script will be called again (with same feed) when the 'Refresh' button is pressed in the event feed UI. bus = dbus.SessionBus() iface = dbus.Interface(bus.get_object('com.maemo.eventFeed', '/'), 'com.maemo.eventFeed') # Get the event feed dbus object iface.addRefreshAction(source_name, refresh_action) # Add the refresh action to the event feed. last_run = script_last_run() # Time when script was last run. Will be used to check against the date/time of each item in the feed. rss = urllib2.urlopen(feed).read() doc = DOM.parseString(rss) items = doc.getElementsByTagName('item') link = title = body = images = [] footer = timestamp = for item in items: for node in item.childNodes: nodeName = node.nodeName if nodeName == 'link': link = node.firstChild.data elif nodeName == 'title': title = node.firstChild.data elif nodeName == 'description': body = node.firstChild.data elif nodeName == 'dc:creator': footer = node.firstChild.data elif nodeName == 'pubDate': timestamp = node.firstChild.data elif nodeName == 'content:encoded': images = get_images(node.firstChild.data) try: item_date_time = datetime.datetime.strptime(timestamp[0:timestamp.rfind(' ')], '%a, %d %b %Y %H:%M:%S') except: print 'Cannot parse item date/time. Using default' item_date_time = datetime.datetime.min if item_date_time > last_run: print iface.addEvent(source_name, display_name, icon, title, body, images, footer, timestamp, '%s %s' % (action, link)) # If item is new, add an event to the event feed and print the reply. set_script_last_run(datetime.datetime.now().strftime('%Y, %m, %d, %H, %M, %S')) def script_last_run(): """ Read serialized date/time from last_run.txt. """ date_time_string = last_run = datetime.datetime.min try: with open(LAST_RUN_DATE_TIME_FILE, 'r') as file: date_time_string = file.read() file.close() if date_time_string != : try: last_run = datetime.datetime.strptime(date_time_string, '%Y, %m, %d, %H, %M, %S') except: print 'Saved date/time in incorrect format. Using default' except IOError: print 'Cannot read date/time from file. Using default.' return last_run def set_script_last_run(date_time_string): """ Serialize the date/time the script was last run to last_run.txt. """ try: with open(LAST_RUN_DATE_TIME_FILE, 'w') as file: file.write(unicode(date_time_string)) file.close() except IOError: print 'Cannot write date/time to file' def get_images(content): """ Try to extract image links from the content:encoded node. """ images = re.findall('http://[^\s]+jpg|http://[^\s]+png', content) if len(images) > 2: images = images[0:2] return images if __name__ == '__main__': if len(sys.argv) > 1: sys.exit(get_rss_feed(sys.argv[1])) else: sys.exit(get_rss_feed())
marxian 15:09, 4 October 2012 (UTC)
- This page was last modified on 4 October 2012, at 19:54.
- This page has been accessed 5,745 times.