rubyhexagon 1.6.4 → 2.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.
Files changed (38) hide show
  1. checksums.yaml +5 -5
  2. data/lib/rubyhexagon.rb +34 -18
  3. data/lib/rubyhexagon/api.rb +96 -0
  4. data/lib/rubyhexagon/{login.rb → api/artist.rb} +9 -19
  5. data/lib/rubyhexagon/api/note.rb +50 -0
  6. data/lib/rubyhexagon/api/pool.rb +51 -0
  7. data/lib/rubyhexagon/api/post.rb +92 -0
  8. data/lib/rubyhexagon/api/post/flag.rb +36 -0
  9. data/lib/rubyhexagon/api/post/tag_item.rb +36 -0
  10. data/lib/rubyhexagon/api/tag.rb +65 -0
  11. data/lib/rubyhexagon/api/tag/alias.rb +41 -0
  12. data/lib/rubyhexagon/api/tag/implication.rb +41 -0
  13. data/lib/rubyhexagon/api/user.rb +52 -0
  14. data/lib/rubyhexagon/artist.rb +44 -32
  15. data/lib/rubyhexagon/error.rb +4 -5
  16. data/lib/rubyhexagon/note.rb +112 -0
  17. data/lib/rubyhexagon/pool.rb +22 -50
  18. data/lib/rubyhexagon/post.rb +142 -161
  19. data/lib/rubyhexagon/post/flag.rb +78 -0
  20. data/lib/rubyhexagon/post/image.rb +114 -0
  21. data/lib/rubyhexagon/post/tag_item.rb +74 -0
  22. data/lib/rubyhexagon/search/posts.rb +3 -3
  23. data/lib/rubyhexagon/tag.rb +20 -47
  24. data/lib/rubyhexagon/tag/alias.rb +87 -0
  25. data/lib/rubyhexagon/tag/implication.rb +91 -0
  26. data/lib/rubyhexagon/tag/type.rb +79 -0
  27. data/lib/rubyhexagon/user.rb +24 -30
  28. data/lib/rubyhexagon/user/level.rb +92 -0
  29. metadata +22 -13
  30. data/lib/rubyhexagon/helper/api.rb +0 -99
  31. data/lib/rubyhexagon/image.rb +0 -122
  32. data/lib/rubyhexagon/level.rb +0 -58
  33. data/lib/rubyhexagon/search/flag_history.rb +0 -62
  34. data/lib/rubyhexagon/search/pools.rb +0 -62
  35. data/lib/rubyhexagon/search/tag_history.rb +0 -61
  36. data/lib/rubyhexagon/search/tags.rb +0 -139
  37. data/lib/rubyhexagon/tag_change.rb +0 -69
  38. data/lib/rubyhexagon/type.rb +0 -72
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: e2917bb296b7de0e3037e5d5bcc42c35453f07a9857e06e317b2612164b3e216
4
- data.tar.gz: f6af1287f5c4a38251b3e47656655e45d677f40a0d2aefab0cdadf54525aac74
2
+ SHA1:
3
+ metadata.gz: dd11e83da3191060c9511173288f9af58a6750c9
4
+ data.tar.gz: eaa6a515b4ad4d00d1dff2a0766c735b7873cfa6
5
5
  SHA512:
6
- metadata.gz: f15e5974d2fbefb56b0a509dd34e55611e8209a1aab23b4ef84dfd24c0f5f5d3d3abacf0bd1c462ab66c653886c0970974fc31097d140e0804d72b5ee49e8e6d
7
- data.tar.gz: 08e271ac11e45c9430d39047a0a25d335a3bdf3ce18cab4d2170334842c8c23e1645ed0c418934af1005709e1a01ef17ed5542bb5296e7610c43669337d1c4c2
6
+ metadata.gz: 4aedb99ec447252a7b9abf1e327d339b55ba0472f15606f0bdee32fa968bf092e9deca3025a64413b1179ec089bb9567ffa72fb26632dd171dcecc20f15651a4
7
+ data.tar.gz: f1923e822369f550161992477889872e8659a25c1f8817d5c373b89e68b16b20fe98a3df3acdb2026fcc9151e391dbb61471289d1f8411f3f928c29681e568c3
data/lib/rubyhexagon.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright 2014-2018 Maxine Michalski <maxine@furfind.net>
3
+ # Copyright 2014-2018, 2020 Maxine Michalski <maxine@furfind.net>
4
4
  #
5
5
  # This file is part of rubyhexagon.
6
6
  #
@@ -20,34 +20,38 @@
20
20
  require 'net/http'
21
21
  require 'uri'
22
22
  require 'json'
23
- require 'digest/md5'
23
+ require 'cgi'
24
+ require 'tempfile'
24
25
 
25
- require_relative 'rubyhexagon/helper/api'
26
26
  require_relative 'rubyhexagon/error'
