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
@@ -0,0 +1,91 @@
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 Tag
21
+ # Class to hold implication information.
22
+ #
23
+ # @author Maxine Michalski
24
+ # @since 2.0.0
25
+ class Implication
26
+ # @return [Integer] id of implication
27
+ attr_reader :id
28
+
29
+ # @return [E621::Tag] implying tag
30
+ attr_reader :tag
31
+
32
+ # @return [E621::Tag] implied tag
33
+ attr_reader :implies
34
+
35
+ # @author Maxine Michalski
36
+ #
37
+ # Initializer for Implication.
38
+ #
39
+ # @raise InvalidIDError if implication ID is not valid
40
+ # @raise ArgumentError hash not valid
41
+ #
42
+ # @param imply [Hash] implication data, fetched from e621
43
+ # @option imply [Integer] :id implication ID
44
+ # @option imply [Integer] :consequent_id implying tag ID
45
+ # @option imply [Integer] :predicate_id implied tag ID
46
+ # @option imply [TrueClass|FalseClass] :pending statud
47
+ #
48
+ # @return the object
49
+ def initialize(imply)
50
+ unless imply.is_a?(Hash)
51
+ raise ArgumentError, "#{imply.class} is not a Hash"
52
+ end
53
+ if imply.keys != %i[id consequent_id predicate_id pending]
54
+ mis = %i[id consequent_id predicate_id pending] - imply.keys
55
+ raise ArgumentError, "Missing key#{mis.count > 1 ? 's' : ''}: #{mis}"
56
+ end
57
+ imply.each do |k, v|
58
+ if %i[id pending].include?(k)
59
+ if k == :id && !(v.is_a?(Integer) && v.positive?)
60
+ raise InvalidIDError, "Invalid id: #{v}"
61
+ end
62
+ instance_variable_set("@#{k}".to_sym, v)
63
+ elsif k == :consequent_id
64
+ @tag = E621::Tag.new(id: v)
65
+ elsif k == :predicate_id
66
+ @implies = E621::Tag.new(id: v)
67
+ end
68
+ end
69
+ end
70
+
71
+ # @author Maxine Michalski
72
+ #
73
+ # Comparison method for Types, to give a more meaningful comparison.
74
+ #
75
+ # @return [TrueClass, FalseClass]
76
+ def ==(other)
77
+ other.is_a?(Implication) && @id == other.id
78
+ end
79
+
80
+ # @author Maxine Michalski
81
+ #
82
+ # Check if this implication is pending confirmation.
83
+ #
84
+ # @return [TrueClass] tag implication is pending
85
+ # @return [FalseClass] tag implication is not pending
86
+ def pending?
87
+ @pending
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,79 @@
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 Tag
21
+ # Class to hold type information.
22
+ #
23
+ # @api private
24
+ # @author Maxine Michalski
25
+ # @since 1.0.0
26
+ class Type
27
+ # @return [Integer] id of type
28
+ attr_reader :id
29
+
30
+ # @return [String] name of type
31
+ attr_reader :name
32
+
33
+ # @author Maxine Michalski
34
+ #
35
+ # Initializer for Type.
36
+ #
37
+ # @raise ArgumentError if type ID is not valid
38
+ #
39
+ # @param type [Hash] type data, fetched from e621
40
+ # @option type [Integer] :id Type ID (can be one of 0, 1, 3, 4 or 5
41
+ # @option locked [TrueClass|FalseClass] :locked status
42
+ #
43
+ # @return the object
44
+ def initialize(type)
45
+ unless type.is_a?(Hash)
46
+ raise ArgumentError, "#{type.class} is not a Hash"
47
+ end
48
+ raise ArgumentError, 'Missing :locked key' if type[:locked].nil?
49
+ unless [0, 1, 3, 4, 5].include?(type[:id])
50
+ raise InvalidIDError, "Unkown type id: #{type[:id].inspect}"
51
+ end
52
+ @id = type[:id]
53
+ @name = [:general, :artist, nil, :copyright, :character,
54
+ :species][@id]
55
+ @locked = type[:locked] ? true : false
56
+ end
57
+
58
+ # @author Maxine Michalski
59
+ #
60
+ # Comparison method for Types, to give a more meaningful comparison.
61
+ #
62
+ # @return [TrueClass, FalseClass]
63
+ def ==(other)
64
+ other.is_a?(Type) && @id == other.id && @name == other.name &&
65
+ @locked == other.locked?
66
+ end
67
+
68
+ # @author Maxine Michalski
69
+ #
70
+ # Check if this type is locked for the tag who has it assigned.
71
+ #
72
+ # @return [TrueClass] tag type is locked
73
+ # @return [FalseClass] tag type is not locked
74
+ def locked?
75
+ @locked
76
+ end
77
+ end
78
+ end
79
+ 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
  #
