Finish plugin updater

This commit is contained in:
Alex Ling 2022-01-22 13:11:58 +00:00
parent 5fac8c6a60
commit 031df3a2bc
7 changed files with 120 additions and 22 deletions

View File

@ -100,14 +100,14 @@ const component = () => {
this.mangaTitle = data.title;
}
data.chapters.forEach((c) => {
c.array = ["hello", "world", "haha", "wtf"]
.sort(() => 0.5 - Math.random())
.slice(0, 2);
c.date = [612892800000, "1625068800000"].sort(
() => 0.5 - Math.random()
)[0];
});
//data.chapters.forEach((c) => {
//c.array = ["hello", "world", "haha", "wtf"]
//.sort(() => 0.5 - Math.random())
//.slice(0, 2);
//c.date = [612892800000, "1625068800000"].sort(
//() => 0.5 - Math.random()
//)[0];
//});
this.allChapters = data.chapters;
this.chapters = data.chapters;
@ -387,7 +387,8 @@ const component = () => {
filters: this.filterSettings,
plugin: this.pid,
name: this.subscriptionName.trim(),
manga: this.mid,
manga: this.mangaTitle,
manga_id: this.mid,
}),
headers: {
"Content-Type": "application/json",

View File

@ -28,6 +28,7 @@ class Config
property disable_login = false
property default_username = ""
property auth_proxy_header_name = ""
property plugin_update_interval_hours : Int32 = 24
property mangadex = Hash(String, String | Int32).new
@[YAML::Field(ignore: true)]

View File

@ -61,6 +61,7 @@ class CLI < Clim
Library.load_instance
Library.default
Plugin::Downloader.default
Plugin::Updater.new
spawn do
begin

View File

@ -143,6 +143,10 @@ class Plugin
SubscriptionList.new(info.dir).ary
end
def list_subscriptions_raw
SubscriptionList.new(info.dir)
end
def unsubscribe(id : String)
list = SubscriptionList.new info.dir
list.reject! &.id.== id

View File

@ -50,35 +50,40 @@ struct Filter
end
def match_chapter(obj : JSON::Any) : Bool
return true if value.nil? || value.to_s.empty?
raw_value = obj[key]
case type
when FilterType::String
raw_value.as_s.lower == value.as_s.lower
when FilterType::NumMin
when FilterType::DateMin
BigFloat.new(raw_value) >= BigFloat.new(value)
when FilterType::NumMax
when FilterType::DateMax
BigFloat.new(raw_value) <= BigFloat.new(value)
raw_value.as_s.downcase == value.to_s.downcase
when FilterType::NumMin, FilterType::DateMin
raw_value.as_bf >= BigFloat.new value.not_nil!.to_f32
when FilterType::NumMax, FilterType::DateMax
raw_value.as_bf <= BigFloat.new value.not_nil!.to_f32
when FilterType::Array
raw_value.as_s.lower.split(",")
.map(&.strip).include? value.as_s.lower.strip
return true if value == "all"
raw_value.as_s.downcase.split(",")
.map(&.strip).includes? value.to_s.downcase.strip
else
false
end
end
end
struct Subscription
# We use class instead of struct so we can update `last_checked` from
# `SubscriptionList`
class Subscription
include JSON::Serializable
property id : String
property plugin_id : String
property manga_id : String
property manga_title : String
property name : String
property created_at : Int64
property last_checked : Int64
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
@created_at = Time.utc.to_unix
@last_checked = Time.utc.to_unix
@ -108,3 +113,14 @@ struct SubscriptionList
File.write @path, @ary.to_pretty_json
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
View 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

View File

@ -661,13 +661,14 @@ struct APIRouter
post "/api/admin/plugin/subscriptions" do |env|
begin
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|
Filter.from_json f.to_json
end
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
plugin = Plugin.new plugin_id