titi 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. data/README.textile +23 -4
  2. data/VERSION +1 -1
  3. data/examples/twitter.rb +4 -12
  4. data/lib/titi.rb +6 -0
  5. data/lib/titi/fetcher.rb +5 -0
  6. data/lib/titi/fetcher/json.rb +32 -0
  7. data/lib/titi/provider.rb +0 -23
  8. data/lib/titi/provider/activity_streams.rb +10 -139
  9. data/lib/titi/provider/activity_streams/activity_streams_struct.rb +46 -0
  10. data/lib/titi/provider/activity_streams/actor.rb +11 -0
  11. data/lib/titi/provider/activity_streams/address.rb +11 -0
  12. data/lib/titi/provider/activity_streams/entry.rb +38 -0
  13. data/lib/titi/provider/activity_streams/feed.rb +25 -0
  14. data/lib/titi/provider/activity_streams/feed.xml.erb +13 -11
  15. data/lib/titi/provider/activity_streams/link.rb +15 -0
  16. data/lib/titi/provider/activity_streams/obj.rb +19 -0
  17. data/lib/titi/provider/ameba/.gitignore +0 -0
  18. data/lib/titi/provider/avatars_united/.gitignore +0 -0
  19. data/lib/titi/provider/baidu/.gitignore +0 -0
  20. data/lib/titi/provider/bebo/.gitignore +0 -0
  21. data/lib/titi/provider/blipfm/.gitignore +0 -0
  22. data/lib/titi/provider/blippr/.gitignore +0 -0
  23. data/lib/titi/provider/bliptv/.gitignore +0 -0
  24. data/lib/titi/provider/blogger/.gitignore +0 -0
  25. data/lib/titi/provider/brightkite/.gitignore +0 -0
  26. data/lib/titi/provider/buzznet/.gitignore +0 -0
  27. data/lib/titi/provider/cinchcast/.gitignore +0 -0
  28. data/lib/titi/provider/corkd/.gitignore +0 -0
  29. data/lib/titi/provider/daily_motion/.gitignore +0 -0
  30. data/lib/titi/provider/delicious/.gitignore +0 -0
  31. data/lib/titi/provider/deviant_art/.gitignore +0 -0
  32. data/lib/titi/provider/digg/.gitignore +0 -0
  33. data/lib/titi/provider/diigo/.gitignore +0 -0
  34. data/lib/titi/provider/douban/.gitignore +0 -0
  35. data/lib/titi/provider/flickr/.gitignore +0 -0
  36. data/lib/titi/provider/flixster/.gitignore +0 -0
  37. data/lib/titi/provider/fotolog/.gitignore +0 -0
  38. data/lib/titi/provider/friendfeed/.gitignore +0 -0
  39. data/lib/titi/provider/friendster/.gitignore +0 -0
  40. data/lib/titi/provider/funny_or_die/.gitignore +0 -0
  41. data/lib/titi/provider/gamer_dna/.gitignore +0 -0
  42. data/lib/titi/provider/gather/.gitignore +0 -0
  43. data/lib/titi/provider/generic_feed.rb +49 -0
  44. data/lib/titi/provider/generic_feed/.gitignore +0 -0
  45. data/lib/titi/provider/goodreads/.gitignore +0 -0
  46. data/lib/titi/provider/google_reader/.gitignore +0 -0
  47. data/lib/titi/provider/hatena/.gitignore +0 -0
  48. data/lib/titi/provider/hi5/.gitignore +0 -0
  49. data/lib/titi/provider/hulu/.gitignore +0 -0
  50. data/lib/titi/provider/hyves/.gitignore +0 -0
  51. data/lib/titi/provider/identica/.gitignore +0 -0
  52. data/lib/titi/provider/ilike/.gitignore +0 -0
  53. data/lib/titi/provider/jaiku/.gitignore +0 -0
  54. data/lib/titi/provider/joost/.gitignore +0 -0
  55. data/lib/titi/provider/lastfm/.gitignore +0 -0
  56. data/lib/titi/provider/librarything/.gitignore +0 -0
  57. data/lib/titi/provider/list_of_providers.rb +142 -0
  58. data/lib/titi/provider/livejournal/.gitignore +0 -0
  59. data/lib/titi/provider/meneame/.gitignore +0 -0
  60. data/lib/titi/provider/metacafe/.gitignore +0 -0
  61. data/lib/titi/provider/mixx/.gitignore +0 -0
  62. data/lib/titi/provider/moby_picture/.gitignore +0 -0
  63. data/lib/titi/provider/multiply/.gitignore +0 -0
  64. data/lib/titi/provider/netlog/.gitignore +0 -0
  65. data/lib/titi/provider/newsvine/.gitignore +0 -0
  66. data/lib/titi/provider/pandora/.gitignore +0 -0
  67. data/lib/titi/provider/photobucket/.gitignore +0 -0
  68. data/lib/titi/provider/photocase/.gitignore +0 -0
  69. data/lib/titi/provider/picasa/.gitignore +0 -0
  70. data/lib/titi/provider/plurk/.gitignore +0 -0
  71. data/lib/titi/provider/posterous/.gitignore +0 -0
  72. data/lib/titi/provider/propeller/.gitignore +0 -0
  73. data/lib/titi/provider/qik/.gitignore +0 -0
  74. data/lib/titi/provider/qype/.gitignore +0 -0
  75. data/lib/titi/provider/raptr/.gitignore +0 -0
  76. data/lib/titi/provider/readernaut/.gitignore +0 -0
  77. data/lib/titi/provider/reddit/.gitignore +0 -0
  78. data/lib/titi/provider/revver/.gitignore +0 -0
  79. data/lib/titi/provider/skyrock/.gitignore +0 -0
  80. data/lib/titi/provider/slideshare/.gitignore +0 -0
  81. data/lib/titi/provider/smotri/.gitignore +0 -0
  82. data/lib/titi/provider/smugmug/.gitignore +0 -0
  83. data/lib/titi/provider/stumbleupon/.gitignore +0 -0
  84. data/lib/titi/provider/tumblr/.gitignore +0 -0
  85. data/lib/titi/provider/twelve_seconds/.gitignore +0 -0
  86. data/lib/titi/provider/twine/.gitignore +0 -0
  87. data/lib/titi/provider/twitter.rb +18 -15
  88. data/lib/titi/provider/twitter/.gitignore +0 -0
  89. data/lib/titi/provider/{twitter_rss → twitter}/README.textile +0 -0
  90. data/lib/titi/provider/twitter/models.rb +9 -11
  91. data/lib/titi/provider/{twitter_rss/models.rb → twitter/rss_feed.rb} +9 -10
  92. data/lib/titi/provider/vimeo/.gitignore +0 -0
  93. data/lib/titi/provider/visualizeus/.gitignore +0 -0
  94. data/lib/titi/provider/wordpress/.gitignore +0 -0
  95. data/lib/titi/provider/xanga/.gitignore +0 -0
  96. data/lib/titi/provider/yelp/.gitignore +0 -0
  97. data/lib/titi/provider/zooomr/.gitignore +0 -0
  98. data/spec/data/provider/ameba/.gitignore +0 -0
  99. data/spec/data/provider/avatars_united/.gitignore +0 -0
  100. data/spec/data/provider/baidu/.gitignore +0 -0
  101. data/spec/data/provider/bebo/.gitignore +0 -0
  102. data/spec/data/provider/blipfm/.gitignore +0 -0
  103. data/spec/data/provider/blippr/.gitignore +0 -0
  104. data/spec/data/provider/bliptv/.gitignore +0 -0
  105. data/spec/data/provider/blogger/.gitignore +0 -0
  106. data/spec/data/provider/brightkite/.gitignore +0 -0
  107. data/spec/data/provider/buzznet/.gitignore +0 -0
  108. data/spec/data/provider/cinchcast/.gitignore +0 -0
  109. data/spec/data/provider/corkd/.gitignore +0 -0
  110. data/spec/data/provider/daily_motion/.gitignore +0 -0
  111. data/spec/data/provider/delicious/.gitignore +0 -0
  112. data/spec/data/provider/delicious/delicious_bookmarks-activity_streams.xml +440 -0
  113. data/spec/data/provider/delicious/delicious_bookmarks-raw_feed.xml +239 -0
  114. data/spec/data/provider/deviant_art/.gitignore +0 -0
  115. data/spec/data/provider/digg/.gitignore +0 -0
  116. data/spec/data/provider/diigo/.gitignore +0 -0
  117. data/spec/data/provider/douban/.gitignore +0 -0
  118. data/spec/data/provider/flickr/.gitignore +0 -0
  119. data/spec/data/provider/flickr/flickr_favorites-activity_streams.xml +1040 -0
  120. data/spec/data/provider/flickr/flickr_favorites-raw_rss.xml +557 -0
  121. data/spec/data/provider/flixster/.gitignore +0 -0
  122. data/spec/data/provider/fotolog/.gitignore +0 -0
  123. data/spec/data/provider/friendfeed/.gitignore +0 -0
  124. data/spec/data/provider/friendster/.gitignore +0 -0
  125. data/spec/data/provider/funny_or_die/.gitignore +0 -0
  126. data/spec/data/provider/gamer_dna/.gitignore +0 -0
  127. data/spec/data/provider/gather/.gitignore +0 -0
  128. data/spec/data/provider/generic_feed/.gitignore +0 -0
  129. data/spec/data/provider/goodreads/.gitignore +0 -0
  130. data/spec/data/provider/google_reader/.gitignore +0 -0
  131. data/spec/data/provider/hatena/.gitignore +0 -0
  132. data/spec/data/provider/hi5/.gitignore +0 -0
  133. data/spec/data/provider/hulu/.gitignore +0 -0
  134. data/spec/data/provider/hyves/.gitignore +0 -0
  135. data/spec/data/provider/identica/.gitignore +0 -0
  136. data/spec/data/provider/identica/identica_statuses-raw_feed.xml +465 -0
  137. data/spec/data/provider/ilike/.gitignore +0 -0
  138. data/spec/data/provider/jaiku/.gitignore +0 -0
  139. data/spec/data/provider/joost/.gitignore +0 -0
  140. data/spec/data/provider/lastfm/.gitignore +0 -0
  141. data/spec/data/provider/librarything/.gitignore +0 -0
  142. data/spec/data/provider/livejournal/.gitignore +0 -0
  143. data/spec/data/provider/meneame/.gitignore +0 -0
  144. data/spec/data/provider/metacafe/.gitignore +0 -0
  145. data/spec/data/provider/mixx/.gitignore +0 -0
  146. data/spec/data/provider/moby_picture/.gitignore +0 -0
  147. data/spec/data/provider/multiply/.gitignore +0 -0
  148. data/spec/data/provider/netlog/.gitignore +0 -0
  149. data/spec/data/provider/newsvine/.gitignore +0 -0
  150. data/spec/data/provider/pandora/.gitignore +0 -0
  151. data/spec/data/provider/photobucket/.gitignore +0 -0
  152. data/spec/data/provider/photocase/.gitignore +0 -0
  153. data/spec/data/provider/picasa/.gitignore +0 -0
  154. data/spec/data/provider/plurk/.gitignore +0 -0
  155. data/spec/data/provider/posterous/.gitignore +0 -0
  156. data/spec/data/provider/propeller/.gitignore +0 -0
  157. data/spec/data/provider/qik/.gitignore +0 -0
  158. data/spec/data/provider/qype/.gitignore +0 -0
  159. data/spec/data/provider/raptr/.gitignore +0 -0
  160. data/spec/data/provider/readernaut/.gitignore +0 -0
  161. data/spec/data/provider/reddit/.gitignore +0 -0
  162. data/spec/data/provider/revver/.gitignore +0 -0
  163. data/spec/data/provider/skyrock/.gitignore +0 -0
  164. data/spec/data/provider/slideshare/.gitignore +0 -0
  165. data/spec/data/provider/smotri/.gitignore +0 -0
  166. data/spec/data/provider/smugmug/.gitignore +0 -0
  167. data/spec/data/provider/stumbleupon/.gitignore +0 -0
  168. data/spec/data/provider/tumblr/.gitignore +0 -0
  169. data/spec/data/provider/tumblr/tumblr_posts-raw_feed.xml +150 -0
  170. data/spec/data/provider/twelve_seconds/.gitignore +0 -0
  171. data/spec/data/provider/twine/.gitignore +0 -0
  172. data/spec/data/provider/twitter/.gitignore +0 -0
  173. data/spec/data/provider/twitter/twitter-api_user_timeline-activity_streams.xml +27 -0
  174. data/spec/data/provider/twitter/twitter-api_user_timeline-raw_json.json +1 -0
  175. data/spec/data/provider/twitter/twitter_rss_user_timeline-activity_streams.xml +46 -0
  176. data/spec/data/provider/twitter/twitter_rss_user_timeline-raw_feed.xml +83 -0
  177. data/spec/data/provider/vimeo/.gitignore +0 -0
  178. data/spec/data/provider/visualizeus/.gitignore +0 -0
  179. data/spec/data/provider/wordpress/.gitignore +0 -0
  180. data/spec/data/provider/xanga/.gitignore +0 -0
  181. data/spec/data/provider/yelp/.gitignore +0 -0
  182. data/spec/data/provider/youtube/youtube_videos-activity_streams.xml +629 -0
  183. data/spec/data/provider/youtube/youtube_videos-raw_feed.xml +51 -0
  184. data/spec/data/provider/zooomr/.gitignore +0 -0
  185. data/spec/spec_helper.rb +3 -2
  186. data/spec/support/compare_to_standard_example.rb +17 -0
  187. data/spec/titi_spec.rb +8 -2
  188. data/titi.gemspec +179 -5
  189. metadata +180 -6
  190. data/lib/titi/provider/generic_rss.rb +0 -50
