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,78 @@
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
+ # Class to represent post flags
22
+ #
23
+ # @author Maxine Michalski
24
+ # @since 2.0.0
25
+ class Flag
26
+ # @return [Integer] id of flag
27
+ attr_reader :id
28
+
29
+ # @return [Time] creation time of flag
30
+ attr_reader :created_at
31
+ # @return [621::Post] Post this flag is addressed to
32
+ attr_reader :post
33
+ # @return [String] reason for flag
34
+ attr_reader :reason
35
+ # @return [E621::User] User who flagged
36
+ attr_reader :user
37
+
38
+ # @author Maxine Michalski
39
+ #
40
+ # Initializer for flags
41
+ #
42
+ # @param flag [Hash] flag data
43
+ #
44
+ # @return the object
45
+ def initialize(flag)
46
+ unless flag.is_a?(Hash)
47
+ raise ArgumentError, "#{flag.class} is not a Hash"
48
+ end
49
+ unless flag.key?(:id)
50
+ raise ArgumentError, 'Not all required keys available!'
51
+ end
52
+ flag.each do |k, v|
53
+ if %i[id reason].include?(k)
54
+ if k == :id && !(v.is_a?(Integer) && v.positive?)
55
+ raise InvalidIDError, "ID out of range: #{v}"
56
+ end
57
+ instance_variable_set("@#{k}".to_sym, v)
58
+ elsif k == :created_at
59
+ @created_at = Time.at(v)
60
+ elsif k == :post_id
61
+ @post = E621::Post.new(id: v)
62
+ elsif k == :user_id
63
+ @user = E621::User.new(id: v)
64
+ end
65
+ end
66
+ end
67
+
68
+ # @author Maxine Michalski
69
+ #
70
+ # Comparison method for flags
71
+ #
72
+ # @return [TrueClass, FalseClass]
73
+ def ==(other)
74
+ other.is_a?(E621::Post::Flag) && @id == other.id
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,114 @@
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
+ # Class for post file data. This is mostly an abstraction to have data
22
+ # structures in a more Ruby like nature.
23
+ #
24
+ # @api private
25
+ # @author Maxine Michalski
26
+ # @since 1.0.0
27
+ class Image
28
+ # @return [URI] url of file
29
+ attr_reader :url
30
+
31
+ # @return [String] extension of file
32
+ attr_reader :ext
33
+
34
+ # @return [Integer] image/video width
35
+ attr_reader :width
36
+
37
+ # @return [Integer] image/video height
38
+ attr_reader :height
39
+
40
+ # @return [Integer] file size in bytes
41
+ attr_reader :size
42
+
43
+ # @author Maxine Michalski
44
+ #
45
+ # Initializer for an Image.
46
+ #
47
+ # @param image [Hash] image information
48
+ # @option image [String] :url URI location
49
+ # @option image [String] :ext extension string
50
+ # @option image [Integer] :width of image
51
+ # @option image [Integer] :height of image
52
+ # @option image [Integer] :size of image
53
+ #
54
+ # @return the object
55
+ def initialize(image)
56
+ unless image.is_a?(Hash)
57
+ raise ArgumentError, "#{image.class} is not a Hash"
58
+ end
59
+ if image.keys != %i[url ext width height size]
60
+ mis = %i[url ext width height size] - image.keys
61
+ raise ArgumentError, "Missing key#{mis.count > 1 ? 's' : ''}: #{mis}"
62
+ end
63
+ image.each do |k, v|
64
+ if %i[ext width height size].include?(k)
65
+ instance_variable_set("@#{k}".to_sym, v)
66
+ elsif k == :url
67
+ @url = URI.parse(v)
68
+ end
69
+ end
70
+ end
71
+
72
+ # @author Maxine Michalski
73
+ #
74
+ # A convenient function to return both width and height.
75
+ #
76
+ # @return [Array<Integer>]
77
+ def resolution
78
+ [@width, @height]
79
+ end
80
+
81
+ # @author Maxine Michalski
82
+ #
83
+ # A convenient function to return the aspect ratio of a given image.
84
+ #
85
+ # @return [Float]
86
+ def aspect_ratio
87
+ @width / @height.to_f
88
+ end
89
+
90
+ # @author Maxine Michalski
91
+ #
92
+ # Comparison method to comapre two Image objects (and sub class objects)
93
+ #
94
+ # @return [TrueClass, FalseClass]
95
+ def ==(other)
96
+ other.is_a?(Image) && @url == other.url && @size == other.size
97
+ end
98
+ end
99
+
100
+ # class for samples, that is just a copy of Image
101
+ #
102
+ # @api private
103
+ # @author Maxine Michalski
104
+ # @since 1.0,0
105
+ class Sample < Image; end
106
+
107
+ # class for previews, that is just a copy of Image
108
+ #
109
+ # @api private
110
+ # @author Maxine Michalski
111
+ # @since 1.0,0
112
+ class Preview < Image; end
113
+ end
114
+ end
@@ -0,0 +1,74 @@
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
+ # Class to represent post tag_items
22
+ #
23
+ # @author Maxine Michalski
24
+ # @since 2.0.0
25
+ class TagItem
26
+ # @return [Integer] id of post information
27
+ attr_reader :id
28
+ # @return [Integer] id of post information
29
+ attr_reader :created_at
30
+ # @return [Integer] id of post information
31
+ attr_reader :post
32
+ # @return [Integer] id of post information
33
+ attr_reader :tags
34
+ # @return [Integer] id of post information
35
+ attr_reader :sources
36
+
37
+ # @author Maxine Michalski
38
+ #
39
+ # Initializer for tag change items
40
+ #
41
+ # @param tag_item [Hash] tag item data
42
+ #
43
+ # @return the object
44
+ def initialize(tag_item)
45
+ unless tag_item.is_a?(Hash)
46
+ raise ArgumentError, "#{tag_item.class} is not a Hash"
47
+ end
48
+ unless (miss = %i[id created_at post_id tags source] -
49
+ tag_item.keys).empty?
50
+ raise ArgumentError, 'Not all required keys available! '\
51
+ "Missing: #{miss}"
52
+ end
53
+ id = tag_item[:id]
54
+ unless id.is_a?(Integer) && id.positive?
55
+ raise InvalidIDError, "ID out of range: #{id}"
56
+ end
57
+ @id = id
58
+ @created_at = Time.at(tag_item[:created_at])
59
+ @post = E621::Post.new(id: tag_item[:post_id])
60
+ @tags = tag_item[:tags].split(' ').map { |t| E621::Tag.new(name: t) }
61
+ @sources = tag_item[:source].split($INPUT_RECORD_SEPARATOR)
62
+ end
63
+
64
+ # @author Maxine Michalski
65
+ #
66
+ # Comparison method for tag change items
67
+ #
68
+ # @return [TrueClass, FalseClass]
69
+ def ==(other)
70
+ other.is_a?(E621::Post::TagItem) && @id == other.id
71
+ end
72
+ end
73
+ end
74
+ 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
  #
