From 19735642722bb5d2370fcebf7ddc5c2897a2b9ef Mon Sep 17 00:00:00 2001 From: Alex Ling Date: Mon, 7 Jun 2021 07:32:32 +0000 Subject: [PATCH] Revert "Subscription manager" This reverts commit a612500b0fabf7259a5ee0c841b0157d191e5bdd. --- migration/subscription.12.cr | 31 --- public/js/download.js | 94 --------- shard.lock | 2 +- src/config.cr | 6 +- src/library/library.cr | 19 -- src/mangadex/ext.cr | 34 ---- src/routes/api.cr | 148 ++------------ src/routes/main.cr | 6 - src/storage.cr | 68 ------- src/util/web.cr | 19 -- src/views/download-manager.html.ecr | 110 +++++------ src/views/download.html.ecr | 292 ++++++++++++++-------------- src/views/layout.html.ecr | 160 ++++++++------- src/views/missing-items.html.ecr | 56 +++--- 14 files changed, 317 insertions(+), 728 deletions(-) delete mode 100644 migration/subscription.12.cr diff --git a/migration/subscription.12.cr b/migration/subscription.12.cr deleted file mode 100644 index 3810755..0000000 --- a/migration/subscription.12.cr +++ /dev/null @@ -1,31 +0,0 @@ -class CreateSubscription < MG::Base - def up : String - # We allow multiple subscriptions for the same manga. - # This can be useful for example when you want to download from multiple - # groups. - <<-SQL - CREATE TABLE subscription ( - id INTEGER PRIMARY KEY, - manga_id INTEGER NOT NULL, - language TEXT, - group_id INTEGER, - min_volume INTEGER, - max_volume INTEGER, - min_chapter INTEGER, - max_chapter INTEGER, - last_checked INTEGER NOT NULL, - created_at INTEGER NOT NULL, - username TEXT NOT NULL, - FOREIGN KEY (username) REFERENCES users (username) - ON UPDATE CASCADE - ON DELETE CASCADE - ); - SQL - end - - def down : String - <<-SQL - DROP TABLE subscription; - SQL - end -end diff --git a/public/js/download.js b/public/js/download.js index 31a803e..4d8504b 100644 --- a/public/js/download.js +++ b/public/js/download.js @@ -280,100 +280,6 @@ const downloadComponent = () => { UIkit.modal($('#modal').get(0)).hide(); this.searchInput = id; this.search(); - }, - - subscribe(langConfirmed = false, groupConfirmed = false) { - const filters = { - manga: this.data.id, - language: this.langChoice === 'All' ? null : this.langChoice, - group: this.groupChoice === 'All' ? null : this.groupChoice, - volume: this.volumeRange === '' ? null : this.volumeRange, - chapter: this.chapterRange === '' ? null : this.chapterRange - }; - - // Get group ID - if (filters.group) { - this.data.chapters.forEach(chp => { - const gid = chp.groups[filters.group]; - if (gid) { - filters.groupId = gid; - return; - } - }); - } - - // Parse range values - if (filters.volume) { - [filters.volumeMin, filters.volumeMax] = this.parseRange(filters.volume); - } - if (filters.chapter) { - [filters.chapterMin, filters.chapterMax] = this.parseRange(filters.chapter); - } - - if (!filters.language && !langConfirmed) { - UIkit.modal.confirm('You didn\'t specify a language in the filtering rules. This might cause Mango to download chapters that are not in your preferred language. Are you sure you want to continue?', { - labels: { - ok: 'Yes', - cancel: 'Cancel' - } - }).then(() => { - this.subscribe(true, groupConfirmed); - }); - return; - } - - if (!filters.group && !groupConfirmed) { - UIkit.modal.confirm('You didn\'t specify a group in the filtering rules. This might cause Mango to download multiple versions of the same chapter. Are you sure you want to continue?', { - labels: { - ok: 'Yes', - cancel: 'Cancel' - } - }).then(() => { - this.subscribe(langConfirmed, true); - }); - return; - } - - const mangaURL = `${mangadex_base_url}/manga/${filters.manga}`; - - console.log(filters); - UIkit.modal.confirm(`All FUTURE chapters matching the following filters will be downloaded:
- - - IMPORTANT: Please make sure you are following the manga on MangaDex, otherwise Mango won't be able to receive any updates. To follow it, visit ${mangaURL} and click "Follow". - `, { - labels: { - ok: 'Confirm', - cancel: 'Cancel' - } - }).then(() => { - $.ajax({ - type: 'POST', - url: `${base_url}api/admin/mangadex/subscriptions`, - data: JSON.stringify({ - subscription: filters - }), - contentType: "application/json", - dataType: 'json' - }) - .done(data => { - console.log(data); - if (data.error) { - alert('danger', `Failed to subscribe. Error: ${data.error}`); - return; - } - alert('success', `You've successfully subscribed to this manga! You can view and manage your subscriptions on the subscription manager page.`); - }) - .fail((jqXHR, status) => { - alert('danger', `Failed to subscribe. Error: [${jqXHR.status}] ${jqXHR.statusText}`); - }); - }); } }; }; diff --git a/shard.lock b/shard.lock index 13ce55d..c22f839 100644 --- a/shard.lock +++ b/shard.lock @@ -54,7 +54,7 @@ shards: mangadex: git: https://github.com/hkalexling/mangadex.git - version: 0.11.0+git.commit.f5b0d64fbb138879fb9228b6e9ff34ec97c3e824 + version: 0.9.0+git.commit.a8e5deb3e6f882f5bc0f4de66e0f6c20aa98a8a6 mg: git: https://github.com/hkalexling/mg.git diff --git a/src/config.cr b/src/config.cr index 6de78a7..332a159 100644 --- a/src/config.cr +++ b/src/config.cr @@ -33,10 +33,8 @@ class Config "download_retries" => 4, "download_queue_db_path" => File.expand_path("~/mango/queue.db", home: true), - "chapter_rename_rule" => "[Vol.{volume} ]" \ - "[Ch.{chapter} ]{title|id}", - "manga_rename_rule" => "{title}", - "subscription_update_interval_hours" => 24, + "chapter_rename_rule" => "[Vol.{volume} ][Ch.{chapter} ]{title|id}", + "manga_rename_rule" => "{title}", } @@singlet : Config? diff --git a/src/library/library.cr b/src/library/library.cr index e359847..a5a4a80 100644 --- a/src/library/library.cr +++ b/src/library/library.cr @@ -42,25 +42,6 @@ class Library end end end - - subscription_interval = Config.current - .mangadex["subscription_update_interval_hours"].as Int32 - unless subscription_interval < 1 - spawn do - loop do - subscriptions = Storage.default.subscriptions - Logger.info "Checking MangaDex for updates on " \ - "#{subscriptions.size} subscriptions" - added_count = 0 - subscriptions.each do |sub| - added_count += sub.check_for_updates - end - Logger.info "Subscription update completed. Added #{added_count} " \ - "chapters to the download queue" - sleep subscription_interval.hours - end - end - end end def titles diff --git a/src/mangadex/ext.cr b/src/mangadex/ext.cr index e919d97..deb09c8 100644 --- a/src/mangadex/ext.cr +++ b/src/mangadex/ext.cr @@ -56,39 +56,5 @@ module MangaDex hash["full_title"] = JSON::Any.new full_title hash.to_json end - - # We don't need to rename the manga title here. It will be renamed in - # src/mangadex/downloader.cr - def to_job : Queue::Job - Queue::Job.new( - id.to_s, - manga_id.to_s, - full_title, - manga_title, - Queue::JobStatus::Pending, - Time.unix timestamp - ) - end - end - - struct User - def updates_after(time : Time, &block : Chapter ->) - page = 1 - stopped = false - until stopped - chapters = followed_updates(page: page).chapters - return if chapters.empty? - chapters.each do |c| - if time > Time.unix c.timestamp - stopped = true - break - end - yield c - end - page += 1 - # Let's not DDOS MangaDex :) - sleep 5.seconds - end - end end end diff --git a/src/routes/api.cr b/src/routes/api.cr index a66210a..c84af20 100644 --- a/src/routes/api.cr +++ b/src/routes/api.cr @@ -986,147 +986,23 @@ struct APIRouter Koa.tags ["admin", "mangadex"] get "/api/admin/mangadex/search" do |env| begin + username = get_username env + token, expires = Storage.default.get_md_token username + + unless expires && token + raise "No token found for user #{username}" + end + + client = MangaDex::Client.from_config + client.token = token + client.token_expires = expires + query = env.params.query["query"] send_json env, { "success" => true, "error" => nil, - "manga" => get_client(env).partial_search query, - }.to_json - rescue e - Logger.error e - send_json env, { - "success" => false, - "error" => e.message, - }.to_json - end - end - - Koa.describe "Lists all MangaDex subscriptions" - Koa.response 200, schema: { - "success" => Bool, - "error" => String?, - "subscriptions?" => [{ - "id" => Int64, - "username" => String, - "manga_id" => Int64, - "language" => String?, - "group_id" => Int64?, - "min_volume" => Int64?, - "max_volume" => Int64?, - "min_chapter" => Int64?, - "max_chapter" => Int64?, - "last_checked" => Int64, - "created_at" => Int64, - }], - } - Koa.tags ["admin", "mangadex", "subscriptions"] - get "/api/admin/mangadex/subscriptions" do |env| - begin - send_json env, { - "success" => true, - "error" => nil, - "subscriptions" => Storage.default.subscriptions, - }.to_json - rescue e - Logger.error e - send_json env, { - "success" => false, - "error" => e.message, - }.to_json - end - end - - Koa.describe "Creates a new MangaDex subscription" - Koa.body schema: { - "subscription" => { - "manga" => Int64, - "language" => String?, - "groupId" => Int64?, - "volumeMin" => Int64?, - "volumeMax" => Int64?, - "chapterMin" => Int64?, - "chapterMax" => Int64?, - }, - } - Koa.response 200, schema: { - "success" => Bool, - "error" => String?, - } - Koa.tags ["admin", "mangadex", "subscriptions"] - post "/api/admin/mangadex/subscriptions" do |env| - begin - json = env.params.json["subscription"].as Hash(String, JSON::Any) - sub = Subscription.new json["manga"].as_i64, get_username env - sub.language = json["language"]?.try &.as_s? - sub.group_id = json["groupId"]?.try &.as_i64? - sub.min_volume = json["volumeMin"]?.try &.as_i64? - sub.max_volume = json["volumeMax"]?.try &.as_i64? - sub.min_chapter = json["chapterMin"]?.try &.as_i64? - sub.max_chapter = json["chapterMax"]?.try &.as_i64? - - Storage.default.save_subscription sub - - send_json env, { - "success" => true, - "error" => nil, - }.to_json - rescue e - Logger.error e - send_json env, { - "success" => false, - "error" => e.message, - }.to_json - end - end - - Koa.describe "Deletes a MangaDex subscription identified by `id`", <<-MD - Does nothing if the subscription was not created by the current user. - MD - Koa.response 200, schema: { - "success" => Bool, - "error" => String?, - } - Koa.tags ["admin", "mangadex", "subscriptions"] - delete "/api/admin/mangadex/subscriptions/:id" do |env| - begin - id = env.params.url["id"].to_i64 - Storage.default.delete_subscription id, get_username env - send_json env, { - "success" => true, - "error" => nil, - }.to_json - rescue e - Logger.error e - send_json env, { - "success" => false, - "error" => e.message, - }.to_json - end - end - - Koa.describe "Triggers an update for a MangaDex subscription identified by `id`", <<-MD - Does nothing if the subscription was not created by the current user. - MD - Koa.response 200, schema: { - "success" => Bool, - "error" => String?, - } - Koa.tags ["admin", "mangadex", "subscriptions"] - post "/api/admin/mangadex/subscriptions/check/:id" do |env| - begin - id = env.params.url["id"].to_i64 - username = get_username env - sub = Storage.default.get_subscription id, username - unless sub - raise "Subscription with id #{id} not found under user #{username}" - end - spawn do - sub.check_for_updates - end - send_json env, { - "success" => true, - "error" => nil, + "manga" => client.partial_search query, }.to_json rescue e Logger.error e diff --git a/src/routes/main.cr b/src/routes/main.cr index 54e3fba..6c1a611 100644 --- a/src/routes/main.cr +++ b/src/routes/main.cr @@ -96,12 +96,6 @@ struct MainRouter end end - get "/download/subscription" do |env| - mangadex_base_url = Config.current.mangadex["base_url"] - username = get_username env - layout "subscription" - end - get "/" do |env| begin username = get_username env diff --git a/src/storage.cr b/src/storage.cr index 164ce40..39116b9 100644 --- a/src/storage.cr +++ b/src/storage.cr @@ -5,7 +5,6 @@ require "base64" require "./util/*" require "mg" require "../migration/*" -require "./subscription" def hash_password(pw) Crypto::Bcrypt::Password.create(pw).to_s @@ -15,9 +14,6 @@ def verify_password(hash, pw) (Crypto::Bcrypt::Password.new hash).verify pw end -SUB_ATTR = %w(manga_id language group_id min_volume max_volume min_chapter - max_chapter username) - class Storage @@insert_entry_ids = [] of IDTuple @@insert_title_ids = [] of IDTuple @@ -549,70 +545,6 @@ class Storage {token, expires} end - def save_subscription(sub : Subscription) - MainFiber.run do - get_db do |db| - {% begin %} - db.exec "insert into subscription (#{SUB_ATTR.join ","}, " \ - "last_checked, created_at) values " \ - "(#{Array.new(SUB_ATTR.size + 2, "?").join ","})", - {% for type in SUB_ATTR %} - sub.{{type.id}}, - {% end %} - sub.last_checked.to_unix, sub.created_at.to_unix - {% end %} - end - end - end - - def subscriptions : Array(Subscription) - subs = [] of Subscription - MainFiber.run do - get_db do |db| - db.query "select * from subscription" do |rs| - subs += Subscription.from_rs rs - end - end - end - subs - end - - def delete_subscription(id : Int64, username : String) - MainFiber.run do - get_db do |db| - db.exec "delete from subscription where id = (?) and username = (?)", - id, username - end - end - end - - def get_subscription(id : Int64, username : String) : Subscription? - sub = nil - MainFiber.run do - get_db do |db| - db.query "select * from subscription where id = (?) and " \ - "username = (?) limit 1", id, username do |rs| - sub = Subscription.from_rs(rs).first? - end - end - end - sub - end - - def update_subscription_last_checked(id : Int64? = nil) - MainFiber.run do - get_db do |db| - if id - db.exec "update subscription set last_checked = (?) where id = (?)", - Time.utc.to_unix, id - else - db.exec "update subscription set last_checked = (?)", - Time.utc.to_unix - end - end - end - end - def close MainFiber.run do unless @db.nil? diff --git a/src/util/web.cr b/src/util/web.cr index efa269d..12459e5 100644 --- a/src/util/web.cr +++ b/src/util/web.cr @@ -107,25 +107,6 @@ macro get_sort_opt end end -# Returns an authorized client -def get_client(username : String) : MangaDex::Client - token, expires = Storage.default.get_md_token username - - unless expires && token - raise "No token found for user #{username}" - end - - client = MangaDex::Client.from_config - client.token = token - client.token_expires = expires - - client -end - -def get_client(env) : MangaDex::Client - get_client get_username env -end - module HTTP class Client private def self.exec(uri : URI, tls : TLSContext = nil) diff --git a/src/views/download-manager.html.ecr b/src/views/download-manager.html.ecr index 2075e01..c264177 100644 --- a/src/views/download-manager.html.ecr +++ b/src/views/download-manager.html.ecr @@ -5,63 +5,61 @@ -
- - - - - - - - - - +
ChapterMangaProgressTimeStatusPluginActions
+ + + + + + + + + + + + + + +
ChapterMangaProgressTimeStatusPluginActions
+
<% content_for "script" do %> diff --git a/src/views/download.html.ecr b/src/views/download.html.ecr index 983cae0..0ea8527 100644 --- a/src/views/download.html.ecr +++ b/src/views/download.html.ecr @@ -1,170 +1,162 @@

Download from MangaDex

-
-
- -
-
-
- -
+
+
+
+
+
+ +
+
- -
-
-
- -
-
-

Title:

-

-

-
-
-

- Filter Chapters - -

-

-
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
-
+
+
+
+ +
+
+

Title:

+

+

+
+
+

Filter Chapters

+

+
+ +
+ +
-
- - - -
-
-

Click on a table row to select the chapter. Drag your mouse over multiple rows to select them all. Hold Ctrl to make multiple non-adjacent selections.

+ +
+ +
-

-
- - - - - - - - - - - - -
IDTitleLanguageGroupVolumeChapterTimestamp