curate_tumblr 1.0.3

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.
Files changed (41) hide show
  1. data/.project +18 -0
  2. data/README.md +219 -0
  3. data/Rakefile +0 -0
  4. data/curate_tumblr.gemspec +12 -0
  5. data/example/kubricklove/kubricklove_config.yaml +20 -0
  6. data/example/kubricklove/links/kubricklove_links +4 -0
  7. data/example/kubricklove_follow.rb +6 -0
  8. data/example/kubricklove_reblog.rb +6 -0
  9. data/example/readme +9 -0
  10. data/lib/curate_tumblr.rb +25 -0
  11. data/lib/curate_tumblr/curator.rb +200 -0
  12. data/lib/curate_tumblr/publish/follow.rb +62 -0
  13. data/lib/curate_tumblr/publish/post.rb +21 -0
  14. data/lib/curate_tumblr/publish/reblog.rb +86 -0
  15. data/lib/curate_tumblr/render/render_follow.rb +29 -0
  16. data/lib/curate_tumblr/render/render_links.rb +132 -0
  17. data/lib/curate_tumblr/render/render_reblog.rb +36 -0
  18. data/lib/curate_tumblr/tumblr/client.rb +347 -0
  19. data/lib/curate_tumblr/tumblr/extract_links.rb +190 -0
  20. data/lib/curate_tumblr/tumblr/infos.rb +102 -0
  21. data/lib/curate_tumblr/utilities/monkey.rb +5 -0
  22. data/lib/curate_tumblr/utilities/utilities.rb +4 -0
  23. data/lib/curate_tumblr/utilities/utilities_client.rb +103 -0
  24. data/lib/curate_tumblr/utilities/utilities_file.rb +50 -0
  25. data/lib/curate_tumblr/utilities/utilities_format.rb +91 -0
  26. data/lib/curate_tumblr/utilities/utilities_validate.rb +54 -0
  27. data/lib/curate_tumblr/values.rb +22 -0
  28. data/spec/curate_tumblr/curator_spec.rb +36 -0
  29. data/spec/curate_tumblr/publish/follow_spec.rb +183 -0
  30. data/spec/curate_tumblr/publish/post_spec.rb +45 -0
  31. data/spec/curate_tumblr/publish/reblog_spec.rb +118 -0
  32. data/spec/curate_tumblr/render/render_follow_spec.rb +36 -0
  33. data/spec/curate_tumblr/render/render_reblog_spec.rb +73 -0
  34. data/spec/curate_tumblr/tumblr/client_spec.rb +69 -0
  35. data/spec/curate_tumblr/tumblr/extract_links_spec.rb +204 -0
  36. data/spec/curate_tumblr/utilities/utilities_validate_spec.rb +27 -0
  37. data/spec/factories.rb +24 -0
  38. data/spec/shared_examples.rb +2 -0
  39. data/spec/shared_values.rb +203 -0
  40. data/spec/spec_helper.rb +95 -0
  41. metadata +116 -0