@@ -2,12 +2,12 @@ h1. titi: Agile Monkeying around with Activity Streams
2
2
 
3
3
  Titi is a first stab at a universal ActivityStream interface.
4
4
 
5
- h3. BUGS:
5
+ h3. How you can help
6
6
 
7
- * The XML output isn't activity stream format: needs namespaces, much more
7
+ * Give the coders something to target: a) Pick an API or feed to add. For ideas, choose one not yet implemented from "Supported Feeds" list, below. b) Get a sample of the raw API or feed output (use your own account so noone files a copyright violation bug report). c) create an appropriately-named file, say @spec/data/providers/PROVIDER_NAME/PROVIDER_FEED_NAME-raw_feed.xml@ or @spec/data/providers/PROVIDER_NAME/PROVIDER_FEED_NAME-raw_api.json@ or whatever. d) If that feed is not yet in activity_streams format, use the raw sample to create an example activity_streams output. e) Issue a pull request.
8
+ * Take an API or feed that has example input and output and code its interface.
8
9
 
9
-
10
- h3. Example
10
+ h2. Example
11
11
 
12
12
  Let's define a super-simple twitter user and status model:
13
13
 
@@ -103,6 +103,25 @@ Here's example output. _note: this isn't canonical activity streams format: the
103
103
  </entry>
