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