Config: clean up the various converters

This commit is contained in:
Samantaz Fox 2023-04-03 00:12:36 +02:00
parent 8bbc46fd98
commit 53f50611c2
No known key found for this signature in database
GPG key ID: F42821059186176E
3 changed files with 79 additions and 157 deletions

View file

@ -53,7 +53,7 @@ class Config
# Number of threads to use for crawling videos from channels (for updating subscriptions) # Number of threads to use for crawling videos from channels (for updating subscriptions)
property channel_threads : Int32 = 1 property channel_threads : Int32 = 1
# Time interval between two executions of the job that crawls channel videos (subscriptions update). # Time interval between two executions of the job that crawls channel videos (subscriptions update).
@[YAML::Field(converter: Preferences::TimeSpanConverter)] @[YAML::Field(converter: IV::Config::TimeSpanConverter)]
property channel_refresh_interval : Time::Span = 30.minutes property channel_refresh_interval : Time::Span = 30.minutes
# Number of threads to use for updating feeds # Number of threads to use for updating feeds
property feed_threads : Int32 = 1 property feed_threads : Int32 = 1
@ -65,7 +65,7 @@ class Config
property db : IV::Config::DBConfig? = nil property db : IV::Config::DBConfig? = nil
# Database configuration using 12-Factor "Database URL" syntax # Database configuration using 12-Factor "Database URL" syntax
@[YAML::Field(converter: Preferences::URIConverter)] @[YAML::Field(converter: IV::Config::URIConverter)]
property database_url : URI = URI.parse("") property database_url : URI = URI.parse("")
# Use polling to keep decryption function up to date # Use polling to keep decryption function up to date
property decrypt_polling : Bool = false property decrypt_polling : Bool = false
@ -111,8 +111,9 @@ class Config
property modified_source_code_url : String? = nil property modified_source_code_url : String? = nil
# Connect to YouTube over 'ipv6', 'ipv4'. Will sometimes resolve fix issues with rate-limiting (see https://github.com/ytdl-org/youtube-dl/issues/21729) # Connect to YouTube over 'ipv6', 'ipv4'. Will sometimes resolve fix issues with rate-limiting (see https://github.com/ytdl-org/youtube-dl/issues/21729)
@[YAML::Field(converter: Preferences::FamilyConverter)] @[YAML::Field(converter: IV::Config::FamilyConverter)]
property force_resolve : Socket::Family = Socket::Family::UNSPEC property force_resolve : Socket::Family = Socket::Family::UNSPEC
# Port to listen for connections (overridden by command line argument) # Port to listen for connections (overridden by command line argument)
property port : Int32 = 3000 property port : Int32 = 3000
# Host to bind (overridden by command line argument) # Host to bind (overridden by command line argument)
@ -123,7 +124,7 @@ class Config
property use_quic : Bool = false property use_quic : Bool = false
# Saved cookies in "name1=value1; name2=value2..." format # Saved cookies in "name1=value1; name2=value2..." format
@[YAML::Field(converter: Preferences::StringToCookies)] @[YAML::Field(converter: IV::Config::CookiesConverter)]
property cookies : HTTP::Cookies = HTTP::Cookies.new property cookies : HTTP::Cookies = HTTP::Cookies.new
# Key for Anti-Captcha # Key for Anti-Captcha
property captcha_key : String? = nil property captcha_key : String? = nil

View file

