twitter-stream 0.1.6 → 0.1.7
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.
Potentially problematic release.
This version of twitter-stream might be problematic. Click here for more details.
- data/Rakefile +3 -1
- data/VERSION +1 -1
- data/lib/twitter/json_stream.rb +54 -8
- data/spec/spec_helper.rb +7 -4
- data/spec/twitter/json_stream.rb +37 -17
- data/twitter-stream.gemspec +5 -2
- metadata +19 -5
data/Rakefile
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
|
2
|
+
|
3
|
+
gem 'rspec', '= 1.3.0'
|
3
4
|
require 'spec/rake/spectask'
|
4
5
|
|
5
6
|
desc "Run all specs"
|
@@ -19,6 +20,7 @@ begin
|
|
19
20
|
gemspec.homepage = "http://github.com/voloko/twitter-stream"
|
20
21
|
gemspec.authors = ["Vladimir Kolesnikov"]
|
21
22
|
gemspec.add_dependency("eventmachine", [">= 0.12.8"])
|
23
|
+
gemspec.add_dependency("roauth", [">= 0.0.2"])
|
22
24
|
gemspec.add_development_dependency("rspec", [">= 1.2.8"])
|
23
25
|
end
|
24
26
|
rescue LoadError
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.7
|
data/lib/twitter/json_stream.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'eventmachine'
|
2
2
|
require 'em/buftok'
|
3
3
|
require 'uri'
|
4
|
+
require 'roauth'
|
4
5
|
|
5
6
|
module Twitter
|
6
7
|
class JSONStream < EventMachine::Connection
|
@@ -27,10 +28,12 @@ module Twitter
|
|
27
28
|
:host => 'stream.twitter.com',
|
28
29
|
:port => 80,
|
29
30
|
:ssl => false,
|
30
|
-
:auth => 'test:test',
|
31
31
|
:user_agent => 'TwitterStream',
|
32
32
|
:timeout => 0,
|
33
|
-
:proxy => ENV['HTTP_PROXY']
|
33
|
+
:proxy => ENV['HTTP_PROXY'],
|
34
|
+
:auth => nil,
|
35
|
+
:oauth => {},
|
36
|
+
:filters => []
|
34
37
|
}
|
35
38
|
|
36
39
|
attr_accessor :code
|
@@ -52,7 +55,7 @@ module Twitter
|
|
52
55
|
host = proxy_uri.host
|
53
56
|
port = proxy_uri.port
|
54
57
|
end
|
55
|
-
|
58
|
+
|
56
59
|
connection = EventMachine.connect host, port, self, options
|
57
60
|
connection.start_tls if options[:ssl]
|
58
61
|
connection
|
@@ -113,10 +116,13 @@ module Twitter
|
|
113
116
|
end
|
114
117
|
|
115
118
|
def connection_completed
|
116
|
-
reset_state
|
117
119
|
send_request
|
118
120
|
end
|
119
121
|
|
122
|
+
def post_init
|
123
|
+
reset_state
|
124
|
+
end
|
125
|
+
|
120
126
|
protected
|
121
127
|
def schedule_reconnect
|
122
128
|
timeout = reconnect_timeout
|
@@ -174,23 +180,42 @@ module Twitter
|
|
174
180
|
def send_request
|
175
181
|
data = []
|
176
182
|
request_uri = @options[:path]
|
183
|
+
|
177
184
|
if @proxy
|
178
185
|
# proxies need the request to be for the full url
|
179
186
|
request_uri = "http#{'s' if @options[:ssl]}://#{@options[:host]}:#{@options[:port]}#{request_uri}"
|
180
187
|
end
|
188
|
+
|
189
|
+
content = @options[:content]
|
190
|
+
|
191
|
+
if !@options[:filters].empty?
|
192
|
+
if @options[:method].to_s.upcase == 'GET'
|
193
|
+
request_uri << "?#{filter_list}"
|
194
|
+
else
|
195
|
+
content = filter_list
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
181
199
|
data << "#{@options[:method]} #{request_uri} HTTP/1.1"
|
182
200
|
data << "Host: #{@options[:host]}"
|
183
|
-
data << "User-
|
184
|
-
|
201
|
+
data << "User-Agent: #{@options[:user_agent]}" if @options[:user_agent]
|
202
|
+
|
203
|
+
if @options[:auth]
|
204
|
+
data << "Authorization: Basic #{[@options[:auth]].pack('m').delete("\r\n")}"
|
205
|
+
elsif @options[:oauth]
|
206
|
+
data << "Authorization: #{oauth_header}"
|
207
|
+
end
|
208
|
+
|
185
209
|
if @proxy && @proxy.user
|
186
210
|
data << "Proxy-Authorization: Basic " + ["#{@proxy.user}:#{@proxy.password}"].pack('m').delete("\r\n")
|
187
211
|
end
|
188
212
|
if @options[:method] == 'POST'
|
189
213
|
data << "Content-type: #{@options[:content_type]}"
|
190
|
-
data << "Content-length: #{
|
214
|
+
data << "Content-length: #{content.length}"
|
191
215
|
end
|
192
216
|
data << "\r\n"
|
193
|
-
|
217
|
+
|
218
|
+
send_data data.join("\r\n") << content
|
194
219
|
end
|
195
220
|
|
196
221
|
def receive_line ln
|
@@ -242,6 +267,27 @@ module Twitter
|
|
242
267
|
@nf_last_reconnect = @af_last_reconnect = nil
|
243
268
|
@reconnect_retries = 0
|
244
269
|
end
|
270
|
+
|
271
|
+
# :filters => %w(miama lebron jesus)
|
272
|
+
# :oauth => {
|
273
|
+
# :consumer_key => [key],
|
274
|
+
# :consumer_secret => [token],
|
275
|
+
# :access_key => [access key],
|
276
|
+
# :access_secret => [access secret]
|
277
|
+
# }
|
278
|
+
def oauth_header
|
279
|
+
uri = "http://#{@options[:host]}#{@options[:path]}"
|
280
|
+
|
281
|
+
params = {
|
282
|
+
'track' => @options[:filters].join(',')
|
283
|
+
}
|
284
|
+
|
285
|
+
::ROAuth.header(@options[:oauth], uri, params, @options[:method])
|
286
|
+
end
|
287
|
+
|
288
|
+
def filter_list
|
289
|
+
"track=#{@options[:filters].join(',')}"
|
290
|
+
end
|
245
291
|
|
246
292
|
end
|
247
293
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
|
3
|
-
$LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
|
2
|
+
$:.unshift File.expand_path("../../lib", __FILE__)
|
4
3
|
|
5
|
-
gem 'rspec'
|
4
|
+
gem 'rspec', '= 1.3.0'
|
6
5
|
require 'spec'
|
7
6
|
require 'spec/mocks'
|
8
7
|
|
8
|
+
require 'twitter/json_stream'
|
9
|
+
|
9
10
|
def fixture_path(path)
|
10
11
|
File.join(File.dirname(__FILE__), '..', 'fixtures', path)
|
11
12
|
end
|
@@ -18,7 +19,9 @@ def connect_stream(opts={}, &blk)
|
|
18
19
|
EM.run {
|
19
20
|
opts.merge!(:host => Host, :port => Port)
|
20
21
|
stop_in = opts.delete(:stop_in) || 0.5
|
21
|
-
|
22
|
+
unless opts[:start_server] == false
|
23
|
+
EM.start_server Host, Port, JSONServer
|
24
|
+
end
|
22
25
|
@stream = JSONStream.connect(opts)
|
23
26
|
blk.call if blk
|
24
27
|
EM.add_timer(stop_in){ EM.stop }
|
data/spec/twitter/json_stream.rb
CHANGED
@@ -61,13 +61,13 @@ describe JSONStream do
|
|
61
61
|
it "should parse headers" do
|
62
62
|
connect_stream
|
63
63
|
stream.code.should == 200
|
64
|
-
stream.headers[0].downcase.should include
|
64
|
+
stream.headers[0].downcase.should include('content-type')
|
65
65
|
end
|
66
66
|
|
67
67
|
it "should parse headers even after connection close" do
|
68
68
|
connect_stream
|
69
69
|
stream.code.should == 200
|
70
|
-
stream.headers[0].downcase.should include
|
70
|
+
stream.headers[0].downcase.should include('content-type')
|
71
71
|
end
|
72
72
|
|
73
73
|
it "should extract records" do
|
@@ -79,20 +79,8 @@ describe JSONStream do
|
|
79
79
|
connect_stream
|
80
80
|
end
|
81
81
|
end
|
82
|
-
|
83
|
-
|
84
|
-
attr_reader :stream
|
85
|
-
before :each do
|
86
|
-
$data_to_send = ''
|
87
|
-
$close_connection = true
|
88
|
-
end
|
89
|
-
|
90
|
-
it "should timeout on inactivity" do
|
91
|
-
connect_stream :stop_in => 1.5 do
|
92
|
-
stream.should_receive(:reconnect)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
82
|
+
|
83
|
+
shared_examples_for "network failure" do
|
96
84
|
it "should reconnect on network failure" do
|
97
85
|
connect_stream do
|
98
86
|
stream.should_receive(:reconnect)
|
@@ -129,9 +117,41 @@ describe JSONStream do
|
|
129
117
|
end
|
130
118
|
timeout.should == 0.25
|
131
119
|
retries.should == 101
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "on network failure" do
|
124
|
+
attr_reader :stream
|
125
|
+
before :each do
|
126
|
+
$data_to_send = ''
|
127
|
+
$close_connection = true
|
132
128
|
end
|
129
|
+
|
130
|
+
it "should timeout on inactivity" do
|
131
|
+
connect_stream :stop_in => 1.5 do
|
132
|
+
stream.should_receive(:reconnect)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
it_should_behave_like "network failure"
|
133
137
|
end
|
134
138
|
|
139
|
+
context "on server unavailable" do
|
140
|
+
|
141
|
+
attr_reader :stream
|
142
|
+
|
143
|
+
# This is to make it so the network failure specs which call connect_stream
|
144
|
+
# can be reused. This way calls to connect_stream won't actually create a
|
145
|
+
# server to listen in.
|
146
|
+
def connect_stream_without_server(opts={},&block)
|
147
|
+
connect_stream_default(opts.merge(:start_server=>false),&block)
|
148
|
+
end
|
149
|
+
alias_method :connect_stream_default, :connect_stream
|
150
|
+
alias_method :connect_stream, :connect_stream_without_server
|
151
|
+
|
152
|
+
it_should_behave_like "network failure"
|
153
|
+
end
|
154
|
+
|
135
155
|
context "on application failure" do
|
136
156
|
attr_reader :stream
|
137
157
|
before :each do
|
@@ -159,4 +179,4 @@ describe JSONStream do
|
|
159
179
|
end
|
160
180
|
end
|
161
181
|
end
|
162
|
-
end
|
182
|
+
end
|
data/twitter-stream.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{twitter-stream}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.7"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Vladimir Kolesnikov"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-08-02}
|
13
13
|
s.description = %q{Simple Ruby client library for twitter streaming API. Uses EventMachine for connection handling. Adheres to twitter's reconnection guidline. JSON format only.}
|
14
14
|
s.email = %q{voloko@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -44,13 +44,16 @@ Gem::Specification.new do |s|
|
|
44
44
|
|
45
45
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
46
46
|
s.add_runtime_dependency(%q<eventmachine>, [">= 0.12.8"])
|
47
|
+
s.add_runtime_dependency(%q<roauth>, [">= 0.0.2"])
|
47
48
|
s.add_development_dependency(%q<rspec>, [">= 1.2.8"])
|
48
49
|
else
|
49
50
|
s.add_dependency(%q<eventmachine>, [">= 0.12.8"])
|
51
|
+
s.add_dependency(%q<roauth>, [">= 0.0.2"])
|
50
52
|
s.add_dependency(%q<rspec>, [">= 1.2.8"])
|
51
53
|
end
|
52
54
|
else
|
53
55
|
s.add_dependency(%q<eventmachine>, [">= 0.12.8"])
|
56
|
+
s.add_dependency(%q<roauth>, [">= 0.0.2"])
|
54
57
|
s.add_dependency(%q<rspec>, [">= 1.2.8"])
|
55
58
|
end
|
56
59
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
8
|
+
- 7
|
9
|
+
version: 0.1.7
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Vladimir Kolesnikov
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-08-02 00:00:00 +04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -32,9 +32,23 @@ dependencies:
|
|
32
32
|
type: :runtime
|
33
33
|
version_requirements: *id001
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
|
-
name:
|
35
|
+
name: roauth
|
36
36
|
prerelease: false
|
37
37
|
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
- 0
|
44
|
+
- 2
|
45
|
+
version: 0.0.2
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rspec
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
38
52
|
requirements:
|
39
53
|
- - ">="
|
40
54
|
- !ruby/object:Gem::Version
|
@@ -44,7 +58,7 @@ dependencies:
|
|
44
58
|
- 8
|
45
59
|
version: 1.2.8
|
46
60
|
type: :development
|
47
|
-
version_requirements: *
|
61
|
+
version_requirements: *id003
|
48
62
|
description: Simple Ruby client library for twitter streaming API. Uses EventMachine for connection handling. Adheres to twitter's reconnection guidline. JSON format only.
|
49
63
|
email: voloko@gmail.com
|
50
64
|
executables: []
|