mirror of
https://github.com/hkalexling/Mango.git
synced 2026-05-01 00:00:55 -04:00
127 lines
2.6 KiB
Crystal
127 lines
2.6 KiB
Crystal
require "uuid"
|
|
require "big"
|
|
|
|
enum FilterType
|
|
String
|
|
NumMin
|
|
NumMax
|
|
DateMin
|
|
DateMax
|
|
Array
|
|
|
|
def self.from_string(str)
|
|
case str
|
|
when "string"
|
|
String
|
|
when "number-min"
|
|
NumMin
|
|
when "number-max"
|
|
NumMax
|
|
when "date-min"
|
|
DateMin
|
|
when "date-max"
|
|
DateMax
|
|
when "array"
|
|
Array
|
|
else
|
|
raise "Unknown filter type with string #{str}"
|
|
end
|
|
end
|
|
end
|
|
|
|
struct Filter
|
|
include JSON::Serializable
|
|
|
|
property key : String
|
|
property value : String | Int32 | Int64 | Float32 | Nil
|
|
property type : FilterType
|
|
|
|
def initialize(@key, @value, @type)
|
|
end
|
|
|
|
def self.from_json(str) : Filter
|
|
json = JSON.parse str
|
|
key = json["key"].as_s
|
|
type = FilterType.from_string json["type"].as_s
|
|
_value = json["value"]
|
|
value = _value.as_s? || _value.as_i? || _value.as_i64? ||
|
|
_value.as_f32? || nil
|
|
self.new key, value, type
|
|
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.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
|
|
return true if value == "all"
|
|
raw_value.as_s.downcase.split(",")
|
|
.map(&.strip).includes? value.to_s.downcase.strip
|
|
else
|
|
false
|
|
end
|
|
end
|
|
end
|
|
|
|
# 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, @manga_title, @name)
|
|
@id = UUID.random.to_s
|
|
@created_at = Time.utc.to_unix
|
|
@last_checked = Time.utc.to_unix
|
|
end
|
|
|
|
def match_chapter(obj : JSON::Any) : Bool
|
|
filters.all? &.match_chapter(obj)
|
|
end
|
|
end
|
|
|
|
struct SubscriptionList
|
|
@dir : String
|
|
@path : String
|
|
|
|
getter ary = [] of Subscription
|
|
|
|
forward_missing_to @ary
|
|
|
|
def initialize(@dir)
|
|
@path = Path[@dir, "subscriptions.json"].to_s
|
|
if File.exists? @path
|
|
@ary = Array(Subscription).from_json File.read @path
|
|
end
|
|
end
|
|
|
|
def save
|
|
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
|