104
104
  </code></pre>
105
105
 
106
+ h2. Supported Feeds
107
+
108
+ The goal is to cover all the following services. Thanks to "Cliqset":http://feedproxy.cliqset.com/feed/selection and Rob Dolin for the list:
109
+
110
+ <pre><code>
111
+ :social => %w[ AvatarsUnited Bebo Brightkite Friendster Friendfeed GamerDna Gather Hi5 Hyves Identica
112
+ Jaiku Multiply Myspace Netlog Plurk Raptr Skyrock Twitter Facebook LinkedIn Plaxo Xing ],
113
+ :blogging => %w[ Ameba Baidu Blogger Douban Livejournal Posterous Tumblr Wordpress Xanga TypePad MoveableType WlSpaces ],
114
+ :bookmarking => %w[ Delicious Digg Diigo GoogleReader Hatena Meneame Mixx Newsvine Propeller Reddit Stumbleupon Twine ],
115
+ :music => %w[ Blipfm Buzznet Ilike Lastfm Pandora Zooomr Zune ],
116
+ :video => %w[ BuddyTv TwelveSeconds Bliptv Cinchcast DailyMotion FunnyOrDie Hulu Joost Metacafe Qik Revver Vimeo Youtube ],
117
+ :photos => %w[ DeviantArt Flickr Fotolog MobyPicture Photobucket Picasa Photocase Slideshare Smotri Smugmug Visualizeus MetroFlog WlSkyDrive ],
118
+ :reviews => %w[ Blippr Corkd Flixster Goodreads Librarything Qype Readernaut Yelp ],
119
+ :messengers => %w[ AIM WlMessenger ],
120
+ :location => %w[ Gowalla Foursquare Tripit UrbanSpoon Whirl ],
121
+ :gaming => %w[ Zynga Playdom MsgrGames ],
122
+ </code></pre>
123
+
124
+
106
125
  h2. Copyright
