rubyhexagon 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/bin/set-sync +184 -148
  2. data/lib/examples/add.rb +57 -0
  3. data/lib/rubyhexagon.rb +1 -1
  4. metadata +3 -2
data/bin/set-sync CHANGED
@@ -26,6 +26,8 @@ require "logger"
26
26
 
27
27
  include E621
28
28
 
29
+ $0 = "E621 Set-sync"
30
+ $form = "%b %e, %Y %I:%M:%S %p"
29
31
 
30
32
  def download(post,name,set)
31
33
  artist = post.tags.split(/\s+/).map do |t|
@@ -38,12 +40,16 @@ def download(post,name,set)
38
40
  end
39
41
  string = [post.created_at.to_i,post.id.pad(8),artist+"_"+name,post.file_ext]
40
42
  string = string.join(".")
43
+ tries = 0
41
44
  begin
42
45
  api = API.new("post")
43
46
  post = Post.new(api.post("show",{"id"=>post.id}))
44
47
  post.download("#{name}/#{string}")
45
48
  rescue
46
- puts $!
49
+ raise if tries > 4
50
+ tries += 1
51
+ puts "#{Time.now.strftime($form)}: #$!"
52
+ @log.info("#$!")
47
53
  sleep 1
48
54
  retry
49
55
  end
@@ -53,173 +59,203 @@ def download(post,name,set)
53
59
  set_files = File.expand_path("~/.hexagon/sets")
54
60
  File.open(set_files+"/#{name}.json","w"){|f|f.print jposts}
55
61
  s = "Downloaded post #{" "*(6-post.id.to_s.length)}#{post.id} from \"#{set["name"]}\"."
56
- puts s
62
+ puts "#{Time.now.strftime($form)}: #{s}"
57
63
  @log.info(s)
58
64
  end
59
- max_wait = 2.5
60
- E621::Config.config = File.expand_path("~/.hexagon/conf.json")
61
- api = API.new("user")
62
- @log = Logger.new(File.expand_path(E621::Config.paths["logging"]))
63
- @log.formatter = proc do |sev,dat,prog,msg|
64
- "#{Time.now.strftime("%b %e, %Y %I:%M:%S %p")} [#{sev.pad(5)}] #{msg}#$/"
65
- end
66
- @log.level = Logger::INFO
67
- @log.info("Program #$0 started.")
68
- uid = api.get("index",{"name"=>api.user}).first["id"]
69
- tags = File.expand_path("~/.hexagon/tags.json")
70
- if !File.exist?(tags) then
71
- @tags = Array.new
72
- else
73
- File.open(tags) do |f|
74
- @tags = f.read.parse
65
+ begin
66
+ run,running = (File.expand_path("~/.hexagon/sets.run")),false
67
+ if File.exist?(run) then
68
+ running = true
69
+ else
70
+ File.open(run,"w"){|f|f.print $$}
75
71
  end
76
- end
77
- @tags = @tags.sort{|k1,k2|k1["id"]<=>k2["id"]}
78
- net = Net::HTTP.new("e621.net",443)
79
- net.use_ssl = true
80
- body,page = [2],1
81
- until body == Array.new do
82
- body = net.get("/tag/index.json?limit=0&order=count&after_id=#{@tags.last["id"]}&page=#{page}").body.parse
83
- body = body.map{|x|x["name"] = x["name"].encode("us-ascii", :invalid => :replace, :undef => :replace, :replace => "");x}
84
- @tags += body
85
- page += 1
86
- end
87
- jtags = @tags.to_json
88
- File.open(tags,"w"){|f|f.print jtags}
89
- @tags = @tags.reject{|x|x["type"]!=1}.map{|x|x["name"]}
90
- Dir.chdir(File.expand_path("~/Dropbox/Furry/e621/sets")) do
91
- sets = Array.new
92
- File.open(File.expand_path("~/.hexagon/sets.json")) do |f|
93
- sets = f.read.parse
72
+ max_wait = 2.5
73
+ E621::Config.config = File.expand_path("~/.hexagon/conf.json")
74
+ api = API.new("user")
75
+ if $stdout.tty? then
76
+ @log = Logger.new($stdout)
77
+ @log.level = Logger::DEBUG
78
+ else
79
+ @log = Logger.new(File.expand_path(E621::Config.paths["logging"]))
80
+ @log.level = Logger::INFO
94
81
  end
