mangadex 5.3.3.1 → 5.4.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +7 -0
- data/Gemfile.lock +2 -2
- data/bin/console +4 -3
- data/docker-compose.yml +9 -0
- 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 +27 -2
- data/lib/mangadex/api/user.rb +51 -7
- data/lib/mangadex/api.rb +0 -1
- data/lib/mangadex/artist.rb +20 -1
- data/lib/mangadex/auth.rb +42 -13
- data/lib/mangadex/author.rb +2 -0
- data/lib/mangadex/chapter.rb +2 -9
- data/lib/mangadex/internal/context.rb +141 -0
- data/lib/mangadex/internal/definition.rb +5 -0
- data/lib/mangadex/internal/request.rb +8 -6
- data/lib/mangadex/internal.rb +1 -0
- data/lib/mangadex/manga.rb +8 -3
- data/lib/mangadex/scanlation_group.rb +3 -0
- 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/user.rb +2 -2
- data/lib/mangadex/version.rb +3 -3
- data/lib/mangadex.rb +25 -12
- metadata +14 -4
- data/lib/mangadex/api/context.rb +0 -137
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 498b3099b585f68a83983fd391d7b379ffa6b37ad41073d14c6b44d426691e5a
|
4
|
+
data.tar.gz: ba5b94653c90682241b2d98c9652fa3614ae7c1fc9b6a735919cea17aa7ab0b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8afe63e8dcd7612a0f85b86a5f9b393f12401c6fdbc21118e490739b6ae5a77790f34f323daa32b9ef4bd9b70be35f7882266b284c2ca7a02acb97992f31c262
|
7
|
+
data.tar.gz: 2cfa10681bad8af8a1968cc528e923d82d9808948d3f174111e65b1a8ffaf6792febc717d5c5cef311c83331c75c0508f9dfde2e6119621e94eb1a954d5aa836
|
data/Dockerfile
ADDED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
mangadex (5.3.3.
|
4
|
+
mangadex (5.3.3.4)
|
5
5
|
activesupport (~> 6.1)
|
6
6
|
psych (~> 4.0.1)
|
7
7
|
rest-client (~> 2.1)
|
@@ -82,7 +82,7 @@ GEM
|
|
82
82
|
smart_properties (1.16.3)
|
83
83
|
sorbet (0.5.9152)
|
84
84
|
sorbet-static (= 0.5.9152)
|
85
|
-
sorbet-runtime (0.5.
|
85
|
+
sorbet-runtime (0.5.9211)
|
86
86
|
sorbet-static (0.5.9152-universal-darwin-20)
|
87
87
|
sorbet-static (0.5.9152-x86_64-linux)
|
88
88
|
tilt (2.0.10)
|
data/bin/console
CHANGED
@@ -3,13 +3,14 @@
|
|
3
3
|
require "bundler/setup"
|
4
4
|
require "mangadex"
|
5
5
|
|
6
|
-
username, password = [
|
6
|
+
username, password, email = [
|
7
7
|
ENV['MD_USERNAME'],
|
8
8
|
ENV['MD_PASSWORD'],
|
9
|
+
ENV['MD_EMAIL'],
|
9
10
|
]
|
10
11
|
|
11
|
-
if username && password
|
12
|
-
Mangadex::Auth.login(username, password)
|
12
|
+
if (username || email) && password
|
13
|
+
Mangadex::Auth.login(username: username, email: email, password: password)
|
13
14
|
end
|
14
15
|
|
15
16
|
# You can add fixtures and/or initialization code here to make experimenting
|
data/docker-compose.yml
ADDED
@@ -0,0 +1,226 @@
|
|
1
|
+
# 🔒 Authenticating with Mangadex
|
2
|
+
|
3
|
+
## Beforehand
|
4
|
+
|
5
|
+
Any actions that can be performed on the mangadex site as a non authenticated user will not require a user to be logged
|
6
|
+
in. Authentication on Mangadex, as per version
|
7
|
+
<a href="https://rubygems.org/gems/mangadex"><img src="https://badgen.net/rubygems/v/mangadex" /></a>
|
8
|
+
will need an `Authorization` HTTP header to be present.
|
9
|
+
|
10
|
+
You can check details on the Mangadex API here: https://api.mangadex.org/docs.html#section/Authentication
|
11
|
+
|
12
|
+
## Authentication & Authorization flow
|
13
|
+
|
14
|
+
The authentication flow happens as such:
|
15
|
+
|
16
|
+
1. You login with your email or username, and password.
|
17
|
+
2. Upon successfully _authenticating_ your account, you will be given a `session` and a `refresh` tokens.
|
18
|
+
3. You must use the `session` token to _authorize_ your account to perform certain actions (ie: create resources, etc.)
|
19
|
+
4. You must use the `refresh` token to refresh the `session` when expired.
|
20
|
+
|
21
|
+
> - The `session` token expires **15 minutes** after been granted.
|
22
|
+
> - The `refresh` token refreshes **1 month** after been granted.
|
23
|
+
|
24
|
+
## Authentication using `mangadex` gem
|
25
|
+
|
26
|
+
Now that the basics of authentication have been covered, let's go over how it's done on with the gem.
|
27
|
+
|
28
|
+
### Logging in
|
29
|
+
|
30
|
+
It's simple to login, whether with your email address or your email address:
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
# With your username
|
34
|
+
Mangadex::Auth.login(username: username, password: password)
|
35
|
+
|
36
|
+
# With your email address
|
37
|
+
Mangadex::Auth.login(email: email, password: password)
|
38
|
+
```
|
39
|
+
|
40
|
+
Upon successful authentication, an instance of `Mangadex::Api::User` will be returned:
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
user = Mangadex::Auth.login(...)
|
44
|
+
|
45
|
+
# The session token, valid for 15 minutes (String).
|
46
|
+
user.session
|
47
|
+
|
48
|
+
# The refresh token, valid for 1 month (String)
|
49
|
+
user.refresh
|
50
|
+
|
51
|
+
# The logged in user's ID (String) (formatted as a UUID)
|
52
|
+
user.mangadex_user_id
|
53
|
+
|
54
|
+
# Time at the which user.session becomes invalid (Time)
|
55
|
+
user.session_valid_until
|
56
|
+
|
57
|
+
# Miscellaneaous data. When logging in, it's an instance of Mangadex::User
|
58
|
+
# (response from the server)
|
59
|
+
user.data
|
60
|
+
```
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
# Refreshes the tokens now (Boolean)
|
64
|
+
user.refresh!
|
65
|
+
|
66
|
+
# Refreshes the tokens if expired, then return user itself (Mangadex::Api::User)
|
67
|
+
user.with_valid_session
|
68
|
+
|
69
|
+
# Returns if user.session has expired (Boolean)
|
70
|
+
user.session_expired?
|
71
|
+
```
|
72
|
+
|
73
|
+
If there's an error, `Mangadex::Errors::AuthenticationError` will be raised. Here's how to handle that scenario:
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
def login(email, password)
|
77
|
+
Mangadex::Auth.login(email: email, password: password)
|
78
|
+
rescue Mangadex::Errors::AuthenticationError => error
|
79
|
+
response = error.response
|
80
|
+
|
81
|
+
# A list of detailed errors from Mangadex. (Array of
|
82
|
+
# Mangadex::Api::Response::Error)
|
83
|
+
response.errors.each do |error|
|
84
|
+
puts error.id
|
85
|
+
puts error.status
|
86
|
+
puts error.title
|
87
|
+
puts error.detail
|
88
|
+
end
|
89
|
+
end
|
90
|
+
```
|
91
|
+
|
92
|
+
### Authenticating requests
|
93
|
+
|
94
|
+
When the user is logged in, all subsequent requests _should_ be authenticated. Here's an example to retrieve a list of manga that the logged in user is _reading_ at the moment:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
user = Mangadex::Auth.login(...)
|
98
|
+
response = Mangadex::Manga.all_reading_status('reading')
|
99
|
+
manga_ids = response['statuses'].keys
|
100
|
+
|
101
|
+
reading_now = Mangadex::Manga.list(ids: manga_ids)
|
102
|
+
```
|
103
|
+
|
104
|
+
If for whatever reason you want to a request not to be authenticated, you can do something like:
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
Mangadex.context.without_user do
|
108
|
+
# your mangadex request(s) here
|
109
|
+
end
|
110
|
+
```
|
111
|
+
|
112
|
+
When logging in, the user's session information will be persisted in the storage. See below [for more details]().
|
113
|
+
|
114
|
+
### Logging out
|
115
|
+
|
116
|
+
Logging the user out is very easy:
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
Mangadex::Auth.logout
|
120
|
+
```
|
121
|
+
|
122
|
+
Here, the `user`'s session will be revoked on Mangadex. It will try to delete the user's session. `Mangadex::Auth.logout` outside of the `with_user` block will not do anything.
|
123
|
+
|
124
|
+
This action also clears the context's user and the storage info associated to this user.
|
125
|
+
|
126
|
+
## Persisting the user session: storage stragegies
|
127
|
+
|
128
|
+
### What is this?
|
129
|
+
|
130
|
+
Using this gem should help you a little bit managing tokens. By default, the gem stores the following information in memory:
|
131
|
+
|
132
|
+
- For a particular user ID:
|
133
|
+
- User session
|
134
|
+
- User refresh token
|
135
|
+
- User session expiry date
|
136
|
+
|
137
|
+
### Why is this a thing?
|
138
|
+
|
139
|
+
Good question. We want to make session management with this gem as easy as possible. The session is used to retrieve a valid logged in user. Here's how it works:
|
140
|
+
|
141
|
+
- When the user logs in, the refresh token, the session token (as well as it's expired date) are stored for that user
|
142
|
+
- When requesting the tokens for the user, a `Mangadex::Api::User` is created with refreshed tokens (if expired).
|
143
|
+
- When logging out, if implemented by you, the users's session details are deleted.
|
144
|
+
|
145
|
+
Here's you retrieve a user from your storage at any point:
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
mangadex_user_id = '...'
|
149
|
+
Mangadex::Api::User.from_storage(mangadex_user_id)
|
150
|
+
```
|
151
|
+
|
152
|
+
It's up to you to decide how you store the user ID. You don't need to worry about saving the storage, the gem takes care of that for you.
|
153
|
+
|
154
|
+
### Ok, ok. How can I use my own strategy?
|
155
|
+
|
156
|
+
By default, this gem ships with `Mangagex::Storage::Memory` which corresponds to the in-memory storage. This should be fine if you don't care much about persisting the user session at any point.
|
157
|
+
|
158
|
+
No assumptions can be made on which storage service you use. That is 100% up to you how the information is stored. Let's say you want to use [redis](https://github.com/redis/redis) for session instead of the default memory storage stragery:
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
require 'redis'
|
162
|
+
|
163
|
+
class BasicRedisStragery < Mangadex::Storage::Basic
|
164
|
+
# Must be implemented
|
165
|
+
def get(mangadex_user_id, key)
|
166
|
+
client.hget(mangadex_user_id, key)
|
167
|
+
end
|
168
|
+
|
169
|
+
# Must be implemented
|
170
|
+
def set(mangadex_user_id, key, value)
|
171
|
+
client.hset(mangadex_user_id, key, value)
|
172
|
+
end
|
173
|
+
|
174
|
+
# Optional - It's a nice-to-have, especially for logging out.
|
175
|
+
def clear(mangadex_user_id)
|
176
|
+
client.del(mangadex_user_id)
|
177
|
+
end
|
178
|
+
|
179
|
+
private
|
180
|
+
|
181
|
+
def client
|
182
|
+
@client ||= Redis.new(url: 'redis://localhost')
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
# Let the gem know which strategy needs to be used
|
187
|
+
Mangadex.configuration.storage_class = BasicRedisStragery
|
188
|
+
```
|
189
|
+
|
190
|
+
> On Rails, you can put this inside an initializer. Example: `config/initializers/mangadex.rb`.
|
191
|
+
|
192
|
+
The snippet of code is an example of how a storage strategy is implemented. It's important to make sure that neither `get` nor `set` raise exceptions.
|
193
|
+
|
194
|
+
> - We recommend using redis if you're developing a web app or a bot where authentication is involed.
|
195
|
+
> - You can even use a the filesystem if you're building a CLI (command line interface).
|
196
|
+
> - We **do not** recommend using SQL at the moment. This might be hard on your app's performance...
|
197
|
+
|
198
|
+
### Can I opt-out?
|
199
|
+
|
200
|
+
Of course. Set `Mangadex::Storage::None` as the prefered strategy:
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
# Either
|
204
|
+
Mangadex.configure do |config|
|
205
|
+
config.storage_class = Mangadex::Storage::None
|
206
|
+
end
|
207
|
+
|
208
|
+
# Or
|
209
|
+
Mangadex.configuration.storage_class = Mangadex::Storage::None
|
210
|
+
```
|
211
|
+
|
212
|
+
## About content ratings
|
213
|
+
|
214
|
+
Each manga/chapter has a content rating (`safe`, `suggestive`, `erotica` and `pornographic`). It might be worth filtering certain titles depending on the audiance. By default, Mangadex filters out every `pornographic` entry.
|
215
|
+
|
216
|
+
Please note that content rating is not tied to the user at the moment on Mangadex. So it was decided **not** to add this responsiblity on this gem. Instead, the content ratings can be specified on context gem as well, like this:
|
217
|
+
|
218
|
+
```ruby
|
219
|
+
# Everything but "suggestive" content - this is an example :p
|
220
|
+
mangas = Mangadex::Api::Content.allow_content_rating('safe', 'erotica', 'pornographic') do
|
221
|
+
response = Mangadex::Manga.list
|
222
|
+
response.data
|
223
|
+
end
|
224
|
+
```
|
225
|
+
|
226
|
+
The advantage of this approach is that you don't have to set the `content_rating` param yourself everywhere.
|
data/docs/context.md
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
# Mangadex contexts
|
2
|
+
|
3
|
+
There is a concept of concepts in this gem. This is there for you to access certain variables at any point in your app.
|
4
|
+
|
5
|
+
## User
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
Mangadex.context.user # => #<Mangadex::Api::User ...>
|
9
|
+
```
|
10
|
+
|
11
|
+
This is set to `nil` before logging in.
|
12
|
+
|
13
|
+
When logging in, the user is stored in the context so that subsequent requests are set to be authenticated with this user.
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
Mangadex::Auth.login(...)
|
17
|
+
Mangadex.context.user.nil? # => false
|
18
|
+
|
19
|
+
custom_lists = Mangadex::CustomList.list
|
20
|
+
```
|
21
|
+
|
22
|
+
If you're not logged in, `Mangadex::Errors::UnauthorizedError` will be raised for any request that requires you to be logged in and authorized to perform a certain account.
|
23
|
+
|
24
|
+
You can set the user in a temporary context:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
Mangadex.context.user # => nil
|
28
|
+
|
29
|
+
temp_user = Mangadex::Api::User.new(mangadex_user_id: 'blabla')
|
30
|
+
Mangadex.context.with_user(temp_user) do
|
31
|
+
Mangadex.context.user # => #<Mangadex::Api::User mangadex_user_id="blabla">
|
32
|
+
end
|
33
|
+
|
34
|
+
Mangadex.context.user # => nil
|
35
|
+
```
|
36
|
+
|
37
|
+
More info on authentication [here]().
|
38
|
+
|
39
|
+
## Content rating
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
Mangadex.context.allowed_content_ratings # => [#<Mangadex::ContentRating ...>, ...]
|
43
|
+
```
|
44
|
+
|
45
|
+
Content ratings are not tied to the user. When set, requests that accept a [`content_rating`](https://api.mangadex.org/docs.html#section/Static-data/Manga-content-rating) parameter, this parameter will be set to `Mangadex.context.allowed_content_ratings` if nothing is specified.
|
46
|
+
|
47
|
+
By default, `safe`, `suggestive` and `erotica` are used on Mangadex. But however, if you want to allow all content ratings, you could do something like:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
Mangadex.context.allow_content_ratings('safe', 'suggestive', 'erotica', 'pornographic')
|
51
|
+
```
|
52
|
+
|
53
|
+
Then, a query to fetch manga will make the following request:
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
Mangadex::Manga.list
|
57
|
+
# GET https://api.mangadex.org/manga?contentRating%5B%5D=safe&contentRating%5B%5D=suggestive&contentRating%5B%5D=erotica&contentRating%5B%5D=pornographic
|
58
|
+
```
|
59
|
+
|
60
|
+
You can also use temporary content ratings:
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
# old content ratings
|
64
|
+
Mangadex.context.allow_content_ratings('safe', 'suggestive', 'erotica', 'pornographic') do
|
65
|
+
# temporary content ratings
|
66
|
+
Mangadex::Manga.list
|
67
|
+
end
|
68
|
+
|
69
|
+
# back to old content ratings
|
70
|
+
```
|
71
|
+
|
72
|
+
## Tags
|
73
|
+
|
74
|
+
Get the list of possible tags on Mangadex:
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
Mangadex.context.tags
|
78
|
+
```
|
79
|
+
|
80
|
+
### API version
|
81
|
+
|
82
|
+
Get the current Mangadex's latest API version
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
Mangadex.context.version
|
86
|
+
```
|
87
|
+
|
88
|
+
A warning message will be printed if there's a mismatch between Mangadex's API version and the gem version. Example:
|
89
|
+
|
90
|
+
| Mangadex's API version | The gem's version | Result |
|
91
|
+
| ---------------------- | ----------------- | ------- |
|
92
|
+
| 5.3.3 | 5.3.3.1 | OK |
|
93
|
+
| 5.3.4 | 5.3.3.4 | Warning |
|
data/lib/config.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# typed: true
|
2
|
+
|
3
|
+
module Mangadex
|
4
|
+
class Config
|
5
|
+
extend T::Sig
|
6
|
+
|
7
|
+
# Class used to persist users
|
8
|
+
# Must respond to: :session, :refresh, :mangadex_user_id
|
9
|
+
sig { returns(Class) }
|
10
|
+
attr_accessor :user_class
|
11
|
+
|
12
|
+
# Persisting strategy. See Mangadex::Storage::Base for more details.
|
13
|
+
sig { returns(Class) }
|
14
|
+
attr_accessor :storage_class
|
15
|
+
|
16
|
+
sig { returns(T::Array[ContentRating]) }
|
17
|
+
attr_accessor :default_content_ratings
|
18
|
+
|
19
|
+
sig { void }
|
20
|
+
def initialize
|
21
|
+
@user_class = Api::User
|
22
|
+
@storage_class = Storage::Memory
|
23
|
+
@default_content_ratings = ContentRating.parse(['safe', 'suggestive', 'erotica'])
|
24
|
+
end
|
25
|
+
|
26
|
+
sig { params(klass: Class).void }
|
27
|
+
def user_class=(klass)
|
28
|
+
missing_methods = [:session, :refresh, :mangadex_user_id] - klass.instance_methods
|
29
|
+
if missing_methods.empty?
|
30
|
+
@user_class = klass
|
31
|
+
else
|
32
|
+
raise ArgumentError, 'user_class must respond to :session, :refresh, :mangadex_user_id'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
sig { params(content_ratings: T::Array[T.any(String, ContentRating)]).void }
|
37
|
+
def default_content_ratings=(content_ratings)
|
38
|
+
@default_content_ratings = ContentRating.parse(content_ratings)
|
39
|
+
end
|
40
|
+
|
41
|
+
def storage_class=(klass)
|
42
|
+
@storage = nil
|
43
|
+
@storage_class = klass
|
44
|
+
end
|
45
|
+
|
46
|
+
def storage
|
47
|
+
@storage ||= storage_class.new
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/errors.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# typed: true
|
2
|
+
|
3
|
+
module Mangadex
|
4
|
+
module Errors
|
5
|
+
# Standard error class for this gem.
|
6
|
+
#
|
7
|
+
# @author thedrummeraki
|
8
|
+
# @since 0.6.0
|
9
|
+
class StandardError < ::StandardError
|
10
|
+
extend T::Sig
|
11
|
+
end
|
12
|
+
|
13
|
+
class UserNotLoggedIn < StandardError
|
14
|
+
sig { returns(String) }
|
15
|
+
def message
|
16
|
+
"You are not logged in. Use [Mangadex::Auth.login] to log in."
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class AuthenticationError < StandardError
|
21
|
+
sig { returns(Mangadex::Api::Response) }
|
22
|
+
attr_accessor :response
|
23
|
+
|
24
|
+
sig { params(response: Mangadex::Api::Response).void }
|
25
|
+
def initialize(response)
|
26
|
+
@response = response
|
27
|
+
end
|
28
|
+
|
29
|
+
sig { returns(String) }
|
30
|
+
def message
|
31
|
+
"Your username or password may not be correct."
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class UnauthorizedError < AuthenticationError
|
36
|
+
sig { returns(String) }
|
37
|
+
def message
|
38
|
+
"Oops, you are not authorized to make this call. Make sure you log in with the right account."
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/mangadex/README.md
CHANGED
@@ -3,12 +3,14 @@
|
|
3
3
|
This is documentation for the `Mangadex` module.
|
4
4
|
|
5
5
|
### Directory
|
6
|
+
|
6
7
|
#### Sub-modules
|
7
8
|
|
8
9
|
- [`Mangadex::Api`](#)
|
9
10
|
- [`Mangadex::Internal`](#)
|
10
11
|
|
11
12
|
#### Fetchable/Resources
|
13
|
+
|
12
14
|
- [`Mangadex::Artist`](#)
|
13
15
|
- [`Mangadex::Auth`](#mangadexauth)
|
14
16
|
- [`Mangadex::Author`](#)
|
@@ -25,6 +27,7 @@ This is documentation for the `Mangadex` module.
|
|
25
27
|
- [`Mangadex::User`](#)
|
26
28
|
|
27
29
|
#### Other classes
|
30
|
+
|
28
31
|
- [`Mangadex::MangadexObject`](#)
|
29
32
|
- [`Mangadex::Types`](#)
|
30
33
|
- [`Mangadex::Version`](#)
|
@@ -51,7 +54,7 @@ Mangadex::Auth.login(username, password)
|
|
51
54
|
```
|
52
55
|
|
53
56
|
Login with your username and password. Upon successful login, the user will be available in a context from
|
54
|
-
`Mangadex
|
57
|
+
`Mangadex.context.user`. This variable can be used anywhere in your application. More info [here](#).
|
55
58
|
|
56
59
|
> - Returns `Mangadex::Api::Response` if request fails.
|
57
60
|
> - Returns `true` if user is logged in.
|
@@ -86,8 +89,9 @@ Mangadex::Auth.refresh_token
|
|
86
89
|
```
|
87
90
|
|
88
91
|
Manually cause a token refresh.
|
92
|
+
|
89
93
|
> Please note that simply calling `Mangadex::Api::Content.user` ensures that the token is valid. More info [here](#).
|
90
94
|
|
91
95
|
> - Returns `nil` if user is not logged (ie: `Mangadex::Api::Content.user` is `nil`)
|
92
96
|
> - Returns `true` if the refresh is successful
|
93
|
-
> - Returns `false` if the refresh is [not successful](#).
|
97
|
+
> - Returns `false` if the refresh is [not successful](#).
|
@@ -41,8 +41,33 @@ module Mangadex
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
def errored?
|
45
|
-
Array(errors).any?
|
44
|
+
def errored?(status=nil)
|
45
|
+
errored = Array(errors).any?
|
46
|
+
return errored if status.nil?
|
47
|
+
|
48
|
+
errors.select { |error| error.status.to_s == status.to_s }.any?
|
49
|
+
end
|
50
|
+
|
51
|
+
def more_results?
|
52
|
+
return unless data.is_a?(Array)
|
53
|
+
|
54
|
+
total > data.count
|
55
|
+
end
|
56
|
+
|
57
|
+
def count
|
58
|
+
data.is_a?(Array) ? data.count : nil
|
59
|
+
end
|
60
|
+
|
61
|
+
def each(&block)
|
62
|
+
if data.is_a?(Array)
|
63
|
+
data.each(&block)
|
64
|
+
else
|
65
|
+
raise ArgumentError, "Expect data to be Array, but got #{data.class}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_a
|
70
|
+
each.to_a
|
46
71
|
end
|
47
72
|
|
48
73
|
def as_json(*)
|
data/lib/mangadex/api/user.rb
CHANGED
@@ -7,13 +7,13 @@ module Mangadex
|
|
7
7
|
attr_accessor :mangadex_user_id, :session, :refresh, :session_valid_until
|
8
8
|
attr_reader :data
|
9
9
|
|
10
|
-
sig { params(mangadex_user_id: String, session: T.nilable(String), refresh: T.nilable(String), data: T.untyped).void }
|
11
|
-
def initialize(mangadex_user_id
|
10
|
+
sig { params(mangadex_user_id: String, session: T.nilable(String), refresh: T.nilable(String), data: T.untyped, session_valid_until: T.nilable(Time)).void }
|
11
|
+
def initialize(mangadex_user_id:, session: nil, refresh: nil, data: nil, session_valid_until: nil)
|
12
12
|
raise ArgumentError, 'Missing mangadex_user_id' if mangadex_user_id.to_s.empty?
|
13
13
|
|
14
14
|
@mangadex_user_id = mangadex_user_id
|
15
15
|
@session = session
|
16
|
-
@session_valid_until = session ? Time.now + (14 * 60) : nil
|
16
|
+
@session_valid_until = session_valid_until ? session_valid_until : (session ? Time.now + (14 * 60) : nil)
|
17
17
|
@refresh = refresh
|
18
18
|
@data = data
|
19
19
|
end
|
@@ -24,9 +24,7 @@ module Mangadex
|
|
24
24
|
def refresh!
|
25
25
|
return false if refresh.nil?
|
26
26
|
|
27
|
-
response = Mangadex::
|
28
|
-
Mangadex::Internal::Request.post('/auth/refresh', payload: { token: refresh })
|
29
|
-
end
|
27
|
+
response = Mangadex::Internal::Request.post('/auth/refresh', payload: { token: refresh })
|
30
28
|
return false unless response['token']
|
31
29
|
|
32
30
|
@session_valid_until = Time.now + (14 * 60)
|
@@ -36,7 +34,7 @@ module Mangadex
|
|
36
34
|
true
|
37
35
|
end
|
38
36
|
|
39
|
-
sig { returns(
|
37
|
+
sig { returns(User) }
|
40
38
|
def with_valid_session
|
41
39
|
session_expired? && refresh!
|
42
40
|
self
|
@@ -48,6 +46,52 @@ module Mangadex
|
|
48
46
|
def session_expired?
|
49
47
|
@session_valid_until.nil? || @session_valid_until <= Time.now
|
50
48
|
end
|
49
|
+
|
50
|
+
sig { returns(T::Boolean) }
|
51
|
+
def persist
|
52
|
+
return false unless valid?
|
53
|
+
|
54
|
+
Mangadex.storage.set(mangadex_user_id, 'session', session) if session
|
55
|
+
Mangadex.storage.set(mangadex_user_id, 'refresh', refresh) if refresh
|
56
|
+
if session_valid_until
|
57
|
+
Mangadex.storage.set(mangadex_user_id, 'session_valid_until', session_valid_until.to_s)
|
58
|
+
end
|
59
|
+
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
63
|
+
sig { returns(T::Boolean) }
|
64
|
+
def valid?
|
65
|
+
!mangadex_user_id.nil? && !mangadex_user_id.strip.empty?
|
66
|
+
end
|
67
|
+
|
68
|
+
sig { params(mangadex_user_id: T.nilable(String)).returns(T.nilable(User)) }
|
69
|
+
def self.from_storage(mangadex_user_id)
|
70
|
+
return if mangadex_user_id.nil?
|
71
|
+
|
72
|
+
session = Mangadex.storage.get(mangadex_user_id, 'session')
|
73
|
+
refresh = Mangadex.storage.get(mangadex_user_id, 'refresh')
|
74
|
+
session_valid_until = Mangadex.storage.get(mangadex_user_id, 'session_valid_until')
|
75
|
+
|
76
|
+
user = if session || refresh || session_valid_until
|
77
|
+
session_valid_until = session_valid_until ? Time.parse(session_valid_until) : nil
|
78
|
+
|
79
|
+
new(
|
80
|
+
mangadex_user_id: mangadex_user_id,
|
81
|
+
session: session,
|
82
|
+
refresh: refresh,
|
83
|
+
session_valid_until: session_valid_until,
|
84
|
+
).with_valid_session
|
85
|
+
else
|
86
|
+
nil
|
87
|
+
end
|
88
|
+
|
89
|
+
if user
|
90
|
+
Mangadex.context.user = user
|
91
|
+
end
|
92
|
+
|
93
|
+
user
|
94
|
+
end
|
51
95
|
end
|
52
96
|
end
|
53
97
|
end
|
data/lib/mangadex/api.rb
CHANGED
data/lib/mangadex/artist.rb
CHANGED
@@ -2,10 +2,29 @@
|
|
2
2
|
require_relative "author"
|
3
3
|
|
4
4
|
module Mangadex
|
5
|
-
class Artist <
|
5
|
+
class Artist < MangadexObject
|
6
6
|
# Indicates if this is an artist
|
7
7
|
#
|
8
8
|
# @return [Boolean] whether this is an artist or not.
|
9
|
+
has_attributes \
|
10
|
+
:name,
|
11
|
+
:image_url,
|
12
|
+
:biography,
|
13
|
+
:twitter,
|
14
|
+
:pixiv,
|
15
|
+
:melon_book,
|
16
|
+
:fan_box,
|
17
|
+
:booth,
|
18
|
+
:nico_video,
|
19
|
+
:skeb,
|
20
|
+
:fantia,
|
21
|
+
:tumblr,
|
22
|
+
:youtube,
|
23
|
+
:website,
|
24
|
+
:version,
|
25
|
+
:created_at,
|
26
|
+
:updated_at
|
27
|
+
|
9
28
|
def artist?
|
10
29
|
true
|
11
30
|
end
|