107
126
 
108
127
  Copyright (c) 2010 Infochimps, Inc. Available under Apache license: see LICENSE for details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.5
1
+ 0.0.6
@@ -1,18 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'rubygems'
3
- require 'restclient'
4
- require 'json'
5
- require 'active_support'
6
-
7
3
  TITI_DIR = File.dirname(File.expand_path(__FILE__+'/..')) unless defined?(TITI_DIR)
8
4
  $: << TITI_DIR+'/lib' unless $:.include?(TITI_DIR+'/lib')
9
-
10
- require 'titi'
5
+ require 'titi' ; include Titi::Provider
11
6
  require 'titi/provider/twitter'
12
- include Titi::Provider
13
-
14
- tweet = Twitter::Status.get(12233609555)
15
- entry = tweet.to_activity_stream_entry
16
7
 
17
- p tweet.to_hash
18
- puts entry.to_xml
8
+ tweet = Twitter::Status.fetch_status(12233609555)
9
+ tw_feed = tweet.to_activity_stream
10
+ puts tw_feed.to_xml
@@ -1,4 +1,10 @@
1
+ require 'restclient'
2
+ require 'json'
3
+ require 'wukong'
4
+ require 'erubis'
5
+
1
6
  module Titi
2
7
  autoload :Provider, 'titi/provider'
