titi: Agile Monkeying around with Activity Streams
Titi is a first stab at a universal ActivityStream interface.
BUGS:
- The XML output isn’t activity stream format: needs namespaces, much more
Example
Let’s define a super-simple twitter user and status model:
User = Struct.new(
:id, :screen_name, :protected, :followers_count, :friends_count, :statuses_count, :favourites_count, :created_at,
:name, :url, :location, :description, :time_zone, :utc_offset,
:profile_background_color, :profile_text_color, :profile_link_color, :profile_sidebar_border_color, :profile_sidebar_fill_color, :profile_background_tile, :profile_background_image_url, :profile_image_url
)
Status = Struct.new( :id, :created_at, :user, :favorited, :truncated,
:in_reply_to_user_id, :in_reply_to_status_id, :text, :source,
:in_reply_to_screen_name )
With no other work, we can pull a raw JSON hash off the wire and create model instances:
raw_json_resp = RestClient.get("http://twitter.com/statuses/show/12233609555.json")
Twitter::Status.adapt(JSON.load(raw_json_resp.to_s))
#=> #<struct Titi::Provider::Twitter::Status id=12233609555, created_at="Thu Apr 15 17:01:52 +0000 2010", user=#<struct Titi::Provider::Twitter::User id=1468401, screen_name="sockington", protected=false, followers_count=1520814, friends_count=457, statuses_count=6234, favourites_count=2, created_at=Mon, 19 Mar 2007 03:45:00 +0000, name="Sockamillion", url="http://www.sockington.org/", location="Waltham, MA", description="I am Jason Scott's Cat.", time_zone="Eastern Time (US & Canada)", utc_offset=-18000, profile_background_color="48484c", profile_text_color="000000", profile_link_color="000000", profile_sidebar_border_color="79c021", profile_sidebar_fill_color="585e7e", profile_background_tile=false, profile_background_image_url="http://a1.twimg.com/profile_background_images/6682718/SocksTwitter.jpg", profile_image_url="http://a3.twimg.com/profile_images/77537329/IMG_3738_normal.JPG">, favorited=false, truncated=false, in_reply_to_user_id=nil, in_reply_to_status_id=nil, text="THANK GOODNESS THE LIBRARY OF CONGRESS HAS UNDERSTOOD THE IMPORTANCE OF MY TWEETS what do you mean others are getting in too", source="<a href=\"http://apiwiki.twitter.com/\" rel=\"nofollow\">API</a>", in_reply_to_screen_name=nil>
Titi lets you write a straightforward and compact adaptor to activity stream format:
class Titi::Provider::Twitter::Status
def to_activity_stream_entry
ActivityStreams::Entry.adapt(
:id => %Q{tag:twitter.com,2007:http://twitter.com/#{user.screen_name}/statuses/#{id}},
:title => text,
:content => text,
:published => created_at,
:verb => :post
) do |entry|
entry. = ActivityStreams::Author.new(user.name, user.url)
entry.object = ActivityStreams::ActivityObject.adapt do |activity_obj|
activity_obj.id = id
activity_obj.title = text
activity_obj.published = created_at
activity_obj.updated = created_at
activity_obj. = entry.
end
end
end
end
Where the mapping is direct, you can use an attribute => attribute hash, as shown in the call to ActivityStreams::Entry.adapt. For anything more complex, you can run arbitrary code in the method’s block (the part within the do … end segment)
Here’s example output. note: this isn’t canonical activity streams format: the XML serialization needs work.
tweet = Twitter::Status.get(12233609555)
entry = tweet.to_activity_stream_entry
puts entry.to_xml
<?xml version="1.0" encoding="UTF-8"?>
<entry>
<verb type="symbol">post</verb>
<mood nil="true"></mood>
<category nil="true"></category>
<author>
<name>Sockamillion</name>
<uri>http://www.sockington.org/</uri>
</author>
<title>THANK GOODNESS THE LIBRARY OF CONGRESS HAS UNDERSTOOD THE IMPORTANCE OF MY TWEETS what do you mean others are getting in too</title>
<actor nil="true"></actor>
<published type="datetime">2010-04-15T17:01:52+00:00</published>
<rank nil="true"></rank>
<sync nil="true"></sync>
<id>tag:twitter.com,2007:http://twitter.com/sockington/statuses/12233609555</id>
<content>THANK GOODNESS THE LIBRARY OF CONGRESS HAS UNDERSTOOD THE IMPORTANCE OF MY TWEETS what do you mean others are getting in too</content>
<target nil="true"></target>
<link nil="true"></link>
<object>
<author>
<name>Sockamillion</name>
<uri>http://www.sockington.org/</uri>
</author>
<title>THANK GOODNESS THE LIBRARY OF CONGRESS HAS UNDERSTOOD THE IMPORTANCE OF MY TWEETS what do you mean others are getting in too</title>
<published>Thu Apr 15 17:01:52 +0000 2010</published>
<id type="integer">12233609555</id>
<vevent nil="true"></vevent>
<content nil="true"></content>
<link nil="true"></link>
<updated>Thu Apr 15 17:01:52 +0000 2010</updated>
<object-type nil="true"></object-type>
</object>
<source nil="true"></source>
<updated nil="true"></updated>
</entry>
Copyright
Copyright © 2010 Infochimps, Inc. Available under Apache license: see LICENSE for details.