summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOmar Roth <omarroth@hotmail.com>2019-04-03 11:35:58 -0500
committerOmar Roth <omarroth@hotmail.com>2019-04-03 11:38:41 -0500
commitbd4f5ebcdfb2e4bcbe7872fc76cdbf26e7dd4f80 (patch)
treea30aa7a4500373b8757af1914856744ec854db04
parent1fd7ff5655191385d68f3c65191ed70c0b2e6f0b (diff)
downloadinvidious-bd4f5ebcdfb2e4bcbe7872fc76cdbf26e7dd4f80.tar.gz
invidious-bd4f5ebcdfb2e4bcbe7872fc76cdbf26e7dd4f80.tar.bz2
invidious-bd4f5ebcdfb2e4bcbe7872fc76cdbf26e7dd4f80.zip
Add option to configure default user preferences
-rw-r--r--src/invidious.cr16
-rw-r--r--src/invidious/channels.cr4
-rw-r--r--src/invidious/helpers/helpers.cr104
-rw-r--r--src/invidious/helpers/macros.cr18
-rw-r--r--src/invidious/mixes.cr4
-rw-r--r--src/invidious/playlists.cr4
-rw-r--r--src/invidious/search.cr8
-rw-r--r--src/invidious/users.cr102
-rw-r--r--src/invidious/videos.cr22
9 files changed, 192 insertions, 90 deletions
diff --git a/src/invidious.cr b/src/invidious.cr
index d579ff4e..e97198d8 100644
--- a/src/invidious.cr
+++ b/src/invidious.cr
@@ -1198,22 +1198,22 @@ post "/preferences" do |env|
local = local == "on"
speed = env.params.body["speed"]?.try &.as(String).to_f?
- speed ||= DEFAULT_USER_PREFERENCES.speed
+ speed ||= CONFIG.default_user_preferences.speed
quality = env.params.body["quality"]?.try &.as(String)
- quality ||= DEFAULT_USER_PREFERENCES.quality
+ quality ||= CONFIG.default_user_preferences.quality
volume = env.params.body["volume"]?.try &.as(String).to_i?
- volume ||= DEFAULT_USER_PREFERENCES.volume
+ volume ||= CONFIG.default_user_preferences.volume
comments = [] of String
2.times do |i|
- comments << (env.params.body["comments[#{i}]"]?.try &.as(String) || DEFAULT_USER_PREFERENCES.comments[i])
+ comments << (env.params.body["comments[#{i}]"]?.try &.as(String) || CONFIG.default_user_preferences.comments[i])
end
captions = [] of String
3.times do |i|
- captions << (env.params.body["captions[#{i}]"]?.try &.as(String) || DEFAULT_USER_PREFERENCES.captions[i])
+ captions << (env.params.body["captions[#{i}]"]?.try &.as(String) || CONFIG.default_user_preferences.captions[i])
end
related_videos = env.params.body["related_videos"]?.try &.as(String)
@@ -1225,7 +1225,7 @@ post "/preferences" do |env|
redirect_feed = redirect_feed == "on"
locale = env.params.body["locale"]?.try &.as(String)
- locale ||= DEFAULT_USER_PREFERENCES.locale
+ locale ||= CONFIG.default_user_preferences.locale
dark_mode = env.params.body["dark_mode"]?.try &.as(String)
dark_mode ||= "off"
@@ -1236,10 +1236,10 @@ post "/preferences" do |env|
thin_mode = thin_mode == "on"
max_results = env.params.body["max_results"]?.try &.as(String).to_i?
- max_results ||= DEFAULT_USER_PREFERENCES.max_results
+ max_results ||= CONFIG.default_user_preferences.max_results
sort = env.params.body["sort"]?.try &.as(String)
- sort ||= DEFAULT_USER_PREFERENCES.sort
+ sort ||= CONFIG.default_user_preferences.sort
latest_only = env.params.body["latest_only"]?.try &.as(String)
latest_only ||= "off"
diff --git a/src/invidious/channels.cr b/src/invidious/channels.cr
index b24159db..0a2f3503 100644
--- a/src/invidious/channels.cr
+++ b/src/invidious/channels.cr
@@ -1,5 +1,5 @@
struct InvidiousChannel
- add_mapping({
+ db_mapping({
id: String,
author: String,
updated: Time,
@@ -9,7 +9,7 @@ struct InvidiousChannel
end
struct ChannelVideo
- add_mapping({
+ db_mapping({
id: String,
title: String,
published: Time,
diff --git a/src/invidious/helpers/helpers.cr b/src/invidious/helpers/helpers.cr
index 33d7b6f4..f6c22f64 100644
--- a/src/invidious/helpers/helpers.cr
+++ b/src/invidious/helpers/helpers.cr
@@ -1,4 +1,76 @@
+require "./macros"
+
+struct ConfigPreferences
+ module StringToArray
+ 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
+ unless node.is_a?(YAML::Nodes::Scalar)
+ node.raise "Expected scalar, not #{node.class}"
+ end
+
+ result << node.value
+ end
+ rescue ex
+ if node.is_a?(YAML::Nodes::Scalar)
+ result = [node.value, ""]
+ else
+ result = ["", ""]
+ end
+ end
+
+ result
+ end
+ end
+
+ yaml_mapping({
+ autoplay: {type: Bool, default: false},
+ captions: {type: Array(String), default: ["", "", ""], converter: StringToArray},
+ comments: {type: Array(String), default: ["youtube", ""], converter: StringToArray},
+ continue: {type: Bool, default: false},
+ dark_mode: {type: Bool, default: false},
+ latest_only: {type: Bool, default: false},
+ listen: {type: Bool, default: false},
+ local: {type: Bool, default: false},
+ locale: {type: String, default: "en-US"},
+ max_results: {type: Int32, default: 40},
+ notifications_only: {type: Bool, default: false},
+ quality: {type: String, default: "hd720"},
+ redirect_feed: {type: Bool, default: false},
+ related_videos: {type: Bool, default: true},
+ sort: {type: String, default: "published"},
+ speed: {type: Float32, default: 1.0_f32},
+ thin_mode: {type: Bool, default: false},
+ unseen_only: {type: Bool, default: false},
+ video_loop: {type: Bool, default: false},
+ volume: {type: Int32, default: 100},
+ })
+end
+
struct Config
+ module ConfigPreferencesConverter
+ def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : Preferences
+ Preferences.new(*ConfigPreferences.new(ctx, node).to_tuple)
+ end
+
+ def self.to_yaml(value : Preferences, yaml : YAML::Nodes::Builder)
+ value.to_yaml(yaml)
+ end
+ end
+
YAML.mapping({
channel_threads: Int32, # Number of threads to use for crawling videos from channels (for updating subscriptions)
feed_threads: Int32, # Number of threads to use for updating feeds
@@ -9,20 +81,24 @@ user: String,
port: Int32,
dbname: String,
),
- full_refresh: Bool, # Used for crawling channels: threads should check all videos uploaded by a channel
- https_only: Bool?, # Used to tell Invidious it is behind a proxy, so links to resources should be https://
- hmac_key: String?, # HMAC signing key for CSRF tokens and verifying pubsub subscriptions
- domain: String?, # Domain to be used for links to resources on the site where an absolute URL is required
- use_pubsub_feeds: {type: Bool, default: false}, # Subscribe to channels using PubSubHubbub (requires domain, hmac_key)
- default_home: {type: String, default: "Top"},
- feed_menu: {type: Array(String), default: ["Popular", "Top", "Trending", "Subscriptions"]},
- top_enabled: {type: Bool, default: true},
- captcha_enabled: {type: Bool, default: true},
- login_enabled: {type: Bool, default: true},
- registration_enabled: {type: Bool, default: true},
- statistics_enabled: {type: Bool, default: false},
- admins: {type: Array(String), default: [] of String},
- external_port: {type: Int32 | Nil, default: nil},
+ full_refresh: Bool, # Used for crawling channels: threads should check all videos uploaded by a channel
+ https_only: Bool?, # Used to tell Invidious it is behind a proxy, so links to resources should be https://
+ hmac_key: String?, # HMAC signing key for CSRF tokens and verifying pubsub subscriptions
+ domain: String?, # Domain to be used for links to resources on the site where an absolute URL is required
+ use_pubsub_feeds: {type: Bool, default: false}, # Subscribe to channels using PubSubHubbub (requires domain, hmac_key)
+ default_home: {type: String, default: "Top"},
+ feed_menu: {type: Array(String), default: ["Popular", "Top", "Trending", "Subscriptions"]},
+ top_enabled: {type: Bool, default: true},
+ captcha_enabled: {type: Bool, default: true},
+ login_enabled: {type: Bool, default: true},
+ registration_enabled: {type: Bool, default: true},
+ statistics_enabled: {type: Bool, default: false},
+ admins: {type: Array(String), default: [] of String},
+ external_port: {type: Int32?, default: nil},
+ default_user_preferences: {type: Preferences,
+ default: Preferences.new(*ConfigPreferences.from_yaml("").to_tuple),
+ converter: ConfigPreferencesConverter,
+ },
})
end
diff --git a/src/invidious/helpers/macros.cr b/src/invidious/helpers/macros.cr
index 5991faaf..fda34ed7 100644
--- a/src/invidious/helpers/macros.cr
+++ b/src/invidious/helpers/macros.cr
@@ -1,4 +1,4 @@
-macro add_mapping(mapping)
+macro db_mapping(mapping)
def initialize({{*mapping.keys.map { |id| "@#{id}".id }}})
end
@@ -18,6 +18,22 @@ macro json_mapping(mapping)
end
JSON.mapping({{mapping}})
+ YAML.mapping({{mapping}})
+end
+
+macro yaml_mapping(mapping)
+ def initialize({{*mapping.keys.map { |id| "@#{id}".id }}})
+ end
+
+ def to_a
+ return [{{*mapping.keys.map { |id| "@#{id}".id }}}]
+ end
+
+ def to_tuple
+ return { {{*mapping.keys.map { |id| "@#{id}".id }}} }
+ end
+
+ YAML.mapping({{mapping}})
end
macro templated(filename, template = "template")
diff --git a/src/invidious/mixes.cr b/src/invidious/mixes.cr
index d290ac14..65e03a06 100644
--- a/src/invidious/mixes.cr
+++ b/src/invidious/mixes.cr
@@ -1,5 +1,5 @@
struct MixVideo
- add_mapping({
+ db_mapping({
title: String,
id: String,
author: String,
@@ -11,7 +11,7 @@ struct MixVideo
end
struct Mix
- add_mapping({
+ db_mapping({
title: String,
id: String,
videos: Array(MixVideo),
diff --git a/src/invidious/playlists.cr b/src/invidious/playlists.cr
index 027bcae5..d04a5942 100644
--- a/src/invidious/playlists.cr
+++ b/src/invidious/playlists.cr
@@ -1,5 +1,5 @@
struct PlaylistVideo
- add_mapping({
+ db_mapping({
title: String,
id: String,
author: String,
@@ -13,7 +13,7 @@ struct PlaylistVideo
end
struct Playlist
- add_mapping({
+ db_mapping({
title: String,
id: String,
author: String,
diff --git a/src/invidious/search.cr b/src/invidious/search.cr
index 04eb63a2..9c985552 100644
--- a/src/invidious/search.cr
+++ b/src/invidious/search.cr
@@ -1,5 +1,5 @@
struct SearchVideo
- add_mapping({
+ db_mapping({
title: String,
id: String,
author: String,
@@ -17,7 +17,7 @@ struct SearchVideo
end
struct SearchPlaylistVideo
- add_mapping({
+ db_mapping({
title: String,
id: String,
length_seconds: Int32,
@@ -25,7 +25,7 @@ struct SearchPlaylistVideo
end
struct SearchPlaylist
- add_mapping({
+ db_mapping({
title: String,
id: String,
author: String,
@@ -37,7 +37,7 @@ struct SearchPlaylist
end
struct SearchChannel
- add_mapping({
+ db_mapping({
author: String,
ucid: String,
author_thumbnail: String,
diff --git a/src/invidious/users.cr b/src/invidious/users.cr
index 9140378e..80fc496c 100644
--- a/src/invidious/users.cr
+++ b/src/invidious/users.cr
@@ -11,7 +11,7 @@ struct User
end
end
- add_mapping({
+ db_mapping({
updated: Time,
notifications: Array(String),
subscriptions: Array(String),
@@ -26,29 +26,6 @@ struct User
})
end
-DEFAULT_USER_PREFERENCES = Preferences.new(
- video_loop: false,
- autoplay: false,
- continue: false,
- local: false,
- listen: false,
- speed: 1.0_f32,
- quality: "hd720",
- volume: 100,
- comments: ["youtube", ""],
- captions: ["", "", ""],
- related_videos: true,
- redirect_feed: false,
- locale: "en-US",
- dark_mode: false,
- thin_mode: false,
- max_results: 40,
- sort: "published",
- latest_only: false,
- unseen_only: false,
- notifications_only: false,
-)
-
struct Preferences
module StringToArray
def self.to_json(value : Array(String), json : JSON::Builder)
@@ -71,29 +48,62 @@ struct Preferences
result
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
+ unless node.is_a?(YAML::Nodes::Scalar)
+ node.raise "Expected scalar, not #{node.class}"
+ end
+
+ result << node.value
+ end
+ rescue ex
+ if node.is_a?(YAML::Nodes::Scalar)
+ result = [node.value, ""]
+ else
+ result = ["", ""]
+ end
+ end
+
+ result
+ end
end
json_mapping({
- video_loop: {type: Bool, default: DEFAULT_USER_PREFERENCES.video_loop},
- autoplay: {type: Bool, default: DEFAULT_USER_PREFERENCES.autoplay},
- continue: {type: Bool, default: DEFAULT_USER_PREFERENCES.continue},
- local: {type: Bool, default: DEFAULT_USER_PREFERENCES.local},
- listen: {type: Bool, default: DEFAULT_USER_PREFERENCES.listen},
- speed: {type: Float32, default: DEFAULT_USER_PREFERENCES.speed},
- quality: {type: String, default: DEFAULT_USER_PREFERENCES.quality},
- volume: {type: Int32, default: DEFAULT_USER_PREFERENCES.volume},
- comments: {type: Array(String), default: DEFAULT_USER_PREFERENCES.comments, converter: StringToArray},
- captions: {type: Array(String), default: DEFAULT_USER_PREFERENCES.captions, converter: StringToArray},
- redirect_feed: {type: Bool, default: DEFAULT_USER_PREFERENCES.redirect_feed},
- related_videos: {type: Bool, default: DEFAULT_USER_PREFERENCES.related_videos},
- dark_mode: {type: Bool, default: DEFAULT_USER_PREFERENCES.dark_mode},
- thin_mode: {type: Bool, default: DEFAULT_USER_PREFERENCES.thin_mode},
- max_results: {type: Int32, default: DEFAULT_USER_PREFERENCES.max_results},
- sort: {type: String, default: DEFAULT_USER_PREFERENCES.sort},
- latest_only: {type: Bool, default: DEFAULT_USER_PREFERENCES.latest_only},
- unseen_only: {type: Bool, default: DEFAULT_USER_PREFERENCES.unseen_only},
- notifications_only: {type: Bool, default: DEFAULT_USER_PREFERENCES.notifications_only},
- locale: {type: String, default: DEFAULT_USER_PREFERENCES.locale},
+ autoplay: {type: Bool, default: CONFIG.default_user_preferences.autoplay},
+ captions: {type: Array(String), default: CONFIG.default_user_preferences.captions, converter: StringToArray},
+ comments: {type: Array(String), default: CONFIG.default_user_preferences.comments, converter: StringToArray},
+ continue: {type: Bool, default: CONFIG.default_user_preferences.continue},
+ dark_mode: {type: Bool, default: CONFIG.default_user_preferences.dark_mode},
+ latest_only: {type: Bool, default: CONFIG.default_user_preferences.latest_only},
+ listen: {type: Bool, default: CONFIG.default_user_preferences.listen},
+ local: {type: Bool, default: CONFIG.default_user_preferences.local},
+ locale: {type: String, default: CONFIG.default_user_preferences.locale},
+ max_results: {type: Int32, default: CONFIG.default_user_preferences.max_results},
+ notifications_only: {type: Bool, default: CONFIG.default_user_preferences.notifications_only},
+ quality: {type: String, default: CONFIG.default_user_preferences.quality},
+ redirect_feed: {type: Bool, default: CONFIG.default_user_preferences.redirect_feed},
+ related_videos: {type: Bool, default: CONFIG.default_user_preferences.related_videos},
+ sort: {type: String, default: CONFIG.default_user_preferences.sort},
+ speed: {type: Float32, default: CONFIG.default_user_preferences.speed},
+ thin_mode: {type: Bool, default: CONFIG.default_user_preferences.thin_mode},
+ unseen_only: {type: Bool, default: CONFIG.default_user_preferences.unseen_only},
+ video_loop: {type: Bool, default: CONFIG.default_user_preferences.video_loop},
+ volume: {type: Int32, default: CONFIG.default_user_preferences.volume},
})
end
@@ -174,7 +184,7 @@ def fetch_user(sid, headers, db)
token = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
- user = User.new(Time.now, [] of String, channels, email, DEFAULT_USER_PREFERENCES, nil, token, [] of String)
+ user = User.new(Time.now, [] of String, channels, email, CONFIG.default_user_preferences, nil, token, [] of String)
return user, sid
end
@@ -182,7 +192,7 @@ def create_user(sid, email, password)
password = Crypto::Bcrypt::Password.create(password, cost: 10)
token = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
- user = User.new(Time.now, [] of String, [] of String, email, DEFAULT_USER_PREFERENCES, password.to_s, token, [] of String)
+ user = User.new(Time.now, [] of String, [] of String, email, CONFIG.default_user_preferences, password.to_s, token, [] of String)
return user, sid
end
diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr
index 0e9cf6c6..856b6447 100644
--- a/src/invidious/videos.cr
+++ b/src/invidious/videos.cr
@@ -521,7 +521,7 @@ struct Video
return self.info["length_seconds"].to_i
end
- add_mapping({
+ db_mapping({
id: String,
info: {
type: HTTP::Params,
@@ -818,16 +818,16 @@ def process_video_params(query, preferences)
volume ||= preferences.volume
end
- autoplay ||= DEFAULT_USER_PREFERENCES.autoplay.to_unsafe
- continue ||= DEFAULT_USER_PREFERENCES.continue.to_unsafe
- listen ||= DEFAULT_USER_PREFERENCES.listen.to_unsafe
- local ||= DEFAULT_USER_PREFERENCES.local.to_unsafe
- preferred_captions ||= DEFAULT_USER_PREFERENCES.captions
- quality ||= DEFAULT_USER_PREFERENCES.quality
- related_videos ||= DEFAULT_USER_PREFERENCES.related_videos.to_unsafe
- speed ||= DEFAULT_USER_PREFERENCES.speed
- video_loop ||= DEFAULT_USER_PREFERENCES.video_loop.to_unsafe
- volume ||= DEFAULT_USER_PREFERENCES.volume
+ autoplay ||= CONFIG.default_user_preferences.autoplay.to_unsafe
+ continue ||= CONFIG.default_user_preferences.continue.to_unsafe
+ listen ||= CONFIG.default_user_preferences.listen.to_unsafe
+ local ||= CONFIG.default_user_preferences.local.to_unsafe
+ preferred_captions ||= CONFIG.default_user_preferences.captions
+ quality ||= CONFIG.default_user_preferences.quality
+ related_videos ||= CONFIG.default_user_preferences.related_videos.to_unsafe
+ speed ||= CONFIG.default_user_preferences.speed
+ video_loop ||= CONFIG.default_user_preferences.video_loop.to_unsafe
+ volume ||= CONFIG.default_user_preferences.volume
autoplay = autoplay == 1
continue = continue == 1