95
- sets = sets.sort{|s1,s2|s1["id"]<=>s2["id"]}
96
- set_files = File.expand_path("~/.hexagon/sets")
97
- api = API.new("set")
98
- sets.each do |set|
99
- sid, owner, query = set["id"], set["owner"], set["search"]
100
- set = api.get("show", {"id"=>sid})
101
- posts = set["posts"].map{|post|Post.new(post)}
102
- name = set["shortname"]
103
- @log.info("Fetching set #{set["name"]}")
104
- if !File.exists?(set_files+"/#{name}.json") then
105
- File.open(set_files+"/#{name}.json","w"){|f|f.print "{\"downloads\":[]}"}
106
- end
107
- File.open(set_files+"/#{name}.json"){|f|@posts = f.read.parse}
108
- Dir.mkdir(name) unless File.exist?(name)
109
- posts.each do |post|
110
- next if @posts["downloads"].include?(post.id)
111
- download(post,name,set)
112
- end
113
- next if owner != uid
114
- Search.new("fav:maxine_red #{query} order:id".split(" ")).each_post do |post|
115
- next if @posts["downloads"].include?(post.id)
116
- download(post,name,set)
117
- sleep(rand*max_wait)
82
+ @log.formatter = proc do |sev,dat,prog,msg|
83
+ "#{Time.now.strftime("%b %e, %Y %I:%M:%S %p")} [#{sev.pad(5)}] #{msg}#$/"
84
+ end
85
+ @log.info("Program #$0 started.")
86
+ uid = api.get("index",{"name"=>api.user}).first["id"]
87
+ tags = File.expand_path("~/.hexagon/tags.json")
88
+ if !File.exist?(tags) then
89
+ @tags = Array.new
90
+ else
91
+ File.open(tags) do |f|
92
+ @tags = f.read.parse
118
93
  end
119
94
  end
120
- sets.each do |set|
121
- sid, owner, query = set["id"], set["owner"], set["search"]
122
- next if owner != uid
123
- set = api.get("show", {"id"=>sid})
124
- posts = set["posts"].map{|post|Post.new(post).id}
125
- name = set["shortname"]
126
- local = Dir["#{name}/*"].reject{|x|x.match(/db$/)}.map{|x|x.split(".")[1].to_i}.sort.uniq
127
- (posts-local).each do |id|
128
- post = Post.new({"id"=>id})
129
- f = post.remove_from_set(sid)
130
- if f["success"] then
131
- s = "Removed Post #{" "*(6-post.id.to_s.length)}#{post.id} from \"#{set["name"]}\""
132
- puts "\e[1;33m#{s}\e[0m"
133
- @log.info(s)
134
- else
135
- s = "#{f["reason"].to_s.gsub(/<.+?>/,"")}."
136
- puts "\e[1;31m#{s}\e[0m"
137
- @log.info(s)
95
+ @tags = @tags.sort{|k1,k2|k1["id"]<=>k2["id"]}
96
+ net = Net::HTTP.new("e621.net",443)
97
+ net.use_ssl = true
98
+ body,page = [2],1
99
+ until body == Array.new do
100
+ body = net.get("/tag/index.json?limit=0&order=count&after_id=#{@tags.last["id"]}&page=#{page}").body.parse
101
+ body = body.map{|x|x["name"] = x["name"].encode("us-ascii", :invalid => :replace, :undef => :replace, :replace => "");x}
102
+ @tags += body
103
+ page += 1
104
+ end
105
+ jtags = @tags.to_json
106
+ File.open(tags,"w"){|f|f.print jtags}
107
+ @tags = @tags.reject{|x|x["type"]!=1}.map{|x|x["name"]}
108
+ Dir.chdir(File.expand_path("~/Dropbox/Furry/e621/sets")) do
109
+ sets = Array.new
110
+ File.open(File.expand_path("~/.hexagon/sets.json")) do |f|
111
+ sets = f.read.parse
112
+ end
113
+ sets = sets.sort{|s1,s2|s1["id"]<=>s2["id"]}
114
+ set_files = File.expand_path("~/.hexagon/sets")
115
+ api = API.new("set")
116
+ sets.each do |set|
117
+ sid, owner, query = set["id"], set["owner"], set["search"]
118
+ set = api.get("show", {"id"=>sid})
119
+ @log.info("Fetching set #{set["name"]}")
120
+ posts = set["posts"].map{|post|Post.new(post)}
121
+ name = set["shortname"]
122
+ if !File.exists?(set_files+"/#{name}.json") then
123
+ File.open(set_files+"/#{name}.json","w"){|f|f.print "{\"downloads\":[]}"}
124
+ end
125
+ File.open(set_files+"/#{name}.json"){|f|@posts = f.read.parse}
126
+ Dir.mkdir(name) unless File.exist?(name)
127
+ posts.each do |post|
128
+ next if @posts["downloads"].include?(post.id)
129
+ download(post,name,set)
130
+ end
131
+ next if owner != uid
132
+ Search.new("fav:maxine_red #{query} order:id".split(" ")).each_post do |post|
133
+ next if @posts["downloads"].include?(post.id)
134
+ download(post,name,set)
135
+ sleep(rand*max_wait)
138
136
  end
