tumblr4r 0.7.2 → 0.8.0

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/ChangeLog CHANGED
@@ -1,3 +1,8 @@
1
+ == 0.8.0 / 2011-02-20
2
+ * new: dashboard support.
3
+ * new: active_support 3.0 support.
4
+
5
+
1
6
  == 0.7.2 / 2009-10-15
2
7
  * new: photoset support added.(Thanks to http://github.com/smajda for the patch.)
3
8
 
data/Rakefile CHANGED
@@ -8,7 +8,7 @@ require 'rake/rdoctask'
8
8
  require 'rake/contrib/rubyforgepublisher'
9
9
  require 'rake/contrib/sshpublisher'
10
10
  require 'fileutils'
11
- require 'lib/tumblr4r'
11
+ require './lib/tumblr4r'
12
12
  include FileUtils
13
13
 
14
14
  NAME = "tumblr4r"
data/lib/tumblr4r.rb CHANGED
@@ -1,12 +1,25 @@
1
+ # -*- coding: utf-8 -*-
1
2
  require 'net/http'
2
3
  require 'rubygems'
3
4
  require 'rexml/document'
4
- require 'active_support'
5
+ begin
6
+ require 'active_support/core_ext'
7
+ require 'active_support/core_ext'
8
+ rescue
9
+ require 'activesupport'
10
+ end
11
+
5
12
  require 'logger'
6
13
  require 'cgi'
14
+
7
15
  module Tumblr4r
8
- VERSION = '0.7.2'
16
+ VERSION = '0.8.0'
9
17
  class TumblrError < StandardError
18
+ attr_accessor :attachment
19
+ def initialize(msg, attachment=nil)
20
+ super(msg)
21
+ @attachment = attachment
22
+ end
10
23
  end
11
24
 
12
25
  module POST_TYPE
@@ -28,9 +41,9 @@ module Tumblr4r
28
41
  attr_accessor :hostname, :email, :password, :name, :timezone, :title, :cname,
29
42
  :description, :feeds
30
43
  attr_accessor :logger
31
- # TODO: 変数名もうちょっと考える
32
- API_READ_LIMIT = 50
33
- @@default_log_level = Logger::INFO
44
+ API_READ_MAX_ALLOWED_COUNT = 50
45
+ SLEEP_SECONDS_FOR_EVERY_FETCH = 10.0 # API manual says "Requests are rate-limited to one every 10 seconds."
46
+ @@default_log_level = Logger::DEBUG
34
47
  cattr_accessor :default_log_level
35
48
 
36
49
  class << self
@@ -59,71 +72,127 @@ module Tumblr4r
59
72
  self.site_info
60
73
  end
61
74
 
62
- # TODO: ここの再帰取得ロジックはTumblrAPIとは独立してるので
63
- # TumblrAPIとは独立した形に切り出したり、TumblrAPIとは切り離してテストを書きたいものだ
64
75
  # @param [Symbol|Integer] id_or_type :all, id
76
+ # @param [Hash] options :offset, :limit, :type, :filter, :tagged, :search,
65
77
  # @return [Array<Post>|Post]
66
78
  def find(id_or_type, options = { })
79
+ if id_or_type == :all
80
+ normal_find(options)
81
+ elsif id_or_type.kind_of?(Integer)
82
+ xml = @conn.get({:id => id_or_type})
83
+ posts, start, total = @parser.posts(xml)
84
+ @logger.info("size: #{posts.size}")
85
+ @logger.info("start: #{start}")
86
+ @logger.info("total: #{total}")
87
+ return posts[0]
88
+ else
89
+ raise ArgumentError.new("id_or_type must be :all or Integer, but was #{id_or_type}(<#{id_or_type.class}>)")
90
+ end
91
+ end
92
+
93
+ # TODO: ループごとに実行して欲しい処理をblockで渡せるようにするといいかも?
94
+ # そのブロック引数にエラー情報も渡してあげれば、エラーが起きたのならretryだな、みたいな
95
+ # 指示ができない、、、、かな
96
+ def normal_find(options)
97
+ limit = options[:limit] && options[:limit].to_i
98
+ offset = options[:offset].to_i
99
+ total = self.count(options)
100
+ result = []
67
101
  params = { }
68
- return result if options[:offset] && options[:offset].to_i < 0
69
102
  [:type, :filter, :tagged, :search].each do |option|
70
103
  params[option] = options[option] if options[option]
71
104
  end
72
-
73
- if id_or_type == :all
74
- result = []
75
- # 取得開始位置の初期化
76
- params[:start] = options[:offset] || 0
77
- # goal の設定
78
- total = self.count(options)
79
- if options[:limit]
80
- goal = [total - params[:start],
81
- options[:limit]].min
82
- else
83
- goal = total - params[:start]
105
+ last_fetched_at = nil
106
+ each_fetch(limit, offset, API_READ_MAX_ALLOWED_COUNT, total) do |offset, num|
107
+ params[:start] = offset
108
+ params[:num] = num
109
+ # APIマニュアルにはこっちのスリープ時間については明記されてないが、dashboardと同じ秒数SLEEPしとく
110
+ sleep_secs = last_fetched_at ? SLEEP_SECONDS_FOR_EVERY_FETCH - (Time.now - last_fetched_at) : 0
111
+ if sleep_secs > 0
112
+ logger.debug("sleeping #{sleep_secs} secs.")
113
+ sleep sleep_secs
84
114
  end
85
- # 取得件数の初期化
86
- if goal < 0
87
- return result
88
- elsif goal < API_READ_LIMIT
89
- params[:num] = goal
90
- else
91
- params[:num] = API_READ_LIMIT # :num を指定しないとデフォルトでは20件しかとれない
115
+ xml = @conn.get(params)
116
+ last_fetched_at = Time.now
117
+ posts, start, total = @parser.posts(xml)
118
+ result += posts
119
+ if posts.size == 0
120
+ # Tumblr API の total で得られる値は全く信用ならない。
121
+ # 検索条件を考慮した件数を返してくれない。
122
+ # (つまり、goalは信用ならない)ので、posts.sizeも終了判定に利用する。
123
+ # TODO: もしくは:numの値を足し合わせていって、それとgoalを比較する?
124
+ break
92
125
  end
126
+ posts.size
127
+ end
128
+ result
129
+ end
93
130
 
94
- loop do
95
- xml = @conn.get(params)
96
- posts, start, total = @parser.posts(xml)
97
- @logger.info("size: #{posts.size}")
98
- @logger.info("start: #{start}")
99
- @logger.info("total: #{total}")
100
- result += posts
101
- if result.size >= goal || posts.size == 0
102
- # Tumblr API の total で得られる値は全く信用ならない。
103
- # 検索条件を考慮した件数を返してくれない。
104
- # (つまり、goalは信用ならない)ので、posts.sizeも終了判定に利用する。
105
- # TODO: もしくは:numの値を足し合わせていって、それとgoalを比較する?
106
- break
107
- end
108
- # 取得開始位置の調整
109
- params[:start] += params[:num]
110
- # 取得件数の調整
111
- if (goal - result.size) >= API_READ_LIMIT
112
- params[:num] = API_READ_LIMIT
113
- else
114
- params[:num] = goal - result.size
115
- end
131
+ #, :search,
132
+ # @param [Hash] options :offset, :limit, :type, :filter
133
+ # @return [Array<Post>]
134
+ def dashboard(options = { })
135
+ limit = options[:limit] ? options[:limit].to_i : nil
136
+ offset = options[:offset].to_i
137
+ result = []
138
+ params = {:likes => "1" }
139
+ [:type, :filter].each do |option|
140
+ params[option] = options[option] if options[option]
141
+ end
142
+
143
+ total = 1000 # 明記されてないがたぶん1000件ぐらいが上限?
144
+ last_fetched_at = nil
145
+ each_fetch(limit, offset, API_READ_MAX_ALLOWED_COUNT, total) do |offset, num|
146
+ params[:start] = offset
147
+ params[:num] = num
148
+ sleep_secs = last_fetched_at ? SLEEP_SECONDS_FOR_EVERY_FETCH - (Time.now - last_fetched_at) : 0
149
+ if sleep_secs > 0
150
+ logger.debug("sleeping #{sleep_secs} secs.")
151
+ sleep sleep_secs
116
152
  end
117
- return result
118
- elsif id_or_type.kind_of?(Integer)
119
- xml = @conn.get({:id => id_or_type})
153
+ xml = @conn.dashboard(params)
154
+ last_fetched_at = Time.now
120
155
  posts, start, total = @parser.posts(xml)
121
- @logger.info("size: #{posts.size}")
156
+ result += posts
157
+ if posts.size == 0
158
+ # Tumblr API の total で得られる値は全く信用ならない。
159
+ # 検索条件を考慮した件数を返してくれない。
160
+ # (つまり、goalは信用ならない)ので、posts.sizeも終了判定に利用する。
161
+ # TODO: もしくは:numの値を足し合わせていって、それとgoalを比較する?
162
+ break
163
+ end
164
+ posts.size
165
+ end
166
+ result
167
+ end
168
+
169
+ def each_fetch(limit, offset, max_at_once, total, &block)
170
+ return if offset && offset.to_i < 0
171
+
172
+ # 取得開始位置の初期化
173
+ start = offset || 0
174
+ if limit
175
+ goal = [total - start, limit].min
176
+ else
177
+ goal = total - start
178
+ end
179
+ # 取得件数の初期化
180
+ num = [goal, max_at_once].min
181
+ if num < 0
182
+ return
183
+ end
184
+
185
+ all_fetched = 0
186
+ while all_fetched < goal
187
+ fetched_count = yield(start, num)
188
+ @logger.info("size: #{fetched_count}")
122
189
  @logger.info("start: #{start}")
123
190
  @logger.info("total: #{total}")
124
- return posts[0]
125
- else
126
- raise ArgumentError
191
+ all_fetched += fetched_count
192
+ # 取得開始位置の調整
193
+ start += num
194
+ # 取得件数の調整
195
+ num = [goal - fetched_count, max_at_once].min
127
196
  end
128
197
  end
129
198
 
@@ -150,8 +219,17 @@ module Tumblr4r
150
219
  return new_post
151
220
  end
152
221
 
153
- # @param [Integer] post_id
154
- def delete(post_id)
222
+ # @param [Integer|Post] post_id_or_post
223
+ def delete(post_id_or_post)
224
+ post_id = nil
225
+ case post_id_or_post
226
+ when Tumblr4r::Post
227
+ post_id = post_id_or_post.post_id
228
+ when Integer
229
+ post_id = post_id_or_post
230
+ else
231
+ raise ArgumentError.new("post_id_or_post must be Tumblr4r::Post or Integer, but was #{post_id_or_post}(<#{post_id_or_post.class}>)")
232
+ end
155
233
  return @conn.delete(post_id)
156
234
  end
157
235
 
@@ -173,6 +251,9 @@ module Tumblr4r
173
251
  :private, # Integer(0|1)
174
252
  :generator # String
175
253
 
254
+ attr_accessor :liked, # Boolean
255
+ :reblog_key # String
256
+
176
257
  @@default_generator = nil
177
258
  cattr_accessor :default_generator
178
259
 
@@ -293,7 +374,7 @@ module Tumblr4r
293
374
  when Net::HTTP
294
375
  @conn = http_or_hostname
295
376
  else
296
- raise ArgumentError.new("http_or_hostname must be String or Net::HTTP")
377
+ raise ArgumentError.new("http_or_hostname must be String or Net::HTTP but is #{http_or_hostname.class}")
297
378
  end
298
379
  @email= email
299
380
  @password = password
@@ -321,9 +402,25 @@ module Tumblr4r
321
402
  when Net::HTTPOK
322
403
  return res.body
323
404
  when Net::HTTPNotFound
324
- raise TumblrError.new("no such site(#{@hostname})")
405
+ raise TumblrError.new("no such site(#{@hostname})", res)
325
406
  else
326
- raise TumblrError.new("unexpected response #{res.inspect}")
407
+ raise TumblrError.new("unexpected response #{res.inspect}", res)
408
+ end
409
+ end
410
+
411
+ def dashboard(options = { })
412
+ response = nil
413
+ http = Net::HTTP.new("www.tumblr.com")
414
+ params = options.merge({"email" => @email, "password" => @password, "group" => @group})
415
+ query_string = params.delete_if{|k,v| v == nil }.map{|k,v| "#{k}=#{CGI.escape(v.to_s)}" unless v.nil?}.join("&")
416
+ logger.debug("#### query_string: #{query_string}")
417
+ response = http.post('/api/dashboard', query_string)
418
+ logger.debug(response.body)
419
+ case response
420
+ when Net::HTTPSuccess
421
+ return response.body
422
+ else
423
+ raise TumblrError.new(format_error(response), response)
327
424
  end
328
425
  end
329
426
 
@@ -339,7 +436,7 @@ module Tumblr4r
339
436
  when Net::HTTPOK
340
437
  return true
341
438
  else
342
- raise TumblrError.new(response.inspect + "\n" + response.body)
439
+ raise TumblrError.new(format_error(response), response)
343
440
  end
344
441
  end
345
442
 
@@ -358,10 +455,7 @@ module Tumblr4r
358
455
  when Net::HTTPSuccess
359
456
  return response.body.to_i
360
457
  else
361
- msg = response.inspect + "\n"
362
- response.each{|k,v| msg += "#{k}: #{v}\n"}
363
- msg += response.body
364
- raise TumblrError.new(msg)
458
+ raise TumblrError.new(format_error(response), response)
365
459
  end
366
460
  end
367
461
 
@@ -379,12 +473,16 @@ module Tumblr4r
379
473
  logger.debug("#### response: #{response.code}: #{response.body}")
380
474
  return true
381
475
  else
382
- msg = response.inspect + "\n"
383
- response.each{|k,v| msg += "#{k}: #{v}\n"}
384
- msg += response.body
385
- raise TumblrError.new(msg)
476
+ raise TumblrError.new(format_error(response), response)
386
477
  end
387
478
  end
479
+
480
+ def format_error(response)
481
+ msg = response.inspect + "\n"
482
+ response.each{|k,v| msg += "#{k}: #{v}\n"}
483
+ msg += response.body
484
+ msg
485
+ end
388
486
  end
389
487
 
390
488
  # Tumblr XML API
@@ -446,6 +544,8 @@ module Tumblr4r
446
544
  post.post_id = rexml_post.attributes["id"].to_i
447
545
  post.url = rexml_post.attributes["url"]
448
546
  post.url_with_slug = rexml_post.attributes["url-with-slug"]
547
+ post.liked = (rexml_post.attributes["liked"] == "true")
548
+ post.reblog_key = rexml_post.attributes["reblog-key"]
449
549
  post.type = rexml_post.attributes["type"]
450
550
  # TODO: time 関係の型をStringじゃなくTimeとかにする?
451
551
  post.date_gmt = rexml_post.attributes["date-gmt"]
@@ -0,0 +1,46 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+ require "test/unit"
3
+ require 'pit'
4
+ require 'pp'
5
+ $KCODE='u'
6
+ class Tumblr4rDashboardTest < Test::Unit::TestCase
7
+ include Tumblr4r
8
+ DASHBOARD_TEST_HOST = "tumblr4r-dashboard-test.tumblr.com"
9
+ TOTAL_COUNT = 123
10
+ REGULAR_COUNT = 6
11
+ QUOTE_COUNT = 103
12
+ PHOTO_COUNT = 2
13
+
14
+ def setup
15
+ Site.default_log_level = Logger::DEBUG
16
+ auth_info = Pit.get("tumblr4r-dashbard-test",
17
+ :require => {"email" => "required email",
18
+ "password" => "required password"})
19
+ @site = Site.new(DASHBOARD_TEST_HOST,
20
+ auth_info["email"],
21
+ auth_info["password"])
22
+ end
23
+
24
+ def teardown
25
+ end
26
+ =begin
27
+ def test_find_all
28
+ posts = @site.dashboard
29
+ pp posts
30
+ assert_equal TOTAL_COUNT, posts.size
31
+ end
32
+ =end
33
+ def test_type
34
+ posts = @site.dashboard(:type => "regular")
35
+ assert_equal REGULAR_COUNT, posts.size
36
+ assert posts.all?{|p| p.type == Tumblr4r::POST_TYPE::REGULAR }
37
+
38
+ posts = @site.dashboard(:type => "quote")
39
+ assert_equal QUOTE_COUNT, posts.size
40
+ assert posts.all?{|p| p.type == Tumblr4r::POST_TYPE::QUOTE }
41
+
42
+ posts = @site.dashboard(:type => "photo")
43
+ assert_equal PHOTO_COUNT, posts.size
44
+ assert posts.all?{|p| p.type == Tumblr4r::POST_TYPE::PHOTO }
45
+ end
46
+ end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  require File.dirname(__FILE__) + '/test_helper.rb'
2
3
  require "test/unit"
3
4
  require 'pit'
@@ -53,6 +54,7 @@ class Tumblr4rTest < Test::Unit::TestCase
53
54
  end
54
55
 
55
56
  def test_find
57
+ debugger
56
58
  posts = @site.find(:all)
57
59
  assert_equal 9, posts.size
58
60
  assert_equal Photo, posts[0].class
@@ -144,7 +146,7 @@ EOF
144
146
  assert_equal false, posts[1].bookmarklet
145
147
 
146
148
  assert_equal "", posts[1].regular_title
147
- assert_equal "Tumblr4rのテストです", posts[1].regular_body
149
+ assert_equal "<p>Tumblr4rのテストです</p>", posts[1].regular_body
148
150
  end
149
151
 
150
152
  def test_find_with_type_photo
@@ -166,7 +168,7 @@ EOF
166
168
 
167
169
  assert_equal "<p>Photoのテストです。</p>\n\n<p>ギコです。</p>", posts[1].photo_caption
168
170
  assert_equal "http://www.google.co.jp/", posts[1].photo_link_url
169
- assert_equal "http://5.media.tumblr.com/GyEYZujUYopiula4XKmXhCgmo1_250.jpg", posts[1].photo_url
171
+ assert_equal "http://28.media.tumblr.com/GyEYZujUYopiula4XKmXhCgmo1_250.jpg", posts[1].photo_url
170
172
  assert_equal [], posts[1].photoset
171
173
 
172
174
  # photoset
@@ -182,12 +184,12 @@ EOF
182
184
  assert_equal [], posts[0].tags
183
185
  assert_equal false, posts[0].bookmarklet
184
186
 
185
- assert_equal "Photoset test.", posts[0].photo_caption
187
+ assert_equal "<p>Photoset test.</p>", posts[0].photo_caption
186
188
  assert_equal "", posts[0].photo_link_url
187
- assert_equal "http://22.media.tumblr.com/tumblr_krg7btBOD21qzfaavo1_250.jpg", posts[0].photo_url
188
- assert_equal ["http://22.media.tumblr.com/tumblr_krg7btBOD21qzfaavo1_250.jpg",
189
- "http://6.media.tumblr.com/tumblr_krg7btBOD21qzfaavo2_500.jpg",
190
- "http://16.media.tumblr.com/tumblr_krg7btBOD21qzfaavo3_500.png"], posts[0].photoset
189
+ assert_equal "http://25.media.tumblr.com/tumblr_krg7btBOD21qzfaavo1_250.jpg", posts[0].photo_url
190
+ assert_equal ["http://25.media.tumblr.com/tumblr_krg7btBOD21qzfaavo1_250.jpg",
191
+ "http://30.media.tumblr.com/tumblr_krg7btBOD21qzfaavo2_500.jpg",
192
+ "http://27.media.tumblr.com/tumblr_krg7btBOD21qzfaavo3_500.png"], posts[0].photoset
191
193
 
192
194
  end
193
195
 
@@ -229,7 +231,7 @@ EOF
229
231
 
230
232
  assert_equal "たんぶらー", posts[0].link_text
231
233
  assert_equal "http://www.tumblr.com/", posts[0].link_url
232
- assert_equal "ですくりぷしょん", posts[0].link_description
234
+ assert_equal "<p>ですくりぷしょん</p>", posts[0].link_description
233
235
  end
234
236
 
235
237
  def test_find_with_type_conversation
@@ -274,8 +276,9 @@ EOF
274
276
  assert_equal false, posts[0].bookmarklet
275
277
 
276
278
  assert_equal true, posts[0].audio_plays
277
- assert_equal "tumblr4r miku", posts[0].audio_caption
278
- assert_equal "<embed type=\"application/x-shockwave-flash\" src=\"http://tumblr4rtest.tumblr.com/swf/audio_player.swf?audio_file=http://www.tumblr.com/audio_file/131705561/GyEYZujUYp9df3nv1WMefTH8&color=FFFFFF\" height=\"27\" width=\"207\" quality=\"best\"></embed>", posts[0].audio_player
279
+ assert_equal "<p>tumblr4r miku</p>", posts[0].audio_caption
280
+ # assert_equal "<embed type=\"application/x-shockwave-flash\" src=\"http://tumblr4rtest.tumblr.com/swf/audio_player.swf?audio_file=http://www.tumblr.com/audio_file/131705561/GyEYZujUYp9df3nv1WMefTH8&color=FFFFFF\" height=\"27\" width=\"207\" quality=\"best\"></embed>", posts[0].audio_player
281
+ assert_equal "<embed type=\"application/x-shockwave-flash\" src=\"http://assets.tumblr.com/swf/audio_player.swf?audio_file=http://www.tumblr.com/audio_file/131705561/GyEYZujUYp9df3nv1WMefTH8&color=FFFFFF\" height=\"27\" width=\"207\" quality=\"best\"></embed>", posts[0].audio_player
279
282
  end
280
283
 
281
284
  def test_find_with_type_video
@@ -293,9 +296,9 @@ EOF
293
296
  assert_equal [], posts[0].tags
294
297
  assert_equal false, posts[0].bookmarklet
295
298
 
296
- assert_equal "matrix sappoloaded", posts[0].video_caption
299
+ assert_equal "<p>matrix sappoloaded</p>", posts[0].video_caption
297
300
  assert_equal "http://www.youtube.com/watch?v=FavWH5RhYpw", posts[0].video_source
298
- assert_equal "<object width=\"400\" height=\"336\"><param name=\"movie\" value=\"http://www.youtube.com/v/FavWH5RhYpw&amp;rel=0&amp;egm=0&amp;showinfo=0&amp;fs=1\"></param><param name=\"wmode\" value=\"transparent\"></param><param name=\"allowFullScreen\" value=\"true\"></param><embed src=\"http://www.youtube.com/v/FavWH5RhYpw&amp;rel=0&amp;egm=0&amp;showinfo=0&amp;fs=1\" type=\"application/x-shockwave-flash\" width=\"400\" height=\"336\" allowFullScreen=\"true\" wmode=\"transparent\"></embed></object>", posts[0].video_player
301
+ assert_equal "<object width=\"400\" height=\"325\"><param name=\"movie\" value=\"http://www.youtube.com/v/FavWH5RhYpw&amp;rel=0&amp;egm=0&amp;showinfo=0&amp;fs=1\"></param><param name=\"wmode\" value=\"transparent\"></param><param name=\"allowFullScreen\" value=\"true\"></param><embed src=\"http://www.youtube.com/v/FavWH5RhYpw&amp;rel=0&amp;egm=0&amp;showinfo=0&amp;fs=1\" type=\"application/x-shockwave-flash\" width=\"400\" height=\"325\" allowFullScreen=\"true\" wmode=\"transparent\"></embed></object>", posts[0].video_player
299
302
  end
300
303
 
301
304
  def test_find_with_tagged
@@ -402,6 +405,5 @@ EOF
402
405
  videos = @site.find(:all, :type => Tumblr4r::POST_TYPE::VIDEO)
403
406
  post = @write_site.save(videos[0])
404
407
  end
405
-
406
408
  end
407
409
 
metadata CHANGED
@@ -1,7 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tumblr4r
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.2
4
+ prerelease:
5
+ version: 0.8.0
5
6
  platform: ruby
6
7
  authors:
7
8
  - Tomoki MAEDA
@@ -9,29 +10,30 @@ autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
12
 
12
- date: 2009-10-15 00:00:00 +09:00
13
- default_executable:
13
+ date: 2012-01-26 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
23
  version: 2.3.2
24
- version:
24
+ type: :runtime
25
+ version_requirements: *id001
25
26
  - !ruby/object:Gem::Dependency
26
27
  name: pit
27
- type: :development
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
30
31
  requirements:
31
32
  - - ">="
32
33
  - !ruby/object:Gem::Version
33
34
  version: 0.0.6
34
- version:
35
+ type: :development
36
+ version_requirements: *id002
35
37
  description: Tumblr API Wrapper for Ruby
36
38
  email: tmaeda@ruby-sapporo.org
37
39
  executables: []
@@ -46,10 +48,12 @@ files:
46
48
  - ChangeLog
47
49
  - Rakefile
48
50
  - test/test_helper.rb
51
+ - test/tumblr4r_dashboard_test.rb
49
52
  - test/tumblr4r_test.rb
50
53
  - lib/tumblr4r.rb
51
- has_rdoc: true
52
54
  homepage: http://tumblr4r.rubyforge.org
55
+ licenses: []
56
+
53
57
  post_install_message:
54
58
  rdoc_options:
55
59
  - --title
@@ -67,23 +71,24 @@ rdoc_options:
67
71
  require_paths:
68
72
  - lib
69
73
  required_ruby_version: !ruby/object:Gem::Requirement
74
+ none: false
70
75
  requirements:
71
76
  - - ">="
72
77
  - !ruby/object:Gem::Version
73
78
  version: 1.8.6
74
- version:
75
79
  required_rubygems_version: !ruby/object:Gem::Requirement
80
+ none: false
76
81
  requirements:
77
82
  - - ">="
78
83
  - !ruby/object:Gem::Version
79
84
  version: "0"
80
- version:
81
85
  requirements: []
82
86
 
83
87
  rubyforge_project: tumblr4r
84
- rubygems_version: 1.3.1
88
+ rubygems_version: 1.8.11
85
89
  signing_key:
86
- specification_version: 2
90
+ specification_version: 3
87
91
  summary: Tumblr API Wrapper for Ruby
88
92
  test_files:
93
+ - test/tumblr4r_dashboard_test.rb
89
94
  - test/tumblr4r_test.rb