27
- require_relative 'rubyhexagon/user'
28
- require_relative 'rubyhexagon/tag'
27
+
29
28
  require_relative 'rubyhexagon/artist'
30
- require_relative 'rubyhexagon/type'
31
- require_relative 'rubyhexagon/image'
32
- require_relative 'rubyhexagon/level'
29
+ require_relative 'rubyhexagon/note'
33
30
  require_relative 'rubyhexagon/post'
31
+ require_relative 'rubyhexagon/post/flag'
32
+ require_relative 'rubyhexagon/post/tag_item'
34
33
  require_relative 'rubyhexagon/pool'
35
- require_relative 'rubyhexagon/login'
36
- require_relative 'rubyhexagon/tag_change'
37
- require_relative 'rubyhexagon/search/posts'
38
- require_relative 'rubyhexagon/search/pools'
39
- require_relative 'rubyhexagon/search/tags'
40
- require_relative 'rubyhexagon/search/flag_history'
41
- require_relative 'rubyhexagon/search/tag_history'
34
+ require_relative 'rubyhexagon/post/image'
35
+ require_relative 'rubyhexagon/tag'
36
+ require_relative 'rubyhexagon/tag/alias'
37
+ require_relative 'rubyhexagon/tag/implication'
38
+ require_relative 'rubyhexagon/tag/type'
39
+ require_relative 'rubyhexagon/user'
40
+ require_relative 'rubyhexagon/user/level'
42
41
 
43
42
  # Namespace for all classes in this gem.
44
43
  # @author Maxine Michalski
45
44
  # @since 0.4.3
46
45
  module Rubyhexagon
47
- MAJOR = 1
48
- MINOR = 6
49
- PATCH = 4
46
+ # Major version part
47
+ MAJOR = 2
48
+ # Minor version part
49
+ MINOR = 0
50
+ # Patch version part
51
+ PATCH = 0
52
+ # Name of gem
50
53
  NAME = 'rubyhexagon'
54
+ # Full version string
51
55
  VERSION = "#{MAJOR}.#{MINOR}.#{PATCH}"
52
56
  end
53
57
 
@@ -55,3 +59,15 @@ end
55
59
  # break old code.
56
60
  # Both module names can be used.
57
61
  E621 = Rubyhexagon
62
+
63
+ require_relative 'rubyhexagon/api'
64
+ require_relative 'rubyhexagon/api/artist'
65
+ require_relative 'rubyhexagon/api/note'
66
+ require_relative 'rubyhexagon/api/post'
67
+ require_relative 'rubyhexagon/api/post/flag'
68
+ require_relative 'rubyhexagon/api/post/tag_item'
69
+ require_relative 'rubyhexagon/api/pool'
70
+ require_relative 'rubyhexagon/api/tag'
71
+ require_relative 'rubyhexagon/api/tag/alias'
72
+ require_relative 'rubyhexagon/api/tag/implication'
73
+ require_relative 'rubyhexagon/api/user'
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2014-2018, 2020 Maxine Michalski <maxine@furfind.net>
4
+ #
5
+ # This file is part of rubyhexagon.
6
+ #
7
+ # rubyhexagon is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # rubyhexagon is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
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
+
19
+ module Rubyhexagon
20
+ # General API helper class.
21
+ #
22
+ # Not to be used directly!
23
+ #
24
+ # @api private
25
+ # @author Maxine Michalski
26
+ # @since 0.4.3
27
+ class API
28
+ # User agent to send with every request
29
+ USER_AGENT = { 'User-Agent' =>
30
+ "#{Rubyhexagon::NAME}/#{Rubyhexagon::VERSION} "\
31
+ '(by maxine_red on e621' }.freeze
32
+ # Lock path for locking file. This is needed to ensure API request limits.
33
+ LOCK_PATH = '/var/lock/rubyhexagon.lock'
34
+
35
+ # @author Maxine Michalski
36
+ #
37
+ # Fetch data from the e621 web interface
38
+ #
39
+ # @param noun [Symbol] first part of interface, like 'post', 'tag', etc.
40
+ # @param action [Symbol] second part of interface, like 'show', 'index'
41
+ # @param query [Hash] query hash for interface
42
+ #
43
+ # @return [Hash|Array] A decoded JSON string
44
+ def self.fetch(noun, action, query)
45
+ unless noun.is_a?(Symbol) && action.is_a?(Symbol) && query.is_a?(Hash)
46
+ raise ArgumentError, 'Two symbols and a hash are required!'
47
+ end
48
+ http = Net::HTTP.new('e621.net', 443)
49
+ http.use_ssl = true
50
+ query = query.map { |k, v| "#{k}=#{v}" }.join('&')
51
+ lock do
52
+ data = http.get("/#{noun}/#{action}.json?#{query}", USER_AGENT).body
53
+ JSON.parse(data, symbolize_names: true)
54
+ end
55
+ end
56
+
57
+ # @author Maxine Michalski
58
+ #
59
+ # Download from a URI, needed for image download
60
+ #
61
+ # @param uri [URI] URI to download
62
+ #
63
+ # @return [Tempfile] A temporary file, that holds downloaded data.
64
+ def self.download(uri)
65
+ raise ArgumentError, 'URI required' unless uri.is_a?(URI)
66
+ http = Net::HTTP.new(uri.host, uri.port)
67
+ http.use_ssl = true if uri.port == 443
68
+ temp = Tempfile.new(File.basename(uri.path))
69
+ temp.write(http.get("#{uri.path}?#{uri.query}", USER_AGENT).body)
70
+ temp.rewind
71
+ temp
72
+ end
73
+
74
+ # @author Maxine Michalski
75
+ #
76
+ # A method to make locking easier and that ensures 1 request per scondd.
77
+ #
78
+ # @return [Object]
79
+ def self.lock
80
+ lock_file = File.open(LOCK_PATH, 'a', 0o666)
81
+ lock_file.flock(File::LOCK_EX)
82
+ lock_file.truncate(0)
83
+ lock_file.print $PROCESS_ID
84
+ begin
85
+ data = yield
86
+ sleep 1
87
+ ensure
88
+ lock_file.flock(File::LOCK_UN)
89
+ lock_file.close
90
+ end
91
+ data
92
+ end
93
+ private_class_method :new
94
+ private_class_method :lock
95
+ end
96
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright 2014-2018 Maxine Michalski <maxine@furfind.net>
3
+ # Copyright 2014-2018, 2020 Maxine Michalski <maxine@furfind.net>
4
4
  #
