mangadex 5.3.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 +7 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +81 -0
- data/LICENSE.txt +21 -0
- data/README.md +42 -0
- data/Rakefile +6 -0
- data/bin/console +23 -0
- data/bin/setup +8 -0
- data/lib/extensions.rb +12 -0
- data/lib/mangadex/README.md +93 -0
- data/lib/mangadex/api/context.rb +53 -0
- data/lib/mangadex/api/response.rb +104 -0
- data/lib/mangadex/api/user.rb +48 -0
- data/lib/mangadex/api/version.rb +21 -0
- data/lib/mangadex/api.rb +5 -0
- data/lib/mangadex/artist.rb +13 -0
- data/lib/mangadex/auth.rb +56 -0
- data/lib/mangadex/author.rb +101 -0
- data/lib/mangadex/chapter.rb +105 -0
- data/lib/mangadex/content_rating.rb +75 -0
- data/lib/mangadex/cover_art.rb +93 -0
- data/lib/mangadex/custom_list.rb +127 -0
- data/lib/mangadex/internal/definition.rb +162 -0
- data/lib/mangadex/internal/request.rb +121 -0
- data/lib/mangadex/internal/with_attributes.rb +120 -0
- data/lib/mangadex/internal.rb +3 -0
- data/lib/mangadex/manga.rb +188 -0
- data/lib/mangadex/mangadex_object.rb +62 -0
- data/lib/mangadex/relationship.rb +46 -0
- data/lib/mangadex/report_reason.rb +39 -0
- data/lib/mangadex/scanlation_group.rb +97 -0
- data/lib/mangadex/sorbet.rb +42 -0
- data/lib/mangadex/tag.rb +10 -0
- data/lib/mangadex/types.rb +24 -0
- data/lib/mangadex/upload.rb +78 -0
- data/lib/mangadex/user.rb +103 -0
- data/lib/mangadex/version.rb +4 -0
- data/lib/mangadex.rb +35 -0
- data/mangadex.gemspec +35 -0
- data/sorbet/config +3 -0
- data/sorbet/rbi/gems/activesupport.rbi +1267 -0
- data/sorbet/rbi/gems/coderay.rbi +285 -0
- data/sorbet/rbi/gems/concurrent-ruby.rbi +1662 -0
- data/sorbet/rbi/gems/domain_name.rbi +52 -0
- data/sorbet/rbi/gems/http-accept.rbi +101 -0
- data/sorbet/rbi/gems/http-cookie.rbi +119 -0
- data/sorbet/rbi/gems/i18n.rbi +133 -0
- data/sorbet/rbi/gems/method_source.rbi +64 -0
- data/sorbet/rbi/gems/mime-types-data.rbi +17 -0
- data/sorbet/rbi/gems/mime-types.rbi +218 -0
- data/sorbet/rbi/gems/netrc.rbi +51 -0
- data/sorbet/rbi/gems/pry.rbi +1898 -0
- data/sorbet/rbi/gems/psych.rbi +471 -0
- data/sorbet/rbi/gems/rake.rbi +660 -0
- data/sorbet/rbi/gems/rest-client.rbi +454 -0
- data/sorbet/rbi/gems/rspec-core.rbi +1939 -0
- data/sorbet/rbi/gems/rspec-expectations.rbi +1150 -0
- data/sorbet/rbi/gems/rspec-mocks.rbi +1100 -0
- data/sorbet/rbi/gems/rspec-support.rbi +280 -0
- data/sorbet/rbi/gems/rspec.rbi +15 -0
- data/sorbet/rbi/gems/tzinfo.rbi +586 -0
- data/sorbet/rbi/gems/unf.rbi +19 -0
- data/sorbet/rbi/hidden-definitions/errors.txt +3942 -0
- data/sorbet/rbi/hidden-definitions/hidden.rbi +8210 -0
- data/sorbet/rbi/sorbet-typed/lib/activesupport/>=6/activesupport.rbi +37 -0
- data/sorbet/rbi/sorbet-typed/lib/activesupport/all/activesupport.rbi +1850 -0
- data/sorbet/rbi/sorbet-typed/lib/minitest/all/minitest.rbi +108 -0
- data/sorbet/rbi/sorbet-typed/lib/rake/all/rake.rbi +645 -0
- data/sorbet/rbi/sorbet-typed/lib/rspec-core/all/rspec-core.rbi +1891 -0
- data/sorbet/rbi/todo.rbi +7 -0
- metadata +243 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
# typed: false
|
2
|
+
module Mangadex
|
3
|
+
class Auth
|
4
|
+
class << self
|
5
|
+
def login(username, password)
|
6
|
+
response = Mangadex::Internal::Request.post(
|
7
|
+
'/auth/login',
|
8
|
+
payload: {
|
9
|
+
username: username,
|
10
|
+
password: password,
|
11
|
+
},
|
12
|
+
)
|
13
|
+
return response if response.is_a?(Mangadex::Api::Response) && response.errored?
|
14
|
+
|
15
|
+
session = response.dig('token', 'session')
|
16
|
+
refresh = response.dig('token', 'refresh')
|
17
|
+
|
18
|
+
mangadex_user = Mangadex::Internal::Request.get('/user/me', headers: { Authorization: session })
|
19
|
+
|
20
|
+
user = Mangadex::Api::User.new(
|
21
|
+
mangadex_user.data.id,
|
22
|
+
session: session,
|
23
|
+
refresh: refresh,
|
24
|
+
data: mangadex_user.data,
|
25
|
+
)
|
26
|
+
Mangadex::Api::Context.user = user
|
27
|
+
!user.session_expired?
|
28
|
+
end
|
29
|
+
|
30
|
+
def check_token
|
31
|
+
JSON.parse(
|
32
|
+
Mangadex::Internal::Request.get(
|
33
|
+
'/auth/check',
|
34
|
+
raw: true,
|
35
|
+
)
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
def logout
|
40
|
+
return true if Mangadex::Api::Context.user.nil?
|
41
|
+
|
42
|
+
response = Mangadex::Internal::Request.post(
|
43
|
+
'/auth/logout',
|
44
|
+
)
|
45
|
+
return reponse if response.is_a?(Mangadex::Api::Response) && response.errored?
|
46
|
+
|
47
|
+
Mangadex::Api::Context.user = nil
|
48
|
+
true
|
49
|
+
end
|
50
|
+
|
51
|
+
def refresh_token
|
52
|
+
!(Mangadex::Api::Context.user&.refresh!).nil?
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# typed: true
|
2
|
+
|
3
|
+
require_relative 'mangadex_object'
|
4
|
+
|
5
|
+
module Mangadex
|
6
|
+
class Author < MangadexObject
|
7
|
+
has_attributes :name, :image_url, :biography, :version, :created_at, :updated_at
|
8
|
+
|
9
|
+
# List all authors.
|
10
|
+
# Path: +GET /author+
|
11
|
+
# Reference: https://api.mangadex.org/docs.html#operation/get-author
|
12
|
+
#
|
13
|
+
# @return [Mangadex::Api::Response] with a collection of authors
|
14
|
+
sig { params(args: T::Api::Arguments).returns(Mangadex::Api::Response[Author]) }
|
15
|
+
def self.list(**args)
|
16
|
+
Mangadex::Internal::Request.get(
|
17
|
+
'/author',
|
18
|
+
Mangadex::Internal::Definition.validate(args, {
|
19
|
+
limit: { accepts: Integer },
|
20
|
+
offset: { accepts: Integer },
|
21
|
+
ids: { accepts: [String] },
|
22
|
+
name: { accepts: String },
|
23
|
+
order: { accepts: Hash },
|
24
|
+
includes: { accepts: [String] },
|
25
|
+
})
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Create an author.
|
30
|
+
# Path: +POST /author+
|
31
|
+
# Reference: https://api.mangadex.org/docs.html#operation/post-author
|
32
|
+
#
|
33
|
+
# @return [Mangadex::Api::Response] with newly created author
|
34
|
+
sig { params(args: T::Api::Arguments).returns(Mangadex::Api::Response[Author]) }
|
35
|
+
def self.create(**args)
|
36
|
+
Mangadex::Internal::Request.post(
|
37
|
+
'/author',
|
38
|
+
payload: Mangadex::Internal::Definition.validate(args, {
|
39
|
+
name: { accepts: String, required: true },
|
40
|
+
version: { accepts: Integer },
|
41
|
+
})
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Get an author by ID.
|
46
|
+
# Path: +GET /author/:id+
|
47
|
+
# Reference: https://api.mangadex.org/docs.html#operation/get-author-id
|
48
|
+
#
|
49
|
+
# @return [Mangadex::Api::Response] with a entity of author
|
50
|
+
sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[Author]) }
|
51
|
+
def self.get(id, **args)
|
52
|
+
Mangadex::Internal::Request.get(
|
53
|
+
format('/author/%{id}', id: id),
|
54
|
+
Mangadex::Internal::Definition.validate(args, {
|
55
|
+
includes: { accepts: [String] },
|
56
|
+
})
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Update an author.
|
61
|
+
# Path: +POST /author/:id+
|
62
|
+
# Reference: https://api.mangadex.org/docs.html#operation/put-author-id
|
63
|
+
#
|
64
|
+
# @return [Mangadex::Api::Response] with a entity of author
|
65
|
+
sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[Author]) }
|
66
|
+
def self.update(id, **args)
|
67
|
+
Mangadex::Internal::Request.put(
|
68
|
+
format('/author/%{id}', id: id),
|
69
|
+
payload: Mangadex::Internal::Definition.validate(args, {
|
70
|
+
name: { accepts: String },
|
71
|
+
version: { accepts: Integer, required: true },
|
72
|
+
})
|
73
|
+
)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Delete an author.
|
77
|
+
# Path: +DELETE /author/:id+
|
78
|
+
# Reference: https://api.mangadex.org/docs.html#operation/delete-author-id
|
79
|
+
#
|
80
|
+
# @param id Author's ID
|
81
|
+
# @return [Hash]
|
82
|
+
sig { params(id: String).returns(Hash) }
|
83
|
+
def self.delete(id)
|
84
|
+
Mangadex::Internal::Request.delete(
|
85
|
+
format('/author/%{id}', id: id)
|
86
|
+
)
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.inspect_attributes
|
90
|
+
[:name]
|
91
|
+
end
|
92
|
+
|
93
|
+
# Indicates if this is an artist
|
94
|
+
#
|
95
|
+
# @return [Boolean] whether this is an artist or not.
|
96
|
+
sig { returns(T::Boolean) }
|
97
|
+
def artist?
|
98
|
+
false
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# typed: false
|
2
|
+
require_relative "mangadex_object"
|
3
|
+
|
4
|
+
module Mangadex
|
5
|
+
class Chapter < MangadexObject
|
6
|
+
include Internal::WithAttributes
|
7
|
+
|
8
|
+
has_attributes \
|
9
|
+
:title,
|
10
|
+
:volume,
|
11
|
+
:chapter,
|
12
|
+
:translated_language,
|
13
|
+
:hash,
|
14
|
+
:data,
|
15
|
+
:data_saver,
|
16
|
+
:last_chapter,
|
17
|
+
:uploader,
|
18
|
+
:external_url,
|
19
|
+
:version,
|
20
|
+
:created_at,
|
21
|
+
:updated_at,
|
22
|
+
:publish_at
|
23
|
+
|
24
|
+
sig { params(args: T::Api::Arguments).returns(Mangadex::Api::Response[Chapter]) }
|
25
|
+
def self.list(**args)
|
26
|
+
Mangadex::Internal::Request.get(
|
27
|
+
'/chapter',
|
28
|
+
Mangadex::Internal::Definition.chapter_list(args),
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[Chapter]) }
|
33
|
+
def self.get(id, **args)
|
34
|
+
Mangadex::Internal::Request.get(
|
35
|
+
'/chapter/%{id}' % {id: id},
|
36
|
+
Mangadex::Internal::Definition.validate(args, {
|
37
|
+
includes: { accepts: [String] },
|
38
|
+
}),
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[Chapter]) }
|
43
|
+
def self.update(id, **args)
|
44
|
+
Mangadex::Internal::Request.put(
|
45
|
+
'/chapter/%{id}' % {id: id},
|
46
|
+
payload: Mangadex::Internal::Definition.validate(args, {
|
47
|
+
title: { accepts: String },
|
48
|
+
volume: { accepts: String },
|
49
|
+
chapter: { accepts: String },
|
50
|
+
translated_language: { accepts: %r{^[a-zA-Z\-]{2,5}$} },
|
51
|
+
groups: { accepts: [String] },
|
52
|
+
version: { accepts: Integer, required: true },
|
53
|
+
}),
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
sig { params(id: String).returns(Hash) }
|
58
|
+
def self.delete(id)
|
59
|
+
Mangadex::Internal::Request.delete(
|
60
|
+
'/chapter/%{id}' % {id: id},
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
sig { returns(String) }
|
65
|
+
def title
|
66
|
+
attributes&.title.presence || chapter.presence && "Chapter #{chapter}" || "N/A"
|
67
|
+
end
|
68
|
+
|
69
|
+
sig { returns(T.nilable(String)) }
|
70
|
+
def locale
|
71
|
+
found_locale = translated_language.split('-').first
|
72
|
+
return if found_locale.nil?
|
73
|
+
|
74
|
+
ISO_639.find(found_locale)
|
75
|
+
end
|
76
|
+
|
77
|
+
sig { returns(T.nilable(String)) }
|
78
|
+
def locale_name
|
79
|
+
locale&.english_name
|
80
|
+
end
|
81
|
+
|
82
|
+
sig { returns(Integer) }
|
83
|
+
def page_count
|
84
|
+
Array(data).count
|
85
|
+
end
|
86
|
+
|
87
|
+
sig { returns(T.nilable(String)) }
|
88
|
+
def preview_image_url
|
89
|
+
return if data_saver.empty?
|
90
|
+
|
91
|
+
"https://uploads.mangadex.org/data-saver/#{attributes.hash}/#{data_saver.first}"
|
92
|
+
end
|
93
|
+
|
94
|
+
def as_json(*)
|
95
|
+
super.merge({
|
96
|
+
locale_name: locale_name,
|
97
|
+
preview_image_url: preview_image_url,
|
98
|
+
})
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.attributes_to_inspect
|
102
|
+
[:id, :type, :title, :volume, :chapter, :page_count, :publish_at]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# typed: false
|
2
|
+
require "active_support/string_inquirer"
|
3
|
+
require "active_support/core_ext/module/delegation"
|
4
|
+
|
5
|
+
module Mangadex
|
6
|
+
class ContentRating
|
7
|
+
extend T::Sig
|
8
|
+
include Comparable
|
9
|
+
|
10
|
+
VALUES = [
|
11
|
+
SAFE = 'safe',
|
12
|
+
SUGGESTIVE = 'suggestive',
|
13
|
+
EROTICA = 'erotica',
|
14
|
+
PORNOGRAPHIC = 'pornographic',
|
15
|
+
].freeze
|
16
|
+
|
17
|
+
SCORES = {
|
18
|
+
SAFE => 0,
|
19
|
+
SUGGESTIVE => 1,
|
20
|
+
EROTICA => 2,
|
21
|
+
PORNOGRAPHIC => 3,
|
22
|
+
}.freeze
|
23
|
+
|
24
|
+
delegate_missing_to :value
|
25
|
+
|
26
|
+
sig { params(content_rating: T::Api::ContentRating).returns(T::Array[ContentRating]) }
|
27
|
+
def self.anything_below(content_rating)
|
28
|
+
SCORES.keys.map { |key| ContentRating.new(key) }.select { |record| record <= content_rating }.sort
|
29
|
+
end
|
30
|
+
|
31
|
+
sig { params(value: T.any(T::Api::Text, T::Api::ContentRating)).void }
|
32
|
+
def initialize(value)
|
33
|
+
@value = ensure_value!(value.to_s)
|
34
|
+
end
|
35
|
+
|
36
|
+
sig { returns(ActiveSupport::StringInquirer) }
|
37
|
+
def value
|
38
|
+
ActiveSupport::StringInquirer.new(@value)
|
39
|
+
end
|
40
|
+
|
41
|
+
sig { params(other: T.any(ContentRating, String, Symbol)).returns(Integer) }
|
42
|
+
def <=>(other)
|
43
|
+
other_score = if other.is_a?(ContentRating)
|
44
|
+
other.score
|
45
|
+
else
|
46
|
+
ContentRating.new(other).score
|
47
|
+
end
|
48
|
+
|
49
|
+
score <=> other_score
|
50
|
+
end
|
51
|
+
|
52
|
+
alias_method :safer_than?, :<
|
53
|
+
alias_method :spicier_than?, :>
|
54
|
+
|
55
|
+
sig { returns(Integer) }
|
56
|
+
def score
|
57
|
+
SCORES[value]
|
58
|
+
end
|
59
|
+
|
60
|
+
sig { returns(String) }
|
61
|
+
def to_s
|
62
|
+
value.to_s
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
sig { params(value: T.any(T::Api::Text, T::Api::ContentRating)).void }
|
68
|
+
def ensure_value!(value)
|
69
|
+
return value if value.is_a?(ContentRating)
|
70
|
+
return value if VALUES.include?(value)
|
71
|
+
|
72
|
+
raise ArgumentError, "Invalid content rating: '#{value}'. Must be one of #{VALUES}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# typed: false
|
2
|
+
require_relative "mangadex_object"
|
3
|
+
|
4
|
+
module Mangadex
|
5
|
+
class CoverArt < MangadexObject
|
6
|
+
has_attributes \
|
7
|
+
:description,
|
8
|
+
:volume,
|
9
|
+
:file_name,
|
10
|
+
:created_at,
|
11
|
+
:updated_at,
|
12
|
+
:version
|
13
|
+
|
14
|
+
sig { params(args: T::Api::Arguments).returns(Mangadex::Api::Response[CoverArt]) }
|
15
|
+
def self.list(**args)
|
16
|
+
Mangadex::Internal::Request.get(
|
17
|
+
'/cover',
|
18
|
+
Mangadex::Internal::Definition.validate(args, {
|
19
|
+
limit: { accepts: Integer },
|
20
|
+
offset: { accepts: Integer },
|
21
|
+
manga: { accepts: [String] },
|
22
|
+
ids: { accepts: [String] },
|
23
|
+
uploaders: { accepts: [String] },
|
24
|
+
order: { accepts: Hash },
|
25
|
+
includes: { accepts: [String] },
|
26
|
+
})
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
sig do
|
31
|
+
params(
|
32
|
+
file: String,
|
33
|
+
volume: T.nilable(T.any(String, Integer)),
|
34
|
+
manga_id: String,
|
35
|
+
).returns(Mangadex::Api::Response[CoverArt])
|
36
|
+
end
|
37
|
+
def self.upload(file, volume=nil, manga_id:)
|
38
|
+
args = { file: file, volume: volume }
|
39
|
+
Mangadex::Internal::Request.post(
|
40
|
+
'/cover/%{manga_id}' % {manga_id: manga_id},
|
41
|
+
payload: Mangadex::Internal::Definition.validate(args, {
|
42
|
+
file: { accepts: String, required: true },
|
43
|
+
volume: { accepts: %r{^(0|[1-9]\\d*)((\\.\\d+){1,2})?[a-z]?$} } # todo: double check regexp here
|
44
|
+
})
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[CoverArt]) }
|
49
|
+
def self.get(id, **args)
|
50
|
+
Mangadex::Internal::Request.get(
|
51
|
+
'/cover/%{id}' % {id: id},
|
52
|
+
Mangadex::Internal::Definition.validate(args, {
|
53
|
+
includes: { accepts: [String] },
|
54
|
+
})
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[CoverArt]) }
|
59
|
+
def self.edit(id, **args)
|
60
|
+
Mangadex::Internal::Request.put(
|
61
|
+
'/cover/%{id}' % {id: id},
|
62
|
+
Mangadex::Internal::Definition.validate(args, {
|
63
|
+
volume: { accepts: String },
|
64
|
+
description: { accepts: String },
|
65
|
+
version: { accepts: Integer, required: true }
|
66
|
+
})
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
sig { params(id: String).returns(Hash) }
|
71
|
+
def self.delete(id)
|
72
|
+
Mangadex::Internal::Request.delete(
|
73
|
+
'/cover/%{id}' % {id: id},
|
74
|
+
)
|
75
|
+
end
|
76
|
+
|
77
|
+
sig { params(size: T::Api::Text).returns(T.nilable(String)) }
|
78
|
+
def image_url(size: :small)
|
79
|
+
return unless manga.present?
|
80
|
+
|
81
|
+
extension = case size.to_sym
|
82
|
+
when :original
|
83
|
+
''
|
84
|
+
when :medium
|
85
|
+
'.512.jpg'
|
86
|
+
else # :small by default
|
87
|
+
'.256.jpg'
|
88
|
+
end
|
89
|
+
|
90
|
+
"https://uploads.mangadex.org/covers/#{manga.id}/#{file_name}#{extension}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
# typed: false
|
2
|
+
require_relative "mangadex_object"
|
3
|
+
|
4
|
+
module Mangadex
|
5
|
+
class CustomList < MangadexObject
|
6
|
+
has_attributes \
|
7
|
+
:name,
|
8
|
+
:visibility,
|
9
|
+
:version
|
10
|
+
|
11
|
+
sig { params(args: T::Api::Arguments).returns(Mangadex::Api::Response[CustomList]) }
|
12
|
+
def self.create(**args)
|
13
|
+
Mangadex::Internal::Request.post(
|
14
|
+
'/list',
|
15
|
+
payload: Mangadex::Internal::Definition.validate(args, {
|
16
|
+
name: { accepts: String, required: true },
|
17
|
+
visibility: { accepts: %w(public private), converts: :to_s },
|
18
|
+
manga: { accepts: String },
|
19
|
+
version: { accepts: Integer },
|
20
|
+
}),
|
21
|
+
auth: true,
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
sig { params(id: String).returns(Mangadex::Api::Response[CustomList]) }
|
26
|
+
def self.get(id)
|
27
|
+
Mangadex::Internal::Request.get(
|
28
|
+
'/list/%{id}' % {id: id},
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[CustomList]) }
|
33
|
+
def self.update(id, **args)
|
34
|
+
Mangadex::Internal::Request.put(
|
35
|
+
'/list/%{id}' % {id: id},
|
36
|
+
payload: Mangadex::Internal::Definition.validate(args, {
|
37
|
+
name: { accepts: String },
|
38
|
+
visibility: { accepts: %w(private public) },
|
39
|
+
manga: { accepts: String },
|
40
|
+
version: { accepts: Integer, required: true },
|
41
|
+
})
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
sig { params(id: String).returns(T::Boolean) }
|
46
|
+
def self.delete(id)
|
47
|
+
Mangadex::Internal::Request.delete(
|
48
|
+
'/list/%{id}' % {id: id},
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[Chapter]) }
|
53
|
+
def self.feed(id, **args)
|
54
|
+
Mangadex::Internal::Request.get(
|
55
|
+
'/list/%{id}/feed' % {id: id},
|
56
|
+
Mangadex::Internal::Definition.chapter_list(args),
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
sig { params(id: String, list_id: String).returns(T::Boolean) }
|
61
|
+
def self.add_manga(id, list_id:)
|
62
|
+
response = Mangadex::Internal::Request.post(
|
63
|
+
'/manga/%{id}/list/%{list_id}' % {id: id, list_id: list_id},
|
64
|
+
)
|
65
|
+
if response.is_a?(Hash)
|
66
|
+
response['result'] == 'ok'
|
67
|
+
else
|
68
|
+
!response.errored?
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
sig { params(id: String, list_id: String).returns(T::Boolean) }
|
73
|
+
def self.remove_manga(id, list_id:)
|
74
|
+
response = Mangadex::Internal::Request.delete(
|
75
|
+
'/manga/%{id}/list/%{list_id}' % {id: id, list_id: list_id},
|
76
|
+
)
|
77
|
+
if response.is_a?(Hash)
|
78
|
+
response['result'] == 'ok'
|
79
|
+
else
|
80
|
+
!response.errored?
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
sig { params(args: T::Api::Arguments).returns(Mangadex::Api::Response[CustomList]) }
|
85
|
+
def self.list(**args)
|
86
|
+
Mangadex::Internal::Request.get(
|
87
|
+
'/user/list',
|
88
|
+
Mangadex::Internal::Definition.validate(args, {
|
89
|
+
limit: { accepts: Integer },
|
90
|
+
offset: { accepts: Integer },
|
91
|
+
}),
|
92
|
+
)
|
93
|
+
end
|
94
|
+
|
95
|
+
sig { params(user_id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[CustomList]) }
|
96
|
+
def self.user_list(user_id, **args)
|
97
|
+
Mangadex::Internal::Request.get(
|
98
|
+
'/user/%{id}/list' % {id: user_id},
|
99
|
+
Mangadex::Internal::Definition.validate(args, {
|
100
|
+
limit: { accepts: Integer },
|
101
|
+
offset: { accepts: Integer },
|
102
|
+
}),
|
103
|
+
)
|
104
|
+
end
|
105
|
+
|
106
|
+
sig { params(id: String).returns(T::Boolean) }
|
107
|
+
def add_manga(id)
|
108
|
+
Mangadex::CustomList.add_manga(id, list_id: self.id)
|
109
|
+
end
|
110
|
+
|
111
|
+
sig { params(id: String).returns(T::Boolean) }
|
112
|
+
def remove_manga(id)
|
113
|
+
Mangadex::CustomList.remove_manga(id, list_id: self.id)
|
114
|
+
end
|
115
|
+
|
116
|
+
sig { params(args: T::Api::Arguments).returns(T.nilable(Mangadex::Api::Response[Manga])) }
|
117
|
+
def manga_details(**args)
|
118
|
+
ids = mangas.map(&:id)
|
119
|
+
ids.any? ? Mangadex::Manga.list(**args.merge(ids: ids)) : nil
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.inspect_attributes
|
123
|
+
[:name, :visibility]
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|