@ -0,0 +1,74 @@
module Invidious::Config
module CookiesConverter
def self.to_yaml(value : HTTP::Cookies, yaml : YAML::Nodes::Builder)
(value.map { |c| "#{c.name}=#{c.value}" }).join("; ").to_yaml(yaml)
end
def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : HTTP::Cookies
unless node.is_a?(YAML::Nodes::Scalar)
node.raise "Expected scalar, not #{node.class}"
end
cookies = HTTP::Cookies.new
node.value.split(";").each do |cookie|
next if cookie.strip.empty?
name, value = cookie.split("=", 2)
cookies << HTTP::Cookie.new(name.strip, value.strip)
end
return cookies
end
end
module FamilyConverter
def self.to_yaml(value : Socket::Family, yaml : YAML::Nodes::Builder)
case value
when Socket::Family::UNSPEC then yaml.scalar nil
when Socket::Family::INET then yaml.scalar "ipv4"
when Socket::Family::INET6 then yaml.scalar "ipv6"
when Socket::Family::UNIX then raise "Invalid socket family #{value}"
end
end
def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : Socket::Family
if node.is_a?(YAML::Nodes::Scalar)
case node.value.downcase
when "ipv4" then Socket::Family::INET
when "ipv6" then Socket::Family::INET6
else
Socket::Family::UNSPEC
end
else
node.raise "Expected scalar, not #{node.class}"
end
end
end
module URIConverter
def self.to_yaml(value : URI, yaml : YAML::Nodes::Builder)
yaml.scalar value.normalize!
end
def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : URI
if node.is_a?(YAML::Nodes::Scalar)
URI.parse node.value
else
node.raise "Expected scalar, not #{node.class}"
end
end
end
module TimeSpanConverter
def self.to_yaml(value : Time::Span, yaml : YAML::Nodes::Builder)
return yaml.scalar value.total_minutes.to_i32
end
def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : Time::Span
if node.is_a?(YAML::Nodes::Scalar)
return decode_interval(node.value)
else
node.raise "Expected scalar, not #{node.class}"
end
end
end
end

View file

