diff --git a/config/sql/compilations.sql b/config/sql/compilations.sql index 95d2d0af2..5802c9a87 100644 --- a/config/sql/compilations.sql +++ b/config/sql/compilations.sql @@ -22,7 +22,8 @@ CREATE TABLE IF NOT EXISTS public.compilations created timestamptz, updated timestamptz, privacy compilation_privacy, - index int8[] + index int8[], + first_video_id text ); GRANT ALL ON public.compilations TO current_user; diff --git a/locales/en-US.json b/locales/en-US.json index 73fbd177a..f34089aa1 100644 --- a/locales/en-US.json +++ b/locales/en-US.json @@ -244,6 +244,7 @@ "Not a playlist.": "Not a playlist.", "Playlist does not exist.": "Playlist does not exist.", "Could not pull trending pages.": "Could not pull trending pages.", + "Compilation does not exist.": "Compilation does not exist.", "Hidden field \"challenge\" is a required field": "Hidden field \"challenge\" is a required field", "Hidden field \"token\" is a required field": "Hidden field \"token\" is a required field", "Erroneous challenge": "Erroneous challenge", diff --git a/src/invidious/compilations.cr b/src/invidious/compilations.cr index bf532ac97..5710e6b29 100644 --- a/src/invidious/compilations.cr +++ b/src/invidious/compilations.cr @@ -95,6 +95,7 @@ struct Compilation property views : Int64 property updated : Time property thumbnail : String? + property first_video_id : String def to_json(offset, json : JSON::Builder, video_id : String? = nil) json.object do @@ -169,6 +170,7 @@ struct InvidiousCompilation @[DB::Field(converter: InvidiousCompilation::CompilationPrivacyConverter)] property privacy : CompilationPrivacy = CompilationPrivacy::Private property index : Array(Int64) + property first_video_id : String @[DB::Field(ignore: true)] property thumbnail_id : String? @@ -248,15 +250,16 @@ def create_compilation(title, privacy, user) LOGGER.info("generated compilation id") compilation = InvidiousCompilation.new({ - title: title.byte_slice(0, 150), - id: compid, - author: user.email, - description: "", # Max 5000 characters - video_count: 0, - created: Time.utc, - updated: Time.utc, - privacy: privacy, - index: [] of Int64, + title: title.byte_slice(0, 150), + id: compid, + author: user.email, + description: "", # Max 5000 characters + video_count: 0, + created: Time.utc, + updated: Time.utc, + privacy: privacy, + index: [] of Int64, + first_video_id: "" }) LOGGER.info("Creating compilation db") @@ -268,15 +271,16 @@ end def subscribe_compilation(user, compilation) compilation = InvidiousCompilation.new({ - title: compilation.title.byte_slice(0, 150), - id: compilation.id, - author: user.email, - description: "", # Max 5000 characters - video_count: compilation.video_count, - created: Time.utc, - updated: compilation.updated, - privacy: CompilationPrivacy::Private, - index: [] of Int64, + title: compilation.title.byte_slice(0, 150), + id: compilation.id, + author: user.email, + description: "", # Max 5000 characters + video_count: compilation.video_count, + created: Time.utc, + updated: compilation.updated, + privacy: CompilationPrivacy::Private, + index: [] of Int64, + first_video_id: "" }) Invidious::Database::Compilations.insert(compilation) @@ -329,6 +333,19 @@ def get_compilation(compid : String) #end end +def update_first_video_id(compid : String) + if compilation = Invidious::Database::Compilations.select(id: compid) + compilation_index_array = compilation.index + first_index = compilation_index_array[0] + first_id = Invidious::Database::CompilationVideos.select_id_from_index(first_index) + if !first_id.nil? + Invidious::Database::Compilations.update_first_video_id(compid, first_id) + end + else + raise NotFoundException.new("Compilation does not exist.") + end +end + def get_compilation_videos(compilation : InvidiousCompilation | Compilation, offset : Int32, video_id = nil) LOGGER.info("1. get_compilation") LOGGER.info("Getting compilation") diff --git a/src/invidious/database/compilations.cr b/src/invidious/database/compilations.cr index 29c6987f5..daf597b0b 100644 --- a/src/invidious/database/compilations.cr +++ b/src/invidious/database/compilations.cr @@ -90,6 +90,15 @@ module Invidious::Database::Compilations PG_DB.exec(request, id, index) end + def update_first_video_id(id : String, first_video_id : String) + request = <<-SQL + UPDATE compilations + SET first_video_id = $2 + WHERE id = $1 + SQL + + PG_DB.exec(request, id, first_video_id) + end # ------------------- # Select # ------------------- @@ -112,6 +121,16 @@ module Invidious::Database::Compilations return PG_DB.query_all(request, author, as: InvidiousCompilation) end + def select_index_array(id : String) + request = <<-SQL + SELECT index FROM compilations + WHERE id = $1 + LIMIT 1 + SQL + + PG_DB.query_one?(request, id, as: String) + end + # ------------------- # Select (filtered) # ------------------- @@ -249,6 +268,16 @@ module Invidious::Database::CompilationVideos return PG_DB.query_one?(request, order_index, as: String) end + def select_id_from_index(index : Int64) + request = <<-SQL + SELECT id FROM compilation_videos + WHERE index = $1 + LIMIT 1 + SQL + + return PG_DB.query_one?(request, index, as: String) + end + def select_index_from_order_index(order_index : Int32) request = <<-SQL SELECT index FROM compilation_videos diff --git a/src/invidious/database/migrations/0011_create_compilations_table.cr b/src/invidious/database/migrations/0011_create_compilations_table.cr index 304041834..4bf5a8145 100644 --- a/src/invidious/database/migrations/0011_create_compilations_table.cr +++ b/src/invidious/database/migrations/0011_create_compilations_table.cr @@ -24,7 +24,8 @@ module Invidious::Database::Migrations created timestamptz, updated timestamptz, privacy compilation_privacy, - index int8[] + index int8[], + first_video_id text ); SQL diff --git a/src/invidious/routes/compilations.cr b/src/invidious/routes/compilations.cr index 7add2bf66..c592eb70f 100644 --- a/src/invidious/routes/compilations.cr +++ b/src/invidious/routes/compilations.cr @@ -129,7 +129,7 @@ module Invidious::Routes::Compilations sid = sid.as(String) compid = env.params.query["list"]? - if !compid || !compid.starts_with?("IV") + if !compid || !compid.starts_with?("IVCMP") return env.redirect referer end @@ -238,50 +238,30 @@ module Invidious::Routes::Compilations title = env.params.body["title"]?.try &.delete("<>") || "" privacy = CompilationPrivacy.parse(env.params.body["privacy"]? || "Private") - #title = env.params.json["title"].try &.as(String).delete("<>").byte_slice(0, 150) || compilation.title - #privacy = env.params.json["privacy"]?.try { |p| CompilationPrivacy.parse(p.as(String).downcase) } || compilation.privacy - - #if title != compilation.title || - # privacy != compilation.privacy - # updated = Time.utc - #else - # updated = compilation.updated - #end - Invidious::Database::Compilations.update(compid, title, privacy, "", compilation.updated) - #{1...Invidious::Database::Compilations.count_owned_by(user.email)}.each do |index| - # start_timestamp = env.params.json["_start_timestamp"]?.try &.as(String).byte_slice(0, 150) || compilation.title - compilation_video_cardinality = Invidious::Database::CompilationVideos.select_ids(compid, compilation.index).size + (0..compilation.index.size - 1).each do |index| + compilation_video_index = compilation.index[index] + compilation_video = Invidious::Database::CompilationVideos.select_video(compid, compilation.index, compilation_video_index, 0, 1) + json_timestamp_query_start = compilation_video_index.to_s + "_start_timestamp" - (0..compilation_video_cardinality-1).each do |index| - LOGGER.info("for loop cycle #{index} of #{Invidious::Database::Compilations.count_owned_by(user.email)}") - compilation_video_id = Invidious::Database::CompilationVideos.select_id_from_order_index(order_index: index) - #compilation_video_index = Invidious::Database::CompilationVideos.select_index_from_order_index(order_index: index) - compilation_video = Invidious::Database::CompilationVideos.select(compid, compilation.index, 0, 1) - #numerical_string = index.to - json_timestamp_query = index.to_s + "_start_timestamp" - LOGGER.info("adjust #{json_timestamp_query} ") - start_timestamp = env.params.body[json_timestamp_query]?.try &.as(String).byte_slice(0, 8) - LOGGER.info("render #{env.params.body[json_timestamp_query]?} ") - if !start_timestamp.nil? && !compilation_video_id.nil? - LOGGER.info("adjust #{json_timestamp_query} which renders as #{start_timestamp}") + start_timestamp = env.params.body[json_timestamp_query_start]?.try &.as(String).byte_slice(0, 8) + if !start_timestamp.nil? && !compilation_video[0].id.nil? start_timestamp_seconds = decode_length_seconds(start_timestamp) if !start_timestamp_seconds.nil? if start_timestamp_seconds >= 0 && start_timestamp_seconds <= compilation_video[0].length_seconds - LOGGER.info("adjusting timestamps to #{start_timestamp_seconds} which is #{start_timestamp_seconds.to_i}") - Invidious::Database::CompilationVideos.update_start_timestamp(compilation_video_id, start_timestamp_seconds.to_i) + Invidious::Database::CompilationVideos.update_start_timestamp(compilation_video[0].id, start_timestamp_seconds.to_i) end end end - json_timestamp_query = index.to_s + "_end_timestamp" - end_timestamp = env.params.json[json_timestamp_query]?.try &.as(String).byte_slice(0, 8) - if !end_timestamp.nil? && !compilation_video_id.nil? + json_timestamp_query_end = compilation_video_index.to_s + "_end_timestamp" + end_timestamp = env.params.json[json_timestamp_query_end]?.try &.as(String).byte_slice(0, 8) + if !end_timestamp.nil? && !compilation_video[0].id.nil? end_timestamp_seconds = decode_length_seconds(end_timestamp) if !end_timestamp_seconds.nil? - if end_timestamp_seconds >= 0 && end_timestamp_seconds <= compilation_video[0].ending_timestamp_seconds - Invidious::Database::CompilationVideos.update_end_timestamp(compilation_video_id, end_timestamp_seconds) + if end_timestamp_seconds >= 0 && end_timestamp_seconds <= compilation_video[0].ending_timestamp_seconds && end_timestamp_seconds > compilation_video[0].starting_timestamp_seconds + Invidious::Database::CompilationVideos.update_end_timestamp(compilation_video[0].id, end_timestamp_seconds) end end end @@ -309,7 +289,7 @@ module Invidious::Routes::Compilations sid = sid.as(String) compid = env.params.query["list"]? - if !compid || !compid.starts_with?("IV") + if !compid || !compid.starts_with?("IVCMP") return env.redirect referer end @@ -445,10 +425,12 @@ module Invidious::Routes::Compilations Invidious::Database::CompilationVideos.insert(compilation_video) Invidious::Database::Compilations.update_video_added(compilation_id, compilation_video.index) + update_first_video_id(compilation_id) when "action_remove_video" index = env.params.query["set_video_id"] Invidious::Database::CompilationVideos.delete(index) Invidious::Database::Compilations.update_video_removed(compilation_id, index) + update_first_video_id(compilation_id) when "action_move_video_before" # TODO: Compilation stub #video_index = compilation.index @@ -473,6 +455,7 @@ module Invidious::Routes::Compilations compilation_index_array.insert(compilation_index_array_position-1,compilation_video[0].index) Invidious::Database::Compilations.move_video_before(compilation_id, compilation_index_array) end + update_first_video_id(compilation_id) else return error_json(400, "Unsupported action #{action}") end diff --git a/src/invidious/routes/watch.cr b/src/invidious/routes/watch.cr index e63bfc8c0..bd0f46e1c 100644 --- a/src/invidious/routes/watch.cr +++ b/src/invidious/routes/watch.cr @@ -39,8 +39,13 @@ module Invidious::Routes::Watch embed_link += embed_params.to_s end - plid = env.params.query["list"]?.try &.gsub(/[^a-zA-Z0-9_-]/, "") - continuation = process_continuation(env.params.query, plid, id) + if env.params.query["list"]?.try &.starts_with? "IVPL" + plid = env.params.query["list"]?.try &.gsub(/[^a-zA-Z0-9_-]/, "") + continuation = process_continuation(env.params.query, plid, id) + elsif env.params.query["list"]?.try &.starts_with? "IVCMP" + compid = env.params.query["list"]?.try &.gsub(/[^a-zA-Z0-9_-]/, "") + continuation = process_continuation(env.params.query, compid, id) + end nojs = env.params.query["nojs"]? diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index f38b33e5b..d13e90dc1 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -410,9 +410,9 @@ def fetch_video(id, region) return video end -def process_continuation(query, plid, id) +def process_continuation(query, list_id, id) continuation = nil - if plid + if list_id if index = query["index"]?.try &.to_i? continuation = index else diff --git a/src/invidious/views/compilation.ecr b/src/invidious/views/compilation.ecr index 2520dc0c5..b86fac39d 100644 --- a/src/invidious/views/compilation.ecr +++ b/src/invidious/views/compilation.ecr @@ -11,11 +11,13 @@