mirror of
https://github.com/hkalexling/Mango.git
synced 2025-08-03 03:15:31 -04:00
Add MangaDex login page
This commit is contained in:
parent
3c3549a489
commit
df7e2270a4
20
migration/md_account.11.cr
Normal file
20
migration/md_account.11.cr
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
class CreateMangaDexAccount < MG::Base
|
||||||
|
def up : String
|
||||||
|
<<-SQL
|
||||||
|
CREATE TABLE md_account (
|
||||||
|
username TEXT NOT NULL PRIMARY KEY,
|
||||||
|
token TEXT NOT NULL,
|
||||||
|
expire INTEGER NOT NULL,
|
||||||
|
FOREIGN KEY (username) REFERENCES users (username)
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
|
||||||
|
def down : String
|
||||||
|
<<-SQL
|
||||||
|
DROP TABLE md_account;
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
end
|
61
public/js/mangadex.js
Normal file
61
public/js/mangadex.js
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
const component = () => {
|
||||||
|
return {
|
||||||
|
username: '',
|
||||||
|
password: '',
|
||||||
|
expires: undefined,
|
||||||
|
loading: true,
|
||||||
|
loggingIn: false,
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.loading = true;
|
||||||
|
$.ajax({
|
||||||
|
type: 'GET',
|
||||||
|
url: `${base_url}api/admin/mangadex/expires`,
|
||||||
|
contentType: "application/json",
|
||||||
|
})
|
||||||
|
.done(data => {
|
||||||
|
console.log(data);
|
||||||
|
if (data.error) {
|
||||||
|
alert('danger', `Failed to retrieve MangaDex token status. Error: ${data.error}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.expires = data.expires;
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
.fail((jqXHR, status) => {
|
||||||
|
alert('danger', `Failed to retrieve MangaDex token status. Error: [${jqXHR.status}] ${jqXHR.statusText}`);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
login() {
|
||||||
|
if (!(this.username && this.password)) return;
|
||||||
|
this.loggingIn = true;
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: `${base_url}api/admin/mangadex/login`,
|
||||||
|
contentType: "application/json",
|
||||||
|
dataType: 'json',
|
||||||
|
data: JSON.stringify({
|
||||||
|
username: this.username,
|
||||||
|
password: this.password
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.done(data => {
|
||||||
|
console.log(data);
|
||||||
|
if (data.error) {
|
||||||
|
alert('danger', `Failed to log in. Error: ${data.error}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.expires = data.expires;
|
||||||
|
})
|
||||||
|
.fail((jqXHR, status) => {
|
||||||
|
alert('danger', `Failed to log in. Error: [${jqXHR.status}] ${jqXHR.statusText}`);
|
||||||
|
})
|
||||||
|
.always(() => {
|
||||||
|
this.loggingIn = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
get expired() {
|
||||||
|
return this.expires && moment().diff(moment.unix(this.expires)) > 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
@ -54,7 +54,7 @@ shards:
|
|||||||
|
|
||||||
mangadex:
|
mangadex:
|
||||||
git: https://github.com/hkalexling/mangadex.git
|
git: https://github.com/hkalexling/mangadex.git
|
||||||
version: 0.5.0+git.commit.323110c56c2d5134ce4162b27a9b24ec34137fcb
|
version: 0.6.0+git.commit.d87a1d7a6e84d122814b38618954dcc73fc5553b
|
||||||
|
|
||||||
mg:
|
mg:
|
||||||
git: https://github.com/hkalexling/mg.git
|
git: https://github.com/hkalexling/mg.git
|
||||||
|
@ -73,5 +73,9 @@ struct AdminRouter
|
|||||||
get "/admin/missing" do |env|
|
get "/admin/missing" do |env|
|
||||||
layout "missing-items"
|
layout "missing-items"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
get "/admin/mangadex" do |env|
|
||||||
|
layout "mangadex"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -905,6 +905,57 @@ struct APIRouter
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Koa.describe "Logs the current user into their MangaDex account, and " \
|
||||||
|
"saves the token."
|
||||||
|
Koa.tag "admin"
|
||||||
|
post "/api/admin/mangadex/login" do |env|
|
||||||
|
begin
|
||||||
|
username = env.params.json["username"].as String
|
||||||
|
password = env.params.json["password"].as String
|
||||||
|
mango_username = get_username env
|
||||||
|
|
||||||
|
client = MangaDex::Client.from_config
|
||||||
|
client.auth username, password
|
||||||
|
|
||||||
|
Storage.default.save_md_token mango_username, client.token.not_nil!,
|
||||||
|
client.token_expires
|
||||||
|
|
||||||
|
send_json env, {
|
||||||
|
"success" => true,
|
||||||
|
"error" => nil,
|
||||||
|
"expires" => client.token_expires.to_unix,
|
||||||
|
}.to_json
|
||||||
|
rescue e
|
||||||
|
Logger.error e
|
||||||
|
send_json env, {
|
||||||
|
"success" => false,
|
||||||
|
"error" => e.message,
|
||||||
|
}.to_json
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Koa.describe "Returns the expiration date of the mangadex token if the " \
|
||||||
|
"current user has logged in to MangaDex"
|
||||||
|
Koa.tag "admin"
|
||||||
|
get "/api/admin/mangadex/expires" do |env|
|
||||||
|
begin
|
||||||
|
username = get_username env
|
||||||
|
_, expires = Storage.default.get_md_token username
|
||||||
|
|
||||||
|
send_json env, {
|
||||||
|
"success" => true,
|
||||||
|
"error" => nil,
|
||||||
|
"expires" => expires.try &.to_unix,
|
||||||
|
}.to_json
|
||||||
|
rescue e
|
||||||
|
Logger.error e
|
||||||
|
send_json env, {
|
||||||
|
"success" => false,
|
||||||
|
"error" => e.message,
|
||||||
|
}.to_json
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
doc = Koa.generate
|
doc = Koa.generate
|
||||||
@@api_json = doc.to_json if doc
|
@@api_json = doc.to_json if doc
|
||||||
|
|
||||||
|
@ -514,6 +514,37 @@ class Storage
|
|||||||
delete_missing "titles", id
|
delete_missing "titles", id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def save_md_token(username : String, token : String, expire : Time)
|
||||||
|
MainFiber.run do
|
||||||
|
get_db do |db|
|
||||||
|
count = db.query_one "select count(*) from md_account where " \
|
||||||
|
"username = (?)", username, as: Int64
|
||||||
|
if count == 0
|
||||||
|
db.exec "insert into md_account values (?, ?, ?)", username, token,
|
||||||
|
expire.to_unix
|
||||||
|
else
|
||||||
|
db.exec "update md_account set token = (?), expire = (?) " \
|
||||||
|
"where username = (?)", token, expire.to_unix, username
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_md_token(username) : Tuple(String?, Time?)
|
||||||
|
token = nil
|
||||||
|
expires = nil
|
||||||
|
MainFiber.run do
|
||||||
|
get_db do |db|
|
||||||
|
db.query_one? "select token, expire from md_account where " \
|
||||||
|
"username = (?)", username do |res|
|
||||||
|
token = res.read String
|
||||||
|
expires = Time.unix res.read Int64
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
{token, expires}
|
||||||
|
end
|
||||||
|
|
||||||
def close
|
def close
|
||||||
MainFiber.run do
|
MainFiber.run do
|
||||||
unless @db.nil?
|
unless @db.nil?
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
<option>System</option>
|
<option>System</option>
|
||||||
</select>
|
</select>
|
||||||
</li>
|
</li>
|
||||||
|
<li><a class="uk-link-reset" href="<%= base_url %>admin/mangadex">Connect to MangaDex</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<hr class="uk-divider-icon">
|
<hr class="uk-divider-icon">
|
||||||
|
1
src/views/components/jquery-ui.html.ecr
Normal file
1
src/views/components/jquery-ui.html.ecr
Normal file
@ -0,0 +1 @@
|
|||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
|
1
src/views/components/moment.html.ecr
Normal file
1
src/views/components/moment.html.ecr
Normal file
@ -0,0 +1 @@
|
|||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
|
@ -63,7 +63,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<% content_for "script" do %>
|
<% content_for "script" do %>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
|
<%= render_component "moment" %>
|
||||||
<script src="<%= base_url %>js/alert.js"></script>
|
<script src="<%= base_url %>js/alert.js"></script>
|
||||||
<script src="<%= base_url %>js/download-manager.js"></script>
|
<script src="<%= base_url %>js/download-manager.js"></script>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
@ -110,8 +110,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<% content_for "script" do %>
|
<% content_for "script" do %>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
|
<%= render_component "moment" %>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
|
<%= render_component "jquery-ui" %>
|
||||||
<script src="<%= base_url %>js/alert.js"></script>
|
<script src="<%= base_url %>js/alert.js"></script>
|
||||||
<script src="<%= base_url %>js/download.js"></script>
|
<script src="<%= base_url %>js/download.js"></script>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
39
src/views/mangadex.html.ecr
Normal file
39
src/views/mangadex.html.ecr
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<div x-data="component()" x-init="init()">
|
||||||
|
<h2 class="uk-title">Connect to MangaDex</h2>
|
||||||
|
<div class"uk-grid-small" uk-grid x-show="!loading" x-cloak>
|
||||||
|
<div class="uk-width-1-2@s" x-show="!expires">
|
||||||
|
<p>This step is optional but highly recommended if you are using the MangaDex downloader. Connecting to MangaDex allows you to:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Search MangaDex by search terms in addition to manga IDs</li>
|
||||||
|
<li>Automatically download new chapters when they are available</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="uk-width-1-2@s" x-show="expires">
|
||||||
|
<p>
|
||||||
|
<span x-show="!expired">You have logged in to MangaDex!</span>
|
||||||
|
<span x-show="expired">You have logged in to MangaDex but the token has expired.</span>
|
||||||
|
The expiration date of your token is <code x-text="moment.unix(expires).format('MMMM Do YYYY, HH:mm:ss')"></code>.
|
||||||
|
<span x-show="!expired">If the integration is not working, you</span>
|
||||||
|
<span x-show="expired">You</span>
|
||||||
|
can log in again and the token will be updated.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="uk-width-1-2@s">
|
||||||
|
<div class="uk-margin">
|
||||||
|
<div class="uk-inline uk-width-1-1"><span class="uk-form-icon" uk-icon="icon:user"></span><input class="uk-input uk-form-large" type="text" x-model="username" @keydown.enter.debounce="login()"></div>
|
||||||
|
</div>
|
||||||
|
<div class="uk-margin">
|
||||||
|
<div class="uk-inline uk-width-1-1"><span class="uk-form-icon" uk-icon="icon:lock"></span><input class="uk-input uk-form-large" type="password" x-model="password" @keydown.enter.debounce="login()"></div>
|
||||||
|
</div>
|
||||||
|
<div class="uk-margin"><button class="uk-button uk-button-primary uk-button-large uk-width-1-1" @click="login()" :disabled="loggingIn">Login</button></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<% content_for "script" do %>
|
||||||
|
<%= render_component "moment" %>
|
||||||
|
<script src="<%= base_url %>js/alert.js"></script>
|
||||||
|
<script src="<%= base_url %>js/mangadex.js"></script>
|
||||||
|
<% end %>
|
@ -68,7 +68,7 @@
|
|||||||
var pid = "<%= plugin.not_nil!.info.id %>";
|
var pid = "<%= plugin.not_nil!.info.id %>";
|
||||||
</script>
|
</script>
|
||||||
<% end %>
|
<% end %>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
|
<%= render_component "jquery-ui" %>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/jquery.tablesorter.combined.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/jquery.tablesorter.combined.min.js"></script>
|
||||||
<script src="<%= base_url %>js/alert.js"></script>
|
<script src="<%= base_url %>js/alert.js"></script>
|
||||||
<script src="<%= base_url %>js/plugin-download.js"></script>
|
<script src="<%= base_url %>js/plugin-download.js"></script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user