3
8
  autoload :Adaptor, 'titi/adaptor'
9
+ autoload :Fetcher, 'titi/fetcher'
4
10
  end
@@ -0,0 +1,5 @@
1
+ module Titi
2
+ module Fetcher
3
+ autoload :Json, 'titi/fetcher/json'
4
+ end
5
+ end
@@ -0,0 +1,32 @@
1
+ module Titi::Fetcher
2
+ module Json
3
+ module ClassMethods
4
+
5
+ def parse raw_json_str
6
+ begin
7
+ return JSON.load(raw_json_str)
8
+ rescue StandardError => e
9
+ warn e
10
+ return { }
11
+ end
12
+ end
13
+
14
+ # Call the twitter API and fetch tweet with given ID
15
+ #
16
+ # @example
17
+ # tweet = Status.get(12233609555)
18
+ # tweet.text
19
+ # #=> "THANK GOODNESS THE LIBRARY OF CONGRESS HAS UNDERSTOOD THE IMPORTANCE OF MY TWEETS what do you mean others are getting in too"
20
+ #
21
+ def get url
22
+ parse RestClient.get(url).to_s
23
+ end
24
+
25
+ def from_file filename
26
+ parse File.open(filename)
27
+ end
28
+ end
29
+ # Standard hack to add class methods
30
+ def self.included(base) base.class_eval{ extend ClassMethods } ; end
31
+ end
32
+ end
@@ -1,4 +1,3 @@
1
- require 'wukong'
2
1
  module Titi
3
2
  module Provider
4
3
  autoload :ActivityStreams, 'titi/provider/activity_streams'
@@ -16,25 +15,3 @@ module Titi
16
15
  # autoload :WordPress , 'titi/provider/word_press'
17
16
  end
18
17
  end