@@ -60,8 +60,8 @@ module Rubyhexagon
60
60
  # This method accepts blocks and only returns one page without blocks
61
61
  #
62
62
  # @return [Array<Post>] an array of posts
63
- def self.list(tags, limit = 320, before_id = 2_000_000)
64
- parameters = { tags: tags, limit: limit, before_id: before_id }
63
+ def self.list(tags, limit = 320)
64
+ parameters = { tags: tags, limit: limit }
65
65
  posts = fetch_posts(parameters)
66
66
  while block_given? && posts != []
67
67
  posts.each { |post| yield post }
@@ -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
  #
@@ -31,73 +31,46 @@ module Rubyhexagon
31
31
  # @return [Integer] number of posts that have this tag assigned to them
32
32
  attr_reader :count
33
33
 
34
- # @return [Type] type of this tag
34
+ # @return [Tag::Type] type of this tag
35
35
  attr_reader :type
36
36
 
37
37
  # @author Maxine Michalski
38
38
  #
39
39
  # Initializer for Tag.
40
40
  #
41
- # @raise InvalidIDError
41
+ # @raise InvalidIDError|ArgumentError
42
42
  #
43
- # @param id [Integer] tag data, fetched from e621
43
+ # @param tag [Hash] tag data
44
44
  #
45
45
  # @return the object
46
- def initialize(id)
47
- unless id.is_a?(Integer) && id.positive?
48
- raise InvalidIDError, "ID out of range: #{id}"
46
+ def initialize(tag)
47
+ raise ArgumentError, "#{tag.class} is not a Hash" unless tag.is_a?(Hash)
48
+ if tag[:id].nil? && tag[:name].nil?
49
+ raise ArgumentError, 'At least :id or :name must be given!'
50
+ end
51
+ tag[:type_locked] = false if tag[:type_locked].nil?
52
+ tag.each do |k, v|
53
+ if %i[id name count].include?(k)
54
+ if k == :id && !(v.is_a?(Integer) && v.positive?)
55
+ raise InvalidIDError, "ID out of range: #{v}"
56
+ end
57
+ instance_variable_set("@#{k}".to_sym, v)
58
+ elsif k == :type
59
+ @type = E621::Tag::Type.new(id: v, locked: tag[:type_locked])
60
+ end
49
61
  end