@ -1,6 +1,5 @@
struct Preferences struct Preferences
include JSON::Serializable include JSON::Serializable
include YAML::Serializable
property annotations : Bool = CONFIG.default_user_preferences.annotations property annotations : Bool = CONFIG.default_user_preferences.annotations
property annotations_subscribed : Bool = CONFIG.default_user_preferences.annotations_subscribed property annotations_subscribed : Bool = CONFIG.default_user_preferences.annotations_subscribed
@ -8,17 +7,14 @@ struct Preferences
property automatic_instance_redirect : Bool = CONFIG.default_user_preferences.automatic_instance_redirect property automatic_instance_redirect : Bool = CONFIG.default_user_preferences.automatic_instance_redirect
@[JSON::Field(converter: Preferences::StringToArray)] @[JSON::Field(converter: Preferences::StringToArray)]
@[YAML::Field(converter: Preferences::StringToArray)]
property captions : Array(String) = CONFIG.default_user_preferences.captions property captions : Array(String) = CONFIG.default_user_preferences.captions
@[JSON::Field(converter: Preferences::StringToArray)] @[JSON::Field(converter: Preferences::StringToArray)]
@[YAML::Field(converter: Preferences::StringToArray)]
property comments : Array(String) = CONFIG.default_user_preferences.comments property comments : Array(String) = CONFIG.default_user_preferences.comments
property continue : Bool = CONFIG.default_user_preferences.continue property continue : Bool = CONFIG.default_user_preferences.continue
property continue_autoplay : Bool = CONFIG.default_user_preferences.continue_autoplay property continue_autoplay : Bool = CONFIG.default_user_preferences.continue_autoplay
@[JSON::Field(converter: Preferences::BoolToString)] @[JSON::Field(converter: Preferences::BoolToString)]
@[YAML::Field(converter: Preferences::BoolToString)]
property dark_mode : String = CONFIG.default_user_preferences.dark_mode property dark_mode : String = CONFIG.default_user_preferences.dark_mode
property latest_only : Bool = CONFIG.default_user_preferences.latest_only property latest_only : Bool = CONFIG.default_user_preferences.latest_only
property listen : Bool = CONFIG.default_user_preferences.listen property listen : Bool = CONFIG.default_user_preferences.listen
@ -78,27 +74,6 @@ struct Preferences
end end
end end
end end
def self.to_yaml(value : String, yaml : YAML::Nodes::Builder)
yaml.scalar value
end
def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : String
unless node.is_a?(YAML::Nodes::Scalar)
node.raise "Expected scalar, not #{node.class}"
end
case node.value
when "true"
"dark"
when "false"
"light"
when ""
CONFIG.default_user_preferences.dark_mode
else
node.value
end
end
end end
module ClampInt module ClampInt
@ -109,58 +84,6 @@ struct Preferences
def self.from_json(value : JSON::PullParser) : Int32 def self.from_json(value : JSON::PullParser) : Int32
value.read_int.clamp(0, MAX_ITEMS_PER_PAGE).to_i32 value.read_int.clamp(0, MAX_ITEMS_PER_PAGE).to_i32
end end
def self.to_yaml(value : Int32, yaml : YAML::Nodes::Builder)
yaml.scalar value
end
def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : Int32
node.value.clamp(0, MAX_ITEMS_PER_PAGE)
end
end
module FamilyConverter
def self.to_yaml(value : Socket::Family, yaml : YAML::Nodes::Builder)
case value
when Socket::Family::UNSPEC
yaml.scalar nil
when Socket::Family::INET
yaml.scalar "ipv4"
when Socket::Family::INET6
yaml.scalar "ipv6"
when Socket::Family::UNIX
raise "Invalid socket family #{value}"
end
end
def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : Socket::Family
if node.is_a?(YAML::Nodes::Scalar)
case node.value.downcase
when "ipv4"
Socket::Family::INET
when "ipv6"
Socket::Family::INET6
else
Socket::Family::UNSPEC
end
else
node.raise "Expected scalar, not #{node.class}"
end
end
end
module URIConverter
def self.to_yaml(value : URI, yaml : YAML::Nodes::Builder)
yaml.scalar value.normalize!
end
def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : URI
if node.is_a?(YAML::Nodes::Scalar)
URI.parse node.value
else
node.raise "Expected scalar, not #{node.class}"
end
end
end end
module ProcessString module ProcessString
@ -171,14 +94,6 @@ struct Preferences
def self.from_json(value : JSON::PullParser) : String def self.from_json(value : JSON::PullParser) : String
HTML.escape(value.read_string[0, 100]) HTML.escape(value.read_string[0, 100])
end end
def self.to_yaml(value : String, yaml : YAML::Nodes::Builder)
yaml.scalar value
end
def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : String
HTML.escape(node.value[0, 100])
end
end end
module StringToArray module StringToArray
@ -202,73 +117,5 @@ struct Preferences
result result
end end
def self.to_yaml(value : Array(String), yaml : YAML::Nodes::Builder)
yaml.sequence do
value.each do |element|
yaml.scalar element
end
end
end
def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : Array(String)
begin
unless node.is_a?(YAML::Nodes::Sequence)
node.raise "Expected sequence, not #{node.class}"
end
result = [] of String
node.nodes.each do |item|
unless item.is_a?(YAML::Nodes::Scalar)
node.raise "Expected scalar, not #{item.class}"
end
result << HTML.escape(item.value[0, 100])
end
rescue ex
if node.is_a?(YAML::Nodes::Scalar)
result = [HTML.escape(node.value[0, 100]), ""]
else
result = ["", ""]
end
end
result
end
end
module StringToCookies
def self.to_yaml(value : HTTP::Cookies, yaml : YAML::Nodes::Builder)
(value.map { |c| "#{c.name}=#{c.value}" }).join("; ").to_yaml(yaml)
end
def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : HTTP::Cookies
unless node.is_a?(YAML::Nodes::Scalar)
node.raise "Expected scalar, not #{node.class}"
end
cookies = HTTP::Cookies.new
node.value.split(";").each do |cookie|
next if cookie.strip.empty?
name, value = cookie.split("=", 2)
cookies << HTTP::Cookie.new(name.strip, value.strip)
end
cookies
end
end
module TimeSpanConverter
def self.to_yaml(value : Time::Span, yaml : YAML::Nodes::Builder)
return yaml.scalar value.total_minutes.to_i32
end
def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : Time::Span
if node.is_a?(YAML::Nodes::Scalar)
return decode_interval(node.value)
else
node.raise "Expected scalar, not #{node.class}"
end
end
end end
end end