5
5
  # This file is part of rubyhexagon.
6
6
  #
@@ -13,30 +13,20 @@
13
13
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
14
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
15
  # GNU General Public License for more details.
16
- #
17
16
  # You should have received a copy of the GNU General Public License
18
17
  # along with rubyhexagon. If not, see <http://www.gnu.org/licenses/>.
19
18
 
20
- require 'singleton'
21
-
22
19
  module Rubyhexagon
23
- # A singleton class to store API login credentials. This is used to make sure
24
- # that those data can be used on outgoing API calls, but also centralizes
25
- # their use.
20
+ # A class to interact with the e621 web interface.
26
21
  #
27
22
  # @author Maxine Michalski
28
- # @since 1.5.0
29
- class Login
30
- include Singleton
31
-
32
- # @return [String] login name for user
33
- attr_accessor :login
34
-
35
- # @return [String] api key for calls
36
- attr_accessor :password_hash
37
-
38
- def setup?
39
- !(@login.nil? || @password_hash.nil?)
23
+ # @since 2.0.0
24
+ class Artist
25
+ def self.list(query)
26
+ raise ArgumentError, 'A Hash is required' unless query.is_a?(Hash)
27
+ E621::API.fetch(:artist, :index, query).map do |artist|
28
+ new(artist)
29
+ end
40
30
  end
41
31
  end
