rubyhexagon 1.6.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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