139
- sleep(rand*max_wait)
140
137
  end
141
- (local-posts).each do |id|
142
- next if id == 0
143
- post = Post.new({"id"=>id})
144
- f = post.add_to_set(sid)
145
- if f["success"] then
146
- s = "Added Post #{" "*(6-post.id.to_s.length)}#{post.id} to \"#{set["name"]}\"."
147
- puts s
148
- @log.info(s)
149
- else
150
- s = "#{f["reason"].gsub(/<.+?>/,"")}. Removing local file."
151
- puts s
152
- @log.info(s)
153
- File.unlink(Dir["#{set["shortname"]}/*.#{"0"*(8-post.id.to_s.length)}#{post.id}.*"].first)
138
+ sets.each do |set|
139
+ sid, owner, query = set["id"], set["owner"], set["search"]
140
+ next if owner != uid
141
+ set = api.get("show", {"id"=>sid})
142
+ posts = set["posts"].map{|post|Post.new(post).id}
143
+ name = set["shortname"]
144
+ local = Dir["#{name}/*"].reject{|x|x.match(/db$/)}.map{|x|x.split(".")[1].to_i}.sort.uniq
145
+ (posts-local).each do |id|
146
+ post = Post.new({"id"=>id})
147
+ f = post.remove_from_set(sid)
148
+ if f["success"] then
149
+ s = "Removed Post #{" "*(6-post.id.to_s.length)}#{post.id} from \"#{set["name"]}\""
150
+ puts "#{Time.now.strftime($form)}: \e[1;33m#{s}\e[0m"
151
+ @log.info(s)
152
+ else
153
+ s = "#{f["reason"].to_s.gsub(/<.+?>/,"")}."
154
+ puts "#{Time.now.strftime($form)}: \e[1;31m#{s}\e[0m"
155
+ @log.info(s)
156
+ end
157
+ sleep(rand*max_wait)
158
+ end
159
+ (local-posts).each do |id|
160
+ next if id == 0
161
+ post = Post.new({"id"=>id})
162
+ f = post.add_to_set(sid)
163
+ if f["success"] then
164
+ s = "Added Post #{" "*(6-post.id.to_s.length)}#{post.id} to \"#{set["name"]}\"."
165
+ puts "#{Time.now.strftime($form)}: #{s}"
166
+ @log.info(s)
167
+ else
168
+ s = "#{f["reason"].gsub(/<.+?>/,"")}. Removing local file."
169
+ puts "#{Time.now.strftime($form)}: #{s}"
170
+ @log.info(s)
171
+ File.unlink(Dir["#{set["shortname"]}/*.#{"0"*(8-post.id.to_s.length)}#{post.id}.*"].first)
172
+ end
173
+ sleep(rand*max_wait)
154
174
  end
155
- sleep(rand*max_wait)
156
175
  end
157
176
  end
158
- end
159
- Dir.chdir(File.expand_path("~/Dropbox/Furry/e621/pools")) do
160
- pools = Array.new
161
- File.open(File.expand_path("~/.hexagon/pools.json")) do |f|
162
- pools = f.read.parse.sort.uniq
163
- end
164
- pool_files = File.expand_path("~/.hexagon/pools")
165
- api = API.new("pool")
166
- pools.each do |pool|
167
- spool = {"updated_at"=>0, "posts"=>[]}
168
- npool = api.get("show",{"id"=>pool})
169
- pool = Pool.new(npool)
170
- begin
171
- pfile = pool_files+"/#{pool.id.pad(5)}.json"
172
- rescue
173
- @log.error("Error occured: #{npool.inspect}")
174
- raise
175
- end
176
- if !File.exists?(pfile) then
177
- File.open(pfile,"w"){|f|f.print spool.to_json}
178
- spool = Pool.new(spool)
179
- else
180
- File.open(pfile){|f|spool = Pool.new(f.read.parse)}
181
- end
182
- posts = Array.new
183
- next if pool.updated_at.to_i <= spool.updated_at.to_i
184
- (pool.post_count/24.0).ceil.times do |page|
185
- posts += pool.posts.map{|post|Post.new(post)}
186
- pool = Pool.new(api.get("show",{"id"=>pool.id,"page"=>page+2}))
177
+ Dir.chdir(File.expand_path("~/Dropbox/Furry/e621/pools")) do
178
+ pools = Array.new
179
+ File.open(File.expand_path("~/.hexagon/pools.json")) do |f|
180
+ pools = f.read.parse.sort.uniq
187
181
  end
