stream_grabber 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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