42
32
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2014-2018, 2020 Maxine Michalski <maxine@furfind.net>
4
+ #
5
+ # This file is part of rubyhexagon.
6
+ #
7
+ # rubyhexagon is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # rubyhexagon is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
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
+
19
+ module Rubyhexagon
20
+ # A class to interact with the e621 web interface.
21
+ #
22
+ # @author Maxine Michalski
23
+ # @since 2.0.0
24
+ class Note
25
+ def self.list(post)
26
+ unless post.is_a?(Hash) || post.is_a?(E621::Post)
27
+ raise ArgumentError, 'A Hash or Post object is required'
28
+ end
29
+ post.store(:post_id, post.delete(:id)) if post.is_a?(Hash)
30
+ post = { post_id: post.id } if post.is_a?(E621::Post)
31
+ E621::API.fetch(:note, :index, post).map do |note|
32
+ new(note)
33
+ end
34
+ end
35
+
36
+ def self.search(query)
37
+ raise ArgumentError, 'A Hash is required' unless query.is_a?(Hash)
38
+ E621::API.fetch(:note, :search, query).map do |note|
39
+ new(note)
40
+ end
41
+ end
42
+
43
+ def self.history(query)
44
+ raise ArgumentError, 'A Hash is required' unless query.is_a?(Hash)
45
+ E621::API.fetch(:note, :history, query).map do |note|
46
+ new(note)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2014-2018, 2020 Maxine Michalski <maxine@furfind.net>
4
+ #
5
+ # This file is part of rubyhexagon.
6
+ #
7
+ # rubyhexagon is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # rubyhexagon is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
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
+
19
+ module Rubyhexagon
20
+ # A class to interact with the e621 web interface.
21
+ #
22
+ # @author Maxine Michalski
23
+ # @since 1.4.0
24
+ class Pool
25
+ def self.show(pool, page = nil)
26
+ unless (pool.is_a?(Hash) && pool[:id].is_a?(Integer)) ||
27
+ pool.is_a?(E621::Pool)
28
+ raise ArgumentError, 'A Hash or pool object are required'
29
+ end
30
+ id = pool.is_a?(Hash) ? pool[:id] : pool.id
31
+ page = page.nil? ? pool[:page] : page[:page]
32
+ E621::API.fetch(:pool, :show, id: id, page: page)[:posts].map do |post|
33
+ E621::Post.new(post)
34
+ end
35
+ end
36
+
37
+ def self.list(query)
38
+ raise ArgumentError, 'A Hash is required' unless query.is_a?(Hash)
39
+ E621::API.fetch(:pool, :index, query).map do |pool|
40
+ new(pool)
41
+ end
42
+ end
43
+
44
+ def show(page)
45
+ page = page[:page]
46
+ E621::API.fetch(:pool, :show, id: @id, page: page)[:posts].map do |post|
47
+ E621::Post.new(post)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2014-2018, 2020 Maxine Michalski <maxine@furfind.net>
4
+ #
5
+ # This file is part of rubyhexagon.
6
+ #
7
+ # rubyhexagon is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # rubyhexagon is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
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
+
19
+ module Rubyhexagon
20
+ # A class to interact with the e621 web interface.
21
+ #
22
+ # @author Maxine Michalski
23
+ # @since 1.4.0
24
+ class Post
25
+ # @author Maxine Michalski
26
+ #
27
+ # Fetch data for post
28
+ #
29
+ # @param user [Hash|E621::Post] User data to fetch from
30
+ #
31
+ # @return [E621::Post]
32
+ def self.show(post)
33
+ unless (post.is_a?(Hash) && post[:id].is_a?(Integer)) ||
34
+ post.is_a?(E621::Post)
35
+ raise ArgumentError, 'A Hash or post data object are required'
36
+ end
37
+ id = post.is_a?(Hash) ? post[:id] : post.id
38
+ new(E621::API.fetch(:post, :show, id: id))
39
+ end
40
+
41
+ def self.tags(post)
42
+ unless (post.is_a?(Hash) && post[:id].is_a?(Integer)) ||
43
+ post.is_a?(E621::Post)
44
+ raise ArgumentError, 'A Hash or post data object are required'
45
+ end
46
+ id = post.is_a?(Hash) ? post[:id] : post.id
47
+ E621::API.fetch(:post, :tags, id: id).map do |t|
48
+ E621::Tag.new(t)
49
+ end
50
+ end
51
+
52
+ def self.list(query)
53
+ raise ArgumentError, 'A Hash is required' unless query.is_a?(Hash)
54
+ E621::API.fetch(:post, :index, query).map do |post|
55
+ new(post)
56
+ end
57
+ end
58
+
59
+ def self.deleted(query)
60
+ raise ArgumentError, 'A Hash is required' unless query.is_a?(Hash)
61
+ E621::API.fetch(:post, :deleted_index, query).map do |post|
62
+ new(post)
63
+ end
64
+ end
65
+
66
+ def self.popular_by(period)
67
+ unless %i[day week month].include?(period)
68
+ raise ArgumentError, 'Period must be day, week or month'
69
+ end
70
+ E621::API.fetch(:post, "popular_by_#{period}".to_sym, {}).map do |post|
71
+ new(post)
72
+ end
73
+ end
74
+
75
+ def show
76
+ E621::Post.new(E621::API.fetch(:post, :show, id: @id))
77
+ end
78
+
79
+ def download(which)
80
+ unless %i[image preview sample].include?(which)
81
+ raise ArgumentError, 'Unsupported doanload'
82
+ end
83
+ E621::API.download(__send__(which).url)
84
+ end
85
+
86
+ def notes
87
+ E621::API.fetch(:note, :index, post_id: @id).map do |n|
88
+ E621::Note.new(n)
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2014-2018, 2020 Maxine Michalski <maxine@furfind.net>
4
+ #
5
+ # This file is part of rubyhexagon.
6
+ #
7
+ # rubyhexagon is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # rubyhexagon is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
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
+
19
+ module Rubyhexagon
20
+ class Post
21
+ # A class to interact with the e621 web interface.
22
+ #
23
+ # @author Maxine Michalski
24
+ # @since 2.0.0
25
+ class Flag
26
+ def self.list(query)
27
+ unless query.is_a?(Hash)
28
+ raise ArgumentError, 'A Hash or Post object is required'
29
+ end
30
+ E621::API.fetch(:post_flag_history, :index, query).map do |note|
31
+ new(note)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end