188
- pool.name = pool.name.gsub("_"," ").encode("us-ascii", :invalid => :replace, :undef => :replace, :replace => "")
189
- name = pool.name.gsub(/[^0-9, ,_,a-z,\-]/i,"").sub(/\s+$/,"")
190
- Dir.mkdir(name) unless File.exist?(name)
191
- @log.info("Fetching pool #{pool.name}")
192
- posts.each_with_index do |post,id|
193
- id = id.succ
194
- next if spool.posts.include?(post.id)
195
- artist = post.tags.split(/\s+/).map do |t|
196
- @tags[@tags.index(t)] if @tags.index(t)
197
- end
182
+ pool_files = File.expand_path("~/.hexagon/pools")
183
+ api = API.new("pool")
184
+ pools = pools-(1..600).to_a
185
+ pools.each do |id|
186
+ spool = {"updated_at"=>0, "posts"=>[]}
187
+ npool = api.get("show",{"id"=>id})
198
188
  begin
199
- artist = artist.compact.first.sub("_(artist)","")
189
+ pool = Pool.new(npool)
190
+ @log.debug("Fetched pool \"#{pool.name.gsub("_"," ")}\"")
200
191
  rescue
201
- artist = "unknown"
192
+ #$stderr.puts "#{pool.inspect}"
193
+ puts "#{Time.now.strftime($form)}: #{id} raised an error!"
194
+ @log.debug("Pool object: #{pool.inspect}")
195
+ next
202
196
  end
203
- string = [pool.id.pad(5),id.pad(4),post.id.pad(8),artist,name.downcase.gsub(/\s/,"_"),post.file_ext]
204
- string = string.join(".")
205
197
  begin
206
- post.download("#{name}/#{string}")
198
+ pfile = pool_files+"/#{pool.id.pad(5)}.json"
207
199
  rescue
208
- puts $!
209
- sleep 1
210
- retry
200
+ @log.error("Error occured: #{npool.inspect}")
201
+ raise
202
+ end
203
+ if !File.exists?(pfile) then
204
+ File.open(pfile,"w"){|f|f.print spool.to_json}
205
+ spool = Pool.new(spool)
206
+ else
207
+ File.open(pfile){|f|spool = Pool.new(f.read.parse)}
208
+ end
209
+ posts = Array.new
210
+ @log.debug("Skipping pool \"#{pool.name.gsub("_"," ")}\" (#{pool.id.pad(4)})")
211
+ next if pool.updated_at.to_i <= spool.updated_at.to_i
212
+ (pool.post_count/24.0).ceil.times do |page|
213
+ posts += pool.posts.map{|post|Post.new(post)}
214
+ pool = Pool.new(api.get("show",{"id"=>pool.id,"page"=>page+2}))
215
+ end
216
+ pool.name = "Love_Can_Be_Different" if pool.name == "Love_can_be_different"
217
+ pool.name = pool.name.gsub("_"," ").encode("us-ascii", :invalid => :replace, :undef => :replace, :replace => "")
218
+ name = pool.name.gsub(/[^0-9, ,_,a-z,\-]/i,"").sub(/\s+$/,"")
219
+ Dir.mkdir(name) unless File.exist?(name)
220
+ @log.info("Fetching pool #{pool.name}")
221
+ posts.each_with_index do |post,id|
222
+ id = id.succ
223
+ next if spool.posts.include?(post.id)
224
+ artist = post.tags.split(/\s+/).map do |t|
225
+ @tags[@tags.index(t)] if @tags.index(t)
226
+ end
227
+ begin
228
+ artist = artist.compact.first.sub("_(artist)","")
229
+ rescue
230
+ artist = "unknown"
231
+ end
232
+ string = [pool.id.pad(5),id.pad(4),post.id.pad(8),artist,name.downcase.gsub(/\s/,"_"),post.file_ext]
233
+ string = string.join(".")
234
+ tries = 0
235
+ begin
236
+ post.download("#{name}/#{string}")
237
+ rescue
238
+ raise if tries > 4
239
+ tries += 1
240
+ puts "#{Time.now.strftime($form)}: #$!"
241
+ @log.info("#$!")
242
+ sleep 1
243
+ retry
244
+ end
245
+ File.utime(post.created_at,post.created_at,"#{name}/#{string}")
246
+ spool.posts << post.id
247
+ jposts = spool.to_json
248
+ File.open(pfile,"w"){|f|f.print jposts}
249
+ s = "Downloaded post #{post.id.pad(6," ")} (#{id.pad(posts.length.to_s.length," ")}/#{posts.length}) from \"#{pool.name}\"."
250
+ puts "#{Time.now.strftime($form)}: #{s}"
251
+ @log.info(s)
252
+ sleep(rand*max_wait)
211
253
  end
