stream_grabber 0.1.0

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.
data/README.md ADDED
@@ -0,0 +1,67 @@
1
+ StreamGrabber
2
+ =============
3
+
4
+ StreamGrabber is a way of multiplexing streams and feeds together into a timeline, it supports twitter, last.fm and github at the moment but is designed to be fairly trivial to add new sources, providing they have some kind of public facing data stream…
5
+
6
+ Usage
7
+ -----
8
+ At the moment StreamGrabber supports Twitter, last.fm and Github so
9
+ you'll need to give it your username for these sites. Create
10
+ `#{RAILS_ROOT}/config/stream_grabber.yml` so that it looks like the
11
+ following
12
+
13
+ :twitter: username
14
+ :lastfm: username
15
+ :github: username
16
+
17
+ And then you can include the plugin in your Gemfile like so
18
+
19
+ gem 'stream_grabber'
20
+
21
+ and load the helper method in your chosen controller.
22
+
23
+ class HomepageController < ApplicationController
24
+ helper :stream_grabber
25
+
26
+ # blah blah blah
27
+ end
28
+
29
+ then in your views you use
30
+
31
+ <%= generate_stream_list %>
32
+
33
+ to render an ordered list of your most recent activity, most recent
34
+ first. There are a couple of additional options you can pass to
35
+ customise the output, the first is the number of results you'd like back
36
+ (defaults to 15) and the second is the css id and class you wish to be
37
+ applied to the output. You can use these as follows
38
+
39
+ <%= generate_stream_list 5, :class => 'foo' , :id => 'bar' %>
40
+
41
+ Adding new Sources
42
+ ------------------
43
+
44
+ Sources are defined as classes in the StreamGrabber module, they are all
45
+ loaded dynamically so all your new source has to do is conform to the
46
+ following interface
47
+
48
+ module StreamGrabber
49
+ class Twitter
50
+ def initialize(user_name)
51
+ # do your setup in here to grab and parse the stream
52
+ end
53
+
54
+ def last_five
55
+ # returns your data as a timestamp keyed hash
56
+ end
57
+ end
58
+ end
59
+
60
+ And as long as `last_five` returns a hash with timestamps as keys, then
61
+ whatever is in the hash values will be squirted into the `li` elements
62
+ in the resulting list.
63
+
64
+ Over engineered? Damn Straight!!
65
+
66
+ If you want to add sources, please give me a pull request and I'll merge
67
+ them straight in.
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require "rubygems"
2
+ require "rake/gempackagetask"
3
+ require "rake/testtask"
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.test_files = FileList['test/*_test.rb']
7
+ t.verbose = true
8
+ end
9
+
10
+ task :default => [:test]
11
+
@@ -0,0 +1,14 @@
1
+ module StreamGrabberHelper
2
+ def generate_stream_list(num=15, *args)
3
+ if args.present?
4
+ css_class = args.first[:class]
5
+ css_id = args.first[:id]
6
+ end
7
+
8
+ data = StreamGrabber.grab(num).inject([]){ |memo,acc| memo << content_tag(:li,raw(acc[1])) }
9
+
10
+ content_tag :ol, {:class => css_class || 'activity_list', :id => css_id || 'stream_grabber'} do
11
+ raw(data.join("\n"))
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,24 @@
1
+ require 'simple-rss'
2
+ require 'open-uri'
3
+ require 'pp'
4
+
5
+ module StreamGrabber
6
+ class Github
7
+ def initialize(user_name)
8
+ @doc = SimpleRSS.parse(open("https://github.com/#{user_name}.private.actor.atom?token=4ec7548d4e071bdc85462077a69bcdf2"))
9
+ end
10
+
11
+ def last_five
12
+ commits = {}
13
+ @doc.items.first(5).each do |item|
14
+ date = Time.parse(item[:updated].to_s).to_i
15
+ commits[date] = message_from(item[:link], item[:title])
16
+ end
17
+ commits
18
+ end
19
+
20
+ def message_from(link, title)
21
+ %Q{<a href="#{link}">#{title}</a>"}
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ require 'nokogiri'
2
+ require 'open-uri'
3
+
4
+ module StreamGrabber
5
+ class LastFm
6
+ def initialize(user_name)
7
+ @user_name = user_name
8
+ @doc ||= Nokogiri::XML(open("http://ws.audioscrobbler.com/2.0/?method=user.getlovedtracks&user=#{user_name}&api_key=b25b959554ed76058ac220b7b2e0a026"))
9
+ end
10
+
11
+ def last_five
12
+ tracks = {}
13
+ ff = @doc.xpath("//track").first(5)
14
+ ff.each do |elem|
15
+ date_loved = elem.>('date').first['uts'].to_i
16
+ artist_name = elem.css('artist > name').text
17
+ track_name = elem.>('name').text
18
+ url = elem.>('url').text
19
+ tracks[date_loved] = message_for(artist_name,track_name, url)
20
+ end
21
+ tracks
22
+ end
23
+
24
+ def message_for(artist, title, url)
25
+ %Q{ #{@user_name} loved the track <a href="#{url}">#{title} by #{artist}</a> on Last.fm }
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,25 @@
1
+ require 'json'
2
+ require 'open-uri'
3
+
4
+ module StreamGrabber
5
+ class Twitter
6
+ def initialize(user_name)
7
+ @user_name = user_name
8
+ @doc = JSON.load(open("http://api.twitter.com/1/statuses/user_timeline.json?count=6&screen_name=#{user_name}"))
9
+ end
10
+
11
+ def last_five
12
+ tweets = {}
13
+ @doc.each do |tweet|
14
+ date = Time.parse(tweet["created_at"]).to_i
15
+ tweets[date] = message_from(tweet["text"], tweet["id"])
16
+ end
17
+ tweets
18
+ end
19
+
20
+ def message_from(text, id)
21
+ %Q{<a href="http://twitter.com/#{@user_name}/status/#{id}">#{text}</a>}
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,42 @@
1
+ require 'stream_grabber/last_fm'
2
+ require 'stream_grabber/github'
3
+ require 'stream_grabber/twitter'
4
+ require 'rails'
5
+
6
+ if ENV['OFFLINE']
7
+ # use test data if we are developing offline
8
+ require File.expand_path(File.join(File.dirname(__FILE__), *%w[.. test test_helper.rb]))
9
+ end
10
+
11
+ module StreamGrabber
12
+
13
+ class Engine < Rails::Engine; end
14
+
15
+ class << self
16
+ def usernames
17
+ @usernames ||= YAML.load_file(Rails.root + 'config/stream_grabber.yml')
18
+ end
19
+
20
+ def mux_stream
21
+ messages = {}
22
+ StreamGrabber.constants.each do |klass|
23
+ k = StreamGrabber.const_get(klass)
24
+ if k.instance_of?(Class) and k.method_defined?('last_five')
25
+ name = k.name.partition('::').last.split(/(?=[A-Z])/).join("_").downcase
26
+ user_name = usernames[name.to_sym]
27
+ messages.merge!(k.new(user_name).send(:last_five))
28
+ end
29
+ end
30
+ arr = messages.sort.reverse
31
+ end
32
+
33
+ def grab_all
34
+ mux_stream
35
+ end
36
+
37
+ def grab(n)
38
+ mux_stream.first(n)
39
+ end
40
+ end
41
+
42
+ end