rubyhexagon 0.4.3 → 1.0.0
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.
- checksums.yaml +5 -5
- data/lib/rubyhexagon.rb +36 -28
- data/lib/rubyhexagon/artist.rb +92 -0
- data/lib/rubyhexagon/error.rb +21 -0
- data/lib/rubyhexagon/helper/api.rb +93 -0
- data/lib/rubyhexagon/image.rb +112 -0
- data/lib/rubyhexagon/level.rb +56 -0
- data/lib/rubyhexagon/post.rb +256 -0
- data/lib/rubyhexagon/search/posts.rb +99 -0
- data/lib/rubyhexagon/search/tags.rb +65 -0
- data/lib/rubyhexagon/tag.rb +89 -0
- data/lib/rubyhexagon/type.rb +70 -0
- data/lib/rubyhexagon/user.rb +78 -0
- metadata +34 -21
- data/lib/api.rb +0 -79
- data/lib/container.rb +0 -45
- data/lib/pool.rb +0 -71
- data/lib/post.rb +0 -50
- data/lib/search.rb +0 -100
- data/lib/set.rb +0 -59
- data/lib/standard/error.rb +0 -24
- data/lib/standard/hash.rb +0 -29
- data/lib/standard/http.rb +0 -92
- data/lib/standard/int.rb +0 -36
- data/lib/standard/string.rb +0 -91
- data/lib/standard/time.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1920d433c32360d24b4091fa37a7132f9fac4ccf36b400e034b2491679bee5b0
|
4
|
+
data.tar.gz: 7abdf32fcfaf560525b03697b7c68e63faff335bb6677c3569631b6d6b71b69e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a682ee7cba26e33eed44ddc234d41ea8ea31fd8e1dc06d9838ad2096aecc0fb97bcd47721dfb4731181ee02f675c283d4948a98a73957636239d8a1b5b639b5
|
7
|
+
data.tar.gz: 23b285239417e638de6b8873d8023b0840cb2039fb778382f367d7c9e8542da653737ea002108307fc9bfcbf6dd0790d72fc5b387ab62e6365e2aa4eeb73000c
|
data/lib/rubyhexagon.rb
CHANGED
@@ -1,33 +1,41 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# Copyright 2014-2018 Maxine Michalski <maxine@furfind.net>
|
2
|
+
#
|
3
|
+
# This file is part of rubyhexagon.
|
4
|
+
#
|
5
|
+
# rubyhexagon is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# rubyhexagon is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with rubyhexagon. If not, see <http://www.gnu.org/licenses/>.
|
3
17
|
|
4
|
-
|
18
|
+
require 'open-uri'
|
19
|
+
require 'uri'
|
20
|
+
require 'json'
|
21
|
+
require 'digest/md5'
|
5
22
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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 "container"
|
27
|
-
require "search"
|
28
|
-
require "pool"
|
23
|
+
require 'rubyhexagon/helper/api'
|
24
|
+
require 'rubyhexagon/error'
|
25
|
+
require 'rubyhexagon/user'
|
26
|
+
require 'rubyhexagon/tag'
|
27
|
+
require 'rubyhexagon/artist'
|
28
|
+
require 'rubyhexagon/type'
|
29
|
+
require 'rubyhexagon/image'
|
30
|
+
require 'rubyhexagon/level'
|
31
|
+
require 'rubyhexagon/post'
|
32
|
+
require 'rubyhexagon/search/posts'
|
33
|
+
require 'rubyhexagon/search/tags'
|
29
34
|
|
35
|
+
# Namespace for all classes in this gem.
|
36
|
+
# @author Maxine Michalski
|
37
|
+
# @since 0.4.3
|
30
38
|
module E621
|
31
|
-
|
32
|
-
|
39
|
+
NAME = 'rubyhexagon'.freeze
|
40
|
+
VERSION = '1.0.0'.freeze
|
33
41
|
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# Copyright 2014-2018 Maxine Michalski <maxine@furfind.net>
|
2
|
+
#
|
3
|
+
# This file is part of rubyhexagon.
|
4
|
+
#
|
5
|
+
# rubyhexagon is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# rubyhexagon is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with rubyhexagon. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
module E621
|
18
|
+
# Class to hold information about an artist on e621
|
19
|
+
#
|
20
|
+
# @author Maxine Michalski
|
21
|
+
# @since 1.0.0
|
22
|
+
class Artist
|
23
|
+
# @return [Integer] id of artist
|
24
|
+
attr_reader :id
|
25
|
+
|
26
|
+
# @return [String] name of artist
|
27
|
+
attr_reader :name
|
28
|
+
|
29
|
+
# @return [Array<String>] alternative names for artist
|
30
|
+
attr_reader :alternative_names
|
31
|
+
|
32
|
+
# @return [Array<URI>] links to find artist
|
33
|
+
attr_reader :urls
|
34
|
+
|
35
|
+
# @author Maxine Michalski
|
36
|
+
#
|
37
|
+
# Initializer for Artist.
|
38
|
+
#
|
39
|
+
# @param artist [Hash] artist data, fetched from e621
|
40
|
+
#
|
41
|
+
# @return the object
|
42
|
+
def initialize(artist)
|
43
|
+
@name = artist
|
44
|
+
end
|
45
|
+
|
46
|
+
# @author Maxine Michalski
|
47
|
+
#
|
48
|
+
# Fills this object with additional artist data
|
49
|
+
def show!
|
50
|
+
artist = API.new.fetch('artist', 'index', name: @name).first
|
51
|
+
@id = artist[:id].to_i
|
52
|
+
@alternative_names = artist[:other_names].split(/,\s+/)
|
53
|
+
@urls = artist[:urls].map { |u| URI(u) }
|
54
|
+
@active = artist[:is_active]
|
55
|
+
end
|
56
|
+
|
57
|
+
# @author Maxine Michalski
|
58
|
+
#
|
59
|
+
# Returns a filled Artist object
|
60
|
+
#
|
61
|
+
# @return [Artist] filled out artist object
|
62
|
+
def show
|
63
|
+
artist = Artist.new(@name)
|
64
|
+
artist.show!
|
65
|
+
artist
|
66
|
+
end
|
67
|
+
|
68
|
+
# @author Maxine Michalski
|
69
|
+
#
|
70
|
+
# Comparison method for artists
|
71
|
+
#
|
72
|
+
# @return [TrueClass, FalseClass]
|
73
|
+
def ==(other)
|
74
|
+
return false unless other.is_a?(Artist)
|
75
|
+
if @id && other.id
|
76
|
+
@id == other.id && @name == other.name
|
77
|
+
else
|
78
|
+
@name == other.name
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# @author Maxine Michalski
|
83
|
+
#
|
84
|
+
# Check if this artist is active
|
85
|
+
#
|
86
|
+
# @return [TrueClass] artist is active
|
87
|
+
# @return [FalseClass] artist is not active
|
88
|
+
def active?
|
89
|
+
@active
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Copyright 2014-2018 Maxine Michalski <maxine@furfind.net>
|
2
|
+
#
|
3
|
+
# This file is part of rubyhexagon.
|
4
|
+
#
|
5
|
+
# rubyhexagon is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# rubyhexagon is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with rubyhexagon. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
# Error class to show an ID is out of range or not an Integer
|
18
|
+
#
|
19
|
+
# @author Maxine Michalski
|
20
|
+
# @since 1.0.0
|
21
|
+
class InvalidIDError < StandardError; end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# Copyright 2014-2018 Maxine Michalski <maxine@furfind.net>
|
2
|
+
#
|
3
|
+
# This file is part of rubyhexagon.
|
4
|
+
#
|
5
|
+
# rubyhexagon is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# rubyhexagon is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with rubyhexagon. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
module E621
|
19
|
+
# An interface class, to unify calls from other code to e621 [dot] net.
|
20
|
+
# This class handles rate limiting, as well as provides a more uniform
|
21
|
+
# approach in making requests.
|
22
|
+
# It also ensures that a proper user agent is sent, as required by the e621
|
23
|
+
# API.
|
24
|
+
#
|
25
|
+
# @api private
|
26
|
+
# @author Maxine Michalski
|
27
|
+
# @since 0.4.3
|
28
|
+
class API
|
29
|
+
# User agent, used to identify this gem against e621.
|
30
|
+
#
|
31
|
+
# @return [Hash] hash that can be used with open-uri
|
32
|
+
attr_reader :user_agent
|
33
|
+
|
34
|
+
# @author Maxine Michalski
|
35
|
+
#
|
36
|
+
# Initializer for API. All methods are instance methods.
|
37
|
+
#
|
38
|
+
# @return the object
|
39
|
+
def initialize(rspec = false)
|
40
|
+
@user_agent = { 'User-Agent' =>
|
41
|
+
"#{E621::NAME}/#{E621::VERSION} (by maxine_red on e621" }
|
42
|
+
@base = 'https://e621.net'
|
43
|
+
lock_path = '/tmp/rubyhexagon.lock'
|
44
|
+
@lock_file = File.open(lock_path, 'a')
|
45
|
+
@rspec = rspec
|
46
|
+
end
|
47
|
+
|
48
|
+
# @author Maxine Michalski
|
49
|
+
#
|
50
|
+
# @param noun [String] the e621 noun (post, tag, user, artist, etc.)
|
51
|
+
# @param action [String] action to be performed on noun (list, show, etc.)
|
52
|
+
# @param query [Hash] a hash with extra information, which is dependent on
|
53
|
+
# noun and action
|
54
|
+
#
|
55
|
+
# Fetches information from e621 and returns data to caller. This also takes
|
56
|
+
# into account rate limiting.
|
57
|
+
#
|
58
|
+
# @return [Hash] JSON parsed response.
|
59
|
+
def fetch(noun, action, query)
|
60
|
+
query = query.to_a.map { |q| "#{q.first}=#{q.last}" }.join('&')
|
61
|
+
lock do
|
62
|
+
if @rspec || !defined? RSpec
|
63
|
+
JSON.parse(open("#{@base}/#{noun}/#{action}.json?#{query}",
|
64
|
+
@user_agent).read, symbolize_names: true)
|
65
|
+
else # In RSpec environment?
|
66
|
+
JSON.parse(open("spec/data/#{noun}/#{action}.json?#{query}")
|
67
|
+
.read, symbolize_names: true)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
# @author Maxine Michalski
|
75
|
+
#
|
76
|
+
# (see #fetch)
|
77
|
+
# A wrapper for actual requests, to minimize method length.
|
78
|
+
def lock
|
79
|
+
@lock_file.flock(File::LOCK_EX)
|
80
|
+
@lock_file.truncate(0)
|
81
|
+
@lock_file.print $PROCESS_ID
|
82
|
+
begin
|
83
|
+
data = yield
|
84
|
+
# There is a hard limit of 2 requests per second, but to be nice we wait
|
85
|
+
# a whole second between requests.
|
86
|
+
sleep 1 if @rspec || !defined? RSpec
|
87
|
+
ensure
|
88
|
+
@lock_file.flock(File::LOCK_UN)
|
89
|
+
end
|
90
|
+
data
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# Copyright 2014-2018 Maxine Michalski <maxine@furfind.net>
|
2
|
+
#
|
3
|
+
# This file is part of rubyhexagon.
|
4
|
+
#
|
5
|
+
# rubyhexagon is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# rubyhexagon is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with rubyhexagon. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
module E621
|
18
|
+
# Class for post file data. This is mostly an abstraction to have data
|
19
|
+
# structures in a more Ruby like nature.
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
# @author Maxine Michalski
|
23
|
+
# @since 1.0.0
|
24
|
+
class Image
|
25
|
+
# @return [URI] url of file
|
26
|
+
attr_reader :url
|
27
|
+
|
28
|
+
# @return [String] extension of file
|
29
|
+
attr_reader :ext
|
30
|
+
|
31
|
+
# @return [Integer] image/video width
|
32
|
+
attr_reader :width
|
33
|
+
|
34
|
+
# @return [Integer] image/video height
|
35
|
+
attr_reader :height
|
36
|
+
|
37
|
+
# @return [String] MD5 hash sum
|
38
|
+
attr_reader :md5
|
39
|
+
|
40
|
+
# @author Maxine Michalski
|
41
|
+
#
|
42
|
+
# Initializer for a File. This is not a Ruby file class, but an abstraction
|
43
|
+
# of e621 file information.
|
44
|
+
#
|
45
|
+
# @param file [Hash] file information
|
46
|
+
#
|
47
|
+
# @return the object
|
48
|
+
def initialize(file)
|
49
|
+
@url = URI(file[:url])
|
50
|
+
@md5 = File.basename(file[:url]).sub(/\.\w{3,4}$/, '')
|
51
|
+
@ext = file[:ext]
|
52
|
+
@width = file[:width].to_i
|
53
|
+
@height = file[:height].to_i
|
54
|
+
@user_agent = { 'User-Agent' =>
|
55
|
+
"#{E621::NAME}/#{E621::VERSION} (by maxine_red on e621" }
|
56
|
+
end
|
57
|
+
|
58
|
+
# @author Maxine Michalski
|
59
|
+
#
|
60
|
+
# Comparison method to comapre two Image objects (and sub class objects)
|
61
|
+
#
|
62
|
+
# @return [TrueClass, FalseClass]
|
63
|
+
def ==(other)
|
64
|
+
other.is_a?(Image) && @md5 == other.md5
|
65
|
+
end
|
66
|
+
|
67
|
+
# @author Maxine Michalski
|
68
|
+
#
|
69
|
+
# Retrieve data from e621 and save it to file.
|
70
|
+
#
|
71
|
+
# @param dirname [String] path where to save. This needs be an existing
|
72
|
+
# directory. This overwrites existing files.
|
73
|
+
# @raise [ArgumentError] Argument given is not an existing directory
|
74
|
+
def save!(dirname = './')
|
75
|
+
raise ArgumentError, 'Not a directory!' unless File.directory?(dirname)
|
76
|
+
loop do
|
77
|
+
stream = open(@url, @user_agent).read
|
78
|
+
File.open("#{dirname}/#{File.basename(@url.path)}", 'w') do |f|
|
79
|
+
f.print stream
|
80
|
+
end
|
81
|
+
break if Digest::MD5.hexdigest(stream) == @md5
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
class Sample < Image; end
|
86
|
+
|
87
|
+
# Class for post file data. This is mostly an abstraction to have data
|
88
|
+
# structures in a more Ruby like nature.
|
89
|
+
# This class just holds an adapted version of #save!, to handle the case of
|
90
|
+
# preview images having a different MD5 hash sum attribute than they actually
|
91
|
+
# should have.
|
92
|
+
# That is an e621 issue though.
|
93
|
+
#
|
94
|
+
# @api private
|
95
|
+
# @author Maxine Michalski
|
96
|
+
# @since 1.0.0
|
97
|
+
class Preview < Image
|
98
|
+
# @author Maxine Michalski
|
99
|
+
#
|
100
|
+
# Retrieve data from e621 and save it to file.
|
101
|
+
#
|
102
|
+
# @param dirname [String] path where to save. This needs be an existing
|
103
|
+
# directory. This overwrites existing files.
|
104
|
+
# @raise [ArgumentError] Argument given is not an existing directory
|
105
|
+
def save!(dirname = './')
|
106
|
+
raise ArgumentError, 'Not a directory!' unless File.directory?(dirname)
|
107
|
+
File.open("#{dirname}/#{File.basename(@url.path)}", 'w') do |f|
|
108
|
+
f.print open(@url, @user_agent).read
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# Copyright 2014-2018 Maxine Michalski <maxine@furfind.net>
|
2
|
+
#
|
3
|
+
# This file is part of rubyhexagon.
|
4
|
+
#
|
5
|
+
# rubyhexagon is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# rubyhexagon is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with rubyhexagon. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
module E621
|
18
|
+
# Class to hold level information.
|
19
|
+
#
|
20
|
+
# @api private
|
21
|
+
# @author Maxine Michalski
|
22
|
+
# @since 1.0.0
|
23
|
+
class Level
|
24
|
+
# @return [Integer] id of level
|
25
|
+
attr_reader :id
|
26
|
+
|
27
|
+
# @return [String] name of level
|
28
|
+
attr_reader :name
|
29
|
+
|
30
|
+
# @author Maxine Michalski
|
31
|
+
#
|
32
|
+
# Initializer for Level a user can have. This is just to have a more Ruby
|
33
|
+
# like interface to it.
|
34
|
+
#
|
35
|
+
# @param level [Hash] level a user can have.
|
36
|
+
#
|
37
|
+
# @return the object
|
38
|
+
def initialize(level)
|
39
|
+
@id = level
|
40
|
+
@name = if @id.between?(31, 39)
|
41
|
+
[nil, nil, :contributor, :'former staff', :janotor][@id - 30]
|
42
|
+
else
|
43
|
+
%i[unactivated blocked member privileged mod admin][@id / 10]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# @author Maxine Michalski
|
48
|
+
#
|
49
|
+
# Comparison method for Level objects
|
50
|
+
#
|
51
|
+
# @return [TrueClass, FalseClass]
|
52
|
+
def ==(other)
|
53
|
+
other.is_a?(Level) && @id == other.id && @name == other.name
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|