nhentai-api 0.2.2 → 1.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 32a8382ebb1c8c5d33c1ea5baa94070fc31c788e31c628c7708fa6b29d839d94
4
- data.tar.gz: 1481e553fa7663d4898b07f60814413be9efb5ccd8c233bf84d0c08281edf934
3
+ metadata.gz: 962d39c7b5641737d50b8aae5f6d66b94b330642abe758beb50ada6d1f10008e
4
+ data.tar.gz: e5ce54e4cb8e87e9aac4c8339df0073a20ec33a95ea467691eb75d3b4b77f59b
5
5
  SHA512:
6
- metadata.gz: 585e38f3cb7d7397158535f4bca3dd10fde1fb70bcf4ecddff39eaee1178a6f1cb50ad668897e838087265ab1d61e1617bddbdcede672d1f8de46fd6a5945a7c
7
- data.tar.gz: a5246ab1e9eec631fed5a883822e9190bf004e88840b6cc9d3a13cb516371019a61c77a7808d04eaebd325ba5a23e823c930351f16f5063164cc8b963fd5c2e5
6
+ metadata.gz: 5a463e10bb67f877c7768f59e0da29be55e2df000b7b0cb6032725d9d040c0614e2a3298cd0e8718c008644d3b70659d8634fea53727c632a1df0d2998b2e7d5
7
+ data.tar.gz: 8157e7ed49c0e59bfbca4433d9f2f1534514f6e3ee5d9a4ff2485dc0c9f216d766de7c3e3b410593f0e76f614face9f7995a68d3e8690627c19d178884acb80a
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Doujinshi
4
+ def initialize(id:)
5
+ case id
6
+ when Integer, String
7
+ @id = id
8
+ @client = Net::HTTP.get_response(URI("https://nhentai.net/api/gallery/#{id}"))
9
+ return unless exists?
10
+
11
+ @response = JSON.parse(client.body)
12
+ when Hash
13
+ @response = id
14
+ end
15
+ end
16
+
17
+ def self.random
18
+ fetch('https://nhentai.net/random')
19
+ end
20
+
21
+ def exists?
22
+ client.code == '200'
23
+ end
24
+
25
+ def media_id
26
+ response['media_id']
27
+ end
28
+
29
+ def num_pages
30
+ response['num_pages']
31
+ end
32
+
33
+ def title(type: :pretty)
34
+ response['title'][type.to_s]
35
+ end
36
+
37
+ def cover
38
+ "https://t.nhentai.net/galleries/#{media_id}/cover.#{IMAGE_EXTENSION[response['images']['cover']['t']]}"
39
+ end
40
+
41
+ def page(page: 1)
42
+ "https://i.nhentai.net/galleries/#{media_id}/#{page}.#{IMAGE_EXTENSION[response['images']['pages'][page - 1]['t']]}"
43
+ end
44
+
45
+ def pages
46
+ (1..num_pages).map { |page| page(page: page) }
47
+ end
48
+
49
+ def thumbnail(page: 1)
50
+ "https://t.nhentai.net/galleries/#{media_id}/#{page}t.#{IMAGE_EXTENSION[response['images']['pages'][page - 1]['t']]}"
51
+ end
52
+
53
+ def thumbnails
54
+ (1..num_pages).map { |page| thumbnail(page: page) }
55
+ end
56
+
57
+ def count_favorites
58
+ response['num_favorites']
59
+ end
60
+
61
+ def upload_date
62
+ Time.at(response['upload_date']).utc
63
+ end
64
+
65
+ %w[tags parodies characters artists groups languages categories].each do |method|
66
+ define_method method do
67
+ return instance_variable_get("@#{method}") if instance_variable_defined?("@#{method}")
68
+
69
+ res = response['tags'].select { |tag| tag['type'] == SINGULAR_TAG[method] }
70
+ instance_variable_set("@#{method}", parsing_informations(res))
71
+ end
72
+
73
+ define_method "count_#{method}" do
74
+ send(method).size
75
+ end
76
+
77
+ define_method "#{method}?" do
78
+ !send(method).empty?
79
+ end
80
+ end
81
+
82
+ def related
83
+ client = Net::HTTP.get_response(URI("https://nhentai.net/api/gallery/#{id}/related"))
84
+ response = JSON.parse(client.body)
85
+
86
+ response['result'].map { |doujin| Doujinshi.new(id: doujin) }
87
+ end
88
+
89
+ private
90
+
91
+ attr_reader :client, :response, :id
92
+
93
+ def parsing_informations(res)
94
+ res.map do |line|
95
+ OpenStruct.new(
96
+ id: line['id'],
97
+ name: line['name'],
98
+ count: line['count'],
99
+ url: line['url']
100
+ )
101
+ end
102
+ end
103
+
104
+ def self.fetch(uri_str)
105
+ client = Net::HTTP.get_response(URI(uri_str))
106
+
107
+ case client
108
+ when Net::HTTPFound then new(id: client['location'][3..-2])
109
+ when Net::HTTPRedirection then fetch("https://nhentai.net#{client['location']}")
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ %w[tag parody character artist group language category].each do |class_name|
4
+ c = Class.new do
5
+ attr_reader :client
6
+
7
+ def initialize(keyword:, sort: :none, page: 1)
8
+ @client = Net::HTTP.get_response(URI("https://nhentai.net/#{class_name}/#{keyword.tr(' ', '-')}/#{SORT[sort]}?page=#{page}"))
9
+ end
10
+
11
+ def count
12
+ res = client.body.match(%r{<a.*class="count">(.*)<\/span><\/a>})
13
+ return 0 if res.nil?
14
+
15
+ count = res[1]
16
+ count[-1] == 'K' ? count.to_i * 1000 : count.to_i
17
+ end
18
+
19
+ def listing
20
+ res = client.body.split(%r{<div class="gallery".+?>(.*?)<\/div>}).select { |line| line.include?('<a href="/g/') }
21
+ parse_tiles(res)
22
+ end
23
+
24
+ def exists?
25
+ @client.code == '200'
26
+ end
27
+
28
+ private
29
+
30
+ def class_name
31
+ self.class.name.split('::').last.downcase
32
+ end
33
+ end
34
+
35
+ Kernel.const_set(class_name.capitalize, c)
36
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Search
4
+ def initialize(options:, sort: :none, page: 1)
5
+ @options = options
6
+ @client = Net::HTTP.get_response(URI("https://nhentai.net/api/galleries/search?query=#{string_options}&sort=#{SORT[sort]}&page=#{page}"))
7
+ return unless exists?
8
+
9
+ @response = JSON.parse(client.body)
10
+ end
11
+
12
+ def exists?
13
+ client.code == '200'
14
+ end
15
+
16
+ def count
17
+ response['result'].count
18
+ end
19
+
20
+ def num_pages
21
+ response['num_pages']
22
+ end
23
+
24
+ def per_page
25
+ response['per_page']
26
+ end
27
+
28
+ def listing
29
+ response['result'].map { |doujin| Doujinshi.new(id: doujin) }
30
+ end
31
+
32
+ private
33
+
34
+ attr_reader :options, :client, :response
35
+
36
+ def string_options
37
+ %i[keywords tags pages dates]
38
+ .map { |symbol| send("parse_#{symbol}", options[symbol]) if options[symbol] }
39
+ .join(' ')
40
+ end
41
+
42
+ def parse_pages(pages)
43
+ pages.map { |page| "pages:#{page.tr(' ', '')}" }
44
+ end
45
+
46
+ def parse_dates(dates)
47
+ dates.map { |date| "uploaded:#{date.tr(' ', '')}" }
48
+ end
49
+
50
+ def parse_tags(tags)
51
+ ary = []
52
+
53
+ %i[included excluded].each do |type|
54
+ next if tags[type].nil?
55
+
56
+ %i[tags parodies characters artists groups languages categories].each do |subtype|
57
+ next if tags[type][subtype].empty? || tags[type][subtype].nil?
58
+
59
+ ary <<
60
+ tags[type][subtype]
61
+ .map { |word| word.include?(' ') ? "\"#{word}\"" : word }
62
+ .map { |word| word.prepend("#{subtype}:") }
63
+ .map { |word| type == :excluded ? word.prepend('-') : word }
64
+ end
65
+ end
66
+
67
+ ary
68
+ end
69
+
70
+ def parse_keywords(keywords)
71
+ %i[included excluded].map do |type|
72
+ next if keywords[type].nil?
73
+
74
+ keywords[type]
75
+ .map { |word| type == :excluded ? word.prepend('-') : word }
76
+ .map { |word| word.include?(' ') ? "\"#{word}\"" : word }
77
+ end
78
+ end
79
+ end
data/lib/nhentai-api.rb CHANGED
@@ -1,552 +1,36 @@
1
- require 'net/http'
2
- require 'time'
3
-
4
- class Info
5
- attr_reader :id, :name, :count, :url
6
-
7
- def initialize(id, name, count, url)
8
- @id = id
9
- @name = name
10
- @count = count
11
- @url = url
12
- end
13
- end
14
-
15
- class Doujinshi
16
- attr_reader :id, :client, :media_id, :count_pages
17
-
18
- def initialize(id)
19
- @id = id
20
- @client = Net::HTTP.get_response(URI("https://nhentai.net/g/#{@id}/"))
21
- if self.exists?
22
- @media_id = @client.body.match(%r{\/([0-9]+)\/cover})[1]
23
- @count_pages = @client.body.match(/Pages:\s*.*>([0-9]+)</)[1].to_i
24
- end
25
- end
26
-
27
- #
28
- # Check if a doujinshi with the given id exist
29
- #
30
- # @return [Bool] true if the doujinshi exist, otherwise false
31
- # @since 0.1.0
32
- # @example
33
- # doujinshi.exists? #=> true
34
- #
35
- def exists?
36
- @client.code == '200'
37
- end
38
-
39
- #
40
- # Give the title of a doujinshi
41
- #
42
- # @return [String] the title of a given doujinshi
43
- # @since 0.1.0
44
- # @example
45
- # doujinshi.title #=> '[Illumination. (Ogadenmon)] Android no Ecchi na Yatsu | Horny Androids (NieR:Automata) [English] =TLL + mrwayne= [Digital]'
46
- #
47
- def title
48
- @client.body.match(/"pretty">(.*?)</)[1]
49
- end
50
-
51
- #
52
- # Give the cover's URL of a doujinshi
53
- #
54
- # @return [String] the cover's URL of a given doujinshi
55
- # @since 0.1.0
56
- # @example
57
- # doujinshi.cover #=> 'https://t.nhentai.net/galleries/1170172/cover.jpg'
58
- #
59
- def cover
60
- res = @client.body.match(%r{https://t.nhentai.net/galleries/#{@media_id}/cover\.(.{3})"})
61
-
62
- "https://t.nhentai.net/galleries/#{@media_id}/cover.#{res[1]}"
63
- end
64
-
65
- #
66
- # Give the URL of a given page of a doujinshi
67
- #
68
- # @param [Integer] page a particular page of a doujinshi
69
- # @return [String] the URL of a given page of a doujinshi
70
- # @since 0.1.0
71
- # @example
72
- # doujinshi.get_page #=> 'https://i.nhentai.net/galleries/1170172/1.jpg'
73
- # doujinshi.get_page(10) #=> 'https://i.nhentai.net/galleries/1170172/10.jpg'
74
- #
75
- def page(page = 1)
76
- res = @client.body.match(%r{https://t.nhentai.net/galleries/#{@media_id}/#{page}t\.(.{3})"})
77
-
78
- "https://i.nhentai.net/galleries/#{@media_id}/#{page}.#{res[1]}"
79
- end
80
-
81
- #
82
- # Give the URL of a all pages of a doujinshi
83
- #
84
- # @return [Array] array pages' URL
85
- # @since 0.1.0
86
- # @example
87
- # doujinshi.pages #=> ['https://i.nhentai.net/galleries/1170172/1.jpg', ..., 'https://i.nhentai.net/galleries/1170172/31.jpg']
88
- #
89
- def pages
90
- (1..@count_pages).map { |page| page(page) }
91
- end
92
-
93
- #
94
- # Give the thumbnail's URL of a given page of a doujinshi
95
- #
96
- # @param [Integer] page a particular page of a doujinshi
97
- # @return [String] the thumbnail's URL of a given page of a doujinshi
98
- # @since 0.1.0
99
- # @example
100
- # doujinshi.get_thumbnail #=> 'https://t.nhentai.net/galleries/1170172/1t.jpg'
101
- # doujinshi.get_thumbnail(10) #=> 'https://t.nhentai.net/galleries/1170172/10t.jpg'
102
- #
103
- def thumbnail(page = 1)
104
- res = @client.body.match(%r{https://t.nhentai.net/galleries/#{@media_id}/(#{page}t\..{3})"})
105
-
106
- "https://t.nhentai.net/galleries/#{@media_id}/#{res[1]}"
107
- end
108
-
109
- #
110
- # Give the URL of a all thumbnails of a doujinshi
111
- #
112
- # @return [Array] an array thumbnails' URL
113
- # @since 0.1.0
114
- # @example
115
- # doujinshi.thumbnails #=> ['https://t.nhentai.net/galleries/1170172/1t.jpg',..., 'https://t.nhentai.net/galleries/1170172/31t.jpg']
116
- #
117
- def thumbnails
118
- (1..@count_pages).map { |page| thumbnail(page) }
119
- end
120
-
121
- #
122
- # Give the number of favorites on a doujinshi
123
- #
124
- # @return [Integer] a counter of favorites on a given doujinshi
125
- # @since 0.1.0
126
- # @example
127
- # doujinshi.num_favorites #=> 13326
128
- #
129
- def count_favorites
130
- regex = %r{<span>Favorite <span class="nobold">.(\d+).<\/span><\/span>}
131
-
132
- @client.body.match(regex)[1].to_i
133
- end
134
-
135
- #
136
- # Give the upload date of a doujinshi
137
- #
138
- # @return [Integer] the upload date of a given doujinshi
139
- # @since 0.1.0
140
- # @example
141
- # doujinshi.upload_date #=> 2018-01-17 15:56:16 +0000
142
- #
143
- def upload_date
144
- Time.iso8601(@client.body.match(/<time .+ datetime="(.*?)"/)[1])
145
- end
146
-
147
- #
148
- # Give all tags of a doujinshi
149
- #
150
- # @return [Array] of Tag class of a given doujinshi
151
- # @since 0.1.0
152
- # @example
153
- # doujinshi.tags
154
- #
155
- def tags
156
- res = @client.body.match(%r{Tags:\s*<span class="tags">(.+)<\/span>})
157
- return [] if res.nil?
158
-
159
- parse_tags(res[1])
160
- end
161
-
162
- #
163
- # Give a counter of tags
164
- #
165
- # @return [Integer] of tags
166
- # @since 0.1.0
167
- # @example
168
- # doujinshi.count_tags #=> 9
169
- #
170
- def count_tags
171
- res = @client.body.match(%r{Tags:\s*<span class="tags">(.+)<\/span>})
172
-
173
- res.nil? ? 0 : parse_tags(res[1]).length
174
- end
175
-
176
- #
177
- # Check if a particular doujinshi have some tags
178
- #
179
- # @return [Bool] true if the doujinshi have tags, otherwise false
180
- # @since 0.1.0
181
- # @example
182
- # doujinshi.tags? #=> true
183
- #
184
- def tags?
185
- !@client.body.match(%r{Tags:\s*<span class="tags">(.+)<\/span>}).nil?
186
- end
187
-
188
- #
189
- # Give all parodies of a doujinshi
190
- #
191
- # @since 0.1.0
192
- # @see Doujinshi#tags
193
- #
194
- def parodies
195
- res = @client.body.match(%r{Parodies:\s+<span class="tags">(.+)<\/span>})
196
- return [] if res.nil?
197
-
198
- parse_tags(res[1])
199
- end
200
-
201
- #
202
- # Give a counter of parodies
203
- #
204
- # @since 0.1.0
205
- # @see Doujinshi#count_tags
206
- #
207
- def count_parodies
208
- res = @client.body.match(%r{Parodies:\s+<span class="tags">(.+)<\/span>})
209
-
210
- res.nil? ? 0 : parse_tags(res[1]).length
211
- end
212
-
213
- #
214
- # Check if a particular doujinshi have some parodies
215
- #
216
- # @since 0.1.0
217
- # @see Doujinshi#tags?
218
- #
219
- def parodies?
220
- !@client.body.match(%r{Parodies:\s+<span class="tags">(.+)<\/span>}).nil?
221
- end
222
-
223
- #
224
- # Give all characters of a doujinshi
225
- #
226
- # @since 0.1.0
227
- # @see Doujinshi#tags
228
- #
229
- def characters
230
- res = @client.body.match(%r{Characters:\s+<span class="tags">(.+)<\/span>})
231
- return [] if res.nil?
232
-
233
- parse_tags(res[1])
234
- end
235
-
236
- #
237
- # Give a counter of characters
238
- #
239
- # @since 0.1.0
240
- # @see Doujinshi#count_tags
241
- #
242
- def count_characters
243
- res = @client.body.match(%r{Characters:\s+<span class="tags">(.+)<\/span>})
244
-
245
- res.nil? ? 0 : parse_tags(res[1]).length
246
- end
247
-
248
- #
249
- # Check if a particular doujinshi have some characters
250
- #
251
- # @since 0.1.0
252
- # @see Doujinshi#tags?
253
- #
254
- def characters?
255
- !@client.body.match(%r{Characters:\s+<span class="tags">(.+)<\/span>}).nil?
256
- end
257
-
258
- #
259
- # Give all artists of a doujinshi
260
- #
261
- # @since 0.1.0
262
- # @see Doujinshi#tags
263
- #
264
- def artists
265
- res = @client.body.match(%r{Artists:\s+<span class="tags">(.+)<\/span>})
266
- return [] if res.nil?
267
-
268
- parse_tags(res[1])
269
- end
270
-
271
- #
272
- # Give a counter of artists
273
- #
274
- # @since 0.1.0
275
- # @see Doujinshi#count_tags
276
- #
277
- def count_artists
278
- res = @client.body.match(%r{Artists:\s+<span class="tags">(.+)<\/span>})
279
-
280
- res.nil? ? 0 : parse_tags(res[1]).length
281
- end
282
-
283
- #
284
- # Check if a particular doujinshi have some artists
285
- #
286
- # @since 0.1.0
287
- # @see Doujinshi#tags?
288
- #
289
- def artists?
290
- !@client.body.match(%r{Artists:\s+<span class="tags">(.+)<\/span>}).nil?
291
- end
292
-
293
- #
294
- # Give all groups of a doujinshi
295
- #
296
- # @since 0.1.0
297
- # @see Doujinshi#tags
298
- #
299
- def groups
300
- res = @client.body.match(%r{Groups:\s+<span class="tags">(.+)<\/span>})
301
- return [] if res.nil?
302
-
303
- parse_tags(res[1])
304
- end
305
-
306
- #
307
- # Give a counter of groups
308
- #
309
- # @since 0.1.0
310
- # @see Doujinshi#count_tags
311
- #
312
- def count_groups
313
- res = @client.body.match(%r{Groups:\s+<span class="tags">(.+)<\/span>})
314
-
315
- res.nil? ? 0 : parse_tags(res[1]).length
316
- end
317
-
318
- #
319
- # Check if a particular doujinshi have some groups
320
- #
321
- # @since 0.1.0
322
- # @see Doujinshi#tags?
323
- #
324
- def groups?
325
- !@client.body.match(%r{Groups:\s+<span class="tags">(.+)<\/span>}).nil?
326
- end
327
-
328
- #
329
- # Give all languages of a doujinshi
330
- #
331
- # @since 0.1.0
332
- # @see Doujinshi#tags
333
- #
334
- def languages
335
- res = @client.body.match(%r{Languages:\s+<span class="tags">(.+)<\/span>})
336
- return [] if res.nil?
337
-
338
- parse_tags(res[1])
339
- end
340
-
341
- #
342
- # Give a counter of languages
343
- #
344
- # @since 0.1.0
345
- # @see Doujinshi#count_tags
346
- #
347
- def count_languages
348
- res = @client.body.match(%r{Languages:\s+<span class="tags">(.+)<\/span>})
349
-
350
- res.nil? ? 0 : parse_tags(res[1]).length
351
- end
352
-
353
- #
354
- # Check if a particular doujinshi have some languages
355
- #
356
- # @since 0.1.0
357
- # @see Doujinshi#tags?
358
- #
359
- def languages?
360
- !@client.body.match(%r{Languages:\s+<span class="tags">(.+)<\/span>}).nil?
361
- end
362
-
363
- #
364
- # Give all categories of a doujinshi
365
- #
366
- # @since 0.1.0
367
- # @see Doujinshi#tags
368
- #
369
- def categories
370
- res = @client.body.match(%r{Categories:\s+<span class="tags">(.+)<\/span>})
371
- return [] if res.nil?
372
-
373
- parse_tags(res[1])
374
- end
375
-
376
- #
377
- # Give a counter of categories
378
- #
379
- # @since 0.1.0
380
- # @see Doujinshi#count_tags
381
- #
382
- def count_categories
383
- res = @client.body.match(%r{Categories:\s+<span class="tags">(.+)<\/span>})
384
-
385
- res.nil? ? 0 : parse_tags(res[1]).length
386
- end
387
-
388
- #
389
- # Check if a particular doujinshi have some categories
390
- #
391
- # @since 0.1.0
392
- # @see Doujinshi#tags?
393
- #
394
- def categories?
395
- !@client.body.match(%r{Categories:\s+<span class="tags">(.+)<\/span>}).nil?
396
- end
397
-
398
- #
399
- # @private
400
- #
401
-
402
- private
403
-
404
- def parse_tags(res)
405
- res.split(%r{<a(.+?)<\/a>}).reject(&:empty?).map do |line|
406
- id = line.match(/tag-(\d+)/)[1]
407
- name = line.match(/">(.+?)</)[1].strip
408
- count = line.match(/class="count">(\d+.)</)[1]
409
- url = line.match(/href=\"(.+?)\"/)[1]
410
-
411
- count = count[-1] == 'K' ? count.to_i * 1000 : count.to_i
412
-
413
- Info.new(id, name, count, url)
414
- end
415
- end
416
- end
417
-
418
- class Tag
419
- #
420
- # List all doujinshi of the page of a given tag
421
- #
422
- # @param [String] keyword of the research
423
- # @param [Integer] sort optional, 1 is sorting by time, 2 is by popularity
424
- # @param [Integer] page each page can return 25 doujinshi
425
- # @return [Array] array of Info
426
- # @since 0.2.0
427
- #
428
- def self.listing(keyword, sort = 1, page = 1)
429
- keyword.tr!(' ', '-')
430
- sort = sort == 1 ? '' : 'popular'
431
- client = Net::HTTP.get_response(URI("https://nhentai.net/tag/#{keyword}/#{sort}?page=#{page}"))
432
- res = client.body.split(%r{<div class="gallery".+?>(.+)</div>}).select { |line| line.include?('<a href="/g/') }
433
-
434
- parse_tags(res)
435
- end
436
-
437
- #
438
- # @private
439
- #
440
- def self.parse_tags(res)
441
- res.map do |line|
442
- id = line.match(%r{/g/(\d+)/})[1]
443
- name = line.match(%r{<div class="caption">(.+)</div>})[1].strip
444
- count = 1
445
- url = "/g/#{id}"
446
-
447
- Info.new(id, name, count, url)
448
- end
449
- end
450
- end
451
-
452
- class Parody < Tag
453
- #
454
- # List all doujinshi of the page of a given parody
455
- #
456
- # @since 0.2.0
457
- # @see Tag#listing
458
- #
459
- def self.listing(keyword, sort = 1, page = 1)
460
- keyword.tr!(' ', '-')
461
- sort = sort == 1 ? '' : 'popular'
462
- client = Net::HTTP.get_response(URI("https://nhentai.net/parody/#{keyword}/#{sort}?page=#{page}"))
463
- res = client.body.split(%r{<div class="gallery".+?>(.+)</div>}).select { |line| line.include?('<a href="/g/') }
464
-
465
- parse_tags(res)
466
- end
467
- end
468
-
469
- class Character < Tag
470
- #
471
- # List all doujinshi of the page of a given character
472
- #
473
- # @since 0.2.0
474
- # @see Tag#listing
475
- #
476
- def self.listing(keyword, sort = 1, page = 1)
477
- keyword.tr!(' ', '-')
478
- sort = sort == 1 ? '' : 'popular'
479
- client = Net::HTTP.get_response(URI("https://nhentai.net/character/#{keyword}/#{sort}?page=#{page}"))
480
- res = client.body.split(%r{<div class="gallery".+?>(.+)</div>}).select { |line| line.include?('<a href="/g/') }
481
-
482
- parse_tags(res)
483
- end
484
- end
485
-
486
- class Artist < Tag
487
- #
488
- # List all doujinshi of the page of a given artists
489
- #
490
- # @since 0.2.0
491
- # @see Tag#listing
492
- #
493
- def self.listing(keyword, sort = 1, page = 1)
494
- keyword.tr!(' ', '-')
495
- sort = sort == 1 ? '' : 'popular'
496
- client = Net::HTTP.get_response(URI("https://nhentai.net/artist/#{keyword}/#{sort}?page=#{page}"))
497
- res = client.body.split(%r{<div class="gallery".+?>(.+)</div>}).select { |line| line.include?('<a href="/g/') }
498
-
499
- parse_tags(res)
500
- end
501
- end
502
-
503
- class Group < Tag
504
- #
505
- # List all doujinshi of the page of a given group
506
- #
507
- # @since 0.2.0
508
- # @see Tag#listing
509
- #
510
- def self.listing(keyword, sort = 1, page = 1)
511
- keyword.tr!(' ', '-')
512
- sort = sort == 1 ? '' : 'popular'
513
- client = Net::HTTP.get_response(URI("https://nhentai.net/group/#{keyword}/#{sort}?page=#{page}"))
514
- res = client.body.split(%r{<div class="gallery".+?>(.+)</div>}).select { |line| line.include?('<a href="/g/') }
515
-
516
- parse_tags(res)
517
- end
518
- end
519
-
520
- class Language < Tag
521
- #
522
- # List all doujinshi of the page of a given language
523
- #
524
- # @since 0.2.0
525
- # @see Tag#listing
526
- #
527
- def self.listing(keyword, sort = 1, page = 1)
528
- keyword.tr!(' ', '-')
529
- sort = sort == 1 ? '' : 'popular'
530
- client = Net::HTTP.get_response(URI("https://nhentai.net/language/#{keyword}/#{sort}?page=#{page}"))
531
- res = client.body.split(%r{<div class="gallery".+?>(.+)</div>}).select { |line| line.include?('<a href="/g/') }
532
-
533
- parse_tags(res)
534
- end
535
- end
536
-
537
- class Category < Tag
538
- #
539
- # List all doujinshi of the page of a given category
540
- #
541
- # @since 0.2.0
542
- # @see Tag#listing
543
- #
544
- def self.listing(keyword, sort = 1, page = 1)
545
- keyword.tr!(' ', '-')
546
- sort = sort == 1 ? '' : 'popular'
547
- client = Net::HTTP.get_response(URI("https://nhentai.net/category/#{keyword}/#{sort}?page=#{page}"))
548
- res = client.body.split(%r{<div class="gallery".+?>(.+)</div>}).select { |line| line.include?('<a href="/g/') }
549
-
550
- parse_tags(res)
1
+ # frozen_string_literal: true
2
+
3
+ %w[net/http ostruct time json].each { |e| require e }
4
+ %w[doujinshi search key].each { |e| require "nhentai-api/#{e}" }
5
+
6
+ SORT = {
7
+ today: 'popular-today',
8
+ week: 'popular-week',
9
+ all_time: 'popular'
10
+ }.freeze
11
+
12
+ IMAGE_EXTENSION = {
13
+ 'j' => 'jpg',
14
+ 'p' => 'png',
15
+ 'g' => 'gif'
16
+ }.freeze
17
+
18
+ SINGULAR_TAG = {
19
+ 'tags' => 'tag',
20
+ 'parodies' => 'parody',
21
+ 'characters' => 'character',
22
+ 'artists' => 'artist',
23
+ 'groups' => 'group',
24
+ 'languages' => 'language',
25
+ 'categories' => 'category'
26
+ }.freeze
27
+
28
+ def parse_tiles(res)
29
+ res.map do |line|
30
+ id = line.match(%r{/g/(\d+)/})[1]
31
+ name = line.match(/<div class="caption">(.+)/)[1].strip
32
+ url = "/g/#{id}"
33
+
34
+ OpenStruct.new(id: id, name: name, url: url)
551
35
  end
552
36
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nhentai-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gael Roussel
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-17 00:00:00.000000000 Z
11
+ date: 2022-05-20 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: nhentai-api is a basic and easy to use API for nhentai.net
14
14
  email: gaelroussel@protonmail.com
@@ -17,13 +17,18 @@ extensions: []
17
17
  extra_rdoc_files: []
18
18
  files:
19
19
  - lib/nhentai-api.rb
20
+ - lib/nhentai-api/doujinshi.rb
21
+ - lib/nhentai-api/key.rb
22
+ - lib/nhentai-api/search.rb
20
23
  homepage: https://rubygems.org/gems/nhentai-api
21
24
  licenses:
22
25
  - MIT
23
26
  metadata:
24
- documentation_uri: https://www.rubydoc.info/github/groussel42/nhentai-api
25
27
  source_code_uri: https://github.com/Mraiih/nhentai-api
26
- post_install_message:
28
+ changelog_uri: https://github.com/Mraiih/nhentai-api/blob/master/CHANGELOG.md
29
+ documentation_uri: https://github.com/Mraiih/nhentai-api/wiki/Documentation
30
+ funding_uri: https://ko-fi.com/mraiih
31
+ post_install_message:
27
32
  rdoc_options: []
28
33
  require_paths:
29
34
  - lib
@@ -38,9 +43,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
38
43
  - !ruby/object:Gem::Version
39
44
  version: '0'
40
45
  requirements: []
41
- rubyforge_project:
42
- rubygems_version: 2.7.6
43
- signing_key:
46
+ rubygems_version: 3.1.6
47
+ signing_key:
44
48
  specification_version: 4
45
49
  summary: nhentai-api is a basic and easy to use API for nhentai.net
46
50
  test_files: []