intridea-tweetstream 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.rdoc +77 -0
- data/Rakefile +51 -0
- data/VERSION +1 -0
- data/lib/tracker.rb +12 -0
- data/lib/tweetstream.rb +5 -0
- data/lib/tweetstream/client.rb +109 -0
- data/lib/tweetstream/daemon.rb +40 -0
- data/lib/tweetstream/hash.rb +16 -0
- data/lib/tweetstream/status.rb +8 -0
- data/lib/tweetstream/user.rb +5 -0
- data/spec/data/statuses.json +1 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/tweetstream/client_spec.rb +122 -0
- data/spec/tweetstream/hash_spec.rb +19 -0
- data/spec/tweetstream/status_spec.rb +9 -0
- data/spec/tweetstream_spec.rb +5 -0
- metadata +105 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Intridea, Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
= TweetStream
|
2
|
+
|
3
|
+
TweetStream provides simple Ruby access to Twitter's Streaming API
|
4
|
+
(http://apiwiki.twitter.com/Streaming-API-Documentation).
|
5
|
+
|
6
|
+
== Installation
|
7
|
+
|
8
|
+
The TweetStream gem is available on GitHub and Gemcutter. To get the
|
9
|
+
latest gem from GitHub:
|
10
|
+
|
11
|
+
gem sources -a http://gems.github.com/
|
12
|
+
gem install intridea-tweetstream
|
13
|
+
|
14
|
+
To install from Gemcutter:
|
15
|
+
|
16
|
+
gem sources -a http://gemcutter.org/
|
17
|
+
gem install tweetstream
|
18
|
+
|
19
|
+
== Usage
|
20
|
+
|
21
|
+
Using TweetStream is quite simple:
|
22
|
+
|
23
|
+
require 'rubygems'
|
24
|
+
require 'tweetstream'
|
25
|
+
|
26
|
+
# This will pull a sample of all tweets based on
|
27
|
+
# your Twitter account's Streaming API role.
|
28
|
+
TweetStream::Client.new('username','password').sample do |status|
|
29
|
+
# The status object is a special Hash with
|
30
|
+
# method access to its keys.
|
31
|
+
puts "#{status.text}"
|
32
|
+
end
|
33
|
+
|
34
|
+
You can also use it to track keywords or follow a given set of
|
35
|
+
user ids:
|
36
|
+
|
37
|
+
# Use 'track' to track a list of single-word keywords
|
38
|
+
TweetStream::Client.new('username','password').track('term1', 'term2') do |status|
|
39
|
+
puts "#{status.text}"
|
40
|
+
end
|
41
|
+
|
42
|
+
# Use 'follow' to follow a group of user ids (integers, not screen names)
|
43
|
+
TweetStream::Client.new('username','password').follow(14252, 53235) do |status|
|
44
|
+
puts "#{status.text}"
|
45
|
+
end
|
46
|
+
|
47
|
+
The methods available to TweetStream::Client will be kept in parity
|
48
|
+
with the methods available on the Streaming API wiki page.
|
49
|
+
|
50
|
+
== Daemonizing
|
51
|
+
|
52
|
+
It is also possible to create a daemonized script quite easily
|
53
|
+
using the TweetStream library:
|
54
|
+
|
55
|
+
# The third argument is an optional process name
|
56
|
+
TweetStream::Client.new('username','password', 'tracker').track('term1', 'term2') do |status|
|
57
|
+
# do something in the background
|
58
|
+
end
|
59
|
+
|
60
|
+
If you put the above into a script and run the script with <tt>ruby scriptname.rb</tt>, you will see a list of daemonization commands such
|
61
|
+
as start, stop, and run.
|
62
|
+
|
63
|
+
== Note on Patches/Pull Requests
|
64
|
+
|
65
|
+
* Fork the project.
|
66
|
+
* Make your feature addition or bug fix.
|
67
|
+
* Add tests for it. This is important so I don't break it in a future version unintentionally.
|
68
|
+
* Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
69
|
+
* Send me a pull request. Bonus points for topic branches.
|
70
|
+
|
71
|
+
== Contributors
|
72
|
+
|
73
|
+
* Michael Bleigh (initial gem)
|
74
|
+
|
75
|
+
== Copyright
|
76
|
+
|
77
|
+
Copyright (c) 2009 Intridea, Inc. (http://www.intridea.com/). See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "tweetstream"
|
8
|
+
gem.summary = %Q{TweetStream is a simple wrapper for consuming the Twitter Streaming API.}
|
9
|
+
gem.description = %Q{TweetStream allows you to easily consume the Twitter Streaming API utilizing the YAJL Ruby gem.}
|
10
|
+
gem.email = "michael@intridea.com"
|
11
|
+
gem.homepage = "http://github.com/intridea/tweetstream"
|
12
|
+
gem.authors = ["Michael Bleigh"]
|
13
|
+
gem.files = FileList["[A-Z]*", "{lib,spec}/**/*"] - FileList["**/*.log"]
|
14
|
+
gem.add_development_dependency "rspec"
|
15
|
+
gem.add_dependency 'yajl-ruby', '>= 0.6.3'
|
16
|
+
gem.add_dependency 'daemons'
|
17
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
18
|
+
end
|
19
|
+
rescue LoadError
|
20
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'spec/rake/spectask'
|
24
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
25
|
+
spec.libs << 'lib' << 'spec'
|
26
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
27
|
+
end
|
28
|
+
|
29
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
30
|
+
spec.libs << 'lib' << 'spec'
|
31
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
32
|
+
spec.rcov = true
|
33
|
+
end
|
34
|
+
|
35
|
+
task :spec => :check_dependencies
|
36
|
+
|
37
|
+
task :default => :spec
|
38
|
+
|
39
|
+
require 'rake/rdoctask'
|
40
|
+
Rake::RDocTask.new do |rdoc|
|
41
|
+
if File.exist?('VERSION')
|
42
|
+
version = File.read('VERSION')
|
43
|
+
else
|
44
|
+
version = ""
|
45
|
+
end
|
46
|
+
|
47
|
+
rdoc.rdoc_dir = 'rdoc'
|
48
|
+
rdoc.title = "tweetstream #{version}"
|
49
|
+
rdoc.rdoc_files.include('README*')
|
50
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
51
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.1
|
data/lib/tracker.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'tweetstream'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
File.open('tracker.log', File::WRONLY | File::APPEND | File::CREAT) do |file|
|
6
|
+
log = Logger.new(file)
|
7
|
+
|
8
|
+
TweetStream::Daemon.new('mbleigh','hotmail', 'tracker').track('fail') do |status|
|
9
|
+
log.info "[#{status.user.screen_name}] #{status.text}"
|
10
|
+
puts "[#{status.user.screen_name}] #{status.text}"
|
11
|
+
end
|
12
|
+
end
|
data/lib/tweetstream.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'cgi'
|
3
|
+
require 'yajl'
|
4
|
+
require 'yajl/http_stream'
|
5
|
+
|
6
|
+
module TweetStream
|
7
|
+
# Provides simple access to the Twitter Streaming API (http://apiwiki.twitter.com/Streaming-API-Documentation)
|
8
|
+
# for Ruby scripts that need to create a long connection to
|
9
|
+
# Twitter for tracking and other purposes.
|
10
|
+
#
|
11
|
+
# Basic usage of the library is to call one of the provided
|
12
|
+
# methods and provide a block that will perform actions on
|
13
|
+
# a yielded TweetStream::Status. For example:
|
14
|
+
#
|
15
|
+
# TweetStream::Client.new('user','pass').track('fail') do |status|
|
16
|
+
# puts "[#{status.user.screen_name}] #{status.text}"
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# For information about a daemonized TweetStream client,
|
20
|
+
# view the TweetStream::Daemon class.
|
21
|
+
class Client
|
22
|
+
attr_accessor :username, :password
|
23
|
+
|
24
|
+
# Create a new client with the Twitter credentials
|
25
|
+
# of the account you want to be using its API quota.
|
26
|
+
def initialize(user, pass)
|
27
|
+
self.username = user
|
28
|
+
self.password = pass
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns all public statuses. The Firehose is not a generally
|
32
|
+
# available resource. Few applications require this level of access.
|
33
|
+
# Creative use of a combination of other resources and various access
|
34
|
+
# levels can satisfy nearly every application use case.
|
35
|
+
def firehose(query_parameters = {}, &block)
|
36
|
+
start('statuses/firehose', query_parameters, &block)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns all retweets. The retweet stream is not a generally available
|
40
|
+
# resource. Few applications require this level of access. Creative
|
41
|
+
# use of a combination of other resources and various access levels
|
42
|
+
# can satisfy nearly every application use case. As of 9/11/2009,
|
43
|
+
# the site-wide retweet feature has not yet launched,
|
44
|
+
# so there are currently few, if any, retweets on this stream.
|
45
|
+
def retweet(query_parameters = {}, &block)
|
46
|
+
start('statuses/retweet', query_parameters, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns a random sample of all public statuses. The default access level
|
50
|
+
# provides a small proportion of the Firehose. The "Gardenhose" access
|
51
|
+
# level provides a proportion more suitable for data mining and
|
52
|
+
# research applications that desire a larger proportion to be statistically
|
53
|
+
# significant sample.
|
54
|
+
def sample(query_parameters = {}, &block)
|
55
|
+
start('statuses/sample', query_parameters, &block)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Specify keywords to track. Queries are subject to Track Limitations,
|
59
|
+
# described in Track Limiting and subject to access roles, described in
|
60
|
+
# the statuses/filter method. Track keywords are case-insensitive logical
|
61
|
+
# ORs. Terms are exact-matched, and also exact-matched ignoring
|
62
|
+
# punctuation. Phrases, keywords with spaces, are not supported.
|
63
|
+
# Keywords containing punctuation will only exact match tokens.
|
64
|
+
# Query parameters may be passed as the last argument.
|
65
|
+
def track(*keywords, &block)
|
66
|
+
query_params = keywords.pop if keywords.last.is_a?(::Hash)
|
67
|
+
query_params ||= {}
|
68
|
+
start('statuses/filter', query_params.merge(:track => keywords.join(',')), &block)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns public statuses from or in reply to a set of users. Mentions
|
72
|
+
# ("Hello @user!") and implicit replies ("@user Hello!" created without
|
73
|
+
# pressing the reply "swoosh") are not matched. Requires integer user
|
74
|
+
# IDs, not screen names. Query parameters may be passed as the last argument.
|
75
|
+
def follow(*user_ids, &block)
|
76
|
+
query_params = user_ids.pop if user_ids.last.is_a?(::Hash)
|
77
|
+
query_params ||= {}
|
78
|
+
start('statuses/filter', query_params.merge(:follow => user_ids.join(',')), &block)
|
79
|
+
end
|
80
|
+
|
81
|
+
#:nodoc:
|
82
|
+
def start(path, query_parameters = {}, &block)
|
83
|
+
uri = build_uri(path, query_parameters)
|
84
|
+
|
85
|
+
Yajl::HttpStream.get(uri, :symbolize_keys => true) do |hash|
|
86
|
+
yield TweetStream::Status.new(hash)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
protected
|
91
|
+
|
92
|
+
#:nodoc:
|
93
|
+
def build_uri(path, query_parameters = {})
|
94
|
+
URI.parse("http://#{self.username}:#{self.password}@stream.twitter.com/1/#{path}.json#{build_query_parameters(query_parameters)}")
|
95
|
+
end
|
96
|
+
|
97
|
+
#:nodoc:
|
98
|
+
def build_query_parameters(query)
|
99
|
+
return '' unless query && query.is_a?(::Hash) && query.size > 0
|
100
|
+
pairs = []
|
101
|
+
|
102
|
+
query.each_pair do |k,v|
|
103
|
+
pairs << "#{k.to_s}=#{CGI.escape(v.to_s)}"
|
104
|
+
end
|
105
|
+
|
106
|
+
"?#{pairs.join('&')}"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'daemons'
|
2
|
+
|
3
|
+
# A daemonized TweetStream client that will allow you to
|
4
|
+
# create backgroundable scripts for application specific
|
5
|
+
# processes. For instance, if you create a script called
|
6
|
+
# <tt>tracker.rb</tt> and fill it with this:
|
7
|
+
#
|
8
|
+
# require 'rubygems'
|
9
|
+
# require 'tweetstream'
|
10
|
+
#
|
11
|
+
# TweetStream::Daemon.new('user','pass', 'tracker').track('intridea') do |status|
|
12
|
+
# # do something here
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# And then you call this from the shell:
|
16
|
+
#
|
17
|
+
# ruby tracker.rb start
|
18
|
+
#
|
19
|
+
# A daemon process will spawn that will automatically
|
20
|
+
# run the code in the passed block whenever a new tweet
|
21
|
+
# matching your search term ('intridea' in this case)
|
22
|
+
# is posted.
|
23
|
+
#
|
24
|
+
class TweetStream::Daemon < TweetStream::Client
|
25
|
+
# Initialize a Daemon with the credentials of the
|
26
|
+
# Twitter account you wish to use. The daemon has
|
27
|
+
# an optional process name for use when querying
|
28
|
+
# running processes.
|
29
|
+
def initialize(user, pass, app_name=nil)
|
30
|
+
@app_name = app_name
|
31
|
+
super(user, pass)
|
32
|
+
end
|
33
|
+
|
34
|
+
#:nodoc:
|
35
|
+
def start(path, query_parameters = {}, &block)
|
36
|
+
Daemons.run_proc(@app_name || 'tweetstream', :multiple => true) do
|
37
|
+
super(path, query_parameters, &block)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#:nodoc:
|
2
|
+
class TweetStream::Hash < ::Hash
|
3
|
+
def initialize(other_hash)
|
4
|
+
other_hash.keys.each do |key|
|
5
|
+
self[key.to_sym] = other_hash[key]
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def method_missing(method_name, *args)
|
10
|
+
if key?(method_name.to_sym)
|
11
|
+
self[method_name.to_sym]
|
12
|
+
else
|
13
|
+
super
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"favorited":false,"text":"listening to Where U Headed by Universal Playaz. http://iLike.com/s/9zpOZ #musicmonday something for the ladies","in_reply_to_user_id":null,"in_reply_to_screen_name":null,"source":"<a href=\"http://www.iLike.com\" rel=\"nofollow\">iLike</a>","truncated":false,"created_at":"Tue Sep 22 01:29:13 +0000 2009","user":{"statuses_count":378,"favourites_count":1,"profile_text_color":"666666","location":"Atlanta, Ga","profile_background_image_url":"http://a3.twimg.com/profile_background_images/36516125/Universal_Playaz.jpg","profile_link_color":"2FC2EF","description":"Paper Chaser","following":null,"verified":false,"notifications":null,"profile_sidebar_fill_color":"252429","profile_image_url":"http://a1.twimg.com/profile_images/413331530/DIESELSTATScopy_normal.jpg","url":"http://www.myspace.com/DieselDtheg","profile_sidebar_border_color":"181A1E","screen_name":"DieselD2143","profile_background_tile":true,"followers_count":75,"protected":false,"time_zone":"Eastern Time (US & Canada)","created_at":"Thu Jun 18 15:56:32 +0000 2009","name":"Diesel D","friends_count":119,"profile_background_color":"1A1B1F","id":48392351,"utc_offset":-18000},"in_reply_to_status_id":null,"id":4161231023} {"favorited":false,"text":"David Bowie and Nine Inch Nails perform \"Hurt\" http://bit.ly/AOaWG #musicmonday #nineinchnails #nin","in_reply_to_user_id":null,"in_reply_to_screen_name":null,"source":"web","truncated":false,"created_at":"Tue Sep 22 01:29:16 +0000 2009","user":{"statuses_count":668,"favourites_count":25,"profile_text_color":"445d85","location":"S\u00e3o Paulo, Brazil","profile_background_image_url":"http://a3.twimg.com/profile_background_images/38174991/GeorgeRomero-oil-400.jpg","profile_link_color":"555757","description":"You think I ain't worth a dollar, but I feel like a millionaire","following":null,"verified":false,"notifications":null,"profile_sidebar_fill_color":"a3a7ad","profile_image_url":"http://a1.twimg.com/profile_images/96034368/n1076431955_30001395_7912_normal.jpg","url":null,"profile_sidebar_border_color":"c7d1ed","screen_name":"RenatonMiranda","profile_background_tile":true,"followers_count":111,"protected":false,"time_zone":"Santiago","created_at":"Sat Mar 14 15:03:59 +0000 2009","name":"Renato Miranda","friends_count":143,"profile_background_color":"287356","id":24379310,"utc_offset":-14400},"in_reply_to_status_id":null,"id":4161232008} {"favorited":false,"text":"#musicmonday ,time to download some songs today!! :)","in_reply_to_user_id":null,"in_reply_to_screen_name":null,"source":"web","truncated":false,"created_at":"Tue Sep 22 01:29:19 +0000 2009","user":{"statuses_count":188,"favourites_count":0,"profile_text_color":"3D1957","location":"under the water","profile_background_image_url":"http://s.twimg.com/a/1253562286/images/themes/theme10/bg.gif","profile_link_color":"FF0000","description":"ask me ","following":null,"verified":false,"notifications":null,"profile_sidebar_fill_color":"7AC3EE","profile_image_url":"http://a1.twimg.com/profile_images/421281292/twit_pic_normal.jpg","url":"http://www.exploretalent.com/contest_video.php?talentnum=2053105&cm_id=3398","profile_sidebar_border_color":"65B0DA","screen_name":"julieanne11343","profile_background_tile":true,"followers_count":9,"protected":false,"time_zone":"Pacific Time (US & Canada)","created_at":"Mon Jul 20 21:08:22 +0000 2009","name":"Julieanne","friends_count":17,"profile_background_color":"642D8B","id":58591151,"utc_offset":-28800},"in_reply_to_status_id":null,"id":4161233120} {"text":"#Musicmonday \"Dont be tardy f0r the party\"","truncated":false,"source":"<a href=\"http://twitterhelp.blogspot.com/2008/05/twitter-via-mobile-web-mtwittercom.html\" rel=\"nofollow\">mobile web</a>","in_reply_to_status_id":null,"favorited":false,"created_at":"Tue Sep 22 01:29:19 +0000 2009","user":{"verified":false,"notifications":null,"profile_sidebar_fill_color":"e0ff92","location":"Dope Girl Island","profile_sidebar_border_color":"87bc44","description":"","following":null,"profile_background_tile":false,"followers_count":29,"profile_image_url":"http://a3.twimg.com/profile_images/217487577/badbad_normal.jpg","time_zone":"Eastern Time (US & Canada)","url":null,"friends_count":65,"profile_background_color":"9ae4e8","screen_name":"SwagGirlOnDeck","protected":false,"statuses_count":847,"favourites_count":0,"created_at":"Fri May 01 16:59:15 +0000 2009","profile_text_color":"000000","name":"Mariah Reta","id":36987168,"profile_background_image_url":"http://s.twimg.com/a/1253301564/images/themes/theme1/bg.png","utc_offset":-18000,"profile_link_color":"0000ff"},"in_reply_to_user_id":null,"id":4161233317,"in_reply_to_screen_name":null}
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'tweetstream'
|
6
|
+
require 'spec'
|
7
|
+
require 'spec/autorun'
|
8
|
+
require 'yajl'
|
9
|
+
|
10
|
+
def sample_tweets
|
11
|
+
if @tweets
|
12
|
+
@tweets
|
13
|
+
else
|
14
|
+
@tweets = []
|
15
|
+
Yajl::Parser.parse(File.open(File.dirname(__FILE__) + '/data/statuses.json', 'r')) do |hash|
|
16
|
+
@tweets << hash
|
17
|
+
end
|
18
|
+
@tweets
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Spec::Runner.configure do |config|
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe TweetStream::Client do
|
4
|
+
it 'should set the username and password from the initializers' do
|
5
|
+
@client = TweetStream::Client.new('abc','def')
|
6
|
+
@client.username.should == 'abc'
|
7
|
+
@client.password.should == 'def'
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#build_uri' do
|
11
|
+
before do
|
12
|
+
@client = TweetStream::Client.new('abc','def')
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should return a URI' do
|
16
|
+
@client.send(:build_uri, '').is_a?(URI).should be_true
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should contain the auth information from the client' do
|
20
|
+
@client.send(:build_uri, '').user.should == 'abc'
|
21
|
+
@client.send(:build_uri, '').password.should == 'def'
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should have the specified path with the version prefix and a json extension' do
|
25
|
+
@client.send(:build_uri, 'awesome').path.should == '/1/awesome.json'
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should add on a query string if such parameters are specified' do
|
29
|
+
@client.send(:build_uri, 'awesome', :q => 'abc').query.should == 'q=abc'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#build_query_parameters' do
|
34
|
+
before do
|
35
|
+
@client = TweetStream::Client.new('abc','def')
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should return a blank string if passed a nil value' do
|
39
|
+
@client.send(:build_query_parameters, nil).should == ''
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should return a blank string if passed an empty hash' do
|
43
|
+
@client.send(:build_query_parameters, {}).should == ''
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should add a query parameter for a key' do
|
47
|
+
@client.send(:build_query_parameters, {:query => 'abc'}).should == '?query=abc'
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should escape characters in the value' do
|
51
|
+
@client.send(:build_query_parameters, {:query => 'awesome guy'}).should == '?query=awesome+guy'
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should join multiple pairs together' do
|
55
|
+
['?a=b&c=d','?c=d&a=b'].include?(@client.send(:build_query_parameters, {:a => 'b', :c => 'd'})).should be_true
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#start' do
|
60
|
+
before do
|
61
|
+
@client = TweetStream::Client.new('abc','def')
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should make a call to Yajl::HttpStream' do
|
65
|
+
Yajl::HttpStream.should_receive(:get).once.with(URI.parse('http://abc:def@stream.twitter.com/1/cool.json'), :symbolize_keys => true).and_return({})
|
66
|
+
@client.start('cool')
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should yield a TwitterStream::Status for each update' do
|
70
|
+
Yajl::HttpStream.should_receive(:get).once.with(URI.parse('http://abc:def@stream.twitter.com/1/statuses/filter.json?track=musicmonday'), :symbolize_keys => true).and_yield(sample_tweets[0])
|
71
|
+
@client.track('musicmonday') do |status|
|
72
|
+
status.is_a?(TweetStream::Status).should be_true
|
73
|
+
@yielded = true
|
74
|
+
end
|
75
|
+
@yielded.should be_true
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe ' API methods' do
|
80
|
+
before do
|
81
|
+
@client = TweetStream::Client.new('abc','def')
|
82
|
+
end
|
83
|
+
|
84
|
+
%w(firehose retweet sample).each do |method|
|
85
|
+
it "##{method} should make a call to start with \"statuses/#{method}\"" do
|
86
|
+
@client.should_receive(:start).once.with('statuses/' + method, {})
|
87
|
+
@client.send(method)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
it '#track should make a call to start with "statuses/filter" and a track query parameter' do
|
92
|
+
@client.should_receive(:start).once.with('statuses/filter', :track => 'test')
|
93
|
+
@client.track('test')
|
94
|
+
end
|
95
|
+
|
96
|
+
it '#track should comma-join multiple arguments' do
|
97
|
+
@client.should_receive(:start).once.with('statuses/filter', :track => 'foo,bar,baz')
|
98
|
+
@client.track('foo', 'bar', 'baz')
|
99
|
+
end
|
100
|
+
|
101
|
+
it '#follow should make a call to start with "statuses/filter" and a follow query parameter' do
|
102
|
+
@client.should_receive(:start).once.with('statuses/filter', :follow => '123')
|
103
|
+
@client.follow(123)
|
104
|
+
end
|
105
|
+
|
106
|
+
it '#follow should comma-join multiple arguments' do
|
107
|
+
@client.should_receive(:start).once.with('statuses/filter', :follow => '123,456')
|
108
|
+
@client.follow(123, 456)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe '#track' do
|
113
|
+
before do
|
114
|
+
@client = TweetStream::Client.new('abc','def')
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should call #start with "statuses/filter" and the provided queries' do
|
118
|
+
@client.should_receive(:start).once.with('statuses/filter', :track => 'rock')
|
119
|
+
@client.track('rock')
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe TweetStream::Hash do
|
4
|
+
it 'should be initialized by passing in an existing hash' do
|
5
|
+
TweetStream::Hash.new(:abc => 123)[:abc].should == 123
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should symbolize incoming keys' do
|
9
|
+
TweetStream::Hash.new('abc' => 123)[:abc].should == 123
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should allow access via method calls' do
|
13
|
+
TweetStream::Hash.new(:abc => 123).abc.should == 123
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should still throw NoMethod for non-existent keys' do
|
17
|
+
lambda{TweetStream::Hash.new({}).akabi}.should raise_error(NoMethodError)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe TweetStream::Status do
|
4
|
+
it 'should modify the :user key into a TweetStream::User object' do
|
5
|
+
@status = TweetStream::Status.new(:user => {:screen_name => 'bob'})
|
6
|
+
@status.user.is_a?(TweetStream::User).should be_true
|
7
|
+
@status.user.screen_name.should == 'bob'
|
8
|
+
end
|
9
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: intridea-tweetstream
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Bleigh
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-09-22 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: yajl-ruby
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.6.3
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: daemons
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
description: TweetStream allows you to easily consume the Twitter Streaming API utilizing the YAJL Ruby gem.
|
46
|
+
email: michael@intridea.com
|
47
|
+
executables: []
|
48
|
+
|
49
|
+
extensions: []
|
50
|
+
|
51
|
+
extra_rdoc_files:
|
52
|
+
- LICENSE
|
53
|
+
- README.rdoc
|
54
|
+
files:
|
55
|
+
- LICENSE
|
56
|
+
- README.rdoc
|
57
|
+
- Rakefile
|
58
|
+
- VERSION
|
59
|
+
- lib/tracker.rb
|
60
|
+
- lib/tweetstream.rb
|
61
|
+
- lib/tweetstream/client.rb
|
62
|
+
- lib/tweetstream/daemon.rb
|
63
|
+
- lib/tweetstream/hash.rb
|
64
|
+
- lib/tweetstream/status.rb
|
65
|
+
- lib/tweetstream/user.rb
|
66
|
+
- spec/data/statuses.json
|
67
|
+
- spec/spec.opts
|
68
|
+
- spec/spec_helper.rb
|
69
|
+
- spec/tweetstream/client_spec.rb
|
70
|
+
- spec/tweetstream/hash_spec.rb
|
71
|
+
- spec/tweetstream/status_spec.rb
|
72
|
+
- spec/tweetstream_spec.rb
|
73
|
+
has_rdoc: false
|
74
|
+
homepage: http://github.com/intridea/tweetstream
|
75
|
+
licenses:
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options:
|
78
|
+
- --charset=UTF-8
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: "0"
|
86
|
+
version:
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: "0"
|
92
|
+
version:
|
93
|
+
requirements: []
|
94
|
+
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 1.3.5
|
97
|
+
signing_key:
|
98
|
+
specification_version: 3
|
99
|
+
summary: TweetStream is a simple wrapper for consuming the Twitter Streaming API.
|
100
|
+
test_files:
|
101
|
+
- spec/spec_helper.rb
|
102
|
+
- spec/tweetstream/client_spec.rb
|
103
|
+
- spec/tweetstream/hash_spec.rb
|
104
|
+
- spec/tweetstream/status_spec.rb
|
105
|
+
- spec/tweetstream_spec.rb
|