19
-
20
- # # from Rob Dolin, a list:
21
- # {
22
- # :text_status => %w[ Twitter StatusNet Plurk AIM WlMessenger ],
23
- # :location => %w[ Gowalla Foursquare Tripit Yelp Qype UrbanSpoon Brightkite Whirl ],
24
- # :social => %w[ Facebook MySpace LinkedIn Xing Plaxo ],
25
- # :music => %w[ LastFm Pandora Zune iLike ],
26
- # :bookmarking => %w[ Digg StumbleUpon Delicious Facebook ],
27
- # :video => %w[ YouTube DailyMotion Hulu BuddyTv SkyDrive ],
28
- # :gaming => %w[ Zynga Playdom MsgrGames ],
29
- # :photos => %w[ Flickr Photobucket MetroFlog Fotolog Picasa WlSkyDrive ],
30
- # :blogging => %w[ Blogger WordPress TypePad MySpace MoveableType WlSpaces ],
31
- # }
32
- #
33
- # # See also: http://feedproxy.cliqset.com/feed/selection
34
- # {
35
- # Social => %w[ AvatarsUnited Bebo BrightKite Friendster FriendFeed GamerDNA Gather hi5 Hyves Identica Jaiku Multiply Netlog Plurk Raptr Skyrock Twitter ],
36
- # Blogging => %w[ Ameba Baidu Blogger CustomFeed Douban LiveJournal Posterous Tumblr WordPress Xanga ],
37
- # Bookmarking => %w[ Delicious Digg Diigo GoogleReader Hatena Meneame Mixx Newsvine Propeller Reddit StumbleUpon Twine ],
38
- # Media => %w[ 12seconds BlipFm BlipTv Buzznet Cinchcast Dailymotion DeviantArt Flickr Fotolog FunnyOrDie Hulu iLike Joost LastFm MetaCafe MobyPicture Pandora Photobucket Photocase Picasa Qik Revver SlideShare Smotri SmugMug VisualizeUs Vimeo YouTube Zooomr ],
39
- # Reviews => %w[ Blippr Corkd Flixster Goodreads LibraryThing Qype Readernaut Yelp ],
40
- # }
@@ -1,141 +1,12 @@
1
- module Titi
2
-
3
- module Provider
4
- #
5
- module ActivityStreams
6
- # Some methods common to all ActivityStreams classes
7
- module Common
8
- def to_hash *args
9
- hsh = super(*args)
10
- hsh.each do |attr, val|
11
- hsh[attr] = val.to_hash if val.respond_to?(:to_hash)
12
- end
13
- hsh
14
- end
15
-
16
- def to_xml *args
17
- hsh = self.to_hash
18
- hsh.to_xml :root => self.class.to_s.underscore.gsub(%r{.*/},'')
19
- end
20
-
21
- def has_thingy thingy, *args, &block
22
- thingy_klass = ('ActivityStreams::'+thingy.to_s.classify).constantize
23
- thingy_setter = "#{thingy}="
24
- p [thingy, thingy_klass, thingy_setter]
25
- self.send(thingy_setter, thingy_klass.new) unless self.send(thingy)
26
- self.send(thingy).adapt *args, &block
27
- self.send(thingy)
28
- end
29
-
30
- def method_missing meth, *args, &block
31
- if (meth.to_s =~ /has_(\w+)/) && (self.respond_to?("#{$1}="))
32
- has_thingy $1, *args, &block
33
- else
34
- super
35
- end
36
- end
37
- end
38
-
39
- class ActivityStreamsStruct < ActivityStreamsStruct
40
- def self.new *args, &block
41
- super
42
- include Titi::Adaptor
43
- include Titi::Provider::ActivityStreams::Common
44
- end
45
- end
46
-
47
- Feed = ActivityStreamsStruct.new(
48
- :entry
49
- )
50
- Feed.class_eval do
51
- def adapt thingys
52
- self.entry = thingys.map do |thingy|
53
- thingy.to_activity_stream_entry
54
- end
55
- end
56
- end
57
-
58
- # An ActivityStream entry
59
- # http://activitystrea.ms/spec/1.0/atom-activity-01.html#activityentries
60
- Entry = ActivityStreamsStruct.new(
61
- :id, # ???
62
- :title, # title
63
- :content, # content
64
- :link, # link {"href"=>"http://x.myspacecdn.com/modules/common/static/img/photo.gif", "rel"=>"icon", "type"=>"image/gif"}
65
- :published, # date published
66
- :updated, # date updated
67
- #
68
- :category, # type of entry
69
- :activity_verb, # action it implies:
70
- :sync, # sync
71
- :rank, # rank
72
- #
73
- :actor, # actor
74
- :author, # author {"name"=>["misterflip"], "uri"=>["http://profile.myspace.com/index.cfm?fuseaction=user.viewprofile&friendid=24601"]}
75
- :mood, #
76
- :source,
77
- :obj, # object
78
- :target # target
79
- )
80
- Entry.class_eval do
81
- def published= date_time
82
- self[:published] = DateTime.parse(date_time) rescue nil
83
- end
84
- def updated= date_time
85
- self[:updated] = DateTime.parse(date_time) rescue nil
86
- end
87
- end
88
-
89
- # <link href="http://twitter.com/banksean/statuses/12244282580"
90
- # type="text/xhtml" rel="via" title="Just saw a @cliqset #salmon @-mention interop demo by @jpanzer. Very neat stuff!">
91
- # </link>
92
-
93
- Link = ActivityStreamsStruct.new(
94
- :href,
95
- :title,
96
- :rel,
97
- :type
98
- )
99
- Link.class_eval do
100
- end
101
-
102
- Address = ActivityStreamsStruct.new(
103
- :country,
104
- :locality,
105
- :postalCode,
106
- #
107
- :xml_keys # for debugging, capture the keys from the raw XML hash
108
- )
109
- Address.class_eval do
110
- end
111
-
112
- # ActivityStream author
113
- # http://activitystrea.ms/spec/1.0/atom-activity-01.html#activityactor
114
- Actor = ActivityStreamsStruct.new(
115
- :name,
116
- :uri
117
- )
118
- Actor.class_eval do
119
- end
120
- Author = Actor
121
-
122
- # ActivityStream object.
123
- # We can't call them 'Object' (ruby has a class like that already :)
124
- # http://activitystrea.ms/spec/1.0/atom-activity-01.html#activityobjectelement
125
- Obj = ActivityStreamsStruct.new(
126
- :id,
127
- :title,
128
- :content,
129
- :link,
130
- :published,
131
- :updated,
132
- #
133
- :author,
134
- :object_type, # video, post, file
135
- :vevent
136
- )
137
- Obj.class_eval do
138
- end
139
- end
1
+ module Titi::Provider
2
+ module ActivityStreams
3
+ autoload :ActivityStreamsStruct, 'titi/provider/activity_streams/activity_streams_struct'
4
+ autoload :Actor, 'titi/provider/activity_streams/actor'
5
+ autoload :Author, 'titi/provider/activity_streams/actor'
6
+ autoload :Address, 'titi/provider/activity_streams/address'
7
+ autoload :Entry, 'titi/provider/activity_streams/entry'
8
+ autoload :Feed, 'titi/provider/activity_streams/feed'
9
+ autoload :Link, 'titi/provider/activity_streams/link'
10
+ autoload :Obj, 'titi/provider/activity_streams/obj'
140
11
  end
