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 +5 -0
- data/Rakefile +1 -1
- data/lib/tumblr4r.rb +170 -70
- data/test/tumblr4r_dashboard_test.rb +46 -0
- data/test/tumblr4r_test.rb +15 -13
- metadata +21 -16
data/ChangeLog
CHANGED
data/Rakefile
CHANGED
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
|
-
|
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.
|
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
|
-
|
32
|
-
|
33
|
-
@@default_log_level = Logger::
|
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
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
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
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
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
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
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
|
-
|
118
|
-
|
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
|
-
|
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
|
-
|
125
|
-
|
126
|
-
|
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]
|
154
|
-
def delete(
|
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
|
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
|
-
|
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
|
-
|
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
|
data/test/tumblr4r_test.rb
CHANGED
@@ -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
|
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://
|
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
|
187
|
+
assert_equal "<p>Photoset test.</p>", posts[0].photo_caption
|
186
188
|
assert_equal "", posts[0].photo_link_url
|
187
|
-
assert_equal "http://
|
188
|
-
assert_equal ["http://
|
189
|
-
"http://
|
190
|
-
"http://
|
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 "
|
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=\"
|
301
|
+
assert_equal "<object width=\"400\" height=\"325\"><param name=\"movie\" value=\"http://www.youtube.com/v/FavWH5RhYpw&rel=0&egm=0&showinfo=0&fs=1\"></param><param name=\"wmode\" value=\"transparent\"></param><param name=\"allowFullScreen\" value=\"true\"></param><embed src=\"http://www.youtube.com/v/FavWH5RhYpw&rel=0&egm=0&showinfo=0&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
|
-
|
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:
|
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
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
24
|
+
type: :runtime
|
25
|
+
version_requirements: *id001
|
25
26
|
- !ruby/object:Gem::Dependency
|
26
27
|
name: pit
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
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.
|
88
|
+
rubygems_version: 1.8.11
|
85
89
|
signing_key:
|
86
|
-
specification_version:
|
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
|