@@ -36,6 +36,12 @@ module Rubyhexagon
36
36
  # @return [Time] registration time of this user
37
37
  attr_reader :created_at
38
38
 
39
+ # @return [E621::Post] avatar set by user
40
+ attr_reader :avatar
41
+
42
+ # @return [Array<E621::Tag>] an array of artist tags, associated with user
43
+ attr_reader :artist_tags
44
+
39
45
  # @author Maxine Michalski
40
46
  #
41
47
  # Initializer for User.
@@ -44,30 +50,22 @@ module Rubyhexagon
44
50
  #
45
51
  # @return the object
46
52
  def initialize(user)
47
- @id = user[:id].to_i
48
- @name = user[:name]
49
- end
50
-
51
- # @author Maxine Michalski
52
- #
53
- # Fill this object with user data.
54
- def show!
55
- user = API.new.fetch('user', 'show', id: @id)
56
- @id = user[:id].to_i
57
- @name = user[:name]
58
- @level = Level.new(user[:level].to_i)
59
- @created_at = Time.parse(user[:created_at])
60
- end
61
-
62
- # @author Maxine Michalski
63
- #
64
- # Returns a filled User object
65
- #
66
- # @return [User] filled out user object
67
- def show
68
- user = User.new(id: @id, name: @name)
69
- user.show!
70
- user
53
+ raise ArgumentError, "#{user.class} is not a Hash" unless user.is_a?(Hash)
54
+ raise ArgumentError, 'Hash must include :id' if user[:id].nil?
55
+ user.each do |k, v|
56
+ if %i[id name].include?(k)
57
+ if k == :id && !(v.is_a?(Integer) && v.positive?)
58
+ raise InvalidIDError, "ID out of range: #{v}"
59
+ end
60
+ instance_variable_set("@#{k}".to_sym, v)
61
+ elsif %i[created_at].include?(k)
62
+ instance_variable_set("@#{k}".to_sym, Time.parse(v))
63
+ elsif k == :artist_tags
64
+ @artist_tags = v.map { |t| E621::Tag.new(name: t) }
65
+ elsif k == :avatar_id
66
+ @avatar = E621::Post.new(id: v)
67
+ end
68
+ end
71
69
  end
72
70
 
73
71
  # @author Maxine Michalski
@@ -76,11 +74,7 @@ module Rubyhexagon
76
74
  #
77
75
  # @return [TrueClass, FalseClass]
78
76
  def ==(other)
79
- if @name.nil?
80
- other.is_a?(User) && @id == other.id
81
- else
82
- other.is_a?(User) && @id == other.id && @name == other.name
83
- end
77
+ other.is_a?(User) && @id == other.id
84
78
  end
85
79
  end
86
80
  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
