mirror of
https://github.com/hkalexling/Mango.git
synced 2025-08-05 20:35:35 -04:00
Finish plugin updater
This commit is contained in:
parent
5fac8c6a60
commit
031df3a2bc
@ -100,14 +100,14 @@ const component = () => {
|
|||||||
this.mangaTitle = data.title;
|
this.mangaTitle = data.title;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.chapters.forEach((c) => {
|
//data.chapters.forEach((c) => {
|
||||||
c.array = ["hello", "world", "haha", "wtf"]
|
//c.array = ["hello", "world", "haha", "wtf"]
|
||||||
.sort(() => 0.5 - Math.random())
|
//.sort(() => 0.5 - Math.random())
|
||||||
.slice(0, 2);
|
//.slice(0, 2);
|
||||||
c.date = [612892800000, "1625068800000"].sort(
|
//c.date = [612892800000, "1625068800000"].sort(
|
||||||
() => 0.5 - Math.random()
|
//() => 0.5 - Math.random()
|
||||||
)[0];
|
//)[0];
|
||||||
});
|
//});
|
||||||
|
|
||||||
this.allChapters = data.chapters;
|
this.allChapters = data.chapters;
|
||||||
this.chapters = data.chapters;
|
this.chapters = data.chapters;
|
||||||
@ -387,7 +387,8 @@ const component = () => {
|
|||||||
filters: this.filterSettings,
|
filters: this.filterSettings,
|
||||||
plugin: this.pid,
|
plugin: this.pid,
|
||||||
name: this.subscriptionName.trim(),
|
name: this.subscriptionName.trim(),
|
||||||
manga: this.mid,
|
manga: this.mangaTitle,
|
||||||
|
manga_id: this.mid,
|
||||||
}),
|
}),
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
@ -28,6 +28,7 @@ class Config
|
|||||||
property disable_login = false
|
property disable_login = false
|
||||||
property default_username = ""
|
property default_username = ""
|
||||||
property auth_proxy_header_name = ""
|
property auth_proxy_header_name = ""
|
||||||
|
property plugin_update_interval_hours : Int32 = 24
|
||||||
property mangadex = Hash(String, String | Int32).new
|
property mangadex = Hash(String, String | Int32).new
|
||||||
|
|
||||||
@[YAML::Field(ignore: true)]
|
@[YAML::Field(ignore: true)]
|
||||||
|
@ -61,6 +61,7 @@ class CLI < Clim
|
|||||||
Library.load_instance
|
Library.load_instance
|
||||||
Library.default
|
Library.default
|
||||||
Plugin::Downloader.default
|
Plugin::Downloader.default
|
||||||
|
Plugin::Updater.new
|
||||||
|
|
||||||
spawn do
|
spawn do
|
||||||
begin
|
begin
|
||||||
|
@ -143,6 +143,10 @@ class Plugin
|
|||||||
SubscriptionList.new(info.dir).ary
|
SubscriptionList.new(info.dir).ary
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def list_subscriptions_raw
|
||||||
|
SubscriptionList.new(info.dir)
|
||||||
|
end
|
||||||
|
|
||||||
def unsubscribe(id : String)
|
def unsubscribe(id : String)
|
||||||
list = SubscriptionList.new info.dir
|
list = SubscriptionList.new info.dir
|
||||||
list.reject! &.id.== id
|
list.reject! &.id.== id
|
||||||
|
@ -50,35 +50,40 @@ struct Filter
|
|||||||
end
|
end
|
||||||
|
|
||||||
def match_chapter(obj : JSON::Any) : Bool
|
def match_chapter(obj : JSON::Any) : Bool
|
||||||
|
return true if value.nil? || value.to_s.empty?
|
||||||
raw_value = obj[key]
|
raw_value = obj[key]
|
||||||
case type
|
case type
|
||||||
when FilterType::String
|
when FilterType::String
|
||||||
raw_value.as_s.lower == value.as_s.lower
|
raw_value.as_s.downcase == value.to_s.downcase
|
||||||
when FilterType::NumMin
|
when FilterType::NumMin, FilterType::DateMin
|
||||||
when FilterType::DateMin
|
raw_value.as_bf >= BigFloat.new value.not_nil!.to_f32
|
||||||
BigFloat.new(raw_value) >= BigFloat.new(value)
|
when FilterType::NumMax, FilterType::DateMax
|
||||||
when FilterType::NumMax
|
raw_value.as_bf <= BigFloat.new value.not_nil!.to_f32
|
||||||
when FilterType::DateMax
|
|
||||||
BigFloat.new(raw_value) <= BigFloat.new(value)
|
|
||||||
when FilterType::Array
|
when FilterType::Array
|
||||||
raw_value.as_s.lower.split(",")
|
return true if value == "all"
|
||||||
.map(&.strip).include? value.as_s.lower.strip
|
raw_value.as_s.downcase.split(",")
|
||||||
|
.map(&.strip).includes? value.to_s.downcase.strip
|
||||||
|
else
|
||||||
|
false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
struct Subscription
|
# We use class instead of struct so we can update `last_checked` from
|
||||||
|
# `SubscriptionList`
|
||||||
|
class Subscription
|
||||||
include JSON::Serializable
|
include JSON::Serializable
|
||||||
|
|
||||||
property id : String
|
property id : String
|
||||||
property plugin_id : String
|
property plugin_id : String
|
||||||
property manga_id : String
|
property manga_id : String
|
||||||
|
property manga_title : String
|
||||||
property name : String
|
property name : String
|
||||||
property created_at : Int64
|
property created_at : Int64
|
||||||
property last_checked : Int64
|
property last_checked : Int64
|
||||||
property filters = [] of Filter
|
property filters = [] of Filter
|
||||||
|
|
||||||
def initialize(@plugin_id, @manga_id, @name)
|
def initialize(@plugin_id, @manga_id, @manga_title, @name)
|
||||||
@id = UUID.random.to_s
|
@id = UUID.random.to_s
|
||||||
@created_at = Time.utc.to_unix
|
@created_at = Time.utc.to_unix
|
||||||
@last_checked = Time.utc.to_unix
|
@last_checked = Time.utc.to_unix
|
||||||
@ -108,3 +113,14 @@ struct SubscriptionList
|
|||||||
File.write @path, @ary.to_pretty_json
|
File.write @path, @ary.to_pretty_json
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
struct JSON::Any
|
||||||
|
def as_bf : BigFloat
|
||||||
|
i64_or_f32 = begin
|
||||||
|
as_i64
|
||||||
|
rescue
|
||||||
|
as_f32
|
||||||
|
end
|
||||||
|
BigFloat.new i64_or_f32
|
||||||
|
end
|
||||||
|
end
|
||||||
|
74
src/plugin/updater.cr
Normal file
74
src/plugin/updater.cr
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
require "../config"
|
||||||
|
|
||||||
|
class Plugin
|
||||||
|
class Updater
|
||||||
|
def initialize
|
||||||
|
interval = Config.current.plugin_update_interval_hours
|
||||||
|
return if interval <= 0
|
||||||
|
spawn do
|
||||||
|
loop do
|
||||||
|
Plugin.list.map(&.["id"]).each do |pid|
|
||||||
|
check_updates pid
|
||||||
|
end
|
||||||
|
sleep interval.hours
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_updates(plugin_id : String)
|
||||||
|
Logger.debug "Checking plugin #{plugin_id} for updates"
|
||||||
|
|
||||||
|
plugin = Plugin.new plugin_id
|
||||||
|
if plugin.info.version == 1
|
||||||
|
Logger.debug "Plugin #{plugin_id} is targeting API version 1. " \
|
||||||
|
"Skipping update check"
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
subscriptions = plugin.list_subscriptions_raw
|
||||||
|
subscriptions.each do |sub|
|
||||||
|
check_subscription plugin, sub
|
||||||
|
end
|
||||||
|
subscriptions.save
|
||||||
|
rescue e
|
||||||
|
Logger.error "Error checking plugin #{plugin_id} for updates: " \
|
||||||
|
"#{e.message}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_subscription(plugin : Plugin, sub : Subscription)
|
||||||
|
Logger.debug "Checking subscription #{sub.name} for updates"
|
||||||
|
matches = plugin.new_chapters(sub.manga_id, sub.last_checked)
|
||||||
|
.as_a.select do |chapter|
|
||||||
|
sub.match_chapter chapter
|
||||||
|
end
|
||||||
|
if matches.empty?
|
||||||
|
Logger.debug "No new chapters found."
|
||||||
|
return
|
||||||
|
end
|
||||||
|
Logger.debug "Found #{matches.size} new chapters. " \
|
||||||
|
"Pushing to download queue"
|
||||||
|
jobs = matches.map { |ch|
|
||||||
|
Queue::Job.new(
|
||||||
|
"#{plugin.info.id}-#{ch["id"]}",
|
||||||
|
"", # manga_id
|
||||||
|
ch["title"].as_s,
|
||||||
|
sub.manga_title,
|
||||||
|
Queue::JobStatus::Pending,
|
||||||
|
Time.utc
|
||||||
|
)
|
||||||
|
}
|
||||||
|
inserted_count = Queue.default.push jobs
|
||||||
|
Logger.info "#{inserted_count}/#{matches.size} new chapters added " \
|
||||||
|
"to the download queue. Plugin ID #{plugin.info.id}, " \
|
||||||
|
"subscription name #{sub.name}"
|
||||||
|
if inserted_count != matches.size
|
||||||
|
Logger.error "Failed to add #{matches.size - inserted_count} " \
|
||||||
|
"chapters to download queue"
|
||||||
|
end
|
||||||
|
sub.last_checked = Time.utc.to_unix
|
||||||
|
rescue e
|
||||||
|
Logger.error "Error when checking updates for subscription " \
|
||||||
|
"#{sub.name}: #{e.message}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -661,13 +661,14 @@ struct APIRouter
|
|||||||
post "/api/admin/plugin/subscriptions" do |env|
|
post "/api/admin/plugin/subscriptions" do |env|
|
||||||
begin
|
begin
|
||||||
plugin_id = env.params.json["plugin"].as String
|
plugin_id = env.params.json["plugin"].as String
|
||||||
manga_id = env.params.json["manga"].as String
|
manga_title = env.params.json["manga"].as String
|
||||||
|
manga_id = env.params.json["manga_id"].as String
|
||||||
filters = env.params.json["filters"].as(Array(JSON::Any)).map do |f|
|
filters = env.params.json["filters"].as(Array(JSON::Any)).map do |f|
|
||||||
Filter.from_json f.to_json
|
Filter.from_json f.to_json
|
||||||
end
|
end
|
||||||
name = env.params.json["name"].as String
|
name = env.params.json["name"].as String
|
||||||
|
|
||||||
sub = Subscription.new plugin_id, manga_id, name
|
sub = Subscription.new plugin_id, manga_id, manga_title, name
|
||||||
sub.filters = filters
|
sub.filters = filters
|
||||||
|
|
||||||
plugin = Plugin.new plugin_id
|
plugin = Plugin.new plugin_id
|
||||||
|
Loading…
x
Reference in New Issue
Block a user