jugyo-rubytter 0.5.0 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -0
- data/examples/search.rb +2 -2
- data/lib/rubytter.rb +41 -19
- data/spec/rubytter_spec.rb +51 -6
- data/spec/search.json +1 -0
- metadata +3 -2
data/Rakefile
CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.description = "Rubytter is a simple twitter client."
|
21
21
|
s.files = %w( #{Dir['lib/**/*.rb'].join(' ')}
|
22
22
|
#{Dir['spec/**/*.rb'].join(' ')}
|
23
|
+
#{Dir['spec/**/*.json'].join(' ')}
|
23
24
|
#{Dir['examples/**/*.rb'].join(' ')}
|
24
25
|
README.rdoc
|
25
26
|
History.txt
|
data/examples/search.rb
CHANGED
@@ -4,6 +4,6 @@ require 'rubygems'
|
|
4
4
|
require 'rubytter'
|
5
5
|
|
6
6
|
client = Rubytter.new
|
7
|
-
client.search(ARGV[0] || 'rubytter').
|
8
|
-
puts "#{status.
|
7
|
+
client.search(ARGV[0] || 'rubytter').each do |status|
|
8
|
+
puts "#{status.user.screen_name}: #{status.text}"
|
9
9
|
end
|
data/lib/rubytter.rb
CHANGED
@@ -16,7 +16,7 @@ class Rubytter
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
VERSION = '0.
|
19
|
+
VERSION = '0.6.3'
|
20
20
|
|
21
21
|
attr_reader :login
|
22
22
|
attr_accessor :host, :header
|
@@ -101,31 +101,53 @@ class Rubytter
|
|
101
101
|
send_direct_message(params.merge({:user => user, :text => text}))
|
102
102
|
end
|
103
103
|
|
104
|
-
def search(query, params = {})
|
105
|
-
path = '/search.json'
|
106
|
-
param_str = '?' + to_param_str(params.merge({:q => query}))
|
107
|
-
path = path + param_str unless param_str.empty?
|
108
|
-
req = create_request(Net::HTTP::Get.new(path), false)
|
109
|
-
http_request("search.#{@host}", req)
|
110
|
-
end
|
111
|
-
|
112
104
|
def get(path, params = {})
|
113
105
|
path += '.json'
|
114
|
-
param_str = '?' + to_param_str(params)
|
106
|
+
param_str = '?' + self.class.to_param_str(params)
|
115
107
|
path = path + param_str unless param_str.empty?
|
116
108
|
req = create_request(Net::HTTP::Get.new(path))
|
117
|
-
http_request(@host, req)
|
109
|
+
self.class.json_to_struct(http_request(@host, req))
|
118
110
|
end
|
119
111
|
|
120
112
|
def post(path, params = {})
|
121
113
|
path += '.json'
|
122
|
-
param_str = to_param_str(params)
|
114
|
+
param_str = self.class.to_param_str(params)
|
123
115
|
req = create_request(Net::HTTP::Post.new(path))
|
124
|
-
http_request(@host, req, param_str)
|
116
|
+
self.class.json_to_struct(http_request(@host, req, param_str))
|
125
117
|
end
|
126
|
-
|
127
118
|
alias delete post
|
128
119
|
|
120
|
+
def search(query, params = {})
|
121
|
+
path = '/search.json'
|
122
|
+
param_str = '?' + self.class.to_param_str(params.merge({:q => query}))
|
123
|
+
path = path + param_str unless param_str.empty?
|
124
|
+
req = create_request(Net::HTTP::Get.new(path), false)
|
125
|
+
json_data = http_request("search.#{@host}", req)
|
126
|
+
self.class.json_to_struct(
|
127
|
+
json_data['results'].map do |result|
|
128
|
+
search_result_to_struct(result)
|
129
|
+
end
|
130
|
+
)
|
131
|
+
end
|
132
|
+
|
133
|
+
def search_result_to_struct(json)
|
134
|
+
{
|
135
|
+
'id' => json['id'],
|
136
|
+
'text' => json['text'],
|
137
|
+
'source' => CGI.unescapeHTML(json['source']),
|
138
|
+
'created_at' => json['created_at'],
|
139
|
+
'in_reply_to_user_id' => json['to_usre_id'],
|
140
|
+
'in_reply_to_screen_name' => json['to_usre'],
|
141
|
+
'in_reply_to_status_id' => nil,
|
142
|
+
'user' => {
|
143
|
+
'id' => json['from_user_id'],
|
144
|
+
'name' => nil,
|
145
|
+
'screen_name' => json['from_user'],
|
146
|
+
'profile_image_url' => json['profile_image_url']
|
147
|
+
}
|
148
|
+
}
|
149
|
+
end
|
150
|
+
|
129
151
|
def http_request(host, req, param_str = nil)
|
130
152
|
res = @connection.start(host) do |http|
|
131
153
|
if param_str
|
@@ -134,12 +156,12 @@ class Rubytter
|
|
134
156
|
http.request(req)
|
135
157
|
end
|
136
158
|
end
|
137
|
-
|
159
|
+
json_data = JSON.parse(res.body)
|
138
160
|
case res.code
|
139
161
|
when "200"
|
140
|
-
|
162
|
+
json_data
|
141
163
|
else
|
142
|
-
raise APIError.new(
|
164
|
+
raise APIError.new(json_data['error'], res)
|
143
165
|
end
|
144
166
|
end
|
145
167
|
|
@@ -149,7 +171,7 @@ class Rubytter
|
|
149
171
|
req
|
150
172
|
end
|
151
173
|
|
152
|
-
def json_to_struct(json)
|
174
|
+
def self.json_to_struct(json)
|
153
175
|
case json
|
154
176
|
when Array
|
155
177
|
json.map{|i| json_to_struct(i)}
|
@@ -171,7 +193,7 @@ class Rubytter
|
|
171
193
|
end
|
172
194
|
end
|
173
195
|
|
174
|
-
def to_param_str(hash)
|
196
|
+
def self.to_param_str(hash)
|
175
197
|
raise ArgumentError, 'Argument must be a Hash object' unless hash.is_a?(Hash)
|
176
198
|
hash.to_a.map{|i| i[0].to_s + '=' + CGI.escape(i[1].to_s) }.join('&')
|
177
199
|
end
|
data/spec/rubytter_spec.rb
CHANGED
@@ -113,6 +113,7 @@ class Rubytter
|
|
113
113
|
@rubytter.should_receive(:http_request) do |host, req, param_str|
|
114
114
|
req.path.should == '/search.json?q=test'
|
115
115
|
host.should == 'search.twitter.com'
|
116
|
+
{'results' => []}
|
116
117
|
end
|
117
118
|
@rubytter.search('test')
|
118
119
|
end
|
@@ -122,22 +123,22 @@ class Rubytter
|
|
122
123
|
req.path.should =~ /\/search.json\?/
|
123
124
|
req.path.should =~ /q=test/
|
124
125
|
req.path.should =~ /lang=ja/
|
126
|
+
{'results' => []}
|
125
127
|
end
|
126
128
|
@rubytter.search('test', :lang => 'ja')
|
127
129
|
end
|
128
130
|
|
129
131
|
it 'should respond to to_param_str' do
|
130
|
-
param_str =
|
131
|
-
p param_str
|
132
|
+
param_str = Rubytter.to_param_str(:page => 2, :foo => 'bar')
|
132
133
|
param_str.should =~ /^.+?=.+?&.+?=.+?$/
|
133
134
|
param_str.should =~ /page=2/
|
134
135
|
param_str.should =~ /foo=bar/
|
135
136
|
end
|
136
137
|
|
137
138
|
it 'should raise when call to_param_str with invalid arg' do
|
138
|
-
lambda {
|
139
|
-
lambda {
|
140
|
-
lambda {
|
139
|
+
lambda { Rubytter.to_param_str(nil) }.should raise_error(ArgumentError)
|
140
|
+
lambda { Rubytter.to_param_str('foo') }.should raise_error(ArgumentError)
|
141
|
+
lambda { Rubytter.to_param_str(:bar) }.should raise_error(ArgumentError)
|
141
142
|
end
|
142
143
|
|
143
144
|
it 'should set default header' do
|
@@ -179,7 +180,7 @@ class Rubytter
|
|
179
180
|
:d => {:a => {:a => 1, :b => 2}, :b => 1},
|
180
181
|
:e => [{:a => 1, :b => 2}, {:c => 3}]
|
181
182
|
}
|
182
|
-
struct =
|
183
|
+
struct = Rubytter.json_to_struct(hash)
|
183
184
|
struct.a.should == 'a'
|
184
185
|
struct.b.should == 1
|
185
186
|
struct.c.a.should == 1
|
@@ -197,5 +198,49 @@ class Rubytter
|
|
197
198
|
rubytter.should_receive(:__update_status).with({:status => 'test', :source => "Foo"})
|
198
199
|
rubytter.update('test')
|
199
200
|
end
|
201
|
+
|
202
|
+
it 'should convert search results to struct' do
|
203
|
+
json_data = {
|
204
|
+
'id' => '123',
|
205
|
+
'text' => 'foo foo bar bar',
|
206
|
+
'created_at' => 'Sat, 21 Mar 2009 09:48:20 +0000',
|
207
|
+
'source' => '<a href="http:\/\/twitter.com\/">web<\/a>',
|
208
|
+
'to_usre_id' => '20660692',
|
209
|
+
'to_usre' => 'jugyo_test',
|
210
|
+
'from_user_id' => '3748631',
|
211
|
+
'from_user' => 'jugyo',
|
212
|
+
'profile_image_url' => 'http://s3.amazonaws.com/twitter_production/profile_images/63467667/megane2_normal.png'
|
213
|
+
}
|
214
|
+
rubytter = Rubytter.new('test', 'teat')
|
215
|
+
result = rubytter.search_result_to_struct(json_data)
|
216
|
+
result['id'].should == '123'
|
217
|
+
result['text'].should == 'foo foo bar bar'
|
218
|
+
result['created_at'].should == 'Sat, 21 Mar 2009 09:48:20 +0000'
|
219
|
+
result['source'].should == "<a href=\"http:\\/\\/twitter.com\\/\">web<\\/a>"
|
220
|
+
result['in_reply_to_user_id'].should == '20660692'
|
221
|
+
result['in_reply_to_screen_name'].should == 'jugyo_test'
|
222
|
+
result['user']['id'].should == '3748631'
|
223
|
+
result['user']['screen_name'].should == 'jugyo'
|
224
|
+
result['user']['profile_image_url'].should == 'http://s3.amazonaws.com/twitter_production/profile_images/63467667/megane2_normal.png'
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'should work search' do
|
228
|
+
json_data = JSON.parse open(File.dirname(__FILE__) + '/search.json').read
|
229
|
+
|
230
|
+
@rubytter.stub!(:http_request).and_return(json_data)
|
231
|
+
statuses = @rubytter.search('termtter')
|
232
|
+
status = statuses[0]
|
233
|
+
|
234
|
+
status.id.should == 1365281728
|
235
|
+
status.text.should == "よし、add_hook 呼んでるところが無くなった #termtter"
|
236
|
+
status.created_at.should == "Sat, 21 Mar 2009 09:48:20 +0000"
|
237
|
+
status.source.should == "<a href=\"http://twitter.com/\">web</a>"
|
238
|
+
status.in_reply_to_user_id.should == nil
|
239
|
+
status.in_reply_to_screen_name.should == nil
|
240
|
+
status.in_reply_to_status_id.should == nil
|
241
|
+
status.user.id.should == 74941
|
242
|
+
status.user.screen_name.should == "jugyo"
|
243
|
+
status.user.profile_image_url.should == "http://s3.amazonaws.com/twitter_production/profile_images/63467667/megane2_normal.png"
|
244
|
+
end
|
200
245
|
end
|
201
246
|
end
|
data/spec/search.json
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"results":[{"text":"\u3088\u3057\u3001add_hook \u547c\u3093\u3067\u308b\u3068\u3053\u308d\u304c\u7121\u304f\u306a\u3063\u305f #termtter","to_user_id":null,"from_user":"jugyo","id":1365281728,"from_user_id":74941,"iso_language_code":"ja","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/63467667\/megane2_normal.png","created_at":"Sat, 21 Mar 2009 09:48:20 +0000"},{"text":"[termtter] http:\/\/bit.ly\/9sOWQ jugyo - Changed to use register_hook.","to_user_id":null,"from_user":"termtter","id":1365279197,"from_user_id":3422637,"iso_language_code":"en","source":"<a href="http:\/\/github.com">GitHub<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/69965634\/termtter_normal.jpg","created_at":"Sat, 21 Mar 2009 09:46:51 +0000"},{"text":"test for msagent plugin of termtter","to_user_id":null,"from_user":"jugyo","id":1365258802,"from_user_id":74941,"iso_language_code":"no","source":"<a href="http:\/\/github.com\/jugyo\/termtter">Termtter<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/63467667\/megane2_normal.png","created_at":"Sat, 21 Mar 2009 09:35:24 +0000"},{"text":"termtter -e 'update \u5bdd\u308b' \u307f\u305f\u3044\u306a\u611f\u3058\u3067\u30b3\u30de\u30f3\u30c9\u5b9f\u884c\u3067\u304d\u305f\u3089\u4fbf\u5229\u304b\u306a\u3041","to_user_id":null,"from_user":"jugyo","id":1365097088,"from_user_id":74941,"iso_language_code":"ja","source":"<a href="http:\/\/twitterfon.net\/">TwitterFon<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/63467667\/megane2_normal.png","created_at":"Sat, 21 Mar 2009 08:05:57 +0000"},{"text":"Web \u4e0a\u306e\u3069\u3063\u304b\u3057\u3089\u306b\u30b0\u30eb\u30fc\u30d7\u60c5\u5831\u3092\u7f6e\u3044\u3066\u304a\u3051\u308c\u3070 #termtter","to_user_id":null,"from_user":"jugyo","id":1364954500,"from_user_id":74941,"iso_language_code":"ja","source":"<a href="http:\/\/twitterfon.net\/">TwitterFon<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/63467667\/megane2_normal.png","created_at":"Sat, 21 Mar 2009 06:54:59 +0000"},{"text":"notify-send \u30d7\u30e9\u30b0\u30a4\u30f3\u3092\u4fee\u6b63 #termtter","to_user_id":null,"from_user":"jugyo","id":1364802582,"from_user_id":74941,"iso_language_code":"en","source":"<a href="http:\/\/github.com\/jugyo\/termtter">Termtter<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/63467667\/megane2_normal.png","created_at":"Sat, 21 Mar 2009 05:51:35 +0000"},{"text":"[termtter] http:\/\/bit.ly\/1e3ExY jugyo - Changed to use register_hook.","to_user_id":null,"from_user":"termtter","id":1364800822,"from_user_id":3422637,"iso_language_code":"en","source":"<a href="http:\/\/github.com">GitHub<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/69965634\/termtter_normal.jpg","created_at":"Sat, 21 Mar 2009 05:50:52 +0000"},{"text":"@beatinaniwa termtter!\u30b0\u30eb\u30fc\u30d7\u5316\u30d7\u30e9\u30b0\u30a4\u30f3\u304c\u3042\u308a\u307e\u3059\u3088\uff0e http:\/\/d.hatena.ne.jp\/hakobe932\/20090107\/1231327037","to_user_id":8021,"to_user":"beatinaniwa","from_user":"yaotti","id":1364768285,"from_user_id":31813,"iso_language_code":"ja","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/81045219\/cat_normal.jpg","created_at":"Sat, 21 Mar 2009 05:38:29 +0000"},{"text":"termtter","to_user_id":null,"from_user":"keisuke_n","id":1364718890,"from_user_id":60906,"source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/103481443\/ke-s_normal.png","created_at":"Sat, 21 Mar 2009 05:20:17 +0000"},{"text":"[termtter] http:\/\/bit.ly\/HqTT hitode909 - made load command(this command loads history)","to_user_id":null,"from_user":"termtter","id":1364347378,"from_user_id":3422637,"iso_language_code":"en","source":"<a href="http:\/\/github.com">GitHub<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/69965634\/termtter_normal.jpg","created_at":"Sat, 21 Mar 2009 03:31:32 +0000"},{"text":"[termtter] http:\/\/bit.ly\/1px3BJ hitode909 - group\u306e\u51e6\u7406\u3092\u9ad8\u901f\u5316(\u30e6\u30fc\u30b6\u30fc\u3054\u3068\u306e\u30ed\u30b0\u3092\u30de\u30fc\u30b8\u3059\u308b\u5f62\u306b\u3057\u305f)","to_user_id":null,"from_user":"termtter","id":1364173363,"from_user_id":3422637,"iso_language_code":"ja","source":"<a href="http:\/\/github.com">GitHub<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/69965634\/termtter_normal.jpg","created_at":"Sat, 21 Mar 2009 02:47:09 +0000"},{"text":"[termtter] http:\/\/bit.ly\/l2bs6 hitode909 - limit\u3067ERB\u3092\u4f7f\u3046\u3088\u3046\u306b","to_user_id":null,"from_user":"termtter","id":1363634232,"from_user_id":3422637,"iso_language_code":"pt","source":"<a href="http:\/\/github.com">GitHub<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/69965634\/termtter_normal.jpg","created_at":"Sat, 21 Mar 2009 00:36:12 +0000"},{"text":"[termtter] http:\/\/bit.ly\/Myzz hitode909 - made "get_group_of" method.","to_user_id":null,"from_user":"termtter","id":1363634196,"from_user_id":3422637,"iso_language_code":"en","source":"<a href="http:\/\/github.com">GitHub<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/69965634\/termtter_normal.jpg","created_at":"Sat, 21 Mar 2009 00:36:12 +0000"},{"text":"[termtter] http:\/\/bit.ly\/4QDvO hitode909 - update_editor\u306eid\u88dc\u5b8c\u3092\u30c7\u30d5\u30a9\u30eb\u30c8\u3067\u6709\u52b9\u306b","to_user_id":null,"from_user":"termtter","id":1362078582,"from_user_id":3422637,"iso_language_code":"nl","source":"<a href="http:\/\/github.com">GitHub<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/69965634\/termtter_normal.jpg","created_at":"Fri, 20 Mar 2009 19:18:26 +0000"},{"text":"[termtter] http:\/\/bit.ly\/e0J2 hitode909 - url_addspace\u304c\u52d5\u304b\u306a\u304b\u3063\u305f\u306e\u3092\u4fee\u6b63","to_user_id":null,"from_user":"termtter","id":1362078539,"from_user_id":3422637,"iso_language_code":"es","source":"<a href="http:\/\/github.com">GitHub<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/69965634\/termtter_normal.jpg","created_at":"Fri, 20 Mar 2009 19:18:25 +0000"}],"since_id":0,"max_id":1365281728,"refresh_url":"?since_id=1365281728&q=termtter","results_per_page":15,"next_page":"?page=2&max_id=1365281728&q=termtter","completed_in":0.017248,"page":1,"query":"termtter"}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jugyo-rubytter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jugyo
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-03-21 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -36,6 +36,7 @@ files:
|
|
36
36
|
- lib/rubytter.rb
|
37
37
|
- spec/rubytter_spec.rb
|
38
38
|
- spec/spec_helper.rb
|
39
|
+
- spec/search.json
|
39
40
|
- examples/direct_message.rb
|
40
41
|
- examples/favorite.rb
|
41
42
|
- examples/follow.rb
|