+ class User
21
+ # Class to hold level information.
22
+ #
23
+ # @api private
24
+ # @author Maxine Michalski
25
+ # @since 1.0.0
26
+ class Level
27
+ # @return [Integer] id of level
28
+ attr_reader :id
29
+
30
+ # @return [String] name of level
31
+ attr_reader :name
32
+
33
+ # @author Maxine Michalski
34
+ #
35
+ # Initializer for Level a user can have. This is just to have a more Ruby
36
+ # like interface to it.
37
+ #
38
+ # @param level [Hash] level a user can have.
39
+ #
40
+ # @return the object
41
+ def initialize(level)
42
+ raise ArgumentError, 'No has given.' unless level.is_a?(Hash)
43
+ raise ArgumentError, 'Hash requires an :id key' if level[:id].nil?
44
+ unless [0, 10, 20, 30, 32, 33, 34, 40, 50].include?(level[:id])
45
+ raise InvalidIDError, "Unknown level ID: #{level[:id]}"
46
+ end
47
+ @id = level[:id]
48
+ @name = if @id.between?(31, 39)
49
+ [nil, nil, :contributor, :former_staff, :janitor][@id - 30]
50
+ else
51
+ %i[unactivated blocked member privileged mod admin][@id / 10]
52
+ end
53
+ end
54
+
55
+ # @author Maxine Michalski
56
+ #
57
+ # Comparison method for Level objects
58
+ #
59
+ # @return [TrueClass, FalseClass]
60
+ def ==(other)
61
+ other.is_a?(Level) && @id == other.id && @name == other.name
62
+ end
63
+
64
+ # @author Maxine Michalski
65
+ #
66
+ # Test function for level names.
67
+ #
68
+ # @return [TrueClass|FalseClass]
69
+ def test
70
+ __callee__.to_s.sub(/\?/, '').to_sym == @name
71
+ end
72
+ # @see test
73
+ alias unactivated? test
74
+ # @see test
75
+ alias blocked? test
76
+ # @see test
77
+ alias member? test
78
+ # @see test
79
+ alias privileged? test
80
+ # @see test
81
+ alias contributor? test
82
+ # @see test
83
+ alias former_staff? test
84
+ # @see test
85
+ alias janitor? test
86
+ # @see test
87
+ alias mod? test
88
+ # @see test
89
+ alias admin? test
90
+ end
91
+ end
92
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubyhexagon
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.4
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maxine Michalski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-11 00:00:00.000000000 Z
11
+ date: 2020-01-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -31,23 +31,32 @@ extensions: []
31
31
  extra_rdoc_files: []
32
32
  files:
33
33
  - lib/rubyhexagon.rb
34
+ - lib/rubyhexagon/api.rb
35
+ - lib/rubyhexagon/api/artist.rb
36
+ - lib/rubyhexagon/api/note.rb
37
+ - lib/rubyhexagon/api/pool.rb
38
+ - lib/rubyhexagon/api/post.rb
39
+ - lib/rubyhexagon/api/post/flag.rb
40
+ - lib/rubyhexagon/api/post/tag_item.rb
41
+ - lib/rubyhexagon/api/tag.rb
42
+ - lib/rubyhexagon/api/tag/alias.rb
43
+ - lib/rubyhexagon/api/tag/implication.rb
44
+ - lib/rubyhexagon/api/user.rb
34
45
  - lib/rubyhexagon/artist.rb
35
46
  - lib/rubyhexagon/error.rb
36
- - lib/rubyhexagon/helper/api.rb
37
- - lib/rubyhexagon/image.rb
38
- - lib/rubyhexagon/level.rb
39
- - lib/rubyhexagon/login.rb
47
+ - lib/rubyhexagon/note.rb
40
48
  - lib/rubyhexagon/pool.rb
41
49
  - lib/rubyhexagon/post.rb
42
- - lib/rubyhexagon/search/flag_history.rb
43
- - lib/rubyhexagon/search/pools.rb
50
+ - lib/rubyhexagon/post/flag.rb
51
+ - lib/rubyhexagon/post/image.rb
52
+ - lib/rubyhexagon/post/tag_item.rb
44
53
  - lib/rubyhexagon/search/posts.rb
45
- - lib/rubyhexagon/search/tag_history.rb
46
- - lib/rubyhexagon/search/tags.rb
47
54
  - lib/rubyhexagon/tag.rb
