rhaiker 0.0.1
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.
- data/History.ja.txt +3 -0
- data/History.txt +4 -0
- data/License.txt +20 -0
- data/Manifest.txt +34 -0
- data/README.ja.txt +34 -0
- data/README.txt +51 -0
- data/Rakefile +5 -0
- data/config/hoe.rb +74 -0
- data/config/requirements.rb +15 -0
- data/example/get_followers.rb +32 -0
- data/example/get_following_all_words.rb +29 -0
- data/example/get_hot_keywords.rb +17 -0
- data/example/haiku_update.rb +21 -0
- data/lib/rhaiker.rb +767 -0
- data/lib/rhaiker/utils.rb +113 -0
- data/lib/rhaiker/version.rb +9 -0
- data/lib/rhaiker/xml_parser.rb +211 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +82 -0
- data/setup.rb +1585 -0
- data/spec/rhaiker_spec.rb +318 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +10 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/rspec.rake +21 -0
- data/tasks/website.rake +17 -0
- data/website/index.html +71 -0
- data/website/index.txt +45 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +138 -0
- data/website/template.html.erb +47 -0
- metadata +103 -0
@@ -0,0 +1,318 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe Rhaiker, ' when first created' do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@accessor = Rhaiker.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should be have a user_agent "rhaiker"' do
|
10
|
+
@accessor.user_agent.should be_eql("rhaiker")
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should be have a source "rhaiker"' do
|
14
|
+
@accessor.source.should be_eql("rhaiker")
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'shoud not have a user_id' do
|
18
|
+
@accessor.user_id.should be_nil
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should not have a api_key' do
|
22
|
+
@accessor.api_key.should be_nil
|
23
|
+
end
|
24
|
+
|
25
|
+
after do
|
26
|
+
@accessor = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
describe Rhaiker::Utils, " when use" do
|
32
|
+
before do
|
33
|
+
@accessor = Rhaiker.new
|
34
|
+
@accessor.user_id = 'saronpasu'
|
35
|
+
@accessor.api_key = 'ar3hge2f'
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'create_uri should be URI instance' do
|
39
|
+
@accessor.create_uri(
|
40
|
+
Rhaiker::BaseAddress +
|
41
|
+
'statuses/public_timeline.xml'
|
42
|
+
).should be_a_kind_of(URI)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'create_request with type in :get should be Net::HTTP::Get instance' do
|
46
|
+
uri = mock(:uri)
|
47
|
+
uri.should_receive(:request_uri).and_return('text')
|
48
|
+
@accessor.create_request(:get, uri).should be_a_kind_of(Net::HTTP::Get)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'create_request with type in :post should be Net::HTTP::Post instance' do
|
52
|
+
uri = mock(:uri)
|
53
|
+
uri.should_receive(:request_uri).and_return('text')
|
54
|
+
@accessor.create_request(:post, uri).should be_a_kind_of(Net::HTTP::Post)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'create_request instance should have basic_auth' do
|
58
|
+
uri = mock(:uri)
|
59
|
+
uri.should_receive(:request_uri).and_return('text')
|
60
|
+
@accessor.create_request(
|
61
|
+
:get, uri, true
|
62
|
+
)['Authorization'].should be_eql(
|
63
|
+
"Basic c2Fyb25wYXN1OmFyM2hnZTJm"
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'http_access and return should be REXML::Document' do
|
68
|
+
uri = mock('uri')
|
69
|
+
request = mock('request')
|
70
|
+
@accessor.should_receive(:http_access).and_return(REXML::Document.new('<a/>'))
|
71
|
+
@accessor.http_access(uri, request).should be_a_kind_of(REXML::Document)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'parse_options and return parsed options' do
|
75
|
+
@accessor.parse_options({:status=>'hello',:page=>2}).should be_eql('?status=hello&page=2')
|
76
|
+
end
|
77
|
+
|
78
|
+
after do
|
79
|
+
@accessor = nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe Rhaiker::XML_Parser, 'when use' do
|
84
|
+
before do
|
85
|
+
@accessor = Rhaiker.new
|
86
|
+
@timeline = REXML::Document.new(
|
87
|
+
'<statuses>
|
88
|
+
<status>
|
89
|
+
<id>1234567890</id>
|
90
|
+
<created_at>2008-09-04T04:26:06Z</created_at>
|
91
|
+
<text>ほげ</text>
|
92
|
+
<keyword>ふが</keyword>
|
93
|
+
<in_reply_to_status_id>1234567890</in_reply_to_status_id>
|
94
|
+
<in_reply_to_user_id>saronpasu</in_reply_to_user_id>
|
95
|
+
<favorited>0</favorited>
|
96
|
+
<link>http://h.hatena.ne.jp/saronpasu/1234567890</link>
|
97
|
+
<source>web</source>
|
98
|
+
<replies>
|
99
|
+
<id>1234567890</id>
|
100
|
+
<created_at>2008-09-04T04:26:06Z</created_at>
|
101
|
+
<text>ほげ</text>
|
102
|
+
<keyword>ふが</keyword>
|
103
|
+
<favorited>0</favorited>
|
104
|
+
<link>http://h.hatena.ne.jp/saronpasu/1234567890</link>
|
105
|
+
<source>web</source>
|
106
|
+
<user>
|
107
|
+
<id>saronpasu</id>
|
108
|
+
<name>saronpasu</name>
|
109
|
+
<screen_name>saronpasu</screen_name>
|
110
|
+
<url>http://h.hatena.ne.jp/saronpasu/</url>
|
111
|
+
<profile_image_url>http://www.hatena.ne.jp/sa/saronpasu/profile.gif</profile_image_url>
|
112
|
+
<followers_count>0</followers_count>
|
113
|
+
</user>
|
114
|
+
</replies>
|
115
|
+
<user>
|
116
|
+
<id>saronpasu</id>
|
117
|
+
<name>saronpasu</name>
|
118
|
+
<screen_name>saronpasu</screen_name>
|
119
|
+
<url>http://h.hatena.ne.jp/saronpasu/</url>
|
120
|
+
<profile_image_url>http://www.hatena.ne.jp/sa/saronpasu/profile.gif</profile_image_url>
|
121
|
+
<followers_count>0</followers_count>
|
122
|
+
</user>
|
123
|
+
</status>
|
124
|
+
</statuses>'
|
125
|
+
)
|
126
|
+
@status = REXML::Document.new('
|
127
|
+
<status>
|
128
|
+
<id>1234567890</id>
|
129
|
+
<created_at>2008-09-04T04:26:06Z</created_at>
|
130
|
+
<text>ほげ</text>
|
131
|
+
<keyword>ふが</keyword>
|
132
|
+
<in_reply_to_status_id/>
|
133
|
+
<in_reply_to_user_id/>
|
134
|
+
<favorited>0</favorited>
|
135
|
+
<link>http://h.hatena.ne.jp/saronpasu/1234567890</link>
|
136
|
+
<source>web</source>
|
137
|
+
<user>
|
138
|
+
<id>saronpasu</id>
|
139
|
+
<name>saronpasu</name>
|
140
|
+
<screen_name>saronpasu</screen_name>
|
141
|
+
<url>http://h.hatena.ne.jp/saronpasu/</url>
|
142
|
+
<profile_image_url>http://www.hatena.ne.jp/sa/saronpasu/profile.gif</profile_image_url>
|
143
|
+
<followers_count>0</followers_count>
|
144
|
+
</user>
|
145
|
+
</status>'
|
146
|
+
).root
|
147
|
+
@users = REXML::Document.new(
|
148
|
+
'<users>
|
149
|
+
<user>
|
150
|
+
<id>saronpasu</id>
|
151
|
+
<name>saronpasu</name>
|
152
|
+
<screen_name>saronpasu</screen_name>
|
153
|
+
<url>http://h.hatena.ne.jp/saronpasu/</url>
|
154
|
+
<followers_count>0</followers_count>
|
155
|
+
<profile_image_url>http://www.hatena.ne.jp/sa/saronpasu/profile.gif</profile_image_url>
|
156
|
+
</user>
|
157
|
+
</users>'
|
158
|
+
)
|
159
|
+
@user = REXML::Document.new(
|
160
|
+
'<user>
|
161
|
+
<id>saronpasu</id>
|
162
|
+
<name>saronpasu</name>
|
163
|
+
<screen_name>saronpasu</screen_name>
|
164
|
+
<url>http://h.hatena.ne.jp/saronpasu/</url>
|
165
|
+
<followers_count>0</followers_count>
|
166
|
+
<profile_image_url>http://www.hatena.ne.jp/sa/saronpasu/profile.gif</profile_image_url>
|
167
|
+
</user>'
|
168
|
+
).root
|
169
|
+
@keywords = REXML::Document.new(
|
170
|
+
'<keywords>
|
171
|
+
<keyword>
|
172
|
+
<title>ほげほげ</title>
|
173
|
+
<link>http://h.hatena.ne.jp/keyword/hogehoge</link>
|
174
|
+
<entry_count>0</entry_count>
|
175
|
+
<followers_count>0</followers_count>
|
176
|
+
<related_words>ふがふが</related_words>
|
177
|
+
</keyword>
|
178
|
+
</keywords>'
|
179
|
+
)
|
180
|
+
@keyword = REXML::Document.new(
|
181
|
+
'<keyword>
|
182
|
+
<title>ほげほげ</title>
|
183
|
+
<link>http://h.hatena.ne.jp/keyword/hogehoge</link>
|
184
|
+
<entry_count>0</entry_count>
|
185
|
+
<followers_count>0</followers_count>
|
186
|
+
<related_words>ふがふが</related_words>
|
187
|
+
</keyword>'
|
188
|
+
).root
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'parse_timeline and return Hash in Array Data' do
|
192
|
+
@accessor.parse_timeline(@timeline).should be_a_kind_of(Array)
|
193
|
+
@accessor.parse_timeline(@timeline).first.should be_a_kind_of(Hash)
|
194
|
+
end
|
195
|
+
|
196
|
+
describe 'parse_timeline result' do
|
197
|
+
before do
|
198
|
+
@result = @accessor.parse_timeline(@timeline)
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'have status id' do
|
202
|
+
@result.first.should have_key(:id)
|
203
|
+
end
|
204
|
+
it 'have status text' do
|
205
|
+
@result.first.should have_key(:text)
|
206
|
+
end
|
207
|
+
it 'have status source' do
|
208
|
+
@result.first.should have_key(:source)
|
209
|
+
end
|
210
|
+
it 'have status favorited' do
|
211
|
+
@result.first.should have_key(:favorited)
|
212
|
+
end
|
213
|
+
it 'have status link' do
|
214
|
+
@result.first.should have_key(:link)
|
215
|
+
end
|
216
|
+
it 'have user' do
|
217
|
+
@result.first.should have_key(:user)
|
218
|
+
end
|
219
|
+
it 'have replies' do
|
220
|
+
@result.first.should have_key(:replies)
|
221
|
+
end
|
222
|
+
it 'have in_reply_to' do
|
223
|
+
@result.first.should have_key(:in_reply_to)
|
224
|
+
end
|
225
|
+
|
226
|
+
after do
|
227
|
+
@result = nil
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'parse_status and return Hash Data' do
|
232
|
+
@accessor.parse_status(@status).should be_a_kind_of(Hash)
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'parse_users and return Hash in Array Data' do
|
236
|
+
@accessor.parse_users(@users).should be_a_kind_of(Array)
|
237
|
+
@accessor.parse_users(@users).first.should be_a_kind_of(Hash)
|
238
|
+
end
|
239
|
+
|
240
|
+
describe 'parse_users result' do
|
241
|
+
before do
|
242
|
+
@result = @accessor.parse_users(@users)
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'have user id' do
|
246
|
+
@result.first.should have_key(:id)
|
247
|
+
end
|
248
|
+
it 'have user name' do
|
249
|
+
@result.first.should have_key(:name)
|
250
|
+
end
|
251
|
+
it 'have user screen_name' do
|
252
|
+
@result.first.should have_key(:screen_name)
|
253
|
+
end
|
254
|
+
it 'have user url' do
|
255
|
+
@result.first.should have_key(:url)
|
256
|
+
end
|
257
|
+
it 'have user followers_count' do
|
258
|
+
@result.first.should have_key(:followers_count)
|
259
|
+
end
|
260
|
+
it 'have user profile_image_url' do
|
261
|
+
@result.first.should have_key(:profile_image_url)
|
262
|
+
end
|
263
|
+
|
264
|
+
after do
|
265
|
+
@result = nil
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
it 'parse_user and return Hash Data' do
|
270
|
+
@accessor.parse_user(@user).should be_a_kind_of(Hash)
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'parse_keywords and return Hash in Array Data' do
|
274
|
+
@accessor.parse_keywords(@keywords).should be_a_kind_of(Array)
|
275
|
+
@accessor.parse_keywords(@keywords).first.should be_a_kind_of(Hash)
|
276
|
+
end
|
277
|
+
|
278
|
+
describe 'parse_keywords result' do
|
279
|
+
before do
|
280
|
+
@result = @accessor.parse_keywords(@keywords)
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'have keyword title' do
|
284
|
+
@result.first.should have_key(:title)
|
285
|
+
end
|
286
|
+
it 'have keyword link' do
|
287
|
+
@result.first.should have_key(:link)
|
288
|
+
end
|
289
|
+
it 'have keyword entry_count' do
|
290
|
+
@result.first.should have_key(:entry_count)
|
291
|
+
end
|
292
|
+
it 'have keyword followers_count' do
|
293
|
+
@result.first.should have_key(:followers_count)
|
294
|
+
end
|
295
|
+
it 'have keyword related_keywords' do
|
296
|
+
@result.first.should have_key(:related_keywords)
|
297
|
+
end
|
298
|
+
|
299
|
+
after do
|
300
|
+
@result = nil
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
it 'parse_keyword and return Hash Data' do
|
305
|
+
@accessor.parse_keyword(@keyword).should be_a_kind_of(Hash)
|
306
|
+
end
|
307
|
+
|
308
|
+
after do
|
309
|
+
@accessor = nil
|
310
|
+
@timeline = nil
|
311
|
+
@status = nil
|
312
|
+
@users = nil
|
313
|
+
@user = nil
|
314
|
+
@keywords = nil
|
315
|
+
@keyword = nil
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
desc 'Release the website and new gem version'
|
2
|
+
task :deploy => [:check_version, :website, :release] do
|
3
|
+
puts "Remember to create SVN tag:"
|
4
|
+
puts "svn copy svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/trunk " +
|
5
|
+
"svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/tags/REL-#{VERS} "
|
6
|
+
puts "Suggested comment:"
|
7
|
+
puts "Tagging release #{CHANGES}"
|
8
|
+
end
|
9
|
+
|
10
|
+
desc 'Runs tasks website_generate and install_gem as a local deployment of the gem'
|
11
|
+
task :local_deploy => [:website_generate, :install_gem]
|
12
|
+
|
13
|
+
task :check_version do
|
14
|
+
unless ENV['VERSION']
|
15
|
+
puts 'Must pass a VERSION=x.y.z release version'
|
16
|
+
exit
|
17
|
+
end
|
18
|
+
unless ENV['VERSION'] == VERS
|
19
|
+
puts "Please update your version.rb to match the release version, currently #{VERS}"
|
20
|
+
exit
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'Install the package as a gem, without generating documentation(ri/rdoc)'
|
25
|
+
task :install_gem_no_doc => [:clean, :package] do
|
26
|
+
sh "#{'sudo ' unless Hoe::WINDOZE }gem install pkg/*.gem --no-rdoc --no-ri"
|
27
|
+
end
|
28
|
+
|
29
|
+
namespace :manifest do
|
30
|
+
desc 'Recreate Manifest.txt to include ALL files'
|
31
|
+
task :refresh do
|
32
|
+
`rake check_manifest | patch -p0 > Manifest.txt`
|
33
|
+
end
|
34
|
+
end
|
data/tasks/rspec.rake
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
begin
|
2
|
+
require 'spec'
|
3
|
+
rescue LoadError
|
4
|
+
require 'rubygems'
|
5
|
+
require 'spec'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'spec/rake/spectask'
|
9
|
+
rescue LoadError
|
10
|
+
puts <<-EOS
|
11
|
+
To use rspec for testing you must install rspec gem:
|
12
|
+
gem install rspec
|
13
|
+
EOS
|
14
|
+
exit(0)
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Run the specs under spec/models"
|
18
|
+
Spec::Rake::SpecTask.new do |t|
|
19
|
+
t.spec_opts = ['--options', "spec/spec.opts"]
|
20
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
21
|
+
end
|
data/tasks/website.rake
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
desc 'Generate website files'
|
2
|
+
task :website_generate => :ruby_env do
|
3
|
+
(Dir['website/**/*.txt'] - Dir['website/version*.txt']).each do |txt|
|
4
|
+
sh %{ #{RUBY_APP} script/txt2html #{txt} > #{txt.gsub(/txt$/,'html')} }
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
desc 'Upload website files to rubyforge'
|
9
|
+
task :website_upload do
|
10
|
+
host = "#{rubyforge_username}@rubyforge.org"
|
11
|
+
remote_dir = "/var/www/gforge-projects/#{PATH}/"
|
12
|
+
local_dir = 'website'
|
13
|
+
sh %{rsync -aCv #{local_dir}/ #{host}:#{remote_dir}}
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Generate and upload website files'
|
17
|
+
task :website => [:website_generate, :website_upload, :publish_docs]
|
data/website/index.html
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
4
|
+
<head>
|
5
|
+
<link rel="stylesheet" href="stylesheets/screen.css" type="text/css" media="screen" />
|
6
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
7
|
+
<title>
|
8
|
+
rhaiker
|
9
|
+
</title>
|
10
|
+
<script src="javascripts/rounded_corners_lite.inc.js" type="text/javascript"></script>
|
11
|
+
<style>
|
12
|
+
|
13
|
+
</style>
|
14
|
+
<script type="text/javascript">
|
15
|
+
window.onload = function() {
|
16
|
+
settings = {
|
17
|
+
tl: { radius: 10 },
|
18
|
+
tr: { radius: 10 },
|
19
|
+
bl: { radius: 10 },
|
20
|
+
br: { radius: 10 },
|
21
|
+
antiAlias: true,
|
22
|
+
autoPad: true,
|
23
|
+
validTags: ["div"]
|
24
|
+
}
|
25
|
+
var versionBox = new curvyCorners(settings, document.getElementById("version"));
|
26
|
+
versionBox.applyCornersToAll();
|
27
|
+
}
|
28
|
+
</script>
|
29
|
+
</head>
|
30
|
+
<body>
|
31
|
+
<div id="main">
|
32
|
+
|
33
|
+
<h1>rhaiker</h1>
|
34
|
+
<div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/rhaiker"; return false'>
|
35
|
+
<p>Get Version</p>
|
36
|
+
<a href="http://rubyforge.org/projects/rhaiker" class="numbers">0.0.1</a>
|
37
|
+
</div>
|
38
|
+
<h2>What</h2>
|
39
|
+
<p>Rhaiker is Hatena::Haiku::<span class="caps">API</span> ruby binding.<br />
|
40
|
+
Hatena::Haiku is Japanese micro-blog service.</p>
|
41
|
+
<p>Hatena::Haiku<br />
|
42
|
+
http://h.hatena.ne.jp/</p>
|
43
|
+
<p>Hatena::Haiku::<span class="caps">API</span><br />
|
44
|
+
http://h.hatena.ne.jp/api</p>
|
45
|
+
<h2>Installing</h2>
|
46
|
+
<p><pre class='syntax'><span class="ident">sudo</span> <span class="ident">gem</span> <span class="ident">install</span> <span class="ident">rhaiker</span></pre></p>
|
47
|
+
<h2>The basics</h2>
|
48
|
+
<h2>Demonstration of usage</h2>
|
49
|
+
<p>require ‘rhaiker’</p>
|
50
|
+
<p>rhaiker = Rhaiker.new<br />
|
51
|
+
rhaiker.user_id = ‘your_user_id’<br />
|
52
|
+
rhaiker.api_key = ‘your_api_key’<br />
|
53
|
+
rhaiker.status_update({:status => ’HogeHoge’}</p>
|
54
|
+
<h3>Build and test instructions</h3>
|
55
|
+
<pre>cd rhaiker
|
56
|
+
rake spec
|
57
|
+
rake install_gem</pre>
|
58
|
+
<h2>License</h2>
|
59
|
+
<p>This code is free to use under the terms of the <span class="caps">MIT</span> license.</p>
|
60
|
+
<h2>Contact</h2>
|
61
|
+
<p>Comments are welcome.<br />
|
62
|
+
Send an email to jamneco at gmail dot com.</p>
|
63
|
+
<p class="coda">
|
64
|
+
Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
|
65
|
+
</p>
|
66
|
+
</div>
|
67
|
+
|
68
|
+
<!-- insert site tracking codes here, like Google Urchin -->
|
69
|
+
|
70
|
+
</body>
|
71
|
+
</html>
|