141
12
  end
@@ -0,0 +1,46 @@
1
+ module Titi::Provider::ActivityStreams
2
+ class ActivityStreamsStruct < Struct
3
+ include Titi::Adaptor
4
+
5
+ # Merge given attributes into the hash
6
+ def attributes= hsh
7
+ conv_hsh = {}
8
+ hsh.each do |k,v|
9
+ k = k.to_s.gsub(/:/,'_') if k =~ /:/
10
+ conv_hsh[k] = v
11
+ end
12
+ super hsh
13
+ end
14
+
15
+ # expand to hash, and expand all hash values to hash
16
+ def to_hash *args
17
+ hsh = super(*args)
18
+ hsh.each do |attr, val|
19
+ hsh[attr] = val.to_hash if val.respond_to?(:to_hash)
20
+ end
21
+ hsh
22
+ end
23
+
24
+ # def to_xml *args
25
+ # hsh = self.to_hash
26
+ # hsh.to_xml :root => self.class.to_s.underscore.gsub(%r{.*/},'')
27
+ # end
28
+
29
+ # Use method_missing to dispatch the has_[whatever] setters
30
+ def method_missing meth, *args, &block
31
+ if (meth.to_s =~ /has_(\w+)/) && (self.respond_to?("#{$1}="))
32
+ has_thingy $1, *args, &block
33
+ else
34
+ super
35
+ end
36
+ end
37
+
38
+ def has_thingy thingy, *args, &block
39
+ thingy_klass = ('Titi::Provider::ActivityStreams::'+thingy.to_s.camelize).constantize
40
+ thingy_setter = "#{thingy}="
41
+ self.send(thingy_setter, thingy_klass.new) unless self.send(thingy)
42
+ self.send(thingy).adapt *args, &block
43
+ self.send(thingy)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,11 @@
1
+ module Titi::Provider::ActivityStreams
2
+ # ActivityStream author
3
+ # http://activitystrea.ms/spec/1.0/atom-activity-01.html#activityactor
4
+ Actor = ActivityStreamsStruct.new(
5
+ :name,
6
+ :uri
7
+ )
8
+ Actor.class_eval do
9
+ end
10
+ Author = Actor
11
+ end
@@ -0,0 +1,11 @@
1
+ module Titi::Provider::ActivityStreams
2
+ Address = ActivityStreamsStruct.new(
3
+ :country,
4
+ :locality,
5
+ :postalCode,
6
+ #
7
+ :xml_keys # for debugging, capture the keys from the raw XML hash
8
+ )
9
+ Address.class_eval do
10
+ end
11
+ end
@@ -0,0 +1,38 @@
1
+ module Titi::Provider::ActivityStreams
2
+
3
+ # An ActivityStream entry
4
+ # http://activitystrea.ms/spec/1.0/atom-activity-01.html#activityentries
5
+ Entry = ActivityStreamsStruct.new(
6
+ :id, # ???
7
+ :title, # title
8
+ :content, # content
9
+ :link_alt, # link {"href"=>"http://x.myspacecdn.com/modules/common/static/img/photo.gif", "rel"=>"icon", "type"=>"image/gif"}
10
+ :link_enclosure, # link {"href"=>"http://x.myspacecdn.com/modules/common/static/img/photo.gif", "rel"=>"icon", "type"=>"image/gif"}
11
+ :link_preview, # link {"href"=>"http://x.myspacecdn.com/modules/common/static/img/photo.gif", "rel"=>"icon", "type"=>"image/gif"}
12
+ :link_icon, # link {"href"=>"http://x.myspacecdn.com/modules/common/static/img/photo.gif", "rel"=>"icon", "type"=>"image/gif"}
13
+ :link_related, # link {"href"=>"http://x.myspacecdn.com/modules/common/static/img/photo.gif", "rel"=>"icon", "type"=>"image/gif"}
14
+
15
+ :published, # date published
16
+ :updated, # date updated
17
+ #
18
+ :category, # type of entry
19
+ :activity_verb, # action it implies:
20
+ :sync, # sync
21
+ :rank, # rank
22
+ #
23
+ :actor, # actor
24
+ :author, # author {"name"=>["misterflip"], "uri"=>["http://profile.myspace.com/index.cfm?fuseaction=user.viewprofile&friendid=24601"]}
25
+ :mood, #
26
+ :source,
27
+ :obj, # object
28
+ :target # target
29
+ )
30
+ Entry.class_eval do
31
+ def published= date_time
32
+ self[:published] = DateTime.parse(date_time) rescue nil
33
+ end
34
+ def updated= date_time
35
+ self[:updated] = DateTime.parse(date_time) rescue nil
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,25 @@
1
+ module Titi::Provider::ActivityStreams
2
+ Feed = ActivityStreamsStruct.new(
3
+ :entry
4
+ )
5
+ Feed.class_eval do
6
+ # Location of the .erb file for rendering pretty activity streams XML
7
+ ACTIVITY_STREAMS_TEMPLATE = File.join(File.dirname(__FILE__)+'/feed.xml.erb')
8
+
9
+ def entries
10
+ [entry].flatten
11
+ end
12
+
13
+ def self.activity_streams_template
14
+ @activity_streams_template ||= File.read(ACTIVITY_STREAMS_TEMPLATE)
15
+ end
16
+
17
+ def self.activity_streams_renderer
18
+ @activity_streams_renderer ||= Erubis::Eruby.new(activity_streams_template)
19
+ end
20
+
21
+ def to_xml
22
+ self.class.activity_streams_renderer.result(:feed => self)
23
+ end
24
+ end
25
+ end
@@ -1,27 +1,29 @@
1
1
  <feed>