48
- - lib/rubyhexagon/tag_change.rb
49
- - lib/rubyhexagon/type.rb
55
+ - lib/rubyhexagon/tag/alias.rb
56
+ - lib/rubyhexagon/tag/implication.rb
57
+ - lib/rubyhexagon/tag/type.rb
50
58
  - lib/rubyhexagon/user.rb
59
+ - lib/rubyhexagon/user/level.rb
51
60
  homepage: https://github.com/maxine-red/rubyhexagon
52
61
  licenses:
53
62
  - GPL-3.0
@@ -68,7 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
68
77
  version: '0'
69
78
  requirements: []
70
79
  rubyforge_project:
71
- rubygems_version: 2.7.7
80
+ rubygems_version: 2.5.2.1
72
81
  signing_key:
73
82
  specification_version: 4
74
83
  summary: Rubyhexagon, Ruby bindings for e621.
@@ -1,99 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright 2014-2018 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
- #
17
- # You should have received a copy of the GNU General Public License
18
- # along with rubyhexagon. If not, see <http://www.gnu.org/licenses/>.
19
-
20
- module Rubyhexagon
21
- # An interface class, to unify calls from other code to e621 [dot] net.
22
- # This class handles rate limiting, as well as provides a more uniform
23
- # approach in making requests.
24
- # It also ensures that a proper user agent is sent, as required by the e621
25
- # API.
26
- #
27
- # @api private
28
- # @author Maxine Michalski
29
- # @since 0.4.3
30
- class API
31
- # User agent, used to identify this gem against e621.
32
- #
33
- # @return [Hash] hash that can be used with open-uri
34
- attr_reader :user_agent
35
-
36
- # @author Maxine Michalski
37
- #
38
- # Initializer for API. All methods are instance methods.
39
- #
40
- # @return the object
41
- def initialize
42
- @user_agent = { 'User-Agent' =>
43
- "#{Rubyhexagon::NAME}/#{Rubyhexagon::VERSION} "\
44
- '(by maxine_red on e621' }
45
- @http = Net::HTTP.new('e621.net', 443)
46
- @http.use_ssl = true
47
- lock_path = '/tmp/rubyhexagon.lock'
48
- @lock_file = File.open(lock_path, 'a', 0o666)
49
- end
50
-
51
- # @author Maxine Michalski
52
- #
53
- # @param noun [String] the e621 noun (post, tag, user, artist, etc.)
54
- # @param action [String] action to be performed on noun (list, show, etc.)
55
- # @param query [Hash] a hash with extra information, which is dependent on
56
- # noun and action
57
- #
58
- # Fetches information from e621 and returns data to caller. This also takes
59
- # into account rate limiting.
60
- #
61
- # @return [Hash] JSON parsed response.
62
- def fetch(noun, action, query, method = 'GET')
63
- if Login.instance.setup?
64
- query.store(:login, Login.instance.login)
65
- query.store(:password_hash, Login.instance.password_hash)
66
- end
67
- query = query.map { |k, v| "#{k}=#{v}" }.join('&')
68
- lock do
69
- data = if method == 'GET'
70
- @http.get("/#{noun}/#{action}.json?#{query}", @user_agent).body
71
- else
72
- @http.post("/#{noun}/#{action}.json", query, @user_agent).body
73
- end
74
- JSON.parse(data, symbolize_names: true)
75
- end
76
- end
77
-
78
- # @author Maxine Michalski
79
- #
80
- # (see #fetch)
81
- # A wrapper for actual requests, to minimize method length.
82
- def lock
83
- @lock_file.flock(File::LOCK_EX)
84
- @lock_file.truncate(0)
85
- @lock_file.print $PROCESS_ID
86
- begin
87
- s = Time.now
88
- data = yield
89
- # There is a hard limit of 2 requests per second, but to be nice we wait
90
- # a whole second between requests.
91
- w = 1 - (Time.now - s)
92
- sleep w if w.positive?
93
- ensure
94
- @lock_file.flock(File::LOCK_UN)
95
- end
96
- data
97
- end
98
- end
99
- end