tweetstream 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of tweetstream might be problematic. Click here for more details.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +77 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/lib/tracker.log +0 -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 +109 -0
data/.document
ADDED
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,50 @@
|
|
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.add_development_dependency "rspec"
|
14
|
+
gem.add_dependency 'yajl-ruby', '>= 0.6.3'
|
15
|
+
gem.add_dependency 'daemons'
|
16
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
|
+
end
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'spec/rake/spectask'
|
23
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
24
|
+
spec.libs << 'lib' << 'spec'
|
25
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
26
|
+
end
|
27
|
+
|
28
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
29
|
+
spec.libs << 'lib' << 'spec'
|
30
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
31
|
+
spec.rcov = true
|
32
|
+
end
|
33
|
+
|
34
|
+
task :spec => :check_dependencies
|
35
|
+
|
36
|
+
task :default => :spec
|
37
|
+
|
38
|
+
require 'rake/rdoctask'
|
39
|
+
Rake::RDocTask.new do |rdoc|
|
40
|
+
if File.exist?('VERSION')
|
41
|
+
version = File.read('VERSION')
|
42
|
+
else
|
43
|
+
version = ""
|
44
|
+
end
|
45
|
+
|
46
|
+
rdoc.rdoc_dir = 'rdoc'
|
47
|
+
rdoc.title = "tweetstream #{version}"
|
48
|
+
rdoc.rdoc_files.include('README*')
|
49
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
50
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/lib/tracker.log
ADDED
File without changes
|
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,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tweetstream
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
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 -04: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
|
+
- .document
|
56
|
+
- .gitignore
|
57
|
+
- LICENSE
|
58
|
+
- README.rdoc
|
59
|
+
- Rakefile
|
60
|
+
- VERSION
|
61
|
+
- lib/tracker.log
|
62
|
+
- lib/tracker.rb
|
63
|
+
- lib/tweetstream.rb
|
64
|
+
- lib/tweetstream/client.rb
|
65
|
+
- lib/tweetstream/daemon.rb
|
66
|
+
- lib/tweetstream/hash.rb
|
67
|
+
- lib/tweetstream/status.rb
|
68
|
+
- lib/tweetstream/user.rb
|
69
|
+
- spec/data/statuses.json
|
70
|
+
- spec/spec.opts
|
71
|
+
- spec/spec_helper.rb
|
72
|
+
- spec/tweetstream/client_spec.rb
|
73
|
+
- spec/tweetstream/hash_spec.rb
|
74
|
+
- spec/tweetstream/status_spec.rb
|
75
|
+
- spec/tweetstream_spec.rb
|
76
|
+
has_rdoc: true
|
77
|
+
homepage: http://github.com/intridea/tweetstream
|
78
|
+
licenses: []
|
79
|
+
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options:
|
82
|
+
- --charset=UTF-8
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: "0"
|
90
|
+
version:
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: "0"
|
96
|
+
version:
|
97
|
+
requirements: []
|
98
|
+
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 1.3.5
|
101
|
+
signing_key:
|
102
|
+
specification_version: 3
|
103
|
+
summary: TweetStream is a simple wrapper for consuming the Twitter Streaming API.
|
104
|
+
test_files:
|
105
|
+
- spec/spec_helper.rb
|
106
|
+
- spec/tweetstream/client_spec.rb
|
107
|
+
- spec/tweetstream/hash_spec.rb
|
108
|
+
- spec/tweetstream/status_spec.rb
|
109
|
+
- spec/tweetstream_spec.rb
|