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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cdf99fecbef4c256aa1f0b739a7051d68f7f79a864f2525d7a56d5ee6a2cca79
4
- data.tar.gz: 7250ded43bef9892e3d13323a1cea91c8f45378df330534f1a4f229575a1ebee
3
+ metadata.gz: 498b3099b585f68a83983fd391d7b379ffa6b37ad41073d14c6b44d426691e5a
4
+ data.tar.gz: ba5b94653c90682241b2d98c9652fa3614ae7c1fc9b6a735919cea17aa7ab0b4
5
5
  SHA512:
6
- metadata.gz: ef23c65119a28a69e2c060b69361be24e3558cdce80b6bed93e1a0fc7463e7f87bca81b59c770c4fb378d68368c0da1713723523f4fee445d829ac9d4e0a973b
7
- data.tar.gz: 58b0f5ee9763465a0801ebfbaf825c0009b12138bd20996ac34d5183c68a16ed6d515c8555e02b669c29cdbcb5e12916bb7adfec4d0769edbc7e793597d97334
6
+ metadata.gz: 8afe63e8dcd7612a0f85b86a5f9b393f12401c6fdbc21118e490739b6ae5a77790f34f323daa32b9ef4bd9b70be35f7882266b284c2ca7a02acb97992f31c262
7
+ data.tar.gz: 2cfa10681bad8af8a1968cc528e923d82d9808948d3f174111e65b1a8ffaf6792febc717d5c5cef311c83331c75c0508f9dfde2e6119621e94eb1a954d5aa836
data/Dockerfile ADDED
@@ -0,0 +1,7 @@
1
+ FROM ruby:3.0.3
2
+ RUN gem install bundler:2.2.19 -N
3
+ RUN mkdir /app
4
+ WORKDIR /app
5
+ COPY . /app
6
+
7
+ RUN bundle install --jobs 4 --retry 5 --quiet
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mangadex (5.3.3.1)
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.9161)
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
@@ -0,0 +1,9 @@
1
+ version: "3"
2
+ services:
3
+ gem:
4
+ build: .
5
+ command: bash
6
+ stdin_open: true
7
+ tty: true
8
+ volumes:
9
+ - .:/app
@@ -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
@@ -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::Api::Context.user`. This variable can be used anywhere in your application. More info [here](#).
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(*)
@@ -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, session: nil, refresh: nil, data: nil)
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::Api::Context.without_user do
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(Mangadex::Api::User) }
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
@@ -1,5 +1,4 @@
1
1
  # typed: strict
2
2
  require_relative "api/version_checker"
3
- require_relative "api/context"
4
3
  require_relative "api/response"
5
4
  require_relative "api/user"
@@ -2,10 +2,29 @@
2
2
  require_relative "author"
3
3
 
4
4
  module Mangadex
5
- class Artist < Author
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