rubyhexagon 0.0.1
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/e621_search +116 -0
- data/bin/e621_server +158 -0
- data/bin/fav-sync +82 -0
- data/bin/set-sync +225 -0
- data/lib/api.rb +123 -0
- data/lib/config.rb +46 -0
- data/lib/container.rb +43 -0
- data/lib/pool.rb +50 -0
- data/lib/post.rb +106 -0
- data/lib/rubyhexagon.rb +34 -0
- data/lib/search.rb +73 -0
- data/lib/set.rb +43 -0
- data/lib/standard/error.rb +24 -0
- data/lib/standard/hash.rb +29 -0
- data/lib/standard/http.rb +83 -0
- data/lib/standard/int.rb +36 -0
- data/lib/standard/string.rb +84 -0
- data/lib/standard/time.rb +30 -0
- metadata +67 -0
data/lib/api.rb
ADDED
@@ -0,0 +1,123 @@
|
|
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 "standard/http"
|
21
|
+
|
22
|
+
module E621
|
23
|
+
attr_reader :user
|
24
|
+
class API
|
25
|
+
# Variable mod is the module (Post, Pool, Set,...) this API is called for.
|
26
|
+
def initialize(mod=nil)
|
27
|
+
@http = HTTP.new
|
28
|
+
@mod = mod
|
29
|
+
@user = user_login
|
30
|
+
end
|
31
|
+
# Send commands to API and parse all answers, even errors.
|
32
|
+
# Also make it work with POST and GET requests.
|
33
|
+
def method_missing(method,*args)
|
34
|
+
if [:get,:post].include?(method) then
|
35
|
+
action,request,cookie = args
|
36
|
+
r,tries = request2body(request,cookie),0
|
37
|
+
begin
|
38
|
+
json = @http.__send__(method,"/#@mod/#{action}.json",r)
|
39
|
+
rescue Timeout::Error
|
40
|
+
sleep 2**tries
|
41
|
+
tries += 1
|
42
|
+
#E621.log.debug("#@mod/#{action} failed: #{e.class}")
|
43
|
+
raise if tries >= 4
|
44
|
+
# if we see more than 4 timeout errors, then there
|
45
|
+
# is something wrong
|
46
|
+
retry
|
47
|
+
end
|
48
|
+
#raise APIError,json["reason"] if json.include?("success") && !json["success"]
|
49
|
+
return json
|
50
|
+
else
|
51
|
+
raise NoMethodError, "undefined method #{method} for #{self.class}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
private
|
55
|
+
# This helper function provides the functionality of translating Ruby Hashes
|
56
|
+
# into HTTP POST body strings.
|
57
|
+
def request2body(r,c)
|
58
|
+
s = String.new
|
59
|
+
r.each do |k,v|
|
60
|
+
s += "&" unless s == String.new
|
61
|
+
if v.is_a?(Hash) then
|
62
|
+
t = String.new
|
63
|
+
v.each do |e,a|
|
64
|
+
t += "&" unless t == String.new
|
65
|
+
t += "#{k}[#{e}]=#{a}"
|
66
|
+
end
|
67
|
+
s += t
|
68
|
+
else
|
69
|
+
s += "#{k}=#{v}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
s += "&#@@login" if !c
|
73
|
+
return s
|
74
|
+
end
|
75
|
+
# Perform an API and site login. This function needs to be called once
|
76
|
+
# before any actual API call can be made.
|
77
|
+
def user_login
|
78
|
+
# Cookie login gets eliminated for now.
|
79
|
+
name,pass = String.new, String.new
|
80
|
+
# Perform a re-login if the last time is older than x days. Or if there is
|
81
|
+
# no cookie.
|
82
|
+
passwd = File.expand_path(Config.paths["passwd"])
|
83
|
+
if File.exist?(passwd) then
|
84
|
+
File.open(passwd){|f|@passwd=f.read.parse}
|
85
|
+
else
|
86
|
+
@passwd = {"name"=>"","pass"=>"","last_login"=>0}
|
87
|
+
end
|
88
|
+
if (Time.now.to_i-@passwd["last_login"].to_i) < 3.days then
|
89
|
+
@@login = @passwd["login"]
|
90
|
+
else
|
91
|
+
if @passwd["name"] != "" && @passwd["pass"] != "" then
|
92
|
+
name,pass = @passwd["name"],@passwd["pass"]
|
93
|
+
else
|
94
|
+
puts "No user data found. Please provide user data."
|
95
|
+
name,pass = get_credentials
|
96
|
+
@passwd["name"],@passwd["pass"] = name,pass
|
97
|
+
# Store that data for later use.
|
98
|
+
end
|
99
|
+
request = "name=#{name}&password=#{pass}"
|
100
|
+
body = @http.get("/user/login.json",request)
|
101
|
+
if body.has_key?("success") && (!body["success"] || body["success"] == "failed") then
|
102
|
+
raise AuthentificationError, "Username or password wrong!"
|
103
|
+
else
|
104
|
+
@@login = "login=#{body["name"]}&password_hash=#{body["password_hash"]}"
|
105
|
+
@passwd["login"] = @@login # Save login string for later use.
|
106
|
+
end
|
107
|
+
@passwd["last_login"] = Time.now.to_i
|
108
|
+
# Write everything back!
|
109
|
+
File.open(passwd,"w"){|f|f.print @passwd.to_json}
|
110
|
+
end
|
111
|
+
return @passwd["name"]
|
112
|
+
end
|
113
|
+
# If there is no data saved for login, ask the user. They must know!
|
114
|
+
def get_credentials
|
115
|
+
print "Username: "
|
116
|
+
name = $stdin.gets.chomp
|
117
|
+
print "Password: "
|
118
|
+
pass = `stty_o=$(stty -g);stty -echo;read pass;stty $stty_o; echo $pass`.chomp
|
119
|
+
puts
|
120
|
+
return [name,pass]
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
data/lib/config.rb
ADDED
@@ -0,0 +1,46 @@
|
|
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
|
+
module E621
|
20
|
+
class Config
|
21
|
+
def self.config
|
22
|
+
return @@config
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.paths
|
26
|
+
return @@paths
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.blacklist
|
30
|
+
return @@blacklist
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.config=(config)
|
34
|
+
if File.exist?(config) then
|
35
|
+
File.open(config) do |f|
|
36
|
+
c = f.read.parse
|
37
|
+
@@paths = c.delete("paths")
|
38
|
+
@@blacklist = c.delete("blacklist")
|
39
|
+
@@config = c
|
40
|
+
end
|
41
|
+
else
|
42
|
+
raise ArgumentError, "No configuration file specified. Broken installation!"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/container.rb
ADDED
@@ -0,0 +1,43 @@
|
|
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
|
+
module E621
|
21
|
+
class Container
|
22
|
+
def method_missing(method)
|
23
|
+
if instance_variables.include?("@#{method}".to_sym) then
|
24
|
+
return instance_variable_get("@#{method}")
|
25
|
+
else
|
26
|
+
raise NoMethodError, "undefined method #{method} for #{self.class}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
private
|
30
|
+
def set_variables(container)
|
31
|
+
container.each do |k,v|
|
32
|
+
if (k == "created_at" || k == "updated_at") && v.is_a?(Hash) then
|
33
|
+
v = Time.at(v["s"])
|
34
|
+
elsif (k == "created_at" || k == "updated_at") && !v.is_a?(Hash) then
|
35
|
+
v = Time.at(v)
|
36
|
+
elsif k == "cached_tags" then
|
37
|
+
k = "tags"
|
38
|
+
end
|
39
|
+
instance_variable_set("@#{k}",v)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/pool.rb
ADDED
@@ -0,0 +1,50 @@
|
|
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 "digest/md5"
|
21
|
+
|
22
|
+
module E621
|
23
|
+
class Pool < Container
|
24
|
+
def initialize(post)
|
25
|
+
set_variables(post)
|
26
|
+
end
|
27
|
+
|
28
|
+
def keys
|
29
|
+
return instance_variables.map{|i|i.to_s.sub("@","")}
|
30
|
+
end
|
31
|
+
|
32
|
+
def updated_at=(time)
|
33
|
+
@updated_at = time
|
34
|
+
end
|
35
|
+
|
36
|
+
def name=(name)
|
37
|
+
@name = name
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_json
|
41
|
+
json_hash = Hash.new
|
42
|
+
instance_variables.each do |i|
|
43
|
+
v = instance_variable_get(i)
|
44
|
+
v = v.is_a?(Time) ? v.to_i : v
|
45
|
+
json_hash.store(i.to_s.sub("@",""),v)
|
46
|
+
end
|
47
|
+
return json_hash.to_json
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/post.rb
ADDED
@@ -0,0 +1,106 @@
|
|
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 "digest/md5"
|
21
|
+
|
22
|
+
module E621
|
23
|
+
class Post < Container
|
24
|
+
def initialize(post)
|
25
|
+
set_variables(post)
|
26
|
+
end
|
27
|
+
|
28
|
+
def download_data
|
29
|
+
host,port = @file_url.sub(%r{^.+?//},"").sub(%r{/.+$},""),@file_url.match(/^https/) ? 443 : 80
|
30
|
+
http = HTTP.new(host,port)
|
31
|
+
body = String.new
|
32
|
+
while Digest::MD5.hexdigest(body) != @md5 do
|
33
|
+
body = http.get(@file_url.sub(/^.+?\.net/,""),"")["body"]
|
34
|
+
end
|
35
|
+
return body
|
36
|
+
end
|
37
|
+
|
38
|
+
def download(where)
|
39
|
+
host,port = @file_url.sub(%r{^.+?//},"").sub(%r{/.+$},""),@file_url.match(/^https/) ? 443 : 80
|
40
|
+
http = HTTP.new(host,port)
|
41
|
+
if !File.exist?(where) then
|
42
|
+
body = ""
|
43
|
+
while Digest::MD5.hexdigest(body) != @md5 do
|
44
|
+
body = http.get(@file_url.sub(/^.+?\.net/,""),"")["body"]
|
45
|
+
end
|
46
|
+
File.open(where,"w") do |f|
|
47
|
+
f.print body
|
48
|
+
end
|
49
|
+
else
|
50
|
+
md5 = String.new
|
51
|
+
File.open(where,"r") do |f|
|
52
|
+
md5 = Digest::MD5.hexdigest(f.read)
|
53
|
+
end
|
54
|
+
if md5 != @md5 then
|
55
|
+
body = ""
|
56
|
+
while Digest::MD5.hexdigest(body) != @md5 do
|
57
|
+
body = http.get(@file_url.sub(/^.+?\.net/,""),"")["body"]
|
58
|
+
end
|
59
|
+
File.open(where,"w") do |f|
|
60
|
+
f.print body
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_to_set(id)
|
67
|
+
api = API.new("set")
|
68
|
+
api.post("add_post",{"post_id"=>@id,"set_id"=>id})
|
69
|
+
end
|
70
|
+
|
71
|
+
def remove_from_set(id)
|
72
|
+
api = API.new("set")
|
73
|
+
api.post("remove_post",{"post_id"=>@id,"set_id"=>id})
|
74
|
+
end
|
75
|
+
|
76
|
+
def favorite
|
77
|
+
api = API.new("favorite")
|
78
|
+
api.post("create",{"id"=>@id})
|
79
|
+
end
|
80
|
+
|
81
|
+
def unfavorite
|
82
|
+
api = API.new("favorite")
|
83
|
+
api.post("destroy",{"id"=>@id})
|
84
|
+
end
|
85
|
+
|
86
|
+
def vote(dir)
|
87
|
+
dir = if dir >= 0 then 1 elsif dir < 0 then -1 end
|
88
|
+
api = API.new("post")
|
89
|
+
api.post("vote",{"id"=>@id,"score"=>dir})
|
90
|
+
end
|
91
|
+
|
92
|
+
def keys
|
93
|
+
return instance_variables.map{|i|i.to_s.sub("@","")}
|
94
|
+
end
|
95
|
+
|
96
|
+
def to_json(b=nil)
|
97
|
+
json_hash = Hash.new
|
98
|
+
instance_variables.each do |i|
|
99
|
+
v = instance_variable_get(i)
|
100
|
+
v = v.is_a?(Time) ? v.to_i : v
|
101
|
+
json_hash.store(i.to_s.sub("@",""),v)
|
102
|
+
end
|
103
|
+
return json_hash.to_json
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
data/lib/rubyhexagon.rb
ADDED
@@ -0,0 +1,34 @@
|
|
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 "standard/string"
|
21
|
+
require "standard/int"
|
22
|
+
require "standard/error"
|
23
|
+
require "standard/time"
|
24
|
+
|
25
|
+
require "api"
|
26
|
+
require "config"
|
27
|
+
require "container"
|
28
|
+
require "search"
|
29
|
+
require "pool"
|
30
|
+
|
31
|
+
module E621
|
32
|
+
Name = "rubyhexagon"
|
33
|
+
Version = "0.0.1"
|
34
|
+
end
|
data/lib/search.rb
ADDED
@@ -0,0 +1,73 @@
|
|
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 "post"
|
21
|
+
|
22
|
+
module E621
|
23
|
+
attr_reader :posts
|
24
|
+
class Search
|
25
|
+
# commands update/download
|
26
|
+
def initialize(query)
|
27
|
+
@api,@mt = API.new("post"),Mutex.new
|
28
|
+
@bad_tags = /(\s|^)(#{Config.blacklist.map{|x|Regexp.escape(x)}.join("|")})(\s|$)/
|
29
|
+
@request = {"limit"=>100,"page"=>1,"tags"=>query.join("+")}
|
30
|
+
fetch
|
31
|
+
end
|
32
|
+
|
33
|
+
def next!
|
34
|
+
@request["page"] += 1
|
35
|
+
fetch
|
36
|
+
end
|
37
|
+
|
38
|
+
def each_post
|
39
|
+
while @posts != Array.new do
|
40
|
+
@posts.each do |post|
|
41
|
+
yield post
|
42
|
+
end
|
43
|
+
next!
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def page
|
48
|
+
return @request["page"]
|
49
|
+
end
|
50
|
+
|
51
|
+
def page=(page)
|
52
|
+
@request["page"]=page
|
53
|
+
fetch
|
54
|
+
end
|
55
|
+
|
56
|
+
def previous!
|
57
|
+
@request["page"] -= 1
|
58
|
+
fetch
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_json(a=nil,b=nil)
|
62
|
+
posts = @posts.map{|o|o.to_json}
|
63
|
+
{"name"=>@name,"queries"=>@queries,"posts"=>posts}.to_json
|
64
|
+
end
|
65
|
+
private
|
66
|
+
def fetch
|
67
|
+
@posts = @api.post("index",@request).map do |post|
|
68
|
+
#Post.new(post) unless post["tags"].match(@bad_tags) || post["score"] <= 30
|
69
|
+
Post.new(post) unless post["tags"].match(@bad_tags)
|
70
|
+
end.compact
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/set.rb
ADDED
@@ -0,0 +1,43 @@
|
|
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
|
+
module E621
|
21
|
+
class Set < Container
|
22
|
+
def initialize(post)
|
23
|
+
set_variables(post)
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_post(id)
|
27
|
+
api = API.new("set")
|
28
|
+
api.post("add_post",{"post_id"=>id,"set_id"=>@id})
|
29
|
+
end
|
30
|
+
|
31
|
+
def keys
|
32
|
+
return instance_variables.map{|i|i.to_s.sub("@","")}
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_json
|
36
|
+
json_hash = Hash.new
|
37
|
+
instance_variables.each do |i|
|
38
|
+
json_hash.store(i.to_s.sub("@",""),instance_variable_get(i))
|
39
|
+
end
|
40
|
+
return json_hash.to_json
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,24 @@
|
|
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
|
+
module E621
|
21
|
+
# This is just a set of classes to better differenciate between common errors.
|
22
|
+
class APIError < StandardError; end
|
23
|
+
class AuthentificationError < StandardError; end
|
24
|
+
end
|
@@ -0,0 +1,29 @@
|
|
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
|
+
class Hash
|
21
|
+
def method_missing(m,args=nil)
|
22
|
+
m = m.to_s
|
23
|
+
if self.has_key?(m) then
|
24
|
+
return a[m]
|
25
|
+
else
|
26
|
+
raise NoMethodError, "undefined method #{m} for #{self.class}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,83 @@
|
|
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 "net/http"
|
21
|
+
|
22
|
+
module E621
|
23
|
+
class HTTP
|
24
|
+
def initialize(host="e621.net",port=443)
|
25
|
+
@http = Net::HTTP.new(host,port)
|
26
|
+
@http.use_ssl = true if port == 443
|
27
|
+
end
|
28
|
+
# Small wrapper function for post calls. This way a proper logging is
|
29
|
+
# guaranteed.
|
30
|
+
def post(url,request)
|
31
|
+
return parse_body(@http.post(url,request))
|
32
|
+
end
|
33
|
+
# Small wrapper function for get calls. This way a proper logging is
|
34
|
+
# guaranteed.
|
35
|
+
def get(url,request)
|
36
|
+
return parse_body(@http.get("#{url}?#{request}"))
|
37
|
+
end
|
38
|
+
# #geti gives an immediate response in the form of bytes downloaded. This
|
39
|
+
# won't be included in the gems though.
|
40
|
+
def geti(url,request)
|
41
|
+
uri = "#{url}?#{request}"
|
42
|
+
count = (@http.head(uri)["content-length"].to_i/1024.0).round(1)
|
43
|
+
clength,message = count.to_s.length,String.new
|
44
|
+
@http.get("#{url}?#{request}") do |body|
|
45
|
+
message += body
|
46
|
+
mlength = (message.length/1024.0).round(1)
|
47
|
+
print "Downloaded #{" "*(clength-mlength.to_s.length)}#{mlength}/#{count}kB\r"
|
48
|
+
end
|
49
|
+
return {"body"=>message}
|
50
|
+
end
|
51
|
+
private
|
52
|
+
# As every body gets processed the same, just put it into a seperate method.
|
53
|
+
def parse_body(resp)
|
54
|
+
begin
|
55
|
+
if resp["content-type"].sub(/;.+/,"") == "application/json" then
|
56
|
+
body = resp.body.parse
|
57
|
+
else
|
58
|
+
{"body"=>resp.body}
|
59
|
+
end
|
60
|
+
rescue
|
61
|
+
body = errorcode(resp.code,url) # Emulate a proper API response!
|
62
|
+
end
|
63
|
+
end
|
64
|
+
# Parse all code that returns not in JSON to actual JSON like hashes.
|
65
|
+
def errorcode(code,url)
|
66
|
+
body = {"success"=>false,"reason"=>""}
|
67
|
+
body["reason"] = if code.match(/3\d{2}/) then "We got redirected!"
|
68
|
+
elsif code.match(/403/) then "Access denied!"
|
69
|
+
elsif code.match(/404/) then "File not found!"
|
70
|
+
elsif code.match(/420/) then "Record could not be saved!"
|
71
|
+
elsif code.match(/421/) then "User it throttled, try again later!"
|
72
|
+
elsif code.match(/422/) then "The resource is locked!"
|
73
|
+
elsif code.match(/423/) then "Resource already exists!"
|
74
|
+
elsif code.match(/4\d{2}/) then "We made a bad request!"
|
75
|
+
elsif code.match(/500/) then "Internal server error!"
|
76
|
+
elsif code.match(/503/) then "Server has too much load!"
|
77
|
+
elsif code.match(/5\d{2}/) then "Some unkown server side error!"
|
78
|
+
else "HTTP response code out of range!!"
|
79
|
+
end
|
80
|
+
return body
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|