50
- @id = id
51
- end
52
-
53
- # @author Maxine Michalski
54
- #
55
- # Bang method to fill tag data.
56
- # @notice If the optional parameter is not given, this method makes an API
57
- # call.
58
- #
59
- # @param tag [Hash] optional parameter with API call information
60
- #
61
- # @return [NilClass]
62
- def show!(tag = nil)
63
- tag = API.new.fetch('tag', 'show', id: @id) if tag.nil?
64
- @name = tag[:name]
65
- @count = tag[:count].to_i
66
- @type = (Type.new(tag[:type], tag[:type_locked]) unless tag[:type].nil?)
67
- nil
68
- end
69
-
70
- # @author Maxine Michalski
71
- #
72
- # Method to return a properly filled Tag object.
73
- # @note This makes an additional API call if no argument is given
74
- #
75
- # @param tag [Hash] optional parameter, if information are ready
76
- #
77
- # @return [Tag] Tag filled with all information
78
- def show(tag = nil)
79
- new_tag = Tag.new(@id)
80
- new_tag.show!(tag)
81
- new_tag
82
62
  end
83
63
 
84
64
  # @author Maxine Michalski
85
65
  #
86
66
  # Comparison operator for Tag, to override the default one.
87
- # @note This method looks for same id and same name only.
88
- # @note If there is only a an ID set with one argument, then only compare
89
- # IDs
90
67
  #
91
68
  # @param other [Object] object that should be compared
92
69
  #
93
70
  # @return [TrueClass, FalseClass] test result of comparison
94
71
  def ==(other)
95
72
  return false unless other.is_a?(Tag)
96
- if @name.nil? || other.name.nil?
97
- @id == other.id
98
- else
99
- @id == other.id && @name == other.name
100
- end
73
+ @id == other.id && @name == other.name && @type == other.type
101
74
  end
102
75
  end
103
76
  end
@@ -0,0 +1,87 @@
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 alias information.
22
+ #
23
+ # @author Maxine Michalski
24
+ # @since 2.0.0
25
+ class Alias
26
+ # @return [Integer] id of alias
27
+ attr_reader :id
28
+
29
+ # @return [String] name of alias
30
+ attr_reader :name
31
+
32
+ # @return [E621::Tag] tag this alias is aliased to
33
+ attr_reader :alias_to
34
+
35
+ # @author Maxine Michalski
36
+ #
37
+ # Initializer for Alias.
38
+ #
39
+ # @raise InvalidIDError if alias ID is not valid
40
+ # @raise ArgumentError hash not valid
41
+ #
42
+ # @param ali [Hash] alias data, fetched from e621
43
+ # @option ali [Integer] :id alias ID
44
+ # @option ali [String] :name alias for tag
45
+ # @option ali [Integer] :alias_id ID of tag to alias
46
+ # @option ali [TrueClass|FalseClass] :pending statud
47
+ #
48
+ # @return the object
49
+ def initialize(ali)
50
+ raise ArgumentError, "#{ali.class} is not a Hash" unless ali.is_a?(Hash)
51
+ if ali.keys != %i[id name alias_id pending]
52
+ mis = %i[id name alias_id pending] - ali.keys
53
+ raise ArgumentError, "Missing key#{mis.count > 1 ? 's' : ''}: #{mis}"
54
+ end
55
+ ali.each do |k, v|
56
+ if %i[id name pending].include?(k)
57
+ if k == :id && !(v.is_a?(Integer) && v.positive?)
58
+ raise InvalidIDError, "Invalid id: #{v}"
59
+ end
60
+ instance_variable_set("@#{k}".to_sym, v)
61
+ elsif k == :alias_id
62
+ @alias_to = E621::Tag.new(id: v)
63
+ end
64
+ end
65
+ end
66
+
67
+ # @author Maxine Michalski
68
+ #
69
+ # Comparison method for Types, to give a more meaningful comparison.
70
+ #
71
+ # @return [TrueClass, FalseClass]
72
+ def ==(other)
73
+ other.is_a?(Alias) && @id == other.id
74
+ end
75
+
76
+ # @author Maxine Michalski
77
+ #
78
+ # Check if this alias is pending confirmation.
79
+ #
80
+ # @return [TrueClass] tag alias is pending
81
+ # @return [FalseClass] tag alias is not pending
82
+ def pending?
83
+ @pending
84
+ end
85
+ end
86
+ end
87
+ end