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.
- checksums.yaml +5 -5
- data/lib/rubyhexagon.rb +34 -18
- data/lib/rubyhexagon/api.rb +96 -0
- data/lib/rubyhexagon/{login.rb → api/artist.rb} +9 -19
- data/lib/rubyhexagon/api/note.rb +50 -0
- data/lib/rubyhexagon/api/pool.rb +51 -0
- data/lib/rubyhexagon/api/post.rb +92 -0
- data/lib/rubyhexagon/api/post/flag.rb +36 -0
- data/lib/rubyhexagon/api/post/tag_item.rb +36 -0
- data/lib/rubyhexagon/api/tag.rb +65 -0
- data/lib/rubyhexagon/api/tag/alias.rb +41 -0
- data/lib/rubyhexagon/api/tag/implication.rb +41 -0
- data/lib/rubyhexagon/api/user.rb +52 -0
- data/lib/rubyhexagon/artist.rb +44 -32
- data/lib/rubyhexagon/error.rb +4 -5
- data/lib/rubyhexagon/note.rb +112 -0
- data/lib/rubyhexagon/pool.rb +22 -50
- data/lib/rubyhexagon/post.rb +142 -161
- data/lib/rubyhexagon/post/flag.rb +78 -0
- data/lib/rubyhexagon/post/image.rb +114 -0
- data/lib/rubyhexagon/post/tag_item.rb +74 -0
- data/lib/rubyhexagon/search/posts.rb +3 -3
- data/lib/rubyhexagon/tag.rb +20 -47
- data/lib/rubyhexagon/tag/alias.rb +87 -0
- data/lib/rubyhexagon/tag/implication.rb +91 -0
- data/lib/rubyhexagon/tag/type.rb +79 -0
- data/lib/rubyhexagon/user.rb +24 -30
- data/lib/rubyhexagon/user/level.rb +92 -0
- metadata +22 -13
- data/lib/rubyhexagon/helper/api.rb +0 -99
- data/lib/rubyhexagon/image.rb +0 -122
- data/lib/rubyhexagon/level.rb +0 -58
- data/lib/rubyhexagon/search/flag_history.rb +0 -62
- data/lib/rubyhexagon/search/pools.rb +0 -62
- data/lib/rubyhexagon/search/tag_history.rb +0 -61
- data/lib/rubyhexagon/search/tags.rb +0 -139
- data/lib/rubyhexagon/tag_change.rb +0 -69
- data/lib/rubyhexagon/type.rb +0 -72
data/lib/rubyhexagon/pool.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
|
#
|
@@ -38,8 +38,11 @@ module Rubyhexagon
|
|
38
38
|
# @return [String] returns a description of the current pool
|
39
39
|
attr_reader :description
|
40
40
|
|
41
|
-
# @return [
|
42
|
-
attr_reader :
|
41
|
+
# @return [Integer] returns number of posts inside pool
|
42
|
+
attr_reader :post_count
|
43
|
+
|
44
|
+
# @return [E621::User] returns the user, who has created this pool
|
45
|
+
attr_reader :creator
|
43
46
|
|
44
47
|
# @return [Array<Post>] returns an array of posts, that belong to this pool
|
45
48
|
attr_reader :posts
|
@@ -48,52 +51,26 @@ module Rubyhexagon
|
|
48
51
|
#
|
49
52
|
# Initializer for Pool objects
|
50
53
|
#
|
51
|
-
# @param
|
54
|
+
# @param pool [Hash] Pool information
|
52
55
|
#
|
53
56
|
# @return the object
|
54
|
-
def initialize(
|
55
|
-
unless
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
# @author Maxine Michalski
|
62
|
-
#
|
63
|
-
# @param pool [Hash] pool data, if present
|
64
|
-
#
|
65
|
-
# Fetch data from e621 to current post id
|
66
|
-
def show!(pool = nil)
|
67
|
-
@posts = []
|
68
|
-
if pool.nil?
|
69
|
-
page = 1
|
70
|
-
loop do
|
71
|
-
pool = API.new.fetch('pool', 'show', id: @id, page: page)
|
72
|
-
page += 1
|
73
|
-
@posts += pool[:posts].map do |post|
|
74
|
-
E621::Post.new(post[:id]).show(post)
|
57
|
+
def initialize(pool)
|
58
|
+
raise ArgumentError, "#{pool.class} is not a Hash" unless pool.is_a?(Hash)
|
59
|
+
raise ArgumentError, 'Hash must include :id' if pool[:id].nil?
|
60
|
+
pool.each do |k, v|
|
61
|
+
if %i[id name post_count is_active is_locked description].include?(k)
|
62
|
+
if k == :id && !(v.is_a?(Integer) && v.positive?)
|
63
|
+
raise InvalidIDError, "ID out of range: #{v}"
|
75
64
|
end
|
76
|
-
|
65
|
+
instance_variable_set("@#{k}".to_sym, v)
|
66
|
+
elsif %i[updated_at created_at].include?(k)
|
67
|
+
instance_variable_set("@#{k}".to_sym, Time.at(v[:s]))
|
68
|
+
elsif k == :user_id
|
69
|
+
@creator = E621::User.new(id: v)
|
70
|
+
elsif k == :posts
|
71
|
+
@posts = v.map { |post| E621::Post.new(post) }
|
77
72
|
end
|
78
73
|
end
|
79
|
-
@name = pool[:name]
|
80
|
-
@created_at = Time.at(pool[:created_at][:s].to_i)
|
81
|
-
@updated_at = Time.at(pool[:updated_at][:s].to_i)
|
82
|
-
@description = pool[:description]
|
83
|
-
@user = User.new(id: pool[:user_id])
|
84
|
-
@is_locked = pool[:is_locked]
|
85
|
-
@is_active = pool[:is_active]
|
86
|
-
end
|
87
|
-
|
88
|
-
# @author Maxine Michalski
|
89
|
-
#
|
90
|
-
# @param pool [Hash] pool data, if present
|
91
|
-
#
|
92
|
-
# Fetch data from e621 to current pool id
|
93
|
-
def show(pool = nil)
|
94
|
-
tmp = Pool.new(@id)
|
95
|
-
tmp.show!(pool)
|
96
|
-
tmp
|
97
74
|
end
|
98
75
|
|
99
76
|
# @author Maxine Michalski
|
@@ -122,12 +99,7 @@ module Rubyhexagon
|
|
122
99
|
#
|
123
100
|
# @return [TrueClass,FalseClass]
|
124
101
|
def ==(other)
|
125
|
-
|
126
|
-
other.is_a?(Pool) && @id == other.id
|
127
|
-
else
|
128
|
-
other.is_a?(Pool) && @name == other.name && @id == other.id &&
|
129
|
-
@updated_at == other.updated_at
|
130
|
-
end
|
102
|
+
other.is_a?(Pool) && @id == other.id && @updated_at == other.updated_at
|
131
103
|
end
|
132
104
|
end
|
133
105
|
end
|
data/lib/rubyhexagon/post.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
|
#
|
@@ -26,7 +26,7 @@ module Rubyhexagon
|
|
26
26
|
# @return [Integer] id of post information
|
27
27
|
attr_reader :id
|
28
28
|
|
29
|
-
# @return [User] user object of who uploaded this post
|
29
|
+
# @return [E621::User] user object of who uploaded this post
|
30
30
|
attr_reader :author
|
31
31
|
|
32
32
|
# @return [Time] creation time of post
|
@@ -40,15 +40,15 @@ module Rubyhexagon
|
|
40
40
|
# form
|
41
41
|
attr_reader :sources
|
42
42
|
|
43
|
-
# @return [Array<Artist>] array of artists, that work on the image
|
44
|
-
#
|
43
|
+
# @return [Array<E621::Artist>] array of artists, that work on the image
|
44
|
+
# in this post
|
45
45
|
attr_reader :artists
|
46
46
|
|
47
47
|
# @return [String] description that's associated with this post
|
48
48
|
attr_reader :description
|
49
49
|
|
50
50
|
# @return [Integer] number of people, who favorited this post
|
51
|
-
attr_reader :
|
51
|
+
attr_reader :fav_count
|
52
52
|
|
53
53
|
# @return [Integer] vote score this post holds
|
54
54
|
attr_reader :score
|
@@ -57,252 +57,233 @@ module Rubyhexagon
|
|
57
57
|
# :questionable, :explicit
|
58
58
|
attr_reader :rating
|
59
59
|
|
60
|
-
# @return [
|
60
|
+
# @return [E621:post] parent of this post
|
61
61
|
# @return [NilClass]
|
62
62
|
attr_reader :parent
|
63
63
|
|
64
|
-
# @return [Array<Post>] Array of child posts
|
64
|
+
# @return [Array<E621::Post>] Array of child posts
|
65
65
|
attr_reader :children
|
66
66
|
|
67
67
|
# @return [String] MD5 checksum associated with this post
|
68
68
|
attr_reader :md5
|
69
69
|
|
70
|
-
# @return [
|
70
|
+
# @return [E621::Image] file content of this post
|
71
71
|
attr_reader :image
|
72
72
|
|
73
|
-
# @return [
|
73
|
+
# @return [E621::Sample] sample data in E621::Sample format
|
74
74
|
attr_reader :sample
|
75
75
|
|
76
|
-
# @return [
|
76
|
+
# @return [E621::Preview] preview data in E621::Preview format
|
77
77
|
attr_reader :preview
|
78
78
|
|
79
|
-
# @return [
|
80
|
-
attr_reader :
|
79
|
+
# @return [String|NilClass] reason for deletion, if deleted
|
80
|
+
attr_reader :delreason
|
81
|
+
|
82
|
+
# @return [Array<E621::Tag>] tags of this post
|
83
|
+
attr_reader :tags
|
81
84
|
|
82
85
|
# @author Maxine Michalski
|
83
86
|
#
|
84
87
|
# Initializer for Post.
|
85
88
|
#
|
86
|
-
# @param
|
89
|
+
# @param post [Hash] post data
|
87
90
|
#
|
88
91
|
# @return the object
|
89
|
-
def initialize(
|
90
|
-
|
92
|
+
def initialize(post)
|
93
|
+
raise ArgumentError, "#{post.class} is not a Hash" unless post.is_a?(Hash)
|
94
|
+
post[:id] = post[:id].to_i
|
95
|
+
id = post[:id]
|
91
96
|
raise InvalidIDError, "ID out of range: #{id}" unless id.positive?
|
92
|
-
|
97
|
+
post.each do |k, v|
|
98
|
+
if %i[rating created_at status sources parent_id children
|
99
|
+
description artist tags].include?(k)
|
100
|
+
__send__("setup_#{k}".to_sym, v)
|
101
|
+
elsif %i[id description score fav_count md5 has_comments has_children
|
102
|
+
delreason has_notes].include?(k)
|
103
|
+
instance_variable_set("@#{k}".to_sym, v)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
setup_author(post)
|
107
|
+
setup_files(post)
|
93
108
|
end
|
94
109
|
|
95
110
|
# @author Maxine Michalski
|
96
111
|
#
|
97
|
-
#
|
112
|
+
# Test status with an optional parameter. This is more meant to be used by
|
113
|
+
# alias methods
|
98
114
|
#
|
99
|
-
#
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
setup_additional_data(post)
|
115
|
+
# @param test_var [Symbol] variable under test
|
116
|
+
#
|
117
|
+
# @return [TrueClass]
|
118
|
+
# @return [FalseClass]
|
119
|
+
def test(test_var = nil)
|
120
|
+
test_var ||= __callee__.to_s.sub(/\?/, '').to_sym
|
121
|
+
test_ar = %i[safe questionable explicit]
|
122
|
+
test_ar.include?(test_var) ? @rating == test_var : @status == test_var
|
108
123
|
end
|
124
|
+
alias active? test
|
125
|
+
alias flagged? test
|
126
|
+
alias pending? test
|
127
|
+
alias deleted? test
|
128
|
+
alias safe? test
|
129
|
+
alias questionable? test
|
130
|
+
alias explicit? test
|
109
131
|
|
110
132
|
# @author Maxine Michalski
|
111
133
|
#
|
112
|
-
#
|
134
|
+
# Show if post has comments or not
|
113
135
|
#
|
114
|
-
#
|
115
|
-
def
|
116
|
-
|
117
|
-
|
118
|
-
tmp
|
136
|
+
# @return [TrueClass|FalseClass]
|
137
|
+
def comments?
|
138
|
+
return false if @has_comments.nil?
|
139
|
+
@has_comments
|
119
140
|
end
|
120
141
|
|
121
142
|
# @author Maxine Michalski
|
122
143
|
#
|
123
|
-
#
|
144
|
+
# Show if post has a parent
|
124
145
|
#
|
125
|
-
# @
|
126
|
-
def
|
127
|
-
|
128
|
-
raise ArgumentError, 'Voting requires a positive/negative number'
|
129
|
-
end
|
130
|
-
raise ArgumentError, "Vote can't be zero" if score.zero?
|
131
|
-
score = score.positive? ? 1 : -1
|
132
|
-
res = API.new.fetch('post', 'vote', { id: @id, score: score }, 'POST')
|
133
|
-
if res[:reason] == 'access denied' && !res[:success]
|
134
|
-
raise Rubyhexagon::AccessDenied, res[:message]
|
135
|
-
end
|
136
|
-
nil
|
146
|
+
# @return [TrueClass|FalseClass]
|
147
|
+
def parent?
|
148
|
+
!@parent.nil?
|
137
149
|
end
|
138
150
|
|
139
151
|
# @author Maxine Michalski
|
140
152
|
#
|
141
|
-
#
|
142
|
-
def voteup!
|
143
|
-
vote!(1)
|
144
|
-
end
|
145
|
-
|
146
|
-
# @author Maxine Michalski
|
153
|
+
# Show if post has children
|
147
154
|
#
|
148
|
-
#
|
149
|
-
def
|
150
|
-
|
155
|
+
# @return [TrueClass|FalseClass]
|
156
|
+
def children?
|
157
|
+
return false if @has_children.nil?
|
158
|
+
@has_children
|
151
159
|
end
|
152
160
|
|
153
161
|
# @author Maxine Michalski
|
154
162
|
#
|
155
|
-
#
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
elsif !res[:success] &&
|
161
|
-
res[:reason] == 'You\'ve already favorited this post'
|
162
|
-
raise Rubyhexagon::AlreadyFavorited
|
163
|
-
end
|
164
|
-
nil
|
163
|
+
# Comparison method for posts
|
164
|
+
#
|
165
|
+
# @return [TrueClass, FalseClass]
|
166
|
+
def ==(other)
|
167
|
+
other.is_a?(Post) && @id == other.id
|
165
168
|
end
|
166
169
|
|
167
170
|
# @author Maxine Michalski
|
168
171
|
#
|
169
|
-
#
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
end
|
175
|
-
nil
|
172
|
+
# Has post notes?
|
173
|
+
#
|
174
|
+
# @return [TrueClass, FalseClass]
|
175
|
+
def notes?
|
176
|
+
@has_notes
|
176
177
|
end
|
177
178
|
|
179
|
+
private
|
180
|
+
|
178
181
|
# @author Maxine Michalski
|
179
182
|
#
|
180
|
-
#
|
183
|
+
# Set author information
|
181
184
|
#
|
182
|
-
# @
|
183
|
-
def
|
184
|
-
|
185
|
-
|
186
|
-
end
|
185
|
+
# @param post [Hash] post data
|
186
|
+
def setup_author(post)
|
187
|
+
return if post[:creator_id].nil?
|
188
|
+
@author = E621::User.new(id: post[:creator_id], name: post[:author])
|
187
189
|
end
|
188
190
|
|
189
191
|
# @author Maxine Michalski
|
190
192
|
#
|
191
|
-
#
|
192
|
-
# alias methods
|
193
|
+
# Set rating for post
|
193
194
|
#
|
194
|
-
# @param
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
test_ar.include?(test_var) ? @rating == test_var : @status == test_var
|
195
|
+
# @param rating [String] rating of this post
|
196
|
+
def setup_rating(rating)
|
197
|
+
@rating = case rating
|
198
|
+
when 's' then :safe
|
199
|
+
when 'q' then :questionable
|
200
|
+
when 'e' then :explicit
|
201
|
+
end
|
202
202
|
end
|
203
|
-
alias active? test
|
204
|
-
alias flagged? test
|
205
|
-
alias pending? test
|
206
|
-
alias deleted? test
|
207
|
-
alias safe? test
|
208
|
-
alias questionable? test
|
209
|
-
alias explicit? test
|
210
203
|
|
211
204
|
# @author Maxine Michalski
|
212
205
|
#
|
213
|
-
#
|
206
|
+
# Set creation time
|
214
207
|
#
|
215
|
-
# @
|
216
|
-
|
217
|
-
|
208
|
+
# @param time [Time] Hash that includes creation time in UNIX Epoch on an
|
209
|
+
# `:s` key.
|
210
|
+
def setup_created_at(time)
|
211
|
+
@created_at = Time.at(time[:s]) unless time.nil?
|
218
212
|
end
|
219
213
|
|
220
|
-
private
|
221
|
-
|
222
214
|
# @author Maxine Michalski
|
223
215
|
#
|
224
|
-
#
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
@
|
229
|
-
width: post[:width], height: post[:height],
|
230
|
-
size: post[:file_size])
|
231
|
-
setup_sample(post)
|
232
|
-
setup_preview(post)
|
216
|
+
# Set status of post
|
217
|
+
#
|
218
|
+
# @param status [String] Status of post
|
219
|
+
def setup_status(status)
|
220
|
+
@status = status.to_sym unless status.nil?
|
233
221
|
end
|
234
222
|
|
235
223
|
# @author Maxine Michalski
|
236
224
|
#
|
237
|
-
#
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
225
|
+
# Set sources of post
|
226
|
+
#
|
227
|
+
# @param sources [Array<String>] Sources of post
|
228
|
+
def setup_sources(sources)
|
229
|
+
@sources = sources.nil? ? [] : sources
|
242
230
|
end
|
243
231
|
|
244
232
|
# @author Maxine Michalski
|
245
233
|
#
|
246
|
-
#
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
234
|
+
# Set parent post
|
235
|
+
#
|
236
|
+
# @param parent [Integer] Parent post ID
|
237
|
+
#
|
238
|
+
# @notice A parent post is only set with an ID and further information must
|
239
|
+
# be fetched manually.
|
240
|
+
def setup_parent_id(parent)
|
241
|
+
@parent = parent.nil? ? nil : E621::Post.new(id: parent)
|
251
242
|
end
|
252
243
|
|
253
244
|
# @author Maxine Michalski
|
254
245
|
#
|
255
|
-
#
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
when 'q' then :questionable
|
265
|
-
when 'e' then :explicit
|
266
|
-
end
|
246
|
+
# Set children posts
|
247
|
+
#
|
248
|
+
# @param children [Array<Integer>] Children post IDs
|
249
|
+
#
|
250
|
+
# @notice All children are only set with an ID and further information must
|
251
|
+
# be fetched manually.
|
252
|
+
def setup_children(children)
|
253
|
+
return [] if children.nil?
|
254
|
+
@children = children.split(',').map { |c| E621::Post.new(id: c) }
|
267
255
|
end
|
268
256
|
|
269
257
|
# @author Maxine Michalski
|
270
258
|
#
|
271
|
-
#
|
272
|
-
|
273
|
-
|
274
|
-
|
259
|
+
# Set post description
|
260
|
+
#
|
261
|
+
# @param description [String] Post description
|
262
|
+
#
|
263
|
+
# @notice Empty descriptions are set to nil
|
264
|
+
def setup_description(description)
|
265
|
+
@description = !description.nil? && description.empty? ? nil : description
|
275
266
|
end
|
276
267
|
|
277
|
-
|
278
|
-
|
279
|
-
# Helper function to set author of a post
|
280
|
-
def setup_author(post)
|
281
|
-
@author = User.new(id: post[:creator_id], name: post[:author])
|
268
|
+
def setup_artist(artists)
|
269
|
+
@artists = artists.map { |a| E621::Artist.new(name: CGI.unescape(a)) }
|
282
270
|
end
|
283
|
-
end
|
284
271
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
#
|
289
|
-
# @author Maxine Michalski
|
290
|
-
# @since 1.0.0
|
291
|
-
class DeletedPost < Post
|
292
|
-
# @return [String] deletion reason, when available
|
293
|
-
attr_reader :reason
|
272
|
+
def setup_tags(tags)
|
273
|
+
@tags = tags.split(' ').map { |t| E621::Tag.new(name: t) }
|
274
|
+
end
|
294
275
|
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
276
|
+
def setup_files(post)
|
277
|
+
return if post[:file_url].nil?
|
278
|
+
@image = Image.new(url: post[:file_url], ext: post[:file_ext],
|
279
|
+
width: post[:width], height: post[:height],
|
280
|
+
size: post[:file_size])
|
281
|
+
@sample = Sample.new(url: post[:sample_url], ext: post[:file_ext],
|
282
|
+
width: post[:sample_width],
|
283
|
+
height: post[:sample_height], size: 0)
|
284
|
+
@preview = Preview.new(url: post[:preview_url], ext: 'jpg',
|
285
|
+
width: post[:preview_width],
|
286
|
+
height: post[:preview_height], size: 0)
|
306
287
|
end
|
307
288
|
end
|
308
289
|
end
|