212
- File.utime(post.created_at,post.created_at,"#{name}/#{string}")
213
- spool.posts << post.id
254
+ spool.updated_at = pool.updated_at
214
255
  jposts = spool.to_json
215
256
  File.open(pfile,"w"){|f|f.print jposts}
216
- s = "Downloaded post #{post.id.pad(6," ")} (#{id.pad(posts.length.to_s.length," ")}/#{posts.length}) from \"#{pool.name}\"."
217
- puts s
218
- @log.info(s)
219
- sleep(rand*max_wait)
220
257
  end
221
- spool.updated_at = pool.updated_at
222
- jposts = spool.to_json
223
- File.open(pfile,"w"){|f|f.print jposts}
224
258
  end
259
+ ensure
260
+ File.unlink(run) unless running
225
261
  end
@@ -0,0 +1,57 @@
1
+ =begin
2
+ Copyright 2014 Maxine Red <maxine_red1@yahoo.com>
3
+
4
+ This file is part of rubyhexagon.
5
+
6
+ rubyhexagon is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ rubyhexagon is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with rubyhexagon. If not, see <http://www.gnu.org/licenses/>.
18
+ =end
19
+
20
+ require "json"
21
+
22
+ include E621
23
+
24
+ mod = ARGV.shift
25
+
26
+ $0 = "E621 #{mod}"
27
+
28
+ E621::Config.config = File.expand_path("~/.hexagon/conf.json")
29
+ Dir.chdir(File.expand_path(E621::Config.paths["home"])) do
30
+ pools, api = Array.new, API.new(mod)
31
+ File.open(E621::Config.paths["j#{mod}s"]) do |f|
32
+ pools = JSON.parser.new(f.read).parse
33
+ end
34
+ puts "Old count: #{pools.length}"
35
+ candidates = ARGV.map{|x|x.to_i}.reject{|x|x==0}
36
+ puts "Adding candidates: #{candidates.length}"
37
+ new = ARGV.map{|x|x.to_i}.reject{|x|x==0||pools.include?(x)}
38
+ new.each do |id|
39
+ pool = api.post("show",{"id"=>id})
40
+ if pool["id"] && mod == "pool" then
41
+ pools << id
42
+ elsif pool["id"] && mod == "set" then
43
+ pools << {"id"=>pool["id"],"owner"=>pool["user-id"]}
44
+ end
45
+ end
46
+ puts "Adding: #{new.length}"
47
+ if mod == "pool" then
48
+ pools = pools.sort.uniq
49
+ elsif mod == "set" then
50
+ pools = pools.sort{|k1,k2|k1["id"]<=>k2["id"]}.uniq
51
+ end
52
+ puts "New count: #{pools.length}"
53
+ pools = pools.to_json
54
+ File.open(E621::Config.paths["j#{mod}s"]) do |f|
55
+ f.print pools
56
+ end
57
+ end
data/lib/rubyhexagon.rb CHANGED
@@ -30,5 +30,5 @@ require "pool"
30
30
 
31
31
  module E621
32
32
  Name = "rubyhexagon"
33
- Version = "0.0.5"
33
+ Version = "0.0.6"
34
34
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubyhexagon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
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: 2015-02-15 00:00:00.000000000 Z
12
+ date: 2015-03-01 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Rubyhexagon provides Ruby bindings for the e621 [dot] net API.
15
15
  email: maxine_red1@yahoo.com
@@ -22,6 +22,7 @@ extensions: []
22
22
  extra_rdoc_files: []
23
23
  files:
24
24
  - lib/pool.rb
25
+ - lib/examples/add.rb
25
26
  - lib/rubyhexagon.rb
26
27
  - lib/standard/hash.rb
27
28
  - lib/standard/http.rb