2
+ <%- feed.entries.each do |entry| %>
2
3
  <entry>
3
4
  <title><%= entry.title %></title>
4
5
  <content type="html"><%= entry.content %></content>
5
6
  <id><%= entry.id %></id>
6
7
  <published><%= entry.published %></published>
7
8
  <updated ><%= entry.updated %></updated>
8
- <link type="text/html" rel="alternate" href="<%= entry.alt_link %>"/>
9
- <link type="image/pjpeg" rel="image" href="<%= entry.img_link %>"/>
9
+ <link type="text/html" rel="alternate" href="<%= entry.link_alt %>"/>
10
+ <link type="image/pjpeg" rel="icon" href="<%= entry.link_icon %>"/>
10
11
  <author>
11
12
  <name><%= entry.author.name %></name>
12
- <uri><%= entry.author.url %></uri>
13
+ <uri><%= entry.author.uri %></uri>
13
14
  </author>
14
- <activity:verb><%= entry.verb %></activity:verb>
15
+ <activity:verb><%= entry.activity_verb %></activity:verb>
15
16
  <activity:object>
16
- <id><%= entry.object.id %></id>
17
- <title><%= entry.object.title %></title>
18
- <link type="text/html" rel="alternate" href="<%= entry.object.alt_link %>"/>
19
- <published><%= entry.object.published %></published>
20
- <updated ><%= entry.object.updated %></updated>
17
+ <id><%= entry.obj.id %></id>
18
+ <title><%= entry.obj.title %></title>
19
+ <link type="text/html" rel="alternate" href="<%= entry.obj.link_alt %>"/>
20
+ <published><%= entry.obj.published %></published>
21
+ <updated ><%= entry.obj.updated %></updated>
21
22
  <author>
22
- <name><%= entry.object.author.name %></name>
23
- <uri ><%= entry.object.author.url %></uri>
23
+ <name><%= entry.obj.author.name %></name>
24
+ <uri ><%= entry.obj.author.uri %></uri>
24
25
  </author>
25
26
  </activity:object>
26
27
  </entry>
28
+ <%- end %>
27
29
  </feed>