diff --git a/src/invidious.cr b/src/invidious.cr index 33e56886..b59a09c8 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -52,7 +52,7 @@ TEST_IDS = {"AgbeGFYluEA", "BaW_jenozKc", "a9LDPn-MO4I", "ddFvjfvPnqk" CURRENT_BRANCH = {{ "#{`git branch | sed -n '/\* /s///p'`.strip}" }} CURRENT_COMMIT = {{ "#{`git rev-list HEAD --max-count=1 --abbrev-commit`.strip}" }} CURRENT_VERSION = {{ "#{`git describe --tags --abbrev=0`.strip}" }} -MAX_ITEMS_PER_PAGE = 1000 +MAX_ITEMS_PER_PAGE = 1500 # This is used to determine the `?v=` on the end of file URLs (for cache busting). We # only need to expire modified assets, so we can use this to find the last commit that changes @@ -1346,7 +1346,7 @@ post "/preferences" do |env| local ||= "off" local = local == "on" - speed = env.params.body["speed"]?.try &.as(String).to_f? + speed = env.params.body["speed"]?.try &.as(String).to_f32? speed ||= CONFIG.default_user_preferences.speed quality = env.params.body["quality"]?.try &.as(String) @@ -1402,31 +1402,31 @@ post "/preferences" do |env| notifications_only ||= "off" notifications_only = notifications_only == "on" - preferences = { - "video_loop" => video_loop, - "annotations" => annotations, - "annotations_subscribed" => annotations_subscribed, - "autoplay" => autoplay, - "continue" => continue, - "continue_autoplay" => continue_autoplay, - "listen" => listen, - "local" => local, - "speed" => speed, - "quality" => quality, - "volume" => volume, - "comments" => comments, - "captions" => captions, - "related_videos" => related_videos, - "redirect_feed" => redirect_feed, - "locale" => locale, - "dark_mode" => dark_mode, - "thin_mode" => thin_mode, - "max_results" => max_results, - "sort" => sort, - "latest_only" => latest_only, - "unseen_only" => unseen_only, - "notifications_only" => notifications_only, - }.to_json + preferences = Preferences.from_json({ + annotations: annotations, + annotations_subscribed: annotations_subscribed, + autoplay: autoplay, + captions: captions, + comments: comments, + continue: continue, + continue_autoplay: continue_autoplay, + dark_mode: dark_mode, + latest_only: latest_only, + listen: listen, + local: local, + locale: locale, + max_results: max_results, + notifications_only: notifications_only, + quality: quality, + redirect_feed: redirect_feed, + related_videos: related_videos, + sort: sort, + speed: speed, + thin_mode: thin_mode, + unseen_only: unseen_only, + video_loop: video_loop, + volume: volume, + }.to_json).to_json if user = env.get? "user" user = user.as(User) @@ -2388,9 +2388,9 @@ get "/feed/subscriptions" do |env| user, sid = get_user(sid, headers, PG_DB) end - max_results = user.preferences.max_results - max_results ||= env.params.query["max_results"]?.try &.to_i? - max_results ||= 40 + max_results = env.params.query["max_results"]?.try &.to_i?.try &.clamp(0, MAX_ITEMS_PER_PAGE) + max_results ||= user.preferences.max_results + max_results ||= CONFIG.default_user_preferences.max_results page = env.params.query["page"]?.try &.to_i? page ||= 1 @@ -2424,12 +2424,14 @@ get "/feed/history" do |env| user = user.as(User) - limit = user.preferences.max_results.clamp(0, MAX_ITEMS_PER_PAGE) - if user.watched[(page - 1) * limit]? - watched = user.watched.reverse[(page - 1) * limit, limit] - else - watched = [] of String + max_results = env.params.query["max_results"]?.try &.to_i?.try &.clamp(0, MAX_ITEMS_PER_PAGE) + max_results ||= user.preferences.max_results + max_results ||= CONFIG.default_user_preferences.max_results + + if user.watched[(page - 1) * max_results]? + watched = user.watched.reverse[(page - 1) * max_results, max_results] end + watched ||= [] of String templated "history" end @@ -2525,9 +2527,9 @@ get "/feed/private" do |env| next end - max_results = user.preferences.max_results - max_results = env.params.query["max_results"]?.try &.to_i? - max_results ||= 40 + max_results = env.params.query["max_results"]?.try &.to_i?.try &.clamp(0, MAX_ITEMS_PER_PAGE) + max_results ||= user.preferences.max_results + max_results ||= CONFIG.default_user_preferences.max_results page = env.params.query["page"]?.try &.to_i? page ||= 1 @@ -4030,9 +4032,9 @@ get "/api/v1/auth/feed" do |env| user = env.get("user").as(User) locale = LOCALES[env.get("preferences").as(Preferences).locale]? - max_results = user.preferences.max_results - max_results ||= env.params.query["max_results"]?.try &.to_i? - max_results ||= 40 + max_results = env.params.query["max_results"]?.try &.to_i? + max_results ||= user.preferences.max_results + max_results ||= CONFIG.default_user_preferences.max_results page = env.params.query["page"]?.try &.to_i? page ||= 1 diff --git a/src/invidious/users.cr b/src/invidious/users.cr index 37f3b4f1..a2143c70 100644 --- a/src/invidious/users.cr +++ b/src/invidious/users.cr @@ -41,10 +41,10 @@ struct Preferences begin result = [] of String value.read_array do - result << HTML.escape(value.read_string) + result << HTML.escape(value.read_string[0, 100]) end rescue ex - result = [HTML.escape(value.read_string), ""] + result = [HTML.escape(value.read_string[0, 100]), ""] end result @@ -70,11 +70,11 @@ struct Preferences node.raise "Expected scalar, not #{item.class}" end - result << HTML.escape(item.value) + result << HTML.escape(item.value[0, 100]) end rescue ex if node.is_a?(YAML::Nodes::Scalar) - result = [HTML.escape(node.value), ""] + result = [HTML.escape(node.value[0, 100]), ""] else result = ["", ""] end @@ -84,13 +84,13 @@ struct Preferences end end - module EscapeString + module ProcessString def self.to_json(value : String, json : JSON::Builder) json.string value end def self.from_json(value : JSON::PullParser) : String - HTML.escape(value.read_string) + HTML.escape(value.read_string[0, 100]) end def self.to_yaml(value : String, yaml : YAML::Nodes::Builder) @@ -98,7 +98,25 @@ struct Preferences end def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : String - HTML.escape(node.value) + HTML.escape(node.value[0, 100]) + end + end + + module ClampInt + def self.to_json(value : Int32, json : JSON::Builder) + json.number value + end + + def self.from_json(value : JSON::PullParser) : Int32 + value.read_int.clamp(0, MAX_ITEMS_PER_PAGE).to_i32 + 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 @@ -114,13 +132,13 @@ struct Preferences 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, converter: EscapeString}, - max_results: {type: Int32, default: CONFIG.default_user_preferences.max_results}, + locale: {type: String, default: CONFIG.default_user_preferences.locale, converter: ProcessString}, + max_results: {type: Int32, default: CONFIG.default_user_preferences.max_results, converter: ClampInt}, notifications_only: {type: Bool, default: CONFIG.default_user_preferences.notifications_only}, - quality: {type: String, default: CONFIG.default_user_preferences.quality, converter: EscapeString}, + quality: {type: String, default: CONFIG.default_user_preferences.quality, converter: ProcessString}, 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, converter: EscapeString}, + sort: {type: String, default: CONFIG.default_user_preferences.sort, converter: ProcessString}, 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}, diff --git a/src/invidious/views/channel.ecr b/src/invidious/views/channel.ecr index 9d55f3c3..089b42e3 100644 --- a/src/invidious/views/channel.ecr +++ b/src/invidious/views/channel.ecr @@ -67,7 +67,7 @@