rubyhexagon 0.0.5 → 0.0.6
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/bin/set-sync +184 -148
- data/lib/examples/add.rb +57 -0
- data/lib/rubyhexagon.rb +1 -1
- 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
|
-
|
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
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
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
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
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
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
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
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
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
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
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
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
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
|
-
|
189
|
+
pool = Pool.new(npool)
|
190
|
+
@log.debug("Fetched pool \"#{pool.name.gsub("_"," ")}\"")
|
200
191
|
rescue
|
201
|
-
|
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
|
-
|
198
|
+
pfile = pool_files+"/#{pool.id.pad(5)}.json"
|
207
199
|
rescue
|
208
|
-
|
209
|
-
|
210
|
-
|
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
|
-
|
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
|
data/lib/examples/add.rb
ADDED
@@ -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
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.
|
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-
|
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
|