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/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
@@ -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