curate_tumblr 1.0.4 → 1.0.5
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/README.md +12 -8
- data/curate_tumblr.gemspec +1 -1
- data/lib/curate_tumblr/curator.rb +28 -9
- data/lib/curate_tumblr/publish/reblog.rb +2 -0
- data/lib/curate_tumblr/render/render_links.rb +1 -1
- data/lib/curate_tumblr/tumblr/client.rb +14 -2
- data/lib/curate_tumblr/utilities/monkey.rb +3 -1
- data/lib/curate_tumblr/utilities/utilities_client.rb +4 -0
- data/lib/curate_tumblr/values.rb +1 -0
- data/spec/curate_tumblr/publish/follow_spec.rb +4 -0
- data/spec/curate_tumblr/publish/post_spec.rb +4 -0
- data/spec/curate_tumblr/publish/reblog_spec.rb +4 -0
- data/spec/curate_tumblr/render/render_reblog_spec.rb +3 -2
- data/spec/curate_tumblr/tumblr/client_spec.rb +4 -0
- data/spec/curate_tumblr/tumblr/extract_links_spec.rb +4 -0
- data/spec/spec_helper.rb +1 -1
- metadata +2 -2
data/README.md
CHANGED
@@ -4,7 +4,10 @@ Reblog and follow in your Tumblr from a file of links.
|
|
4
4
|
|
5
5
|
Grow you Tumblr audience by automating the boring tasks !
|
6
6
|
|
7
|
-
|
7
|
+
### v1.0.5 ###
|
8
|
+
* Stop if Tumblr error "Not Authorized" (bad oauth)
|
9
|
+
* Better error messages if problem with directories or config file
|
10
|
+
|
8
11
|
|
9
12
|
### Installation
|
10
13
|
|
@@ -36,7 +39,7 @@ and **config (with oauth)** is in
|
|
36
39
|
|
37
40
|
Please note before all **you have to config oauth** for your tumblr (and put the codes in the config file, see below).
|
38
41
|
|
39
|
-
You can see an example of reblog and follow for a kubrick tumblr in the *example*
|
42
|
+
You can see an example of reblog and follow for a kubrick tumblr in the *example* directory.
|
40
43
|
|
41
44
|
|
42
45
|
## Usage
|
@@ -70,19 +73,19 @@ At the end you must have this codes :
|
|
70
73
|
|
71
74
|
### Config
|
72
75
|
|
73
|
-
Curate Tumblr uses the name of your tumblr to find the
|
76
|
+
Curate Tumblr uses the name of your tumblr to find the directory for links (to reblog and follow) and config file
|
74
77
|
|
75
|
-
#### Create
|
78
|
+
#### Create directories
|
76
79
|
|
77
|
-
Create a
|
80
|
+
Create a directory where you will have your config and links files :
|
78
81
|
|
79
82
|
ex : /home/tumblr
|
80
83
|
|
81
|
-
Create in this
|
84
|
+
Create in this directory another directory with your test tumblr name :
|
82
85
|
|
83
86
|
ex : /home/tumblr/mytumblrtest
|
84
87
|
|
85
|
-
In this
|
88
|
+
In this directory create a directory links and a directory logs
|
86
89
|
|
87
90
|
ex :
|
88
91
|
|
@@ -93,7 +96,7 @@ ex :
|
|
93
96
|
|
94
97
|
#### Create config file
|
95
98
|
|
96
|
-
Create a config file in this
|
99
|
+
Create a config file in this directory.
|
97
100
|
|
98
101
|
You can copy *kubricklove_config.yaml* from the example and rename it with your tumblr name :
|
99
102
|
|
@@ -171,6 +174,7 @@ in the config file set oauth
|
|
171
174
|
|
172
175
|
The application manage these tumblr errors :
|
173
176
|
* *Rate limit exceeded* : too much requests, try to incread the sleep time in config file **=> the application stop**
|
177
|
+
* *No authorized* : problem with oauth in the config file, tokens may be bad **=> the application stop**
|
174
178
|
* *Bad request* : perhaps the link has been deleted
|
175
179
|
* *Too much bad requests* : there is no enough place in the queue, or there is a problem with your tumblr **=> the application stop**
|
176
180
|
|
data/curate_tumblr.gemspec
CHANGED
@@ -2,7 +2,7 @@ Gem::Specification.new do |gem|
|
|
2
2
|
gem.add_dependency 'tumblr_client'
|
3
3
|
gem.add_dependency 'logger'
|
4
4
|
gem.name = 'curate_tumblr'
|
5
|
-
gem.version = '1.0.
|
5
|
+
gem.version = '1.0.5'
|
6
6
|
gem.authors = ['David Tysman']
|
7
7
|
gem.description = 'CurateTumblr - reblog and follow Tumblr links'
|
8
8
|
gem.summary = 'Reblog and follow Tumblr'
|
@@ -53,23 +53,36 @@ module CurateTumblr
|
|
53
53
|
def init_tumblr!( hash_config={} )
|
54
54
|
@is_stop = false
|
55
55
|
check_config_files
|
56
|
+
return false if !check_init_ok
|
56
57
|
hash_config = get_config_from_yaml if hash_config.empty? && !is_stop
|
57
|
-
if
|
58
|
-
puts "\nError : the application can't init. Please check the paths and the config file"
|
59
|
-
return false
|
60
|
-
end
|
58
|
+
return false if !check_init_ok
|
61
59
|
set_log
|
60
|
+
return false if !check_init_ok
|
62
61
|
init_client!( hash_config )
|
62
|
+
return false if !check_init_ok
|
63
63
|
init_infos!( hash_config )
|
64
|
+
return false if !check_init_ok
|
64
65
|
init_extract_links!( hash_config )
|
66
|
+
return false if !check_init_ok
|
65
67
|
init_follow!( hash_config )
|
68
|
+
return false if !check_init_ok
|
66
69
|
init_reblog!( hash_config )
|
70
|
+
return false if !check_init_ok
|
67
71
|
init_post!( hash_config )
|
72
|
+
return false if !check_init_ok
|
68
73
|
true
|
69
74
|
end
|
70
75
|
|
76
|
+
def check_init_ok
|
77
|
+
return return_error( __method__, "the application can't init. Please check the paths and the config file", {}, true ) if @is_stop
|
78
|
+
true
|
79
|
+
end
|
80
|
+
|
71
81
|
def config_from_yaml
|
72
82
|
hash_config = get_config_from_yaml
|
83
|
+
return false if !check_init_ok
|
84
|
+
raise "can't get config from file #{get_filename_config}" if !hash_config
|
85
|
+
raise "config is empty from file #{get_filename_config}" if hash_config.empty?
|
73
86
|
config_client( hash_config )
|
74
87
|
config_infos( hash_config )
|
75
88
|
end
|
@@ -109,7 +122,10 @@ module CurateTumblr
|
|
109
122
|
end
|
110
123
|
|
111
124
|
def get_config_from_yaml
|
112
|
-
|
125
|
+
if @is_stop
|
126
|
+
@log_tumblr.error( "don't get config because must stop" )
|
127
|
+
return false
|
128
|
+
end
|
113
129
|
file_yaml = get_filename_config
|
114
130
|
raise "config file YAML #{file_yaml} doesn't exist" if !File.exist?( file_yaml )
|
115
131
|
begin
|
@@ -147,6 +163,8 @@ module CurateTumblr
|
|
147
163
|
# --- files ---
|
148
164
|
|
149
165
|
def add_tofollow_tofile( is_delete_tofollow=true )
|
166
|
+
raise "no urls to follow" if !@all_tofollow_urls
|
167
|
+
return false if @all_tofollow_urls.empty?
|
150
168
|
@all_tofollow_urls = CurateTumblr.get_format_tumblr_urls( @all_tofollow_urls )
|
151
169
|
return false if !CurateTumblr.add_set_tofile_without_repeat( get_filename_tofollow, @all_tofollow_urls )
|
152
170
|
@all_tofollow_urls = Set.new if is_delete_tofollow
|
@@ -224,17 +242,18 @@ module CurateTumblr
|
|
224
242
|
stop_it!
|
225
243
|
end
|
226
244
|
|
227
|
-
def error( method, message, hash_infos={} )
|
245
|
+
def error( method, message, hash_infos={}, is_display=false )
|
228
246
|
error = "#{@domain} : #{message} in #{method} "
|
229
247
|
if !hash_infos.empty?
|
230
248
|
error = error + " with"
|
231
249
|
hash_infos.each { |key, value| error = error + " [#{key} : #{value}]" }
|
232
250
|
end
|
233
|
-
@log_tumblr.error( error )
|
251
|
+
@log_tumblr.error( error ) if !@log_tumblr.nil?
|
252
|
+
puts "\nError : #{message}" if is_display || @log_tumblr.nil?
|
234
253
|
end
|
235
254
|
|
236
|
-
def return_error( method, message, hash_infos={} )
|
237
|
-
error( method, message, hash_infos )
|
255
|
+
def return_error( method, message, hash_infos={}, is_display=false )
|
256
|
+
error( method, message, hash_infos, is_display )
|
238
257
|
false
|
239
258
|
end
|
240
259
|
end
|
@@ -24,11 +24,13 @@ module CurateTumblr
|
|
24
24
|
if !CurateTumblr.post_id_valid?( post_id )
|
25
25
|
return return_error( __method__, "post_id not valid", { post_id: post_id, reblog_url: reblog_url } )
|
26
26
|
end
|
27
|
+
return false if @is_stop
|
27
28
|
reblog_key = CurateTumblr::Tumblr::ExtractLinks.get_reblog_key_from_reblog_url( reblog_url )
|
28
29
|
if !CurateTumblr.reblog_key_valid?( reblog_key )
|
29
30
|
return return_error( __method__, "reblog_key not valid", { reblog_key: reblog_key, post_id: post_id, reblog_url: reblog_url } )
|
30
31
|
end
|
31
32
|
new_post_id = reblog_post_key( post_id, reblog_key )
|
33
|
+
return false if @is_stop
|
32
34
|
add_tofollow_source_from_post_id( @tumblr_name, new_post_id )
|
33
35
|
new_post_id
|
34
36
|
end
|
@@ -118,6 +118,7 @@ module CurateTumblr
|
|
118
118
|
tumblr_url = get_tumblr_domain if tumblr_url.empty?
|
119
119
|
|
120
120
|
hash_posts_multiple = client_get_posts( tumblr_url, post_id )
|
121
|
+
return false if hash_posts_multiple.has_key?( "status" ) && !check_hash_status( hash_posts_multiple)
|
121
122
|
if !CurateTumblr.hash_multiple_posts_valid?( hash_posts_multiple )
|
122
123
|
log_tumblr.error "#{__method__} hash_posts_multiple #{hash_posts_multiple} are not valid for tumblr_url=#{tumblr_url} and post_id=#{post_id}"
|
123
124
|
return false
|
@@ -228,12 +229,18 @@ module CurateTumblr
|
|
228
229
|
@count_continuous_bad_requests = 0
|
229
230
|
return status_ok
|
230
231
|
end
|
231
|
-
|
232
|
-
return rate_limit_exceeded( is_display, is_log ) if CurateTumblr.hash_status_rate_limit?( hash_status )
|
232
|
+
check_hash_status( hash_status, is_display, is_log )
|
233
233
|
log_tumblr.error( "bad status result #{hash_status}" )
|
234
234
|
false
|
235
235
|
end
|
236
236
|
|
237
|
+
def check_hash_status( hash_status, is_display=true, is_log=true )
|
238
|
+
return not_authorized( is_display, is_log ) if CurateTumblr.hash_status_not_authorized?( hash_status )
|
239
|
+
return rate_limit_exceeded( is_display, is_log ) if CurateTumblr.hash_status_rate_limit?( hash_status )
|
240
|
+
return bad_request( is_display, is_log ) if CurateTumblr.hash_status_bad_request?( hash_status )
|
241
|
+
true
|
242
|
+
end
|
243
|
+
|
237
244
|
def get_status_if_ok( hash_status )
|
238
245
|
return hash_status if !hash_status.is_a? Hash
|
239
246
|
return hash_status if !hash_status.has_key?( "status" )
|
@@ -246,6 +253,11 @@ module CurateTumblr
|
|
246
253
|
false
|
247
254
|
end
|
248
255
|
|
256
|
+
def not_authorized( is_display=true, is_log=true )
|
257
|
+
stop_and_alert( "Not authorized by Tumblr, please check oauth in the config file #{get_filename_config}", is_display, is_log )
|
258
|
+
false
|
259
|
+
end
|
260
|
+
|
249
261
|
def bad_request( is_display=true, is_log=true )
|
250
262
|
@count_continuous_bad_requests += 1
|
251
263
|
if @count_continuous_bad_requests >= COUNT_ALERT_IF_TOO_MUCH_BAD_REQUESTS
|
@@ -1,5 +1,7 @@
|
|
1
1
|
class Hash
|
2
2
|
def check_key( key )
|
3
|
-
|
3
|
+
raise "no key '#{key}' in Hash #{to_s}" if !self.has_key?( key )
|
4
|
+
raise "no key '#{key}' in Hash #{to_s}" if self[key].nil?
|
5
|
+
raise "key '#{key}' is empty in Hash #{to_s}" if self[key].empty?
|
4
6
|
end
|
5
7
|
end
|
@@ -52,6 +52,10 @@ module CurateTumblr
|
|
52
52
|
hash_status?( hash_status, CLIENT_STATUS_BAD_REQUEST )
|
53
53
|
end
|
54
54
|
|
55
|
+
def self.hash_status_not_authorized?( hash_status )
|
56
|
+
hash_status?( hash_status, CLIENT_STATUS_NOT_AUTHORIZED )
|
57
|
+
end
|
58
|
+
|
55
59
|
def self.hash_status?( hash_status, status )
|
56
60
|
return true if !hash_status.has_key?( "status" )
|
57
61
|
return true if hash_status["status"] == status
|
data/lib/curate_tumblr/values.rb
CHANGED
@@ -7,6 +7,10 @@ describe CurateTumblr::Publish::Follow do
|
|
7
7
|
include_context "shared caption post"
|
8
8
|
let(:curator) { FactoryGirl.build( :curator ) }
|
9
9
|
|
10
|
+
before do
|
11
|
+
File.open( curator.get_filename_links, 'w' ) { |file| file.puts "" }
|
12
|
+
end
|
13
|
+
|
10
14
|
describe "to follow after" do
|
11
15
|
it "should follow all links in caption when no source" do
|
12
16
|
ar_links = curator.send( :add_tofollow_tumblr_links_from_caption, caption )
|
@@ -4,6 +4,10 @@ describe CurateTumblr::Publish::Post do
|
|
4
4
|
include_context "shared targets"
|
5
5
|
let(:curator) { FactoryGirl.build( :curator ) }
|
6
6
|
|
7
|
+
before do
|
8
|
+
File.open( curator.get_filename_links, 'w' ) { |file| file.puts "" }
|
9
|
+
end
|
10
|
+
|
7
11
|
describe "get infos post" do
|
8
12
|
it "hash post from tumblr and id post" do
|
9
13
|
hash_post = curator.get_hash_post( target_tumblr, target_post_id )
|
@@ -6,6 +6,10 @@ describe CurateTumblr::Publish::Reblog do
|
|
6
6
|
include_context "shared tags"
|
7
7
|
let(:curator) { FactoryGirl.build( :curator ) }
|
8
8
|
|
9
|
+
before do
|
10
|
+
File.open( curator.get_filename_links, 'w' ) { |file| file.puts "" }
|
11
|
+
end
|
12
|
+
|
9
13
|
describe "reblog link" do
|
10
14
|
let(:tumblr_url) { "youknow-thisistheend.tumblr.com" }
|
11
15
|
let(:post_url) { "http://youknow-thisistheend.tumblr.com/post/54773810226/facebook-auf-we-heart-it" }
|
@@ -19,6 +19,7 @@ describe CurateTumblr::Render::RenderLinks do
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
|
22
23
|
describe "get reblog links from file" do
|
23
24
|
it "read links" do
|
24
25
|
ar_file = render_reblog.get_links_torender_from_file
|
@@ -52,10 +53,10 @@ describe CurateTumblr::Render::RenderLinks do
|
|
52
53
|
render_reblog.links_to_render.count.should eq( links.count )
|
53
54
|
end
|
54
55
|
end
|
55
|
-
|
56
|
+
end
|
56
57
|
|
57
|
-
describe "render" do
|
58
58
|
|
59
|
+
describe "render" do
|
59
60
|
it "all links" do
|
60
61
|
render_reblog.render_links_from_file.should be_true
|
61
62
|
render_reblog.get_count.should eq( count_reblogs )
|
@@ -6,6 +6,10 @@ describe CurateTumblr::Tumblr::Client do
|
|
6
6
|
include_context "shared targets"
|
7
7
|
include_context "shared links"
|
8
8
|
|
9
|
+
before do
|
10
|
+
File.open( curator.get_filename_links, 'w' ) { |file| file.puts "" }
|
11
|
+
end
|
12
|
+
|
9
13
|
describe "status" do
|
10
14
|
it "when rate exceed" do
|
11
15
|
hash_status = get_status_rate_exceed
|
@@ -6,6 +6,10 @@ describe "Extract" do
|
|
6
6
|
|
7
7
|
include_context "shared targets"
|
8
8
|
|
9
|
+
before do
|
10
|
+
File.open( curator.get_filename_links, 'w' ) { |file| file.puts "" }
|
11
|
+
end
|
12
|
+
|
9
13
|
describe "from post url" do
|
10
14
|
it "is tumblr from post url" do
|
11
15
|
CurateTumblr::Tumblr::ExtractLinks.tumblr_url?( target_post_url ).should be_true
|
data/spec/spec_helper.rb
CHANGED
@@ -75,7 +75,7 @@ def files_before( render, links='' )
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def files_after( render )
|
78
|
-
|
78
|
+
#File.delete( render.filename_links ) if File.exists?( render.filename_links )
|
79
79
|
end
|
80
80
|
|
81
81
|
def get_status_rate_exceed
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: curate_tumblr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-08-
|
12
|
+
date: 2013-08-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: tumblr_client
|