data/.project ADDED
@@ -0,0 +1,18 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <projectDescription>
3
+ <name>curate_tumblr</name>
4
+ <comment></comment>
5
+ <projects>
6
+ </projects>
7
+ <buildSpec>
8
+ <buildCommand>
9
+ <name>com.aptana.ide.core.unifiedBuilder</name>
10
+ <arguments>
11
+ </arguments>
12
+ </buildCommand>
13
+ </buildSpec>
14
+ <natures>
15
+ <nature>com.aptana.projects.webnature</nature>
16
+ <nature>com.aptana.ruby.core.rubynature</nature>
17
+ </natures>
18
+ </projectDescription>
data/README.md ADDED
@@ -0,0 +1,219 @@
1
+ # Curate Tumblr Ruby Gem
2
+
3
+ Reblog and follow in your Tumblr from a file of links.
4
+
5
+ Grow you Tumblr audience by automating the boring tasks !
6
+
7
+ ### Installation
8
+
9
+ gem install curate_tumblr
10
+
11
+ ### Quick Example
12
+
13
+ require 'curate_tumblr'
14
+
15
+ **CurateTumblr.reblog( "kubricklove", "/home/tumblr" )**
16
+
17
+ reblog links in the queue of tumblr "kubricklove" where config is in
18
+ /home/tumblr/kubricklove/kubricklove_config.yaml
19
+ and links to reblog are in
20
+ /home/tumblr/kubricklove/links/kubricklove_links
21
+
22
+ ### Features
23
+
24
+ * *polite with tumblr* : random sleep and stop if tumblr send errors
25
+ * *extract informations from posts* : other tumblrs to follow, external links to see...
26
+ * *add visibility to your reblogs* : add tags and link
27
+ * *separate follow from reblog* : not to waste Tumblr requests
28
+ * *config in realtime* : you can stop it or change parameters when running
29
+
30
+ ### Important
31
+
32
+ Please note before all **you have to config oauth** for your tumblr.
33
+
34
+ You can see an example of reblog and follow for a kubrick tumblr in the *example* folder.
35
+
36
+ ## Usage
37
+
38
+ ### oAuth
39
+
40
+ #### Create a Tumblr
41
+
42
+ First create a test tumblr if you have not
43
+
44
+ ex : mytumblrtest.tumblr.com
45
+
46
+ #### oAuth
47
+
48
+ Follow the tumblr process to have oauth authenficiation :
49
+ https://www.tumblr.com/login?redirect_to=%2Foauth%2Fapps
50
+
51
+ more infos : http://www.tumblr.com/docs/en/api/v2#blog-likes
52
+
53
+ This application **must be authorized** by your tumblr
54
+
55
+ #### Result
56
+
57
+ At the end you must have this codes :
58
+
59
+ consumer_key: XX
60
+ consumer_secret: XX
61
+ token: XX
62
+ token_secret: XX
63
+
64
+
65
+ ### Config
66
+
67
+ Curate Tumblr uses the name of your tumblr to find the folder for links (to reblog and follow) and config file
68
+
69
+ #### Create folders
70
+
71
+ Create a folder where you will have your config and links files :
72
+
73
+ ex : /home/tumblr
74
+
75
+ Create in this folder another folder with your test tumblr name :
76
+
77
+ ex : /home/tumblr/mytumblrtest
78
+
79
+ In this folder create a folder links and a folder logs
80
+
81
+ ex :
82
+
83
+ /home/tumblr/mytumblrtest/links
84
+
85
+ /home/tumblr/mytumblrtest/logs
86
+
87
+
88
+ #### Create config file
89
+
90
+ Create a config file in this folder.
91
+
92
+ You can copy *kubricklove_config.yaml* from the example and rename it with your tumblr name :
93
+
94
+ ex /home/tumblr/mytumblrtest/mytumblrtest_config.yaml
95
+
96
+ Put your oauth codes in the config file
97
+
98
+ oauth:
99
+
100
+ consumer_key:
101
+ consumer_secret:
102
+ token:
103
+ token_secret:
104
+
105
+ Congratulations! :-)
106
+
107
+
108
+ ## Some examples
109
+
110
+ #### Reblog or follow from a links file
111
+
112
+ The easy way is to render tumblr links from file, with *CurateTumblr::Render* module :
113
+
114
+ require "curate_tumblr"
115
+
116
+ CurateTumblr.reblog( "mytumblrtest", "/home/tumblr" )
117
+
118
+ CurateTumblr.follow( "mytumblrtest", "/home/tumblr" )
119
+
120
+ #### Reblog or follow a link
121
+
122
+ You can also use *CurateTumblr::Curator* :
123
+
124
+ require "curate_tumblr"
125
+
126
+ curator = Curator.new( "mytumblrtest", "/home/tumblr" )
127
+
128
+ curator.reblog_and_extract( "http://joshbrooksonfilm.tumblr.com/post/58294445822/barry-lyndon-1975-kubrick-1st-viewing-if-i" )
129
+
130
+ curator.reblog_and_extract( "http://oh-lesedi.tumblr.com" )
131
+
132
+ ## Config options
133
+
134
+ client: basic config for manage Tumblr
135
+ * *is_running* : if false stop the application
136
+ * *sleep_before_client_min and max* : random sleep before each request (important to not be blocked by Tumblr)
137
+ * *sleep_before_follow_min and max* : random sleep before following, can simulate a queue
138
+ * *max_requests_and_posts* : max of all requests before stop
139
+ * *max_posted* : max of posted (text, image) before stop
140
+ * *max_reblogged* : max of reblogged before stop
141
+ * *max_followed* : max of followed before stop
142
+ * *oauth: consumer_key, consumer_secret, token, token_secret*
143
+
144
+ infos: infos to add to your posts
145
+ * *tags* : a string with list of tags
146
+ * *title* : to add a link to your tumblr
147
+
148
+
149
+ ## Rspec
150
+
151
+ **Before testing code you have to set oauth and create a config file** (you can copy the example config file)
152
+
153
+ In *spec/factories.rb* change *get_tumblr_name* and *get_tumblr_directory*
154
+
155
+ in the config file set oauth
156
+ oauth:
157
+
158
+ consumer_key:
159
+ consumer_secret:
160
+ token:
161
+ token_secret:
162
+
163
+
164
+ ## Tumblr errors
165
+
166
+ The application manage these tumblr errors :
167
+ * *Rate limit exceeded* : too much requests, try to incread the sleep time in config file **=> the application stop**
168
+ * *Bad request* : perhaps the link has been deleted
169
+ * *Too much bad requests* : there is no enough place in the queue, or there is a problem with your tumblr **=> the application stop**
170
+
171
+
172
+ ## Tips
173
+
174
+ ### Realtime
175
+
176
+ Config file is read before each operation.
177
+
178
+ You can stop a cron reblog or follow by changing *is_running* in config file
179
+ (ex /home/tumblr/mytumblrtest/mytumblrtest_config.yaml)
180
+
181
+ *is_running: false*
182
+
183
+ you can also change other parameters (max to reblog, sleep time...)
184
+
185
+
186
+ ### Problems
187
+
188
+ If strange things happen :
189
+ * please note by default reblogged posts are published in queue (not visible)
190
+ * check there is enough place in the queue (max 300 posts in queue)
191
+ * check your tumblr name (ex : mytumblrtest if you have created mytumblrtest.tumblr.com)
192
+ * check oauth is ok in your config file
193
+ * check log file (ex in /home/tumblr/mytumblrtest/logs)
194
+
195
+ ### About reblog
196
+
197
+ To reblog a post you need its reblog key.
198
+
199
+ You have to send a request to tumblr with the post tumblr and id.
200
+
201
+ You can use :
202
+
203
+ *CurateTumblr::Tumblr::ExtractLinks.get_reblog_key_from_reblog_url*
204
+
205
+ and *reblog_post_key* in CurateTumblr::Publish.Reblog
206
+
207
+
208
+ ## Todo
209
+
210
+ * memory (to not follow tumblrs already followed)
211
+ * hidden oauth (are you enough paranoid ?)
212
+
213
+
214
+ ## Copyright
215
+
216
+ The Curate Tumblr gem is Copyright (c) 2013 David Tysman and is licensed under the MIT License.
217
+ Feel free to use it for any project.
218
+
219
+ Tumblr is Copyright (c) Tumblr, Inc. The Curate Tumblr gem is NOT affiliated with Tumblr, Inc.
data/Rakefile ADDED
File without changes
@@ -0,0 +1,12 @@
1
+ Gem::Specification.new do |gem|
2
+ gem.add_dependency 'tumblr_client'
3
+ gem.add_dependency 'logger'
4
+ gem.name = 'curate_tumblr'
5
+ gem.version = '1.0.3'
6
+ gem.authors = ['David Tysman']
7
+ gem.description = 'CurateTumblr - reblog and follow Tumblr links'
8
+ gem.summary = 'Reblog and follow Tumblr'
9
+ gem.email = 'web@davidtysman.com'
10
+ gem.files = `git ls-files`.split("\n")
11
+ gem.homepage = "https://github.com/davidtysman/curate_tumblr"
12
+ end
@@ -0,0 +1,20 @@
1
+ client:
2
+ is_running: true
3
+ sleep_before_client_min: 1
4
+ sleep_before_client_max: 3
5
+ sleep_before_follow_min: 3*60
6
+ sleep_before_follow_max: 6*60
7
+ max_requests_and_posts: 80
8
+ max_posted: 50
9
+ max_reblogged: 40
10
+ max_followed: 30
11
+ oauth:
12
+ consumer_key: ""
13
+ consumer_secret: ""
14
+ token: ""
15
+ token_secret: ""
16
+
17
+ infos:
18
+ tags: "kubrick, film, classic"
19
+ title: "Kubrick Love <br>&nbsp;&nbsp;&nbsp;&nbsp;Kubrick Photos, Films & Secrets"
20
+
@@ -0,0 +1,4 @@
1
+ http://joshbrooksonfilm.tumblr.com/post/58294445822/barry-lyndon-1975-kubrick-1st-viewing-if-i
2
+ http://www.tumblr.com/reblog/58327106557/9riXdZGo?redirect_to=%2Ftagged%2Fstanley-kubrick
3
+ http://withoutjudgementwhatwouldwedo.tumblr.com/post/58321322530/this-is-my-rifle-there-are-many-like-it-but-this
4
+ http://oh-lesedi.tumblr.com/
@@ -0,0 +1,6 @@
1
+ require "curate_tumblr"
2
+
3
+ CurateTumblr.follow( "kubricklove", "./" )
4
+
5
+
6
+
@@ -0,0 +1,6 @@
1
+ require "curate_tumblr"
2
+
3
+ CurateTumblr.reblog( "kubricklove", "./" )
4
+
5
+
6
+
data/example/readme ADDED
@@ -0,0 +1,9 @@
1
+ Reblog and follow tumblr links in the queue of a (fictive) kubricklove.tumblr.com
2
+
3
+ kubricklove_reblog.rb :
4
+ For each tumblr link, it puts the link in queue with tags and title, puts the tumblr and the source in tofollow links, and search in content if there is any link to follow or to add to external links
5
+ Reblog and Follow scripts set the tumblr name and the folder for config, links and logs.
6
+
7
+ Important : this tumblr doesn't exist and oauth in config yaml is empty
8
+ You can copy this example and make it work by replacing "kubricklove" by your tumblr name and set valid oauth in config file
9
+ To config oauth please follow the tumblr documentation (your tumblr must give the authorization to the application) : http://www.tumblr.com/docs/en/api/v2#blog-likes
@@ -0,0 +1,25 @@
1
+ require 'tumblr_client'
2
+ require 'logger'
3
+ require 'yaml'
4
+
5
+ require 'curate_tumblr/tumblr/client'
6
+ require 'curate_tumblr/tumblr/infos'
7
+ require 'curate_tumblr/tumblr/extract_links'
8
+
9
+ require 'curate_tumblr/publish/post'
10
+ require 'curate_tumblr/publish/reblog'
11
+ require 'curate_tumblr/publish/follow'
12
+
13
+ require 'curate_tumblr/curator'
14
+
15
+ require 'curate_tumblr/values'
16
+ require 'curate_tumblr/utilities/utilities'
17
+ require 'curate_tumblr/utilities/monkey'
18
+
19
+ require 'curate_tumblr/render/render_links'
20
+ require 'curate_tumblr/render/render_reblog'
21
+ require 'curate_tumblr/render/render_follow'
22
+
23
+
24
+
25
+
@@ -0,0 +1,200 @@
1
+
2
+ module CurateTumblr
3
+
4
+ def self.reblog( tumblr_name, directory, is_display_infos=true )
5
+ Render::RenderLinks.render( Render::RenderReblog.new( tumblr_name, directory ), __method__, is_display_infos )
6
+ end
7
+
8
+ def self.follow( tumblr_name, directory, is_display_infos=true )
9
+ Render::RenderLinks.render( Render::RenderFollow.new( tumblr_name, directory ), __method__, is_display_infos )
10
+ end
11
+
12
+ class Curator
13
+ include Tumblr::Client
14
+ include Tumblr::Infos
15
+ include Tumblr::ExtractLinks
16
+ include Publish::Follow
17
+ include Publish::Reblog
18
+ include Publish::Post
19
+
20
+ attr_accessor :tumblr_name, :is_stop, :is_debug, :log_tumblr, :directory
21
+
22
+ class << self
23
+ def create_config_yaml_file( file_yaml, hash_config )
24
+ check_config_hash( hash_config )
25
+ document = get_string_yaml_from_config( hash_config )
26
+ File.open( file_yaml, "w+") { |file| file.puts( document ) }
27
+ end
28
+
29
+ def get_string_yaml_from_config( hash_config )
30
+ Tumblr::Client::get_string_yaml_from_client_config( hash_config ) + "\n\n" +
31
+ Tumblr::Infos::get_string_yaml_from_infos_config( hash_config )
32
+ end
33
+
34
+ def check_config_hash( hash_config )
35
+ raise "config must be a Hash instead of #{hash_config.class}" if !hash_config.is_a?( Hash )
36
+ Tumblr::Client::check_client_config_hash( hash_config )
37
+ Tumblr::Infos::check_infos_config_hash( hash_config )
38
+ hash_config
39
+ end
40
+ end
41
+
42
+ # --- config ---
43
+
44
+ def initialize( tumblr_name, directory='/home/tumblr' )
45
+ @tumblr_name = tumblr_name
46
+ @directory = directory
47
+
48
+ init_tumblr!
49
+ check_config
50
+ @is_debug = false
51
+ end
52
+
53
+ def init_tumblr!( hash_config={} )
54
+ hash_config = get_config_from_yaml if hash_config.empty?
55
+ set_log
56
+ init_client!( hash_config )
57
+ init_infos!( hash_config )
58
+ init_extract_links!( hash_config )
59
+ init_follow!( hash_config )
60
+ init_reblog!( hash_config )
61
+ init_post!( hash_config )
62
+ @is_stop = false
63
+ end
64
+
65
+ def config_from_yaml
66
+ hash_config = get_config_from_yaml
67
+ config_client( hash_config )
68
+ config_infos( hash_config )
69
+ end
70
+
71
+ def get_config_from_yaml
72
+ file_yaml = get_filename_config
73
+ raise "config file YAML #{file_yaml} doesn't exist" if !File.exist?( file_yaml )
74
+ begin
75
+ documents = YAML::load_documents( File.open( file_yaml ) )
76
+ rescue => exception
77
+ raise "can't load config from YAML #{file_yaml} : #{exception} "
78
+ end
79
+ raise "config from YAML #{file_yaml} is empty" if documents.empty?
80
+ Curator.check_config_hash( documents.first )
81
+ end
82
+
83
+ def check_config
84
+ raise "directory is empty" if @directory.empty?
85
+ raise "tumblr_name is empty" if @tumblr_name.empty?
86
+ check_client_config
87
+ check_infos_config
88
+ end
89
+
90
+ # --- options ---
91
+
92
+ def stop_it!( reason='' )
93
+ @is_stop = true
94
+ @log_tumblr.warn( "stop it because " + reason ) if !reason.empty?
95
+ end
96
+
97
+ def debug
98
+ @is_debug = true
99
+ end
100
+
101
+ def can_run?
102
+ return false if self.is_stop
103
+ true
104
+ end
105
+
106
+ # --- files ---
107
+
108
+ def add_tofollow_tofile( is_delete_tofollow=true )
109
+ @all_tofollow_urls = CurateTumblr.get_format_tumblr_urls( @all_tofollow_urls )
110
+ return false if !CurateTumblr.add_set_tofile_without_repeat( get_filename_tofollow, @all_tofollow_urls )
111
+ @all_tofollow_urls = Set.new if is_delete_tofollow
112
+ true
113
+ end
114
+
115
+ def add_externallinks_tofile( is_delete_externallinks=true )
116
+ @all_external_links = CurateTumblr.get_format_urls( @all_external_links)
117
+ return false if !CurateTumblr.add_set_tofile_without_repeat( get_filename_external_links, @all_external_links )
118
+ @all_external_links = Set.new if is_delete_externallinks
119
+ true
120
+ end
121
+
122
+ # --- paths ---
123
+
124
+ def get_path_tumblr
125
+ @directory + "/" + @tumblr_name
126
+ end
127
+
128
+ def get_path_logs
129
+ get_path_tumblr + "/logs"
130
+ end
131
+
132
+ def get_path_links
133
+ get_path_tumblr + "/links"
134
+ end
135
+
136
+ def get_path_config
137
+ get_path_tumblr
138
+ end
139
+
140
+ def get_filename_config
141
+ get_path_config + "/" + @tumblr_name + "_config.yaml"
142
+ end
143
+
144
+ def get_filename_values
145
+ get_path_config + "/" + @tumblr_name + "_values.yaml"
146
+ end
147
+
148
+ def get_filename_log
149
+ get_path_logs + "/" + @tumblr_name + "_log"
150
+ end
151
+
152
+ def get_filename_errors
153
+ get_path_logs + "/" + @tumblr_name + "_errors"
154
+ end
155
+
156
+ def get_filename_links
157
+ get_path_links + "/" + @tumblr_name + "_links"
158
+ end
159
+
160
+ def get_filename_tofollow
161
+ get_path_links + "/" + @tumblr_name + "_tofollow"
162
+ end
163
+
164
+ def get_filename_external_links
165
+ get_path_links + "/" + @tumblr_name + "_external_links"
166
+ end
167
+
168
+ def set_log
169
+ @log_tumblr = Logger.new( get_filename_log )
170
+ end
171
+
172
+ def new_log( info )
173
+ default_log
174
+ @log_tumblr << "\n"
175
+ @log_tumblr.info( info )
176
+ end
177
+
178
+ private
179
+
180
+ def stop_and_alert(message, is_display=true, is_log=true )
181
+ @log_tumblr.error( message ) if is_log
182
+ puts "\n*** Stop it ! #{message} ***" if is_display
183
+ stop_it!
184
+ end
185
+
186
+ def error( method, message, hash_infos={} )
187
+ error = "#{@domain} : #{message} in #{method} "
188
+ if !hash_infos.empty?
189
+ error = error + " with"
190
+ hash_infos.each { |key, value| error = error + " [#{key} : #{value}]" }
191
+ end
192
+ @log_tumblr.error( error )
193
+ end
194
+
195
+ def return_error( method, message, hash_infos={} )
196
+ error( method, message, hash_infos )
197
+ false
198
+ end
199
+ end
200
+ end