mangadex 5.3.1.3 → 5.3.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +2 -2
- data/README.md +1 -1
- data/bin/console +4 -3
- data/docs/authentication.md +226 -0
- data/docs/context.md +93 -0
- data/lib/config.rb +50 -0
- data/lib/errors.rb +42 -0
- data/lib/mangadex/README.md +6 -2
- data/lib/mangadex/api/response.rb +13 -2
- data/lib/mangadex/api/user.rb +51 -7
- data/lib/mangadex/api/version_checker.rb +1 -1
- data/lib/mangadex/api.rb +0 -1
- data/lib/mangadex/auth.rb +42 -13
- data/lib/mangadex/author.rb +28 -1
- data/lib/mangadex/chapter.rb +11 -0
- data/lib/mangadex/content_rating.rb +6 -1
- data/lib/mangadex/cover_art.rb +11 -0
- data/lib/mangadex/custom_list.rb +20 -0
- data/lib/mangadex/internal/context.rb +141 -0
- data/lib/mangadex/internal/definition.rb +13 -0
- data/lib/mangadex/internal/request.rb +29 -10
- data/lib/mangadex/internal/with_attributes.rb +11 -2
- data/lib/mangadex/internal.rb +1 -0
- data/lib/mangadex/manga.rb +25 -3
- data/lib/mangadex/relationship.rb +35 -13
- data/lib/mangadex/scanlation_group.rb +8 -0
- data/lib/mangadex/sorbet.rb +1 -1
- data/lib/mangadex/storage/basic.rb +18 -0
- data/lib/mangadex/storage/memory.rb +23 -0
- data/lib/mangadex/storage/none.rb +9 -0
- data/lib/mangadex/storage.rb +3 -0
- data/lib/mangadex/tag.rb +5 -0
- data/lib/mangadex/upload.rb +10 -0
- data/lib/mangadex/user.rb +9 -2
- data/lib/mangadex/version.rb +2 -2
- data/lib/mangadex.rb +25 -12
- metadata +15 -7
- data/lib/mangadex/api/context.rb +0 -63
data/lib/mangadex/auth.rb
CHANGED
@@ -3,16 +3,20 @@ module Mangadex
|
|
3
3
|
class Auth
|
4
4
|
extend T::Sig
|
5
5
|
|
6
|
-
sig { params(username: String, password: String).returns(T.
|
7
|
-
def self.login(username, password)
|
6
|
+
sig { params(username: T.nilable(String), email: T.nilable(String), password: String).returns(T.nilable(Mangadex::Api::User)) }
|
7
|
+
def self.login(username: nil, email: nil, password: nil)
|
8
|
+
args = { password: password }
|
9
|
+
args.merge!(email: email) if email
|
10
|
+
args.merge!(username: username) if username
|
11
|
+
|
8
12
|
response = Mangadex::Internal::Request.post(
|
9
13
|
'/auth/login',
|
10
|
-
payload: {
|
11
|
-
username:
|
12
|
-
|
13
|
-
|
14
|
+
payload: Mangadex::Internal::Definition.validate(args, {
|
15
|
+
username: { accepts: String },
|
16
|
+
email: { accepts: String },
|
17
|
+
password: { accepts: String, required: true },
|
18
|
+
}),
|
14
19
|
)
|
15
|
-
return response if response.is_a?(Mangadex::Api::Response) && response.errored?
|
16
20
|
|
17
21
|
session = response.dig('token', 'session')
|
18
22
|
refresh = response.dig('token', 'refresh')
|
@@ -20,13 +24,19 @@ module Mangadex
|
|
20
24
|
mangadex_user = Mangadex::Internal::Request.get('/user/me', headers: { Authorization: session })
|
21
25
|
|
22
26
|
user = Mangadex::Api::User.new(
|
23
|
-
mangadex_user.data.id,
|
27
|
+
mangadex_user_id: mangadex_user.data.id,
|
24
28
|
session: session,
|
25
29
|
refresh: refresh,
|
26
30
|
data: mangadex_user.data,
|
27
31
|
)
|
28
|
-
|
29
|
-
|
32
|
+
return if user.session_expired?
|
33
|
+
|
34
|
+
Mangadex.context.user = user
|
35
|
+
|
36
|
+
user.persist
|
37
|
+
user
|
38
|
+
rescue Errors::UnauthorizedError => error
|
39
|
+
raise Errors::AuthenticationError.new(error.response)
|
30
40
|
end
|
31
41
|
|
32
42
|
sig { returns(Hash) }
|
@@ -41,20 +51,39 @@ module Mangadex
|
|
41
51
|
|
42
52
|
sig { returns(T.any(T::Boolean, Mangadex::Api::Response)) }
|
43
53
|
def self.logout
|
44
|
-
return true if Mangadex
|
54
|
+
return true if Mangadex.context.user.nil?
|
45
55
|
|
46
56
|
response = Mangadex::Internal::Request.post(
|
47
57
|
'/auth/logout',
|
48
58
|
)
|
49
59
|
return reponse if response.is_a?(Mangadex::Api::Response) && response.errored?
|
50
60
|
|
51
|
-
|
61
|
+
clear_user
|
62
|
+
true
|
63
|
+
rescue Mangadex::Errors::UnauthorizedError
|
64
|
+
clear_user
|
52
65
|
true
|
53
66
|
end
|
54
67
|
|
55
68
|
sig { returns(T::Boolean) }
|
56
69
|
def self.refresh_token
|
57
|
-
!(Mangadex
|
70
|
+
!(Mangadex.context.user&.refresh!).nil?
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
sig { void }
|
76
|
+
def self.clear_user
|
77
|
+
return if Mangadex.context.user.nil?
|
78
|
+
|
79
|
+
if Mangadex.context.user.respond_to?(:session=)
|
80
|
+
Mangadex.context.user.session = nil
|
81
|
+
end
|
82
|
+
if Mangadex.context.user.respond_to?(:refresh=)
|
83
|
+
Mangadex.context.user.refresh = nil
|
84
|
+
end
|
85
|
+
Mangadex.storage.clear(Mangadex.context.user.mangadex_user_id)
|
86
|
+
Mangadex.context.user = nil
|
58
87
|
end
|
59
88
|
end
|
60
89
|
end
|
data/lib/mangadex/author.rb
CHANGED
@@ -4,7 +4,24 @@ require_relative 'mangadex_object'
|
|
4
4
|
|
5
5
|
module Mangadex
|
6
6
|
class Author < MangadexObject
|
7
|
-
has_attributes
|
7
|
+
has_attributes \
|
8
|
+
:name,
|
9
|
+
:image_url,
|
10
|
+
:biography,
|
11
|
+
:twitter,
|
12
|
+
:pixiv,
|
13
|
+
:melon_book,
|
14
|
+
:fan_box,
|
15
|
+
:booth,
|
16
|
+
:nico_video,
|
17
|
+
:skeb,
|
18
|
+
:fantia,
|
19
|
+
:tumblr,
|
20
|
+
:youtube,
|
21
|
+
:website,
|
22
|
+
:version,
|
23
|
+
:created_at,
|
24
|
+
:updated_at
|
8
25
|
|
9
26
|
# List all authors.
|
10
27
|
# Path: +GET /author+
|
@@ -49,6 +66,8 @@ module Mangadex
|
|
49
66
|
# @return [Mangadex::Api::Response] with a entity of author
|
50
67
|
sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[Author]) }
|
51
68
|
def self.get(id, **args)
|
69
|
+
Mangadex::Internal::Definition.must(id)
|
70
|
+
|
52
71
|
Mangadex::Internal::Request.get(
|
53
72
|
format('/author/%{id}', id: id),
|
54
73
|
Mangadex::Internal::Definition.validate(args, {
|
@@ -64,6 +83,8 @@ module Mangadex
|
|
64
83
|
# @return [Mangadex::Api::Response] with a entity of author
|
65
84
|
sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[Author]) }
|
66
85
|
def self.update(id, **args)
|
86
|
+
Mangadex::Internal::Definition.must(id)
|
87
|
+
|
67
88
|
Mangadex::Internal::Request.put(
|
68
89
|
format('/author/%{id}', id: id),
|
69
90
|
payload: Mangadex::Internal::Definition.validate(args, {
|
@@ -81,6 +102,8 @@ module Mangadex
|
|
81
102
|
# @return [Hash]
|
82
103
|
sig { params(id: String).returns(Hash) }
|
83
104
|
def self.delete(id)
|
105
|
+
Mangadex::Internal::Definition.must(id)
|
106
|
+
|
84
107
|
Mangadex::Internal::Request.delete(
|
85
108
|
format('/author/%{id}', id: id)
|
86
109
|
)
|
@@ -90,6 +113,10 @@ module Mangadex
|
|
90
113
|
[:name]
|
91
114
|
end
|
92
115
|
|
116
|
+
class << self
|
117
|
+
alias_method :view, :get
|
118
|
+
end
|
119
|
+
|
93
120
|
# Indicates if this is an artist
|
94
121
|
#
|
95
122
|
# @return [Boolean] whether this is an artist or not.
|
data/lib/mangadex/chapter.rb
CHANGED
@@ -26,11 +26,14 @@ module Mangadex
|
|
26
26
|
Mangadex::Internal::Request.get(
|
27
27
|
'/chapter',
|
28
28
|
Mangadex::Internal::Definition.chapter_list(args),
|
29
|
+
content_rating: true,
|
29
30
|
)
|
30
31
|
end
|
31
32
|
|
32
33
|
sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[Chapter]) }
|
33
34
|
def self.get(id, **args)
|
35
|
+
Mangadex::Internal::Definition.must(id)
|
36
|
+
|
34
37
|
Mangadex::Internal::Request.get(
|
35
38
|
'/chapter/%{id}' % {id: id},
|
36
39
|
Mangadex::Internal::Definition.validate(args, {
|
@@ -41,6 +44,8 @@ module Mangadex
|
|
41
44
|
|
42
45
|
sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[Chapter]) }
|
43
46
|
def self.update(id, **args)
|
47
|
+
Mangadex::Internal::Definition.must(id)
|
48
|
+
|
44
49
|
Mangadex::Internal::Request.put(
|
45
50
|
'/chapter/%{id}' % {id: id},
|
46
51
|
payload: Mangadex::Internal::Definition.validate(args, {
|
@@ -56,11 +61,17 @@ module Mangadex
|
|
56
61
|
|
57
62
|
sig { params(id: String).returns(Hash) }
|
58
63
|
def self.delete(id)
|
64
|
+
Mangadex::Internal::Definition.must(id)
|
65
|
+
|
59
66
|
Mangadex::Internal::Request.delete(
|
60
67
|
'/chapter/%{id}' % {id: id},
|
61
68
|
)
|
62
69
|
end
|
63
70
|
|
71
|
+
class << self
|
72
|
+
alias_method :view, :get
|
73
|
+
end
|
74
|
+
|
64
75
|
sig { returns(String) }
|
65
76
|
def title
|
66
77
|
attributes&.title.presence || chapter.presence && "Chapter #{chapter}" || "N/A"
|
@@ -28,6 +28,11 @@ module Mangadex
|
|
28
28
|
SCORES.keys.map { |key| ContentRating.new(key) }.select { |record| record <= content_rating }.sort
|
29
29
|
end
|
30
30
|
|
31
|
+
sig { params(content_ratings: T::Array[T.any(T::Api::Text, T::Api::ContentRating)]).returns(T::Array[ContentRating]) }
|
32
|
+
def self.parse(content_ratings)
|
33
|
+
content_ratings.map { |content_rating| ContentRating.new(content_rating) }.uniq
|
34
|
+
end
|
35
|
+
|
31
36
|
sig { params(value: T.any(T::Api::Text, T::Api::ContentRating)).void }
|
32
37
|
def initialize(value)
|
33
38
|
@value = ensure_value!(value.to_s)
|
@@ -64,7 +69,7 @@ module Mangadex
|
|
64
69
|
|
65
70
|
private
|
66
71
|
|
67
|
-
sig { params(value: T.any(T::Api::Text, T::Api::ContentRating)).
|
72
|
+
sig { params(value: T.any(T::Api::Text, T::Api::ContentRating)).returns(T.any(T::Api::Text, T::Api::ContentRating)) }
|
68
73
|
def ensure_value!(value)
|
69
74
|
return value if value.is_a?(ContentRating)
|
70
75
|
return value if VALUES.include?(value)
|
data/lib/mangadex/cover_art.rb
CHANGED
@@ -47,6 +47,8 @@ module Mangadex
|
|
47
47
|
|
48
48
|
sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[CoverArt]) }
|
49
49
|
def self.get(id, **args)
|
50
|
+
Mangadex::Internal::Definition.must(id)
|
51
|
+
|
50
52
|
Mangadex::Internal::Request.get(
|
51
53
|
'/cover/%{id}' % {id: id},
|
52
54
|
Mangadex::Internal::Definition.validate(args, {
|
@@ -57,6 +59,8 @@ module Mangadex
|
|
57
59
|
|
58
60
|
sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[CoverArt]) }
|
59
61
|
def self.edit(id, **args)
|
62
|
+
Mangadex::Internal::Definition.must(id)
|
63
|
+
|
60
64
|
Mangadex::Internal::Request.put(
|
61
65
|
'/cover/%{id}' % {id: id},
|
62
66
|
Mangadex::Internal::Definition.validate(args, {
|
@@ -69,11 +73,18 @@ module Mangadex
|
|
69
73
|
|
70
74
|
sig { params(id: String).returns(Hash) }
|
71
75
|
def self.delete(id)
|
76
|
+
Mangadex::Internal::Definition.must(id)
|
77
|
+
|
72
78
|
Mangadex::Internal::Request.delete(
|
73
79
|
'/cover/%{id}' % {id: id},
|
74
80
|
)
|
75
81
|
end
|
76
82
|
|
83
|
+
class << self
|
84
|
+
alias_method :view, :get
|
85
|
+
alias_method :update, :edit
|
86
|
+
end
|
87
|
+
|
77
88
|
sig { params(size: T::Api::Text).returns(T.nilable(String)) }
|
78
89
|
def image_url(size: :small)
|
79
90
|
return unless manga.present?
|
data/lib/mangadex/custom_list.rb
CHANGED
@@ -24,6 +24,8 @@ module Mangadex
|
|
24
24
|
|
25
25
|
sig { params(id: String).returns(Mangadex::Api::Response[CustomList]) }
|
26
26
|
def self.get(id)
|
27
|
+
Mangadex::Internal::Definition.must(id)
|
28
|
+
|
27
29
|
Mangadex::Internal::Request.get(
|
28
30
|
'/list/%{id}' % {id: id},
|
29
31
|
)
|
@@ -31,6 +33,8 @@ module Mangadex
|
|
31
33
|
|
32
34
|
sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[CustomList]) }
|
33
35
|
def self.update(id, **args)
|
36
|
+
Mangadex::Internal::Definition.must(id)
|
37
|
+
|
34
38
|
Mangadex::Internal::Request.put(
|
35
39
|
'/list/%{id}' % {id: id},
|
36
40
|
payload: Mangadex::Internal::Definition.validate(args, {
|
@@ -44,6 +48,8 @@ module Mangadex
|
|
44
48
|
|
45
49
|
sig { params(id: String).returns(T::Boolean) }
|
46
50
|
def self.delete(id)
|
51
|
+
Mangadex::Internal::Definition.must(id)
|
52
|
+
|
47
53
|
Mangadex::Internal::Request.delete(
|
48
54
|
'/list/%{id}' % {id: id},
|
49
55
|
)
|
@@ -51,14 +57,19 @@ module Mangadex
|
|
51
57
|
|
52
58
|
sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[Chapter]) }
|
53
59
|
def self.feed(id, **args)
|
60
|
+
Mangadex::Internal::Definition.must(id)
|
61
|
+
|
54
62
|
Mangadex::Internal::Request.get(
|
55
63
|
'/list/%{id}/feed' % {id: id},
|
56
64
|
Mangadex::Internal::Definition.chapter_list(args),
|
65
|
+
content_rating: true,
|
57
66
|
)
|
58
67
|
end
|
59
68
|
|
60
69
|
sig { params(id: String, list_id: String).returns(T::Boolean) }
|
61
70
|
def self.add_manga(id, list_id:)
|
71
|
+
Mangadex::Internal::Definition.must(id)
|
72
|
+
|
62
73
|
response = Mangadex::Internal::Request.post(
|
63
74
|
'/manga/%{id}/list/%{list_id}' % {id: id, list_id: list_id},
|
64
75
|
)
|
@@ -71,6 +82,8 @@ module Mangadex
|
|
71
82
|
|
72
83
|
sig { params(id: String, list_id: String).returns(T::Boolean) }
|
73
84
|
def self.remove_manga(id, list_id:)
|
85
|
+
Mangadex::Internal::Definition.must(id)
|
86
|
+
|
74
87
|
response = Mangadex::Internal::Request.delete(
|
75
88
|
'/manga/%{id}/list/%{list_id}' % {id: id, list_id: list_id},
|
76
89
|
)
|
@@ -94,6 +107,8 @@ module Mangadex
|
|
94
107
|
|
95
108
|
sig { params(user_id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[CustomList]) }
|
96
109
|
def self.user_list(user_id, **args)
|
110
|
+
Mangadex::Internal::Definition.must(user_id)
|
111
|
+
|
97
112
|
Mangadex::Internal::Request.get(
|
98
113
|
'/user/%{id}/list' % {id: user_id},
|
99
114
|
Mangadex::Internal::Definition.validate(args, {
|
@@ -103,6 +118,11 @@ module Mangadex
|
|
103
118
|
)
|
104
119
|
end
|
105
120
|
|
121
|
+
class << self
|
122
|
+
alias_method :view, :get
|
123
|
+
alias_method :edit, :update
|
124
|
+
end
|
125
|
+
|
106
126
|
sig { params(id: String).returns(T::Boolean) }
|
107
127
|
def add_manga(id)
|
108
128
|
Mangadex::CustomList.add_manga(id, list_id: self.id)
|
@@ -0,0 +1,141 @@
|
|
1
|
+
# typed: true
|
2
|
+
module Mangadex
|
3
|
+
module Internal
|
4
|
+
class Context
|
5
|
+
extend T::Sig
|
6
|
+
|
7
|
+
sig { returns(T::Array[Mangadex::ContentRating]) }
|
8
|
+
attr_accessor :allowed_content_ratings, :ignore_user
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@allowed_content_ratings = Mangadex.configuration.default_content_ratings
|
12
|
+
end
|
13
|
+
|
14
|
+
sig { returns(T.nilable(String)) }
|
15
|
+
def version
|
16
|
+
@version ||= Mangadex::Api::VersionChecker.check_mangadex_version
|
17
|
+
end
|
18
|
+
|
19
|
+
sig { returns(T.nilable(Mangadex::Api::User)) }
|
20
|
+
def user
|
21
|
+
@ignore_user ? nil : @user&.with_valid_session
|
22
|
+
rescue Mangadex::Errors::UnauthorizedError
|
23
|
+
warn("A user is present but not authenticated!")
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
|
27
|
+
sig { returns(T::Array[Mangadex::Tag]) }
|
28
|
+
def tags
|
29
|
+
@tags ||= Mangadex::Tag.list.data
|
30
|
+
end
|
31
|
+
|
32
|
+
sig { params(user: T.nilable(T.any(Hash, Mangadex::Api::User, Mangadex::User)), block: T.proc.returns(T.untyped)).returns(T.untyped) }
|
33
|
+
def with_user(user, &block)
|
34
|
+
temp_set_value("user", user) do
|
35
|
+
yield
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
sig { params(block: T.proc.returns(T.untyped)).returns(T.untyped) }
|
40
|
+
def without_user(&block)
|
41
|
+
temp_set_value("ignore_user", true) do
|
42
|
+
yield
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
sig { params(user: T.nilable(T.untyped)).void }
|
47
|
+
def user=(user)
|
48
|
+
if user.is_a?(Mangadex::Api::User)
|
49
|
+
@user = user
|
50
|
+
elsif user.is_a?(Mangadex::User)
|
51
|
+
@user = Mangadex::Api::User.new(
|
52
|
+
mangadex_user_id: user.id,
|
53
|
+
data: user,
|
54
|
+
)
|
55
|
+
elsif user.is_a?(Hash)
|
56
|
+
user = Mangadex::Internal::Definition.validate(user, {
|
57
|
+
mangadex_user_id: { accepts: String, required: true },
|
58
|
+
session: { accepts: String },
|
59
|
+
refresh: { accepts: String },
|
60
|
+
})
|
61
|
+
|
62
|
+
@user = Mangadex::Api::User.new(
|
63
|
+
mangadex_user_id: user[:mangadex_user_id],
|
64
|
+
session: user[:session],
|
65
|
+
refresh: user[:refresh],
|
66
|
+
)
|
67
|
+
elsif user_object?(user)
|
68
|
+
@user = Mangadex::Api::User.new(
|
69
|
+
mangadex_user_id: user.mangadex_user_id.to_s,
|
70
|
+
session: user.session,
|
71
|
+
refresh: user.refresh,
|
72
|
+
data: user,
|
73
|
+
)
|
74
|
+
elsif user.nil?
|
75
|
+
@user = nil
|
76
|
+
else
|
77
|
+
raise TypeError, "Invalid user type."
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def allow_content_ratings(*content_ratings, &block)
|
82
|
+
content_ratings = Mangadex::ContentRating.parse(Array(content_ratings))
|
83
|
+
if block_given?
|
84
|
+
content_ratings = Mangadex.context.allowed_content_ratings if content_ratings.empty?
|
85
|
+
|
86
|
+
# set temporarily
|
87
|
+
temp_set_value("allowed_content_ratings", content_ratings) do
|
88
|
+
yield
|
89
|
+
end
|
90
|
+
elsif content_ratings.any?
|
91
|
+
# set "permanently"
|
92
|
+
@allowed_content_ratings = content_ratings
|
93
|
+
else
|
94
|
+
# This is to throw an exception prompting to pass a block if there no params.
|
95
|
+
yield
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def with_allowed_content_ratings(*other_content_ratings, &block)
|
100
|
+
T.unsafe(self).allow_content_ratings(*(allowed_content_ratings + other_content_ratings)) do
|
101
|
+
yield
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Only recommended for development and debugging only
|
106
|
+
def force_raw_requests(&block)
|
107
|
+
if block_given?
|
108
|
+
temp_set_value("force_raw_requests", true) do
|
109
|
+
yield
|
110
|
+
end
|
111
|
+
else
|
112
|
+
!!@force_raw_requests
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def user_object?(user)
|
119
|
+
return false if user.nil?
|
120
|
+
|
121
|
+
missing_methods = [:session, :refresh, :mangadex_user_id] - user.methods
|
122
|
+
return true if missing_methods.empty?
|
123
|
+
|
124
|
+
warn("Potential user object #{user} is missing #{missing_methods}")
|
125
|
+
false
|
126
|
+
end
|
127
|
+
|
128
|
+
def temp_set_value(name, value, &block)
|
129
|
+
setter_method_name = "#{name}="
|
130
|
+
|
131
|
+
current_value = send(name)
|
132
|
+
send(setter_method_name, value)
|
133
|
+
response = yield
|
134
|
+
send(setter_method_name, current_value)
|
135
|
+
response
|
136
|
+
ensure
|
137
|
+
send(setter_method_name, current_value) if current_value
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -120,6 +120,19 @@ module Mangadex
|
|
120
120
|
)
|
121
121
|
end
|
122
122
|
|
123
|
+
def must(*args)
|
124
|
+
args = args.each_with_index.map do |arg, index|
|
125
|
+
["arg_at_position_#{index}".to_sym, arg]
|
126
|
+
end.to_h
|
127
|
+
|
128
|
+
definition = args.keys.map do |key|
|
129
|
+
[key, { required: true }]
|
130
|
+
end.to_h
|
131
|
+
|
132
|
+
validate(args, definition)
|
133
|
+
args.values
|
134
|
+
end
|
135
|
+
|
123
136
|
def validate(args, definition)
|
124
137
|
args = Hash(args).with_indifferent_access
|
125
138
|
definition = Hash(definition).with_indifferent_access
|
@@ -13,9 +13,9 @@ module Mangadex
|
|
13
13
|
attr_accessor :path, :headers, :payload, :method, :raw
|
14
14
|
attr_reader :response
|
15
15
|
|
16
|
-
def self.get(path, params={}, auth: false, headers: nil, raw: false)
|
16
|
+
def self.get(path, params={}, auth: false, headers: nil, raw: false, content_rating: false)
|
17
17
|
new(
|
18
|
-
path_with_params(path, params),
|
18
|
+
path_with_params(path, params, content_rating),
|
19
19
|
method: :get,
|
20
20
|
headers: headers,
|
21
21
|
payload: nil,
|
@@ -54,7 +54,7 @@ module Mangadex
|
|
54
54
|
payload_details = request_payload ? "Payload: #{request_payload}" : "{no-payload}"
|
55
55
|
puts("[#{self.class.name}] #{method.to_s.upcase} #{request_url} #{payload_details}")
|
56
56
|
|
57
|
-
raise Mangadex::UserNotLoggedIn.new if auth && Mangadex
|
57
|
+
raise Mangadex::Errors::UserNotLoggedIn.new if auth && Mangadex.context.user.nil?
|
58
58
|
|
59
59
|
start_time = Time.now
|
60
60
|
|
@@ -62,13 +62,17 @@ module Mangadex
|
|
62
62
|
end_time = Time.now
|
63
63
|
elapsed_time = ((end_time - start_time) * 1000).to_i
|
64
64
|
puts("[#{self.class.name}] took #{elapsed_time} ms")
|
65
|
+
|
66
|
+
raw_request = raw || Mangadex.context.force_raw_requests
|
65
67
|
|
66
|
-
if @response.body
|
67
|
-
|
68
|
+
if (body = @response.body)
|
69
|
+
raw_request ? try_json(body) : Mangadex::Api::Response.coerce(try_json(body))
|
68
70
|
end
|
71
|
+
rescue RestClient::Unauthorized => error
|
72
|
+
raise Errors::UnauthorizedError.new(Mangadex::Api::Response.coerce(try_json(error.response.body)))
|
69
73
|
rescue RestClient::Exception => error
|
70
|
-
if error.response.body
|
71
|
-
|
74
|
+
if (body = error.response.body)
|
75
|
+
raw_request ? try_json(body) : Mangadex::Api::Response.coerce(JSON.parse(body)) rescue raise error
|
72
76
|
else
|
73
77
|
raise error
|
74
78
|
end
|
@@ -76,7 +80,8 @@ module Mangadex
|
|
76
80
|
|
77
81
|
private
|
78
82
|
|
79
|
-
def self.path_with_params(path, params)
|
83
|
+
def self.path_with_params(path, params, content_rating)
|
84
|
+
params = content_rating ? self.with_content_rating(params) : params
|
80
85
|
return path if params.blank?
|
81
86
|
|
82
87
|
params = params.deep_transform_keys do |key|
|
@@ -85,6 +90,14 @@ module Mangadex
|
|
85
90
|
"#{path}?#{params.to_query}"
|
86
91
|
end
|
87
92
|
|
93
|
+
def self.with_content_rating(data)
|
94
|
+
content_rating = data.has_key?(:content_rating) ? data[:content_rating] : []
|
95
|
+
Mangadex.context.allow_content_ratings(*content_rating) do
|
96
|
+
data[:content_rating] = Mangadex.context.allowed_content_ratings
|
97
|
+
end
|
98
|
+
data
|
99
|
+
end
|
100
|
+
|
88
101
|
def request_url
|
89
102
|
request_path = path.start_with?('/') ? path : "/#{path}"
|
90
103
|
"#{BASE_URI}#{request_path}"
|
@@ -97,10 +110,10 @@ module Mangadex
|
|
97
110
|
end
|
98
111
|
|
99
112
|
def request_headers
|
100
|
-
return headers if Mangadex
|
113
|
+
return headers if Mangadex.context.user.nil?
|
101
114
|
|
102
115
|
headers.merge({
|
103
|
-
Authorization: Mangadex
|
116
|
+
Authorization: Mangadex.context.user.with_valid_session.session,
|
104
117
|
})
|
105
118
|
end
|
106
119
|
|
@@ -116,6 +129,12 @@ module Mangadex
|
|
116
129
|
|
117
130
|
raise "Invalid method: #{method}. Must be one of: #{ALLOWED_METHODS}"
|
118
131
|
end
|
132
|
+
|
133
|
+
def try_json(body)
|
134
|
+
JSON.parse(body)
|
135
|
+
rescue JSON::ParserError
|
136
|
+
body
|
137
|
+
end
|
119
138
|
end
|
120
139
|
end
|
121
140
|
end
|
@@ -11,7 +11,8 @@ module Mangadex
|
|
11
11
|
:id,
|
12
12
|
:type,
|
13
13
|
:attributes,
|
14
|
-
:relationships
|
14
|
+
:relationships,
|
15
|
+
:related_type
|
15
16
|
|
16
17
|
class_methods do
|
17
18
|
USING_ATTRIBUTES = {}
|
@@ -30,7 +31,7 @@ module Mangadex
|
|
30
31
|
self.name.split('::').last.underscore
|
31
32
|
end
|
32
33
|
|
33
|
-
def from_data(data)
|
34
|
+
def from_data(data, related_type: nil)
|
34
35
|
base_class_name = self.name.gsub('::', '_')
|
35
36
|
klass_name = self.name
|
36
37
|
target_attributes_class_name = "#{base_class_name}_Attributes"
|
@@ -65,6 +66,7 @@ module Mangadex
|
|
65
66
|
id: data['id'],
|
66
67
|
type: data['type'] || self.type,
|
67
68
|
attributes: attributes,
|
69
|
+
related_type: related_type,
|
68
70
|
}
|
69
71
|
|
70
72
|
initialize_hash.merge!({relationships: relationships}) if relationships.present?
|
@@ -110,6 +112,13 @@ module Mangadex
|
|
110
112
|
else
|
111
113
|
super
|
112
114
|
end
|
115
|
+
elsif !related_type.nil?
|
116
|
+
return super unless method_name.end_with?("?")
|
117
|
+
|
118
|
+
looking_for_related = method_name.to_s.split("?").first
|
119
|
+
return super unless Mangadex::Relationship::RELATED_VALUES.include?(looking_for_related)
|
120
|
+
|
121
|
+
related_type == looking_for_related
|
113
122
|
else
|
114
123
|
super
|
115
124
|
end
|
data/lib/mangadex/internal.rb
CHANGED