From 437f42250e381ab7652e07b4a413bb5d152356e1 Mon Sep 17 00:00:00 2001 From: Wes van der Vleuten <16665772+WesVleuten@users.noreply.github.com> Date: Mon, 7 Nov 2022 03:49:00 +0100 Subject: [PATCH 001/114] Watched marker --- src/invidious/views/components/item.ecr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index 0e959ff2..e53fa075 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -99,7 +99,7 @@ <% else %> <% if !env.get("preferences").as(Preferences).thin_mode %> -
+
"> <% if env.get? "show_watched" %>
" method="post"> From 7b573817734dfd48fc6d1fbdc9a0a99f379f0ed1 Mon Sep 17 00:00:00 2001 From: Wes van der Vleuten <16665772+WesVleuten@users.noreply.github.com> Date: Mon, 7 Nov 2022 19:03:23 +0000 Subject: [PATCH 002/114] Added watch indicator --- assets/css/default.css | 13 ++++++++++ assets/js/watched_widget.js | 27 +++++++++++++++++++++ docker-compose.yml | 4 +-- src/invidious/views/components/item.ecr | 7 +++++- src/invidious/views/feeds/subscriptions.ecr | 3 ++- 5 files changed, 50 insertions(+), 4 deletions(-) diff --git a/assets/css/default.css b/assets/css/default.css index ab2b79e6..30a562e2 100644 --- a/assets/css/default.css +++ b/assets/css/default.css @@ -135,6 +135,9 @@ div.thumbnail { position: relative; box-sizing: border-box; } +div.thumbnail.thumbnail-watched { + background-color: rgba(255,255,255,.4); +} img.thumbnail { position: absolute; @@ -143,6 +146,16 @@ img.thumbnail { left: 0; top: 0; object-fit: cover; + z-index: -1; +} + +div.watched-indicator { + position: absolute; + left: 0; + bottom: 0; + height: 4px; + width: 100%; + background: red; } .length { diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js index f1ac9cb4..10b33c1a 100644 --- a/assets/js/watched_widget.js +++ b/assets/js/watched_widget.js @@ -32,3 +32,30 @@ function mark_unwatched(target) { } }); } + + +var save_player_pos_key = 'save_player_pos'; + +function get_all_video_times() { + return helpers.storage.get(save_player_pos_key) || {}; +} + +var watchedIndicators = document.getElementsByClassName('watched-indicator'); +for (var i = 0; i < watchedIndicators.length; i++) { + var indicator = watchedIndicators[i]; + + var watched_part = get_all_video_times()[indicator.getAttribute('data-id')]; + var total = parseInt(indicator.getAttribute('data-length'), 10); + + var percentage = Math.round((watched_part / total) * 100); + + + if (percentage < 5) { + percentage = 5; + } + if (percentage > 90) { + percentage = 100; + } + + indicator.style.width = percentage + '%'; +} diff --git a/docker-compose.yml b/docker-compose.yml index eb83b020..48ee6a4b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,7 +13,7 @@ services: dockerfile: docker/Dockerfile restart: unless-stopped ports: - - "127.0.0.1:3000:3000" + - "3003:3000" environment: # Please read the following file for a comprehensive list of all available # configuration options and their associated syntax: @@ -23,7 +23,7 @@ services: dbname: invidious user: kemal password: kemal - host: invidious-db + host: invidious-invidious-db-1 port: 5432 check_tables: true # external_port: diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index e53fa075..d63dca14 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -99,7 +99,8 @@ <% else %> <% if !env.get("preferences").as(Preferences).thin_mode %> -
"> + <% item_watched = env.get("user") && env.get("user").as(User).watched && env.get("user").as(User).watched.index(item.id) != nil %> +
"> <% if env.get? "show_watched" %> " method="post"> @@ -124,6 +125,10 @@ <% elsif item.length_seconds != 0 %>

<%= recode_length_seconds(item.length_seconds) %>

<% end %> + + <% if item_watched %> +
+ <% end %>
<% end %>

<%= HTML.escape(item.title) %>

diff --git a/src/invidious/views/feeds/subscriptions.ecr b/src/invidious/views/feeds/subscriptions.ecr index 8d56ad14..add1eefc 100644 --- a/src/invidious/views/feeds/subscriptions.ecr +++ b/src/invidious/views/feeds/subscriptions.ecr @@ -50,7 +50,6 @@ }.to_pretty_json %> -
<% videos.each do |item| %> @@ -58,6 +57,8 @@ <% end %>
+ +
<% if page > 1 %> From f604c1c68bbba81310ca2fd0a7283482840e0a26 Mon Sep 17 00:00:00 2001 From: Wes van der Vleuten <16665772+WesVleuten@users.noreply.github.com> Date: Tue, 8 Nov 2022 23:15:42 +0100 Subject: [PATCH 003/114] Fixed thumbnails with darkreader, Added watched indicator in more locations --- assets/css/default.css | 16 +++++++++++----- assets/js/watched_widget.js | 4 +--- src/invidious/views/components/item.ecr | 16 ++++++++++++++-- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/assets/css/default.css b/assets/css/default.css index 30a562e2..890bd524 100644 --- a/assets/css/default.css +++ b/assets/css/default.css @@ -135,9 +135,7 @@ div.thumbnail { position: relative; box-sizing: border-box; } -div.thumbnail.thumbnail-watched { - background-color: rgba(255,255,255,.4); -} + img.thumbnail { position: absolute; @@ -146,7 +144,15 @@ img.thumbnail { left: 0; top: 0; object-fit: cover; - z-index: -1; +} + +div.watched-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(255,255,255,.4); } div.watched-indicator { @@ -155,7 +161,7 @@ div.watched-indicator { bottom: 0; height: 4px; width: 100%; - background: red; + background-color: red; } .length { diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js index 10b33c1a..ffcdaad8 100644 --- a/assets/js/watched_widget.js +++ b/assets/js/watched_widget.js @@ -41,15 +41,13 @@ function get_all_video_times() { } var watchedIndicators = document.getElementsByClassName('watched-indicator'); +console.log('indicators', watchedIndicators.length); for (var i = 0; i < watchedIndicators.length; i++) { var indicator = watchedIndicators[i]; - var watched_part = get_all_video_times()[indicator.getAttribute('data-id')]; var total = parseInt(indicator.getAttribute('data-length'), 10); - var percentage = Math.round((watched_part / total) * 100); - if (percentage < 5) { percentage = 5; } diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index d63dca14..47d077cf 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -1,3 +1,5 @@ +<% item_watched = !item.is_a?(SearchChannel) && !item.is_a?(SearchPlaylist) && !item.is_a?(InvidiousPlaylist) && !item.is_a?(Category) && env.get("user") && env.get("user").as(User).watched && env.get("user").as(User).watched.index(item.id) != nil %> +
<% case item when %> @@ -40,6 +42,11 @@ <% if item.length_seconds != 0 %>

<%= recode_length_seconds(item.length_seconds) %>

<% end %> + + <% if item_watched %> +
+
+ <% end %>
<% end %>

<%= HTML.escape(item.title) %>

@@ -67,6 +74,11 @@ <% elsif item.length_seconds != 0 %>

<%= recode_length_seconds(item.length_seconds) %>

<% end %> + + <% if item_watched %> +
+
+ <% end %>
<% end %>

<%= HTML.escape(item.title) %>

@@ -99,8 +111,7 @@ <% else %>
<% if !env.get("preferences").as(Preferences).thin_mode %> - <% item_watched = env.get("user") && env.get("user").as(User).watched && env.get("user").as(User).watched.index(item.id) != nil %> -
"> +
<% if env.get? "show_watched" %> " method="post"> @@ -127,6 +138,7 @@ <% end %> <% if item_watched %> +
<% end %>
From c95ee10d6915bd1bb42e8e81f85848f1ad7b6240 Mon Sep 17 00:00:00 2001 From: Wes van der Vleuten <16665772+WesVleuten@users.noreply.github.com> Date: Tue, 8 Nov 2022 23:18:24 +0100 Subject: [PATCH 004/114] Added parital watch indicator on more locations --- src/invidious/views/add_playlist_items.ecr | 2 ++ src/invidious/views/channel.ecr | 2 ++ src/invidious/views/edit_playlist.ecr | 2 ++ src/invidious/views/feeds/playlists.ecr | 2 ++ src/invidious/views/feeds/popular.ecr | 2 ++ src/invidious/views/feeds/trending.ecr | 2 ++ src/invidious/views/hashtag.ecr | 2 ++ src/invidious/views/playlist.ecr | 2 ++ src/invidious/views/playlists.ecr | 2 ++ src/invidious/views/search.ecr | 2 ++ 10 files changed, 20 insertions(+) diff --git a/src/invidious/views/add_playlist_items.ecr b/src/invidious/views/add_playlist_items.ecr index 22870317..70575de3 100644 --- a/src/invidious/views/add_playlist_items.ecr +++ b/src/invidious/views/add_playlist_items.ecr @@ -39,6 +39,8 @@ <% end %>
+ + <% if query %> <%- query_encoded = URI.encode_www_form(query.text, space_to_plus: true) -%>
diff --git a/src/invidious/views/channel.ecr b/src/invidious/views/channel.ecr index dea86abe..1295423e 100644 --- a/src/invidious/views/channel.ecr +++ b/src/invidious/views/channel.ecr @@ -110,6 +110,8 @@ <% end %>
+ +
<% if page > 1 %> diff --git a/src/invidious/views/edit_playlist.ecr b/src/invidious/views/edit_playlist.ecr index 89819ef0..100764c7 100644 --- a/src/invidious/views/edit_playlist.ecr +++ b/src/invidious/views/edit_playlist.ecr @@ -62,6 +62,8 @@ <% end %>
+ +
<% if page > 1 %> diff --git a/src/invidious/views/feeds/playlists.ecr b/src/invidious/views/feeds/playlists.ecr index a59344c4..f9064762 100644 --- a/src/invidious/views/feeds/playlists.ecr +++ b/src/invidious/views/feeds/playlists.ecr @@ -32,3 +32,5 @@ <%= rendered "components/item" %> <% end %>
+ + diff --git a/src/invidious/views/feeds/popular.ecr b/src/invidious/views/feeds/popular.ecr index e77f35b9..919002cd 100644 --- a/src/invidious/views/feeds/popular.ecr +++ b/src/invidious/views/feeds/popular.ecr @@ -16,3 +16,5 @@ <%= rendered "components/item" %> <% end %>
+ + diff --git a/src/invidious/views/feeds/trending.ecr b/src/invidious/views/feeds/trending.ecr index a35c4ee3..76218165 100644 --- a/src/invidious/views/feeds/trending.ecr +++ b/src/invidious/views/feeds/trending.ecr @@ -45,3 +45,5 @@ <%= rendered "components/item" %> <% end %>
+ + diff --git a/src/invidious/views/hashtag.ecr b/src/invidious/views/hashtag.ecr index 0ecfe832..6064af74 100644 --- a/src/invidious/views/hashtag.ecr +++ b/src/invidious/views/hashtag.ecr @@ -24,6 +24,8 @@ <%- end -%>
+ +
<%- if page > 1 -%> diff --git a/src/invidious/views/playlist.ecr b/src/invidious/views/playlist.ecr index df3112db..1df047ba 100644 --- a/src/invidious/views/playlist.ecr +++ b/src/invidious/views/playlist.ecr @@ -106,6 +106,8 @@ <% end %>
+ +
<% if page > 1 %> diff --git a/src/invidious/views/playlists.ecr b/src/invidious/views/playlists.ecr index c8718e7b..6ce8b033 100644 --- a/src/invidious/views/playlists.ecr +++ b/src/invidious/views/playlists.ecr @@ -96,6 +96,8 @@ <% end %>
+ +
diff --git a/src/invidious/views/search.ecr b/src/invidious/views/search.ecr index 254449a1..c4960d08 100644 --- a/src/invidious/views/search.ecr +++ b/src/invidious/views/search.ecr @@ -37,6 +37,8 @@
<%- end -%> + +
<%- if query.page > 1 -%> From 5bcb5f3175247234c63e71ab3b35b7c3574a8fba Mon Sep 17 00:00:00 2001 From: Wes van der Vleuten <16665772+WesVleuten@users.noreply.github.com> Date: Tue, 8 Nov 2022 23:19:27 +0100 Subject: [PATCH 005/114] Removed console.log --- assets/js/watched_widget.js | 1 - 1 file changed, 1 deletion(-) diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js index ffcdaad8..fb4275a3 100644 --- a/assets/js/watched_widget.js +++ b/assets/js/watched_widget.js @@ -41,7 +41,6 @@ function get_all_video_times() { } var watchedIndicators = document.getElementsByClassName('watched-indicator'); -console.log('indicators', watchedIndicators.length); for (var i = 0; i < watchedIndicators.length; i++) { var indicator = watchedIndicators[i]; var watched_part = get_all_video_times()[indicator.getAttribute('data-id')]; From c03f92baf7d2a46c3a9ec91c75da3f6d3d24ca57 Mon Sep 17 00:00:00 2001 From: Wes van der Vleuten <16665772+WesVleuten@users.noreply.github.com> Date: Tue, 8 Nov 2022 23:22:44 +0100 Subject: [PATCH 006/114] Fixed watch indicator when position is not saved --- assets/js/watched_widget.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js index fb4275a3..3cf7c332 100644 --- a/assets/js/watched_widget.js +++ b/assets/js/watched_widget.js @@ -45,6 +45,9 @@ for (var i = 0; i < watchedIndicators.length; i++) { var indicator = watchedIndicators[i]; var watched_part = get_all_video_times()[indicator.getAttribute('data-id')]; var total = parseInt(indicator.getAttribute('data-length'), 10); + if (watched_part === undefined) { + watched_part = total; + } var percentage = Math.round((watched_part / total) * 100); if (percentage < 5) { From d3d9cfdd0d1d0739b88e34fbb39653131d475665 Mon Sep 17 00:00:00 2001 From: Wes van der Vleuten <16665772+WesVleuten@users.noreply.github.com> Date: Wed, 9 Nov 2022 00:32:38 +0100 Subject: [PATCH 007/114] Cleanup --- assets/css/default.css | 1 - assets/js/watched_widget.js | 1 - docker-compose.yml | 4 ++-- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/assets/css/default.css b/assets/css/default.css index 890bd524..9edf3efa 100644 --- a/assets/css/default.css +++ b/assets/css/default.css @@ -136,7 +136,6 @@ div.thumbnail { box-sizing: border-box; } - img.thumbnail { position: absolute; width: 100%; diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js index 3cf7c332..d1b55d28 100644 --- a/assets/js/watched_widget.js +++ b/assets/js/watched_widget.js @@ -33,7 +33,6 @@ function mark_unwatched(target) { }); } - var save_player_pos_key = 'save_player_pos'; function get_all_video_times() { diff --git a/docker-compose.yml b/docker-compose.yml index 48ee6a4b..eb83b020 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,7 +13,7 @@ services: dockerfile: docker/Dockerfile restart: unless-stopped ports: - - "3003:3000" + - "127.0.0.1:3000:3000" environment: # Please read the following file for a comprehensive list of all available # configuration options and their associated syntax: @@ -23,7 +23,7 @@ services: dbname: invidious user: kemal password: kemal - host: invidious-invidious-db-1 + host: invidious-db port: 5432 check_tables: true # external_port: From 8df1c3bb57154dda021add8d11da9e7f4ae88bf1 Mon Sep 17 00:00:00 2001 From: DUOLabs333 Date: Tue, 3 Jan 2023 10:17:47 -0500 Subject: [PATCH 008/114] Add support for timedtext captions --- src/invidious/routes/api/v1/videos.cr | 92 +++++++++++++++------------ src/invidious/videos/caption.cr | 56 +++++++++++++++- 2 files changed, 106 insertions(+), 42 deletions(-) diff --git a/src/invidious/routes/api/v1/videos.cr b/src/invidious/routes/api/v1/videos.cr index a6b2eb4e..918fb421 100644 --- a/src/invidious/routes/api/v1/videos.cr +++ b/src/invidious/routes/api/v1/videos.cr @@ -90,47 +90,52 @@ module Invidious::Routes::API::V1::Videos # as well as some other markup that makes it cumbersome, so we try to fix that here if caption.name.includes? "auto-generated" caption_xml = YT_POOL.client &.get(url).body - caption_xml = XML.parse(caption_xml) - webvtt = String.build do |str| - str << <<-END_VTT - WEBVTT - Kind: captions - Language: #{tlang || caption.language_code} - - - END_VTT - - caption_nodes = caption_xml.xpath_nodes("//transcript/text") - caption_nodes.each_with_index do |node, i| - start_time = node["start"].to_f.seconds - duration = node["dur"]?.try &.to_f.seconds - duration ||= start_time - - if caption_nodes.size > i + 1 - end_time = caption_nodes[i + 1]["start"].to_f.seconds - else - end_time = start_time + duration - end - - start_time = "#{start_time.hours.to_s.rjust(2, '0')}:#{start_time.minutes.to_s.rjust(2, '0')}:#{start_time.seconds.to_s.rjust(2, '0')}.#{start_time.milliseconds.to_s.rjust(3, '0')}" - end_time = "#{end_time.hours.to_s.rjust(2, '0')}:#{end_time.minutes.to_s.rjust(2, '0')}:#{end_time.seconds.to_s.rjust(2, '0')}.#{end_time.milliseconds.to_s.rjust(3, '0')}" - - text = HTML.unescape(node.content) - text = text.gsub(//, "") - text = text.gsub(/<\/font>/, "") - if md = text.match(/(?.*) : (?.*)/) - text = "#{md["text"]}" - end - - str << <<-END_CUE - #{start_time} --> #{end_time} - #{text} - - - END_CUE - end - end + if caption_xml.starts_with?(" i + 1 + end_time = caption_nodes[i + 1]["start"].to_f.seconds + else + end_time = start_time + duration + end + + start_time = "#{start_time.hours.to_s.rjust(2, '0')}:#{start_time.minutes.to_s.rjust(2, '0')}:#{start_time.seconds.to_s.rjust(2, '0')}.#{start_time.milliseconds.to_s.rjust(3, '0')}" + end_time = "#{end_time.hours.to_s.rjust(2, '0')}:#{end_time.minutes.to_s.rjust(2, '0')}:#{end_time.seconds.to_s.rjust(2, '0')}.#{end_time.milliseconds.to_s.rjust(3, '0')}" + + text = HTML.unescape(node.content) + text = text.gsub(//, "") + text = text.gsub(/<\/font>/, "") + if md = text.match(/(?.*) : (?.*)/) + text = "#{md["text"]}" + end + + str << <<-END_CUE + #{start_time} --> #{end_time} + #{text} + + + END_CUE + end + end + end else # Some captions have "align:[start/end]" and "position:[num]%" # attributes. Those are causing issues with VideoJS, which is unable @@ -138,7 +143,12 @@ module Invidious::Routes::API::V1::Videos # # See: https://github.com/iv-org/invidious/issues/2391 webvtt = YT_POOL.client &.get("#{url}&format=vtt").body - .gsub(/([0-9:.]{12} --> [0-9:.]{12}).+/, "\\1") + if webvtt.starts_with?(" [0-9:.]{12}).+/, "\\1") + end end if title = env.params.query["title"]? diff --git a/src/invidious/videos/caption.cr b/src/invidious/videos/caption.cr index 4642c1a7..941b9646 100644 --- a/src/invidious/videos/caption.cr +++ b/src/invidious/videos/caption.cr @@ -30,7 +30,60 @@ module Invidious::Videos return captions_list end - + + def timedtext_to_vtt(timedtext : String, tlang = nil) : String + #In the future, we could just directly work with the url. This is more of a POC + cues = [] of XML::Node + tree = XML.parse(timedtext) + tree = tree.children.first() + + tree.children.each do |item| + if item.name == "body" + item.children.each do |cue| + if cue.name == "p" + cues << cue + end + end + break + end + end + result = String.build do |result| + result << <<-END_VTT + WEBVTT + Kind: captions + Language: #{tlang || @language_code} + + + END_VTT + cues.each_with_index do |node,i| + start_time = node["t"].to_f.milliseconds + + duration = node["d"]?.try &.to_f.milliseconds + + duration ||= start_time + + if cues.size > i + 1 + end_time = cues[i + 1]["t"].to_f.milliseconds + else + end_time = start_time + duration + end + + start_time = "#{start_time.hours.to_s.rjust(2, '0')}:#{start_time.minutes.to_s.rjust(2, '0')}:#{start_time.seconds.to_s.rjust(2, '0')}.#{start_time.milliseconds.to_s.rjust(3, '0')}" + + end_time = "#{end_time.hours.to_s.rjust(2, '0')}:#{end_time.minutes.to_s.rjust(2, '0')}:#{end_time.seconds.to_s.rjust(2, '0')}.#{end_time.milliseconds.to_s.rjust(3, '0')}" + text = String.build do |text| + node.children.each do |s| + text << s.content + end + end + result << start_time + " --> " + end_time + "\n" + result << text + "\n" + result << "\n" + end + end + return result + end + # List of all caption languages available on Youtube. LANGUAGES = { "", @@ -164,5 +217,6 @@ module Invidious::Videos "Yoruba", "Zulu", } + end end From b49ed65a07d1e80eb5430b40dac47e7a2477cd39 Mon Sep 17 00:00:00 2001 From: DUOLabs333 Date: Tue, 3 Jan 2023 10:21:16 -0500 Subject: [PATCH 009/114] Linting --- src/invidious/videos/caption.cr | 97 ++++++++++++++++----------------- 1 file changed, 48 insertions(+), 49 deletions(-) diff --git a/src/invidious/videos/caption.cr b/src/invidious/videos/caption.cr index 941b9646..4049c5d0 100644 --- a/src/invidious/videos/caption.cr +++ b/src/invidious/videos/caption.cr @@ -30,60 +30,60 @@ module Invidious::Videos return captions_list end - - def timedtext_to_vtt(timedtext : String, tlang = nil) : String - #In the future, we could just directly work with the url. This is more of a POC - cues = [] of XML::Node - tree = XML.parse(timedtext) - tree = tree.children.first() - - tree.children.each do |item| - if item.name == "body" - item.children.each do |cue| - if cue.name == "p" - cues << cue - end - end - break - end - end - result = String.build do |result| - result << <<-END_VTT + + def timedtext_to_vtt(timedtext : String, tlang = nil) : String + # In the future, we could just directly work with the url. This is more of a POC + cues = [] of XML::Node + tree = XML.parse(timedtext) + tree = tree.children.first + + tree.children.each do |item| + if item.name == "body" + item.children.each do |cue| + if cue.name == "p" + cues << cue + end + end + break + end + end + result = String.build do |result| + result << <<-END_VTT WEBVTT Kind: captions Language: #{tlang || @language_code} END_VTT - cues.each_with_index do |node,i| - start_time = node["t"].to_f.milliseconds - - duration = node["d"]?.try &.to_f.milliseconds - - duration ||= start_time - - if cues.size > i + 1 - end_time = cues[i + 1]["t"].to_f.milliseconds - else - end_time = start_time + duration - end - - start_time = "#{start_time.hours.to_s.rjust(2, '0')}:#{start_time.minutes.to_s.rjust(2, '0')}:#{start_time.seconds.to_s.rjust(2, '0')}.#{start_time.milliseconds.to_s.rjust(3, '0')}" - - end_time = "#{end_time.hours.to_s.rjust(2, '0')}:#{end_time.minutes.to_s.rjust(2, '0')}:#{end_time.seconds.to_s.rjust(2, '0')}.#{end_time.milliseconds.to_s.rjust(3, '0')}" - text = String.build do |text| - node.children.each do |s| - text << s.content - end - end - result << start_time + " --> " + end_time + "\n" - result << text + "\n" - result << "\n" - end - end - return result - end - + cues.each_with_index do |node, i| + start_time = node["t"].to_f.milliseconds + + duration = node["d"]?.try &.to_f.milliseconds + + duration ||= start_time + + if cues.size > i + 1 + end_time = cues[i + 1]["t"].to_f.milliseconds + else + end_time = start_time + duration + end + + start_time = "#{start_time.hours.to_s.rjust(2, '0')}:#{start_time.minutes.to_s.rjust(2, '0')}:#{start_time.seconds.to_s.rjust(2, '0')}.#{start_time.milliseconds.to_s.rjust(3, '0')}" + + end_time = "#{end_time.hours.to_s.rjust(2, '0')}:#{end_time.minutes.to_s.rjust(2, '0')}:#{end_time.seconds.to_s.rjust(2, '0')}.#{end_time.milliseconds.to_s.rjust(3, '0')}" + text = String.build do |text| + node.children.each do |s| + text << s.content + end + end + result << start_time + " --> " + end_time + "\n" + result << text + "\n" + result << "\n" + end + end + return result + end + # List of all caption languages available on Youtube. LANGUAGES = { "", @@ -217,6 +217,5 @@ module Invidious::Videos "Yoruba", "Zulu", } - end end From 45b8f6d0cd89541d93a479ec20f43ee5c029abf8 Mon Sep 17 00:00:00 2001 From: DUOLabs333 Date: Tue, 3 Jan 2023 10:25:05 -0500 Subject: [PATCH 010/114] More linting --- src/invidious/routes/api/v1/videos.cr | 74 +++++++++++++-------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/invidious/routes/api/v1/videos.cr b/src/invidious/routes/api/v1/videos.cr index 918fb421..eb371241 100644 --- a/src/invidious/routes/api/v1/videos.cr +++ b/src/invidious/routes/api/v1/videos.cr @@ -92,50 +92,50 @@ module Invidious::Routes::API::V1::Videos caption_xml = YT_POOL.client &.get(url).body if caption_xml.starts_with?(" i + 1 - end_time = caption_nodes[i + 1]["start"].to_f.seconds - else - end_time = start_time + duration - end - - start_time = "#{start_time.hours.to_s.rjust(2, '0')}:#{start_time.minutes.to_s.rjust(2, '0')}:#{start_time.seconds.to_s.rjust(2, '0')}.#{start_time.milliseconds.to_s.rjust(3, '0')}" - end_time = "#{end_time.hours.to_s.rjust(2, '0')}:#{end_time.minutes.to_s.rjust(2, '0')}:#{end_time.seconds.to_s.rjust(2, '0')}.#{end_time.milliseconds.to_s.rjust(3, '0')}" - - text = HTML.unescape(node.content) - text = text.gsub(//, "") - text = text.gsub(/<\/font>/, "") - if md = text.match(/(?.*) : (?.*)/) - text = "#{md["text"]}" - end - - str << <<-END_CUE + + caption_nodes = caption_xml.xpath_nodes("//transcript/text") + caption_nodes.each_with_index do |node, i| + start_time = node["start"].to_f.seconds + duration = node["dur"]?.try &.to_f.seconds + duration ||= start_time + + if caption_nodes.size > i + 1 + end_time = caption_nodes[i + 1]["start"].to_f.seconds + else + end_time = start_time + duration + end + + start_time = "#{start_time.hours.to_s.rjust(2, '0')}:#{start_time.minutes.to_s.rjust(2, '0')}:#{start_time.seconds.to_s.rjust(2, '0')}.#{start_time.milliseconds.to_s.rjust(3, '0')}" + end_time = "#{end_time.hours.to_s.rjust(2, '0')}:#{end_time.minutes.to_s.rjust(2, '0')}:#{end_time.seconds.to_s.rjust(2, '0')}.#{end_time.milliseconds.to_s.rjust(3, '0')}" + + text = HTML.unescape(node.content) + text = text.gsub(//, "") + text = text.gsub(/<\/font>/, "") + if md = text.match(/(?.*) : (?.*)/) + text = "#{md["text"]}" + end + + str << <<-END_CUE #{start_time} --> #{end_time} #{text} END_CUE - end - end - end + end + end + end else # Some captions have "align:[start/end]" and "position:[num]%" # attributes. Those are causing issues with VideoJS, which is unable @@ -144,11 +144,11 @@ module Invidious::Routes::API::V1::Videos # See: https://github.com/iv-org/invidious/issues/2391 webvtt = YT_POOL.client &.get("#{url}&format=vtt").body if webvtt.starts_with?(" [0-9:.]{12}).+/, "\\1") - end + webvtt = YT_POOL.client &.get("#{url}&format=vtt").body + .gsub(/([0-9:.]{12} --> [0-9:.]{12}).+/, "\\1") + end end if title = env.params.query["title"]? @@ -371,4 +371,4 @@ module Invidious::Routes::API::V1::Videos end end end -end +end \ No newline at end of file From 9d83e2da4e5c1dffc994dc8acd3f2a74280ffcc4 Mon Sep 17 00:00:00 2001 From: DUOLabs333 Date: Tue, 3 Jan 2023 10:29:17 -0500 Subject: [PATCH 011/114] Add newline --- src/invidious/routes/api/v1/videos.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/routes/api/v1/videos.cr b/src/invidious/routes/api/v1/videos.cr index eb371241..51344508 100644 --- a/src/invidious/routes/api/v1/videos.cr +++ b/src/invidious/routes/api/v1/videos.cr @@ -371,4 +371,4 @@ module Invidious::Routes::API::V1::Videos end end end -end \ No newline at end of file +end From 76758baab83b303e43a41a11bad37058c696905a Mon Sep 17 00:00:00 2001 From: DUOLabs333 Date: Tue, 3 Jan 2023 13:10:26 -0500 Subject: [PATCH 012/114] Removed unneccesary String::Builder and removed cues that was just a blank line --- src/invidious/videos/caption.cr | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/invidious/videos/caption.cr b/src/invidious/videos/caption.cr index 4049c5d0..83a4c82f 100644 --- a/src/invidious/videos/caption.cr +++ b/src/invidious/videos/caption.cr @@ -41,7 +41,9 @@ module Invidious::Videos if item.name == "body" item.children.each do |cue| if cue.name == "p" - cues << cue + if !(cue.children.size == 1 && cue.children[0].content == "\n") + cues << cue + end end end break @@ -71,13 +73,13 @@ module Invidious::Videos start_time = "#{start_time.hours.to_s.rjust(2, '0')}:#{start_time.minutes.to_s.rjust(2, '0')}:#{start_time.seconds.to_s.rjust(2, '0')}.#{start_time.milliseconds.to_s.rjust(3, '0')}" end_time = "#{end_time.hours.to_s.rjust(2, '0')}:#{end_time.minutes.to_s.rjust(2, '0')}:#{end_time.seconds.to_s.rjust(2, '0')}.#{end_time.milliseconds.to_s.rjust(3, '0')}" - text = String.build do |text| - node.children.each do |s| - text << s.content - end - end + result << start_time + " --> " + end_time + "\n" - result << text + "\n" + + node.children.each do |s| + result << s.content + end + result << "\n" result << "\n" end end From 85dd3533bb4f9bc8e007d3b5de158f56db1445ce Mon Sep 17 00:00:00 2001 From: DUOLabs333 Date: Tue, 3 Jan 2023 20:18:10 -0500 Subject: [PATCH 013/114] Fix for the ArithmeticOverflow Problem --- src/invidious/helpers/utils.cr | 2 +- src/invidious/yt_backend/extractors.cr | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/invidious/helpers/utils.cr b/src/invidious/helpers/utils.cr index ed0cca38..59d8953a 100644 --- a/src/invidious/helpers/utils.cr +++ b/src/invidious/helpers/utils.cr @@ -162,7 +162,7 @@ def number_with_separator(number) end def short_text_to_number(short_text : String) : Int64 - matches = /(?\d+(\.\d+)?)\s?(?[mMkKbB])?/.match(short_text) + matches = /(?\d+(\.\d+)?)\s?(?[mMkKbB]|())?/.match(short_text) number = matches.try &.["number"].to_f || 0.0 case matches.try &.["suffix"].downcase diff --git a/src/invidious/yt_backend/extractors.cr b/src/invidious/yt_backend/extractors.cr index edc722cf..326d2d62 100644 --- a/src/invidious/yt_backend/extractors.cr +++ b/src/invidious/yt_backend/extractors.cr @@ -169,7 +169,12 @@ private module Parsers # When public subscriber count is disabled, the subscriberCountText isn't sent by InnerTube. # Always simpleText # TODO change default value to nil + subscriber_count = item_contents.dig?("subscriberCountText", "simpleText") + if !subscriber_count || !subscriber_count.as_s.includes? " subscriber" + subscriber_count = item_contents.dig?("videoCountText", "simpleText") + end + subscriber_count = subscriber_count .try { |s| short_text_to_number(s.as_s.split(" ")[0]).to_i32 } || 0 # Auto-generated channels doesn't have videoCountText From 0d3610f63d726ac038861d3aede8d7339c552d74 Mon Sep 17 00:00:00 2001 From: DUOLabs333 Date: Wed, 4 Jan 2023 18:12:15 -0500 Subject: [PATCH 014/114] Change regex used in short_text_to_number --- src/invidious/helpers/utils.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/helpers/utils.cr b/src/invidious/helpers/utils.cr index 59d8953a..72fdb187 100644 --- a/src/invidious/helpers/utils.cr +++ b/src/invidious/helpers/utils.cr @@ -162,7 +162,7 @@ def number_with_separator(number) end def short_text_to_number(short_text : String) : Int64 - matches = /(?\d+(\.\d+)?)\s?(?[mMkKbB]|())?/.match(short_text) + matches = /(?\d+(\.\d+)?)\s?(?[mMkKbB]?)/.match(short_text) number = matches.try &.["number"].to_f || 0.0 case matches.try &.["suffix"].downcase From 8d08cfe30f550431015a7ecc8845b9c2968e27be Mon Sep 17 00:00:00 2001 From: DUO Labs Date: Thu, 5 Jan 2023 20:42:11 -0500 Subject: [PATCH 015/114] Add comments to src/invidious/yt_backend/extractors.cr Co-authored-by: Samantaz Fox --- src/invidious/yt_backend/extractors.cr | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/invidious/yt_backend/extractors.cr b/src/invidious/yt_backend/extractors.cr index 326d2d62..cd52c73b 100644 --- a/src/invidious/yt_backend/extractors.cr +++ b/src/invidious/yt_backend/extractors.cr @@ -171,6 +171,11 @@ private module Parsers # TODO change default value to nil subscriber_count = item_contents.dig?("subscriberCountText", "simpleText") + + # Since youtube added channel handles, `VideoCountText` holds the number of + # subscribers and `subscriberCountText` holds the handle, except when the + # channel doesn't have a handle (e.g: some topic music channels). + # See https://github.com/iv-org/invidious/issues/3394#issuecomment-1321261688 if !subscriber_count || !subscriber_count.as_s.includes? " subscriber" subscriber_count = item_contents.dig?("videoCountText", "simpleText") end From 32471382c48289bafd0234d5e339fdfefb328da0 Mon Sep 17 00:00:00 2001 From: DUOLabs333 Date: Sun, 8 Jan 2023 16:18:35 -0500 Subject: [PATCH 016/114] Different cosmetic fixes --- src/invidious/routes/api/v1/videos.cr | 6 ++--- src/invidious/videos/caption.cr | 34 ++++++++++++++++++--------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/invidious/routes/api/v1/videos.cr b/src/invidious/routes/api/v1/videos.cr index 51344508..54602112 100644 --- a/src/invidious/routes/api/v1/videos.cr +++ b/src/invidious/routes/api/v1/videos.cr @@ -128,11 +128,11 @@ module Invidious::Routes::API::V1::Videos end str << <<-END_CUE - #{start_time} --> #{end_time} - #{text} + #{start_time} --> #{end_time} + #{text} - END_CUE + END_CUE end end end diff --git a/src/invidious/videos/caption.cr b/src/invidious/videos/caption.cr index 83a4c82f..377f30d6 100644 --- a/src/invidious/videos/caption.cr +++ b/src/invidious/videos/caption.cr @@ -40,8 +40,7 @@ module Invidious::Videos tree.children.each do |item| if item.name == "body" item.children.each do |cue| - if cue.name == "p" - if !(cue.children.size == 1 && cue.children[0].content == "\n") + if cue.name == "p" && !(cue.children.size == 1 && cue.children[0].content == "\n") cues << cue end end @@ -51,12 +50,15 @@ module Invidious::Videos end result = String.build do |result| result << <<-END_VTT - WEBVTT - Kind: captions - Language: #{tlang || @language_code} - - - END_VTT + WEBVTT + Kind: captions + Language: #{tlang || @language_code} + + + END_VTT + + result << "\n\n" + cues.each_with_index do |node, i| start_time = node["t"].to_f.milliseconds @@ -70,11 +72,21 @@ module Invidious::Videos end_time = start_time + duration end - start_time = "#{start_time.hours.to_s.rjust(2, '0')}:#{start_time.minutes.to_s.rjust(2, '0')}:#{start_time.seconds.to_s.rjust(2, '0')}.#{start_time.milliseconds.to_s.rjust(3, '0')}" + # start_time + result << start_time.hours.to_s.rjust(2, '0') + result << ':' << start_time.minutes.to_s.rjust(2, '0') + result << ':' << start_time.seconds.to_s.rjust(2, '0') + result << '.' << start_time.milliseconds.to_s.rjust(3, '0') - end_time = "#{end_time.hours.to_s.rjust(2, '0')}:#{end_time.minutes.to_s.rjust(2, '0')}:#{end_time.seconds.to_s.rjust(2, '0')}.#{end_time.milliseconds.to_s.rjust(3, '0')}" + result << " --> " - result << start_time + " --> " + end_time + "\n" + # end_time + result << end_time.hours.to_s.rjust(2, '0') + result << ':' << end_time.minutes.to_s.rjust(2, '0') + result << ':' << end_time.seconds.to_s.rjust(2, '0') + result << '.' << end_time.milliseconds.to_s.rjust(3, '0') + + result << "\n" node.children.each do |s| result << s.content From 4fc1b8ae86ab3d32955e72c957514799e5e121dc Mon Sep 17 00:00:00 2001 From: DUOLabs333 Date: Sun, 8 Jan 2023 16:20:23 -0500 Subject: [PATCH 017/114] Remove superfluous 'end' --- src/invidious/videos/caption.cr | 1 - 1 file changed, 1 deletion(-) diff --git a/src/invidious/videos/caption.cr b/src/invidious/videos/caption.cr index 377f30d6..95b9d643 100644 --- a/src/invidious/videos/caption.cr +++ b/src/invidious/videos/caption.cr @@ -42,7 +42,6 @@ module Invidious::Videos item.children.each do |cue| if cue.name == "p" && !(cue.children.size == 1 && cue.children[0].content == "\n") cues << cue - end end end break From 456e91426aeeafe889e2ea8887cfc3aa3f92fcd3 Mon Sep 17 00:00:00 2001 From: DUOLabs333 Date: Sun, 8 Jan 2023 16:44:44 -0500 Subject: [PATCH 018/114] Formatting --- src/invidious/videos/caption.cr | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/invidious/videos/caption.cr b/src/invidious/videos/caption.cr index 95b9d643..03bc3fd0 100644 --- a/src/invidious/videos/caption.cr +++ b/src/invidious/videos/caption.cr @@ -41,7 +41,7 @@ module Invidious::Videos if item.name == "body" item.children.each do |cue| if cue.name == "p" && !(cue.children.size == 1 && cue.children[0].content == "\n") - cues << cue + cues << cue end end break @@ -56,8 +56,8 @@ module Invidious::Videos END_VTT - result << "\n\n" - + result << "\n\n" + cues.each_with_index do |node, i| start_time = node["t"].to_f.milliseconds From 4b2d9420247ab83b2690a331c727e0227b5b7a19 Mon Sep 17 00:00:00 2001 From: DUOLabs333 Date: Wed, 11 Jan 2023 15:58:07 -0500 Subject: [PATCH 019/114] Convert tabs to spaces --- src/invidious/routes/api/v1/videos.cr | 22 +++++++++++----------- src/invidious/videos/caption.cr | 8 ++++---- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/invidious/routes/api/v1/videos.cr b/src/invidious/routes/api/v1/videos.cr index 54602112..b10a30ea 100644 --- a/src/invidious/routes/api/v1/videos.cr +++ b/src/invidious/routes/api/v1/videos.cr @@ -98,12 +98,12 @@ module Invidious::Routes::API::V1::Videos webvtt = String.build do |str| str << <<-END_VTT - WEBVTT - Kind: captions - Language: #{tlang || caption.language_code} - - - END_VTT + WEBVTT + Kind: captions + Language: #{tlang || caption.language_code} + + + END_VTT caption_nodes = caption_xml.xpath_nodes("//transcript/text") caption_nodes.each_with_index do |node, i| @@ -128,11 +128,11 @@ module Invidious::Routes::API::V1::Videos end str << <<-END_CUE - #{start_time} --> #{end_time} - #{text} - - - END_CUE + #{start_time} --> #{end_time} + #{text} + + + END_CUE end end end diff --git a/src/invidious/videos/caption.cr b/src/invidious/videos/caption.cr index 03bc3fd0..13f81a31 100644 --- a/src/invidious/videos/caption.cr +++ b/src/invidious/videos/caption.cr @@ -49,12 +49,12 @@ module Invidious::Videos end result = String.build do |result| result << <<-END_VTT - WEBVTT - Kind: captions - Language: #{tlang || @language_code} + WEBVTT + Kind: captions + Language: #{tlang || @language_code} - END_VTT + END_VTT result << "\n\n" From 01acb9bfbfda00c4fdcb8de87c33174d694de530 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Fri, 13 Jan 2023 19:04:37 -0500 Subject: [PATCH 020/114] Login redirect to referer on logged-in user --- src/invidious/helpers/utils.cr | 2 +- src/invidious/routes/login.cr | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/invidious/helpers/utils.cr b/src/invidious/helpers/utils.cr index ed0cca38..4448508c 100644 --- a/src/invidious/helpers/utils.cr +++ b/src/invidious/helpers/utils.cr @@ -259,7 +259,7 @@ def get_referer(env, fallback = "/", unroll = true) end referer = referer.request_target - referer = "/" + referer.gsub(/[^\/?@&%=\-_.0-9a-zA-Z]/, "").lstrip("/\\") + referer = "/" + referer.gsub(/[^\/?@&%=\-_.:,0-9a-zA-Z]/, "").lstrip("/\\") if referer == env.request.path referer = fallback diff --git a/src/invidious/routes/login.cr b/src/invidious/routes/login.cr index 99fc13a2..6454131a 100644 --- a/src/invidious/routes/login.cr +++ b/src/invidious/routes/login.cr @@ -6,14 +6,14 @@ module Invidious::Routes::Login user = env.get? "user" - return env.redirect "/feed/subscriptions" if user + referer = get_referer(env, "/feed/subscriptions") + + return env.redirect referer if user if !CONFIG.login_enabled return error_template(400, "Login has been disabled by administrator.") end - referer = get_referer(env, "/feed/subscriptions") - email = nil password = nil captcha = nil From 1b5fbfc13efa9eace904d24dc89b7fdf72c1ce52 Mon Sep 17 00:00:00 2001 From: techmetx11 Date: Sat, 14 Jan 2023 09:38:55 +0100 Subject: [PATCH 021/114] Video: Add support for the music section --- locales/en-US.json | 3 +++ src/invidious/videos.cr | 3 +++ src/invidious/videos/parser.cr | 22 ++++++++++++++++++++++ src/invidious/views/watch.ecr | 9 +++++++++ 4 files changed, 37 insertions(+) diff --git a/locales/en-US.json b/locales/en-US.json index 12955665..bc6a3275 100644 --- a/locales/en-US.json +++ b/locales/en-US.json @@ -188,6 +188,9 @@ "Engagement: ": "Engagement: ", "Whitelisted regions: ": "Whitelisted regions: ", "Blacklisted regions: ": "Blacklisted regions: ", + "Music artist: ": "Music artist: ", + "Music album: ": "Music album: ", + "Music licenses: ": "Music licenses: ", "Shared `x`": "Shared `x`", "Premieres in `x`": "Premieres in `x`", "Premieres `x`": "Premieres `x`", diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index d626c7d1..be4854fe 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -314,6 +314,9 @@ struct Video getset_string genre getset_string genreUcid getset_string license + getset_string music_artist + getset_string music_album + getset_string music_licenses getset_string shortDescription getset_string subCountText getset_string title diff --git a/src/invidious/videos/parser.cr b/src/invidious/videos/parser.cr index 5df49286..4540dd13 100644 --- a/src/invidious/videos/parser.cr +++ b/src/invidious/videos/parser.cr @@ -309,6 +309,24 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any end end + # Music section + + music_desc = player_response.dig?("engagementPanels", 1, "engagementPanelSectionListRenderer", "content", "structuredDescriptionContentRenderer", "items", 2, "videoDescriptionMusicSectionRenderer", "carouselLockups", 0, "carouselLockupRenderer", "infoRows").try &.as_a + artist = nil + album = nil + music_licenses = nil + + music_desc.try &.each do |desc| + desc_title = extract_text(desc.dig?("infoRowRenderer", "title")) + if desc_title == "ARTIST" + artist = extract_text(desc.dig?("infoRowRenderer", "defaultMetadata")) + elsif desc_title == "ALBUM" + album = extract_text(desc.dig?("infoRowRenderer", "defaultMetadata")) + elsif desc_title == "LICENSES" + music_licenses = extract_text(desc.dig?("infoRowRenderer", "expandedMetadata")) + end + end + # Author infos author = video_details["author"]?.try &.as_s @@ -359,6 +377,10 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any "genre" => JSON::Any.new(genre.try &.as_s || ""), "genreUcid" => JSON::Any.new(genre_ucid.try &.as_s || ""), "license" => JSON::Any.new(license.try &.as_s || ""), + # Music section + "music_artist" => JSON::Any.new(artist || ""), + "music_album" => JSON::Any.new(album || ""), + "music_licenses" => JSON::Any.new(music_licenses || ""), # Author infos "author" => JSON::Any.new(author || ""), "ucid" => JSON::Any.new(ucid || ""), diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index a6f2e524..beab1bb2 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -196,6 +196,15 @@ we're going to need to do it here in order to allow for translations. <% end %>

<% end %> + <% if !video.music_artist.empty? %> +

<%= translate(locale, "Music artist: ") %><%= video.music_artist %>

+ <% end %> + <% if !video.music_album.empty? %> +

<%= translate(locale, "Music album: ") %><%= video.music_album %>

+ <% end %> + <% if !video.music_licenses.empty? %> +

<%= translate(locale, "Music licenses: ") %><%= video.music_licenses %>

+ <% end %>
From fe5b81f2c3caf37e10fd3284a49146e7aefb1530 Mon Sep 17 00:00:00 2001 From: techmetx11 Date: Mon, 16 Jan 2023 13:58:05 +0100 Subject: [PATCH 022/114] Add support for multiple songs --- assets/css/default.css | 35 ++++++++++++++++++++-------- locales/en-US.json | 5 ++-- src/invidious/videos.cr | 12 +++++++--- src/invidious/videos/music.cr | 12 ++++++++++ src/invidious/videos/parser.cr | 33 ++++++++++++++------------ src/invidious/views/watch.ecr | 42 +++++++++++++++++++++++++--------- 6 files changed, 97 insertions(+), 42 deletions(-) create mode 100644 src/invidious/videos/music.cr diff --git a/assets/css/default.css b/assets/css/default.css index 80bf6a20..4ec6f720 100644 --- a/assets/css/default.css +++ b/assets/css/default.css @@ -490,26 +490,31 @@ hr { } /* Description Expansion Styling*/ -#descexpansionbutton { +#descexpansionbutton, +#musicdescexpansionbutton { display: none } -#descexpansionbutton ~ div { +#descexpansionbutton ~ div, +#musicdescexpansionbutton ~ div { overflow: hidden; height: 8.3em; } -#descexpansionbutton:checked ~ div { +#descexpansionbutton:checked ~ div, +#musicdescexpansionbutton:checked ~ div { overflow: unset; height: 100%; } -#descexpansionbutton ~ label { +#descexpansionbutton ~ label, +#musicdescexpansionbutton ~ label { order: 1; margin-top: 20px; } -label[for="descexpansionbutton"]:hover { +label[for="descexpansionbutton"]:hover, +label[for="musicdescexpansionbutton"]:hover { cursor: pointer; } @@ -521,14 +526,24 @@ h4, h5, p, #descriptionWrapper, -#description-box { - unicode-bidi: plaintext; - text-align: start; +#description-box, +#music-description-box, +#musicDescriptionWrapper { + unicode-bidi: plaintext; + text-align: start; } #descriptionWrapper { - max-width: 600px; - white-space: pre-wrap; + max-width: 600px; + white-space: pre-wrap; +} + +#musicDescriptionWrapper { + max-width: 600px; +} + +#music-description-title { + margin-bottom: 0px; } /* Center the "invidious" logo on the search page */ diff --git a/locales/en-US.json b/locales/en-US.json index bc6a3275..20f1a46d 100644 --- a/locales/en-US.json +++ b/locales/en-US.json @@ -188,9 +188,8 @@ "Engagement: ": "Engagement: ", "Whitelisted regions: ": "Whitelisted regions: ", "Blacklisted regions: ": "Blacklisted regions: ", - "Music artist: ": "Music artist: ", - "Music album: ": "Music album: ", - "Music licenses: ": "Music licenses: ", + "Artist: ": "Artist: ", + "Album: ": "Album: ", "Shared `x`": "Shared `x`", "Premieres in `x`": "Premieres in `x`", "Premieres `x`": "Premieres `x`", diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index be4854fe..aa3ef1a8 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -247,6 +247,15 @@ struct Video info["reason"]?.try &.as_s end + def music : Array(VideoMusic) + music_list = Array(VideoMusic).new + + info["music"].as_a.each do |music_json| + music_list << VideoMusic.new(music_json["album"].as_s, music_json["artist"].as_s, music_json["license"].as_s) + end + return music_list + end + # Macros defining getters/setters for various types of data private macro getset_string(name) @@ -314,9 +323,6 @@ struct Video getset_string genre getset_string genreUcid getset_string license - getset_string music_artist - getset_string music_album - getset_string music_licenses getset_string shortDescription getset_string subCountText getset_string title diff --git a/src/invidious/videos/music.cr b/src/invidious/videos/music.cr new file mode 100644 index 00000000..402ae46f --- /dev/null +++ b/src/invidious/videos/music.cr @@ -0,0 +1,12 @@ +require "json" + +struct VideoMusic + include JSON::Serializable + + property album : String + property artist : String + property license : String + + def initialize(@album : String, @artist : String, @license : String) + end +end diff --git a/src/invidious/videos/parser.cr b/src/invidious/videos/parser.cr index 4540dd13..69b04cb6 100644 --- a/src/invidious/videos/parser.cr +++ b/src/invidious/videos/parser.cr @@ -311,20 +311,25 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any # Music section - music_desc = player_response.dig?("engagementPanels", 1, "engagementPanelSectionListRenderer", "content", "structuredDescriptionContentRenderer", "items", 2, "videoDescriptionMusicSectionRenderer", "carouselLockups", 0, "carouselLockupRenderer", "infoRows").try &.as_a - artist = nil - album = nil - music_licenses = nil + music_list = [] of VideoMusic + music_desclist = player_response.dig?("engagementPanels", 1, "engagementPanelSectionListRenderer", "content", "structuredDescriptionContentRenderer", "items", 2, "videoDescriptionMusicSectionRenderer", "carouselLockups").try &.as_a + music_desclist.try &.each do |music_desc| + artist = nil + album = nil + music_license = nil - music_desc.try &.each do |desc| - desc_title = extract_text(desc.dig?("infoRowRenderer", "title")) - if desc_title == "ARTIST" - artist = extract_text(desc.dig?("infoRowRenderer", "defaultMetadata")) - elsif desc_title == "ALBUM" - album = extract_text(desc.dig?("infoRowRenderer", "defaultMetadata")) - elsif desc_title == "LICENSES" - music_licenses = extract_text(desc.dig?("infoRowRenderer", "expandedMetadata")) + music_desc.dig?("carouselLockupRenderer", "infoRows").try &.as_a.try &.each do |desc| + desc_title = extract_text(desc.dig?("infoRowRenderer", "title")) + if desc_title == "ARTIST" + artist = extract_text(desc.dig?("infoRowRenderer", "defaultMetadata")) + elsif desc_title == "ALBUM" + album = extract_text(desc.dig?("infoRowRenderer", "defaultMetadata")) + elsif desc_title == "LICENSES" + music_license = extract_text(desc.dig?("infoRowRenderer", "expandedMetadata")) + end end + music = VideoMusic.new(album.to_s, artist.to_s, music_license.to_s) + music_list << music end # Author infos @@ -378,9 +383,7 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any "genreUcid" => JSON::Any.new(genre_ucid.try &.as_s || ""), "license" => JSON::Any.new(license.try &.as_s || ""), # Music section - "music_artist" => JSON::Any.new(artist || ""), - "music_album" => JSON::Any.new(album || ""), - "music_licenses" => JSON::Any.new(music_licenses || ""), + "music" => JSON.parse(music_list.to_json), # Author infos "author" => JSON::Any.new(author || ""), "ucid" => JSON::Any.new(ucid || ""), diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index beab1bb2..207dae18 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -34,11 +34,13 @@ we're going to need to do it here in order to allow for translations. --> @@ -196,15 +198,6 @@ we're going to need to do it here in order to allow for translations. <% end %>

<% end %> - <% if !video.music_artist.empty? %> -

<%= translate(locale, "Music artist: ") %><%= video.music_artist %>

- <% end %> - <% if !video.music_album.empty? %> -

<%= translate(locale, "Music album: ") %><%= video.music_album %>

- <% end %> - <% if !video.music_licenses.empty? %> -

<%= translate(locale, "Music licenses: ") %><%= video.music_licenses %>

- <% end %>
@@ -244,6 +237,33 @@ we're going to need to do it here in order to allow for translations.
+ <% if !video.music.empty? %> +

<%= translate(locale, "Music") %>

+
+
+ + <% end %>
<% if nojs %> <%= comment_html %> From 8dcc98b3b9d8e189a4c92ab0cbed7e3635341b5d Mon Sep 17 00:00:00 2001 From: DUOLabs333 Date: Mon, 16 Jan 2023 18:37:52 -0500 Subject: [PATCH 023/114] If videCountText lists the number of subscribers, then don't use it in get_video_count --- src/invidious/yt_backend/extractors.cr | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/invidious/yt_backend/extractors.cr b/src/invidious/yt_backend/extractors.cr index cd52c73b..d32f5646 100644 --- a/src/invidious/yt_backend/extractors.cr +++ b/src/invidious/yt_backend/extractors.cr @@ -652,8 +652,13 @@ module HelperExtractors # # Returns a 0 when it's unable to do so def self.get_video_count(container : JSON::Any) : Int32 + puts container if box = container["videoCountText"]? - return extract_text(box).try &.gsub(/\D/, "").to_i || 0 + if (extracted_text = extract_text(box)) && !extracted_text.includes? " subscriber" + return extracted_text.gsub(/\D/, "").to_i + else + return 0 + end elsif box = container["videoCount"]? return box.as_s.to_i else From 86333cd4344267f09ca34a179558dc71fb8b6fb4 Mon Sep 17 00:00:00 2001 From: DUOLabs333 Date: Mon, 16 Jan 2023 18:43:58 -0500 Subject: [PATCH 024/114] Formatting --- src/invidious/yt_backend/extractors.cr | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/invidious/yt_backend/extractors.cr b/src/invidious/yt_backend/extractors.cr index d32f5646..fbb02824 100644 --- a/src/invidious/yt_backend/extractors.cr +++ b/src/invidious/yt_backend/extractors.cr @@ -652,13 +652,13 @@ module HelperExtractors # # Returns a 0 when it's unable to do so def self.get_video_count(container : JSON::Any) : Int32 - puts container + puts container if box = container["videoCountText"]? - if (extracted_text = extract_text(box)) && !extracted_text.includes? " subscriber" - return extracted_text.gsub(/\D/, "").to_i - else - return 0 - end + if (extracted_text = extract_text(box)) && !extracted_text.includes? " subscriber" + return extracted_text.gsub(/\D/, "").to_i + else + return 0 + end elsif box = container["videoCount"]? return box.as_s.to_i else From 67ace4fd9dd1a62ab004b05dc0403cc71ef5e206 Mon Sep 17 00:00:00 2001 From: DUO Labs Date: Mon, 16 Jan 2023 18:50:38 -0500 Subject: [PATCH 025/114] Some indention changes Co-authored-by: Samantaz Fox --- src/invidious/routes/api/v1/videos.cr | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/invidious/routes/api/v1/videos.cr b/src/invidious/routes/api/v1/videos.cr index b10a30ea..4ef877e5 100644 --- a/src/invidious/routes/api/v1/videos.cr +++ b/src/invidious/routes/api/v1/videos.cr @@ -98,12 +98,12 @@ module Invidious::Routes::API::V1::Videos webvtt = String.build do |str| str << <<-END_VTT - WEBVTT - Kind: captions - Language: #{tlang || caption.language_code} - - - END_VTT + WEBVTT + Kind: captions + Language: #{tlang || caption.language_code} + + + END_VTT caption_nodes = caption_xml.xpath_nodes("//transcript/text") caption_nodes.each_with_index do |node, i| @@ -128,11 +128,11 @@ module Invidious::Routes::API::V1::Videos end str << <<-END_CUE - #{start_time} --> #{end_time} - #{text} - - - END_CUE + #{start_time} --> #{end_time} + #{text} + + + END_CUE end end end From ff66cec9209f464ffc269a7d189199a22b5486c0 Mon Sep 17 00:00:00 2001 From: DUOLabs333 Date: Mon, 16 Jan 2023 18:52:17 -0500 Subject: [PATCH 026/114] Remove debug print --- src/invidious/yt_backend/extractors.cr | 1 - 1 file changed, 1 deletion(-) diff --git a/src/invidious/yt_backend/extractors.cr b/src/invidious/yt_backend/extractors.cr index fbb02824..1f7726fb 100644 --- a/src/invidious/yt_backend/extractors.cr +++ b/src/invidious/yt_backend/extractors.cr @@ -652,7 +652,6 @@ module HelperExtractors # # Returns a 0 when it's unable to do so def self.get_video_count(container : JSON::Any) : Int32 - puts container if box = container["videoCountText"]? if (extracted_text = extract_text(box)) && !extracted_text.includes? " subscriber" return extracted_text.gsub(/\D/, "").to_i From f6a4d04070203111c294520301ef6e439e110ade Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Wed, 18 Jan 2023 15:58:59 -0500 Subject: [PATCH 027/114] Redirect auth token to login --- src/invidious/routes/account.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/routes/account.cr b/src/invidious/routes/account.cr index 9bb73136..e6a70ed2 100644 --- a/src/invidious/routes/account.cr +++ b/src/invidious/routes/account.cr @@ -203,7 +203,7 @@ module Invidious::Routes::Account referer = get_referer(env) if !user - return env.redirect referer + return env.redirect "/login?referer=#{URI.encode_path_segment(env.request.resource)}" end user = user.as(User) From cf93c94fc43bdb19160555747409b0a59b0c5f6b Mon Sep 17 00:00:00 2001 From: Samantaz Fox Date: Sat, 21 Jan 2023 15:23:15 +0100 Subject: [PATCH 028/114] Formatting fix for Crystal nightly Changes added by https://github.com/crystal-lang/crystal/pull/12951 --- src/invidious/helpers/json_filter.cr | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/invidious/helpers/json_filter.cr b/src/invidious/helpers/json_filter.cr index b8e8f96d..3f4080ba 100644 --- a/src/invidious/helpers/json_filter.cr +++ b/src/invidious/helpers/json_filter.cr @@ -20,7 +20,7 @@ module JSONFilter /^\(|\(\(|\/\(/ end - def self.parse_fields(fields_text : String) : Nil + def self.parse_fields(fields_text : String, &) : Nil if fields_text.empty? raise FieldsParser::ParseError.new "Fields is empty" end @@ -42,7 +42,7 @@ module JSONFilter parse_nest_groups(fields_text) { |nest_list| yield nest_list } end - def self.parse_single_nests(fields_text : String) : Nil + def self.parse_single_nests(fields_text : String, &) : Nil single_nests = remove_nest_groups(fields_text) if !single_nests.empty? @@ -60,7 +60,7 @@ module JSONFilter end end - def self.parse_nest_groups(fields_text : String) : Nil + def self.parse_nest_groups(fields_text : String, &) : Nil nest_stack = [] of NamedTuple(group_name: String, closing_bracket_index: Int64) bracket_pairs = get_bracket_pairs(fields_text, true) From f47d4f88cc6d7a1f0e92cabd5767e39e0596b63f Mon Sep 17 00:00:00 2001 From: Samantaz Fox Date: Sat, 21 Jan 2023 19:52:14 +0100 Subject: [PATCH 029/114] Deps: Use the right source path when copying .min.css files Thanks to therealresonix for the catch! --- scripts/fetch-player-dependencies.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/fetch-player-dependencies.cr b/scripts/fetch-player-dependencies.cr index ed658b51..813e4ce4 100755 --- a/scripts/fetch-player-dependencies.cr +++ b/scripts/fetch-player-dependencies.cr @@ -129,7 +129,7 @@ dependencies_to_install.each do |dep| dep = "videojs.markers" if dep == "videojs-markers" if File.exists?("#{download_path}/package/dist/#{dep}.css") - if minified && File.exists?("#{tmp_dir_path}/#{dep}/package/dist/#{dep}.min.css") + if minified && File.exists?("#{download_path}/package/dist/#{dep}.min.css") `mv #{download_path}/package/dist/#{dep}.min.css #{dest_path}/#{dep}.css` else `mv #{download_path}/package/dist/#{dep}.css #{dest_path}/#{dep}.css` From 4aa696fa6ea11959e72b7c084d0b55b2c5476a07 Mon Sep 17 00:00:00 2001 From: Wes van der Vleuten <16665772+WesVleuten@users.noreply.github.com> Date: Sat, 21 Jan 2023 23:08:24 +0100 Subject: [PATCH 030/114] Update assets/js/watched_widget.js with suggestion of AHOHNMYC Co-authored-by: AHOHNMYC <24810600+AHOHNMYC@users.noreply.github.com> --- assets/js/watched_widget.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js index d1b55d28..02537111 100644 --- a/assets/js/watched_widget.js +++ b/assets/js/watched_widget.js @@ -39,11 +39,9 @@ function get_all_video_times() { return helpers.storage.get(save_player_pos_key) || {}; } -var watchedIndicators = document.getElementsByClassName('watched-indicator'); -for (var i = 0; i < watchedIndicators.length; i++) { - var indicator = watchedIndicators[i]; - var watched_part = get_all_video_times()[indicator.getAttribute('data-id')]; - var total = parseInt(indicator.getAttribute('data-length'), 10); +document.querySelectorAll('.watched-indicator').forEach(function (indicator) { + var watched_part = get_all_video_times()[indicator.dataset.id]; + var total = parseInt(indicator.dataset.length, 10); if (watched_part === undefined) { watched_part = total; } @@ -57,4 +55,4 @@ for (var i = 0; i < watchedIndicators.length; i++) { } indicator.style.width = percentage + '%'; -} +}); From 7fd205179b5707a2774d83866f5a35b2bd8cfe16 Mon Sep 17 00:00:00 2001 From: Wes van der Vleuten <16665772+WesVleuten@users.noreply.github.com> Date: Sat, 21 Jan 2023 23:24:22 +0100 Subject: [PATCH 031/114] Added suggestions --- src/invidious/views/components/item.ecr | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index 47d077cf..fa12374f 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -1,4 +1,4 @@ -<% item_watched = !item.is_a?(SearchChannel) && !item.is_a?(SearchPlaylist) && !item.is_a?(InvidiousPlaylist) && !item.is_a?(Category) && env.get("user") && env.get("user").as(User).watched && env.get("user").as(User).watched.index(item.id) != nil %> +<% item_watched = !item.is_a?(SearchChannel | SearchPlaylist | InvidiousPlaylist | Category) && env.get?("user").try &.as(User).watched.index(item.id) != nil %>
@@ -42,7 +42,7 @@ <% if item.length_seconds != 0 %>

<%= recode_length_seconds(item.length_seconds) %>

<% end %> - + <% if item_watched %>
@@ -74,7 +74,7 @@ <% elsif item.length_seconds != 0 %>

<%= recode_length_seconds(item.length_seconds) %>

<% end %> - + <% if item_watched %>
From caf9520c865133eb669025f9cd64607546e09a89 Mon Sep 17 00:00:00 2001 From: techmetx11 Date: Sun, 22 Jan 2023 00:12:04 +0100 Subject: [PATCH 032/114] Major improvements --- assets/css/default.css | 41 +++++++++++++++++++++------------- locales/en-US.json | 1 + src/invidious/videos.cr | 9 +++----- src/invidious/videos/parser.cr | 14 +++++++----- src/invidious/views/watch.ecr | 39 +++++++++++++------------------- 5 files changed, 55 insertions(+), 49 deletions(-) diff --git a/assets/css/default.css b/assets/css/default.css index 4ec6f720..9788e9f7 100644 --- a/assets/css/default.css +++ b/assets/css/default.css @@ -491,30 +491,27 @@ hr { /* Description Expansion Styling*/ #descexpansionbutton, -#musicdescexpansionbutton { - display: none +#music-desc-expansion { + display: none; } -#descexpansionbutton ~ div, -#musicdescexpansionbutton ~ div { +#descexpansionbutton ~ div { overflow: hidden; height: 8.3em; } -#descexpansionbutton:checked ~ div, -#musicdescexpansionbutton:checked ~ div { +#descexpansionbutton:checked ~ div { overflow: unset; height: 100%; } -#descexpansionbutton ~ label, -#musicdescexpansionbutton ~ label { +#descexpansionbutton ~ label { order: 1; margin-top: 20px; } label[for="descexpansionbutton"]:hover, -label[for="musicdescexpansionbutton"]:hover { +label[for="music-desc-expansion"]:hover { cursor: pointer; } @@ -527,8 +524,7 @@ h5, p, #descriptionWrapper, #description-box, -#music-description-box, -#musicDescriptionWrapper { +#music-description-box { unicode-bidi: plaintext; text-align: start; } @@ -538,12 +534,27 @@ p, white-space: pre-wrap; } -#musicDescriptionWrapper { - max-width: 600px; +#music-description-box { + display: none; } -#music-description-title { - margin-bottom: 0px; +#music-desc-expansion:checked ~ #music-description-box { + display: block; +} + +#music-desc-expansion ~ label > h3 > .ion-ios-arrow-up, +#music-desc-expansion:checked ~ label > h3 > .ion-ios-arrow-down { + display: none; +} + +#music-desc-expansion:checked ~ label > h3 > .ion-ios-arrow-up, +#music-desc-expansion ~ label > h3 > .ion-ios-arrow-down { + display: inline; +} + +/* Select all the music items except the first one */ +.music-item + .music-item { + border-top: 1px solid #ffffff; } /* Center the "invidious" logo on the search page */ diff --git a/locales/en-US.json b/locales/en-US.json index 20f1a46d..a5c16fd7 100644 --- a/locales/en-US.json +++ b/locales/en-US.json @@ -188,6 +188,7 @@ "Engagement: ": "Engagement: ", "Whitelisted regions: ": "Whitelisted regions: ", "Blacklisted regions: ": "Blacklisted regions: ", + "Music in this video": "Music in this video", "Artist: ": "Artist: ", "Album: ": "Album: ", "Shared `x`": "Shared `x`", diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index aa3ef1a8..436ac82d 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -248,12 +248,9 @@ struct Video end def music : Array(VideoMusic) - music_list = Array(VideoMusic).new - - info["music"].as_a.each do |music_json| - music_list << VideoMusic.new(music_json["album"].as_s, music_json["artist"].as_s, music_json["license"].as_s) - end - return music_list + info["music"].as_a.map { |music_json| + VideoMusic.new(music_json["album"].as_s, music_json["artist"].as_s, music_json["license"].as_s) + } end # Macros defining getters/setters for various types of data diff --git a/src/invidious/videos/parser.cr b/src/invidious/videos/parser.cr index 69b04cb6..0abac32f 100644 --- a/src/invidious/videos/parser.cr +++ b/src/invidious/videos/parser.cr @@ -312,13 +312,18 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any # Music section music_list = [] of VideoMusic - music_desclist = player_response.dig?("engagementPanels", 1, "engagementPanelSectionListRenderer", "content", "structuredDescriptionContentRenderer", "items", 2, "videoDescriptionMusicSectionRenderer", "carouselLockups").try &.as_a - music_desclist.try &.each do |music_desc| + music_desclist = player_response.dig?( + "engagementPanels", 1, "engagementPanelSectionListRenderer", + "content", "structuredDescriptionContentRenderer", "items", 2, + "videoDescriptionMusicSectionRenderer", "carouselLockups" + ) + + music_desclist.try &.as_a.each do |music_desc| artist = nil album = nil music_license = nil - music_desc.dig?("carouselLockupRenderer", "infoRows").try &.as_a.try &.each do |desc| + music_desc.dig?("carouselLockupRenderer", "infoRows").try &.as_a.each do |desc| desc_title = extract_text(desc.dig?("infoRowRenderer", "title")) if desc_title == "ARTIST" artist = extract_text(desc.dig?("infoRowRenderer", "defaultMetadata")) @@ -328,8 +333,7 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any music_license = extract_text(desc.dig?("infoRowRenderer", "expandedMetadata")) end end - music = VideoMusic.new(album.to_s, artist.to_s, music_license.to_s) - music_list << music + music_list << VideoMusic.new(album.to_s, artist.to_s, music_license.to_s) end # Author infos diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index 207dae18..666eb3b0 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -34,13 +34,11 @@ we're going to need to do it here in order to allow for translations. --> @@ -238,27 +236,22 @@ we're going to need to do it here in order to allow for translations.
<% if !video.music.empty? %> -

<%= translate(locale, "Music") %>

+ + +
- <% if video.music.size == 1 %> -
-

<%= translate(locale, "Artist: ") %><%= video.music[0].artist %>

-

<%= translate(locale, "Album: ") %><%= video.music[0].album %>

-

<%= translate(locale, "License: ") %><%= video.music[0].license %>

+ <% video.music.each do |music| %> +
+

<%= translate(locale, "Artist: ") %><%= music.artist %>

+

<%= translate(locale, "Album: ") %><%= music.album %>

+

<%= translate(locale, "License: ") %><%= music.license %>

- <% else %> - -
- <% video.music.each do |music| %> -

<%= translate(locale, "Artist: ") %><%= music.artist %>

-

<%= translate(locale, "Album: ") %><%= music.album %>

-

<%= translate(locale, "License: ") %><%= music.license %>

-
- <% end %> -
- <% end %>

From 24f1d82919d671caa18ea26254d5b8944f20e59c Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 23 Jan 2023 21:59:55 +0100 Subject: [PATCH 033/114] Update Turkish translation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Oğuz Ersen Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/invidious/translations/ Translation: Invidious/Invidious Translations Signed-off-by: Samantaz Fox --- locales/tr.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/locales/tr.json b/locales/tr.json index 7dc256a9..76cce15a 100644 --- a/locales/tr.json +++ b/locales/tr.json @@ -472,5 +472,9 @@ "search_filters_title": "Filtreler", "search_message_change_filters_or_query": "Arama sorgunuzu genişletmeyi ve/veya filtreleri değiştirmeyi deneyin.", "Popular enabled: ": "Popüler Etkin: ", - "error_video_not_in_playlist": "İstenen video bu oynatma listesinde yok. Oynatma listesi ana sayfası için buraya tıklayın." + "error_video_not_in_playlist": "İstenen video bu oynatma listesinde yok. Oynatma listesi ana sayfası için buraya tıklayın.", + "channel_tab_channels_label": "Kanallar", + "channel_tab_shorts_label": "Kısa Çekimler", + "channel_tab_streams_label": "Canlı Yayınlar", + "channel_tab_playlists_label": "Oynatma Listeleri" } From f5b3cee2630750045eabbe6b5e0d009923f1a512 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 23 Jan 2023 21:59:56 +0100 Subject: [PATCH 034/114] Update Korean translation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update Korean translation Co-authored-by: xrfmkrh Co-authored-by: 이정희 Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/invidious/translations/ Translation: Invidious/Invidious Translations Signed-off-by: Samantaz Fox --- locales/ko.json | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/locales/ko.json b/locales/ko.json index af19fd02..d4f3a711 100644 --- a/locales/ko.json +++ b/locales/ko.json @@ -11,7 +11,7 @@ "preferences_dark_mode_label": "테마: ", "Dark mode: ": "다크 모드: ", "preferences_player_style_label": "플레이어 스타일: ", - "preferences_category_visual": "시각 설정", + "preferences_category_visual": "환경 설정", "preferences_vr_mode_label": "VR 영상 활성화(WebGL 필요): ", "preferences_extend_desc_label": "자동으로 비디오 설명을 확장: ", "preferences_annotations_label": "기본으로 주석 표시: ", @@ -150,7 +150,7 @@ "Subscription manager": "구독 관리자", "Save preferences": "설정 저장", "Report statistics: ": "통계 보고: ", - "Registration enabled: ": "등록 활성화: ", + "Registration enabled: ": "회원가입 활성화: ", "Login enabled: ": "로그인 활성화: ", "CAPTCHA enabled: ": "캡차 활성화: ", "Top enabled: ": "Top 활성화: ", @@ -187,8 +187,8 @@ "Polish": "폴란드어", "Persian": "페르시아어", "Pashto": "파슈토어", - "Nyanja": "체와어", - "Norwegian Bokmål": "보크몰", + "Nyanja": "냔자어", + "Norwegian Bokmål": "노르웨이 부크몰어", "Nepali": "네팔어", "Mongolian": "몽골어", "Marathi": "마라티어", @@ -442,7 +442,7 @@ "preferences_save_player_pos_label": "이어서 보기: ", "none": "없음", "videoinfo_started_streaming_x_ago": "`x` 전에 스트리밍을 시작했습니다", - "crash_page_you_found_a_bug": "Invidious에서 버그를 찾은 것 같습니다!", + "crash_page_you_found_a_bug": "인비디어스에서 버그를 찾은 것 같습니다!", "download_subtitles": "자막 - `x`(.vtt)", "user_saved_playlists": "`x`개의 저장된 재생목록", "crash_page_before_reporting": "버그를 보고하기 전에 다음 사항이 있는지 확인합니다:", @@ -456,5 +456,9 @@ "crash_page_report_issue": "위의 방법 중 어느 것도 도움이 되지 않았다면, 깃허브에서 새 이슈를 열고(가능하면 영어로) 메시지에 다음 텍스트를 포함하세요(해당 텍스트를 번역하지 마십시오):", "videoinfo_youTube_embed_link": "임베드", "videoinfo_invidious_embed_link": "임베드 링크", - "error_video_not_in_playlist": "요청한 동영상이 이 재생목록에 없습니다. 재생목록 목록을 보려면 여기를 클릭하십시오." + "error_video_not_in_playlist": "요청한 동영상이 이 재생목록에 없습니다. 재생목록 목록을 보려면 여기를 클릭하십시오.", + "channel_tab_shorts_label": "쇼츠", + "channel_tab_streams_label": "실시간 스트리밍", + "channel_tab_channels_label": "채널", + "channel_tab_playlists_label": "재생목록" } From b3a605c5741917ca210022e6eefa08ecfe5727d7 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 23 Jan 2023 21:59:56 +0100 Subject: [PATCH 035/114] Update Polish translation Co-authored-by: Matthaiks Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/invidious/translations/ Translation: Invidious/Invidious Translations Signed-off-by: Samantaz Fox --- locales/pl.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/locales/pl.json b/locales/pl.json index 6c642475..b9c2a638 100644 --- a/locales/pl.json +++ b/locales/pl.json @@ -324,7 +324,7 @@ "`x` marked it with a ❤": "`x` oznaczonych ❤", "Audio mode": "Tryb audio", "Video mode": "Tryb wideo", - "channel_tab_videos_label": "Filmy", + "channel_tab_videos_label": "Wideo", "Playlists": "Playlisty", "channel_tab_community_label": "Społeczność", "search_filters_sort_option_relevance": "Trafność", @@ -488,5 +488,9 @@ "search_message_use_another_instance": " Możesz także wyszukać w innej instancji.", "search_filters_type_option_all": "Dowolny typ", "search_filters_duration_option_none": "Dowolna długość", - "search_filters_duration_option_medium": "Średnia (4-20 minut)" + "search_filters_duration_option_medium": "Średnia (4-20 minut)", + "channel_tab_streams_label": "Na żywo", + "channel_tab_channels_label": "Kanały", + "channel_tab_playlists_label": "Playlisty", + "channel_tab_shorts_label": "Shorts" } From dd1ffb9283550c81d9c794cbe99d4a85d47d0046 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 23 Jan 2023 21:59:56 +0100 Subject: [PATCH 036/114] Update Arabic translation Co-authored-by: Rex_sa Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/invidious/translations/ Translation: Invidious/Invidious Translations Signed-off-by: Samantaz Fox --- locales/ar.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/locales/ar.json b/locales/ar.json index e31a0e28..55dea5f3 100644 --- a/locales/ar.json +++ b/locales/ar.json @@ -536,5 +536,9 @@ "generic_count_seconds_3": "{{count}} ثوانٍ", "generic_count_seconds_4": "{{count}} ثانية", "generic_count_seconds_5": "{{count}} ثانية", - "error_video_not_in_playlist": "الفيديو المطلوب غير موجود في قائمة التشغيل هذه. انقر هنا للحصول على الصفحة الرئيسية لقائمة التشغيل. " + "error_video_not_in_playlist": "الفيديو المطلوب غير موجود في قائمة التشغيل هذه. انقر هنا للحصول على الصفحة الرئيسية لقائمة التشغيل. ", + "channel_tab_shorts_label": "الفيديوهات القصيرة", + "channel_tab_streams_label": "البث المباشر", + "channel_tab_playlists_label": "قوائم التشغيل", + "channel_tab_channels_label": "القنوات" } From 75d136ce77385eeee04f0c9f42db154ac425eb64 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 23 Jan 2023 21:59:57 +0100 Subject: [PATCH 037/114] Update French translation Co-authored-by: slundi Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/invidious/translations/ Translation: Invidious/Invidious Translations Signed-off-by: Samantaz Fox --- locales/fr.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/locales/fr.json b/locales/fr.json index 59a960d0..9d3e117f 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -472,5 +472,9 @@ "search_filters_date_label": "Date d'ajout", "search_filters_features_option_vr180": "VR180", "search_filters_duration_option_none": "Toutes les durées", - "error_video_not_in_playlist": "La vidéo demandée n'existe pas dans cette liste de lecture. Cliquez ici pour retourner à la liste de lecture." + "error_video_not_in_playlist": "La vidéo demandée n'existe pas dans cette liste de lecture. Cliquez ici pour retourner à la liste de lecture.", + "channel_tab_shorts_label": "Clips", + "channel_tab_streams_label": "En direct", + "channel_tab_playlists_label": "Listes de lecture", + "channel_tab_channels_label": "Chaînes" } From 8cc0f9faf049d3491744a6f3aa71b0bcbe8e6f31 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 23 Jan 2023 21:59:57 +0100 Subject: [PATCH 038/114] Update Italian translation Update Italian translation Co-authored-by: atilluF Co-authored-by: Translator-3000 Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/invidious/translations/ Translation: Invidious/Invidious Translations Signed-off-by: Samantaz Fox --- locales/it.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/locales/it.json b/locales/it.json index 1a0d8efc..f47b032e 100644 --- a/locales/it.json +++ b/locales/it.json @@ -346,7 +346,6 @@ "Video mode": "Modalità video", "channel_tab_videos_label": "Video", "Playlists": "Playlist", - "channel_tab_community_label": "Comunità", "search_filters_sort_option_relevance": "Pertinenza", "search_filters_sort_option_rating": "Valutazione", "search_filters_sort_option_date": "Data di caricamento", @@ -472,5 +471,10 @@ "search_filters_features_option_vr180": "VR180", "search_filters_apply_button": "Applica filtri selezionati", "crash_page_refresh": "provato a ricaricare la pagina", - "error_video_not_in_playlist": "Il video richiesto non esiste in questa playlist. Fai clic qui per la pagina iniziale della playlist." + "error_video_not_in_playlist": "Il video richiesto non esiste in questa playlist. Fai clic qui per la pagina iniziale della playlist.", + "channel_tab_shorts_label": "Short", + "channel_tab_playlists_label": "Playlist", + "channel_tab_channels_label": "Canali", + "channel_tab_streams_label": "Livestream", + "channel_tab_community_label": "Comunità" } From 32bc44e83b0af39b2ce62f7b1445a07b43758595 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 23 Jan 2023 21:59:57 +0100 Subject: [PATCH 039/114] Update Spanish translation Co-authored-by: Jorge Maldonado Ventura Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/invidious/translations/ Translation: Invidious/Invidious Translations Signed-off-by: Samantaz Fox --- locales/es.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/locales/es.json b/locales/es.json index dc63619e..59d6b145 100644 --- a/locales/es.json +++ b/locales/es.json @@ -472,5 +472,9 @@ "search_message_use_another_instance": " También puede buscar en otra instancia.", "search_filters_duration_option_medium": "Medio (4 - 20 minutes)", "Popular enabled: ": "¿Habilitar la sección popular? ", - "error_video_not_in_playlist": "El vídeo solicitado no existe en esta lista de reproducción. Haga clic aquí para acceder a la página de inicio de la lista de reproducción." + "error_video_not_in_playlist": "El vídeo solicitado no existe en esta lista de reproducción. Haga clic aquí para acceder a la página de inicio de la lista de reproducción.", + "channel_tab_streams_label": "Directos", + "channel_tab_channels_label": "Canales", + "channel_tab_shorts_label": "Cortos", + "channel_tab_playlists_label": "Listas de reproducción" } From 68caf355af5282874a16cf47a93fd6ad31088c59 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 23 Jan 2023 21:59:58 +0100 Subject: [PATCH 040/114] Update Esperanto translation Co-authored-by: Jorge Maldonado Ventura Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/invidious/translations/ Translation: Invidious/Invidious Translations Signed-off-by: Samantaz Fox --- locales/eo.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/locales/eo.json b/locales/eo.json index 1a5d9938..56e718f2 100644 --- a/locales/eo.json +++ b/locales/eo.json @@ -325,7 +325,7 @@ "`x` marked it with a ❤": "`x` markis ĝin per ❤", "Audio mode": "Aŭda reĝimo", "Video mode": "Videa reĝimo", - "channel_tab_videos_label": "Filmetoj", + "channel_tab_videos_label": "Videoj", "Playlists": "Ludlistoj", "channel_tab_community_label": "Komunumo", "search_filters_sort_option_relevance": "rilateco", @@ -472,5 +472,9 @@ "generic_subscribers_count_plural": "{{count}} abonantoj", "generic_count_months": "{{count}} monato", "generic_count_months_plural": "{{count}} monatoj", - "preferences_save_player_pos_label": "Konservi ludadan pozicion: " + "preferences_save_player_pos_label": "Konservi ludadan pozicion: ", + "channel_tab_streams_label": "Tujelsendoj", + "channel_tab_playlists_label": "Ludlistoj", + "channel_tab_channels_label": "Kanaloj", + "channel_tab_shorts_label": "Mallongaj" } From 5c024c677b6d99d1143e09fcd3a11b1c0b5812d7 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 23 Jan 2023 21:59:58 +0100 Subject: [PATCH 041/114] Update Ukrainian translation Co-authored-by: Ihor Hordiichuk Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/invidious/translations/ Translation: Invidious/Invidious Translations Signed-off-by: Samantaz Fox --- locales/uk.json | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/locales/uk.json b/locales/uk.json index d063799e..ae2fb5bd 100644 --- a/locales/uk.json +++ b/locales/uk.json @@ -54,7 +54,7 @@ "preferences_continue_label": "Завжди вмикати наступне відео: ", "preferences_continue_autoplay_label": "Автовідтворення наступного відео: ", "preferences_listen_label": "Режим «тільки звук» як усталений: ", - "preferences_local_label": "Програвати відео через проксі? ", + "preferences_local_label": "Відтворення відео через проксі: ", "preferences_speed_label": "Усталена швидкість відео: ", "preferences_quality_label": "Пріорітетна якість відео: ", "preferences_volume_label": "Гучність відео: ", @@ -63,13 +63,13 @@ "reddit": "Reddit", "preferences_captions_label": "Основна мова субтитрів: ", "Fallback captions: ": "Запасна мова субтитрів: ", - "preferences_related_videos_label": "Показувати схожі відео? ", - "preferences_annotations_label": "Завжди показувати анотації? ", + "preferences_related_videos_label": "Показувати схожі відео: ", + "preferences_annotations_label": "Завжди показувати анотації: ", "preferences_category_visual": "Налаштування сайту", "preferences_player_style_label": "Стиль програвача: ", - "Dark mode: ": "Темне оформлення: ", + "Dark mode: ": "Темний режим: ", "preferences_dark_mode_label": "Тема: ", - "dark": "темна", + "dark": "Темна", "light": "Світла", "preferences_thin_mode_label": "Полегшене оформлення: ", "preferences_category_subscription": "Налаштування підписок", @@ -101,11 +101,11 @@ "preferences_category_admin": "Адміністраторські налаштування", "preferences_default_home_label": "Усталена домашня сторінка: ", "preferences_feed_menu_label": "Меню потоку з відео: ", - "Top enabled: ": "Увімкнути топ відео? ", - "CAPTCHA enabled: ": "Увімкнути капчу? ", - "Login enabled: ": "Увімкнути авторизацію? ", - "Registration enabled: ": "Увімкнути реєстрацію? ", - "Report statistics: ": "Повідомляти статистику? ", + "Top enabled: ": "Увімкнути топ відео: ", + "CAPTCHA enabled: ": "Увімкнути CAPTCHA: ", + "Login enabled: ": "Увімкнути вхід: ", + "Registration enabled: ": "Увімкнути реєстрацію: ", + "Report statistics: ": "Повідомляти статистику: ", "Save preferences": "Зберегти налаштування", "Subscription manager": "Менеджер підписок", "Token manager": "Менеджер токенів", @@ -125,7 +125,7 @@ "Private": "Особистий", "View all playlists": "Переглянути всі списки відтворення", "Updated `x` ago": "Оновлено `x` тому", - "Delete playlist `x`?": "Видалити список відтворення \"x\"?", + "Delete playlist `x`?": "Видалити список відтворення `x`?", "Delete playlist": "Видалити список відтворення", "Create playlist": "Створити список відтворення", "Title": "Заголовок", @@ -386,12 +386,12 @@ "Spanish (Mexico)": "Іспанська (Мексика)", "Spanish (Spain)": "Іспанська (Іспанія)", "next_steps_error_message_go_to_youtube": "Перейти до YouTube", - "footer_donate_page": "Пожертвувати", + "footer_donate_page": "Підтримати", "footer_documentation": "Документація", - "footer_source_code": "Вихідний код", - "footer_original_source_code": "Оригінал вихідного коду", - "footer_modfied_source_code": "Змінений вихідний код", - "adminprefs_modified_source_code_url_label": "URL-адреса репозиторію зміненого вихідного коду", + "footer_source_code": "Джерельний код", + "footer_original_source_code": "Оригінал джерельного коду", + "footer_modfied_source_code": "Змінений джерельний код", + "adminprefs_modified_source_code_url_label": "URL-адреса репозиторію зміненого джерельного коду", "none": "нема", "videoinfo_started_streaming_x_ago": "Трансляцію розпочато `x` тому", "crash_page_you_found_a_bug": "Схоже, ви знайшли ваду в Invidious!", @@ -408,7 +408,7 @@ "next_steps_error_message": "Після чого спробуйте: ", "next_steps_error_message_refresh": "Оновити сторінку", "Search": "Пошук", - "preferences_extend_desc_label": "Автоматично розширювати опис відео: ", + "preferences_extend_desc_label": "Автоматично розгортати опис відео: ", "preferences_category_misc": "Різноманітні параметри", "Show less": "Коротше", "preferences_quality_option_small": "Низька", @@ -488,5 +488,9 @@ "search_filters_sort_option_rating": "Рейтингові", "search_filters_sort_option_views": "Популярні", "Popular enabled: ": "Популярне ввімкнено: ", - "error_video_not_in_playlist": "Запитуваного відео в цьому списку відтворення не існує. Клацніть тут, щоб переглянути домашню сторінку списку відтворення." + "error_video_not_in_playlist": "Запитуваного відео в цьому списку відтворення не існує. Клацніть тут, щоб переглянути домашню сторінку списку відтворення.", + "channel_tab_shorts_label": "Shorts", + "channel_tab_streams_label": "Прямі трансляції", + "channel_tab_playlists_label": "Добірки", + "channel_tab_channels_label": "Канали" } From e66e4631567e12f98a6efbb4ddc727a40b511325 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 23 Jan 2023 21:59:58 +0100 Subject: [PATCH 042/114] Update Croatian translation Co-authored-by: Milo Ivir Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/invidious/translations/ Translation: Invidious/Invidious Translations Signed-off-by: Samantaz Fox --- locales/hr.json | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/locales/hr.json b/locales/hr.json index c8414322..7914ab16 100644 --- a/locales/hr.json +++ b/locales/hr.json @@ -7,8 +7,8 @@ "View playlist on YouTube": "Prikaži zbirku na YouTubeu", "newest": "najnovije", "oldest": "najstarije", - "popular": "popularni", - "last": "zadnji", + "popular": "popularne", + "last": "zadnje", "Next page": "Sljedeća stranica", "Previous page": "Prethodna stranica", "Clear watch history?": "Izbrisati povijest gledanja?", @@ -43,9 +43,9 @@ "Time (h:mm:ss):": "Vrijeme (h:mm:ss):", "Text CAPTCHA": "Tekstualni CAPTCHA", "Image CAPTCHA": "Slikovni CAPTCHA", - "Sign In": "Prijava", + "Sign In": "Prijavi se", "Register": "Registriraj se", - "E-mail": "E-mail", + "E-mail": "E-mail adresa", "Google verification code": "Googleov potvrdni kod", "Preferences": "Postavke", "preferences_category_player": "Postavke playera", @@ -488,5 +488,9 @@ "search_filters_apply_button": "Primijeni odabrane filtre", "search_filters_type_option_all": "Bilo koja vrsta", "Popular enabled: ": "Popularni aktivirani: ", - "error_video_not_in_playlist": "Traženi video ne postoji u ovoj zbirci. Pritisni ovdje za početnu stranicu zbirke." + "error_video_not_in_playlist": "Traženi video ne postoji u ovoj zbirci. Pritisni ovdje za početnu stranicu zbirke.", + "channel_tab_streams_label": "Prijenosi uživo", + "channel_tab_playlists_label": "Zbirke", + "channel_tab_channels_label": "Kanali", + "channel_tab_shorts_label": "Kratka videa" } From 9b9fde1054a1418642d5a54f26e964aedb2d2ae6 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 23 Jan 2023 21:59:59 +0100 Subject: [PATCH 043/114] Update Chinese (Traditional) translation Co-authored-by: Jeff Huang Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/invidious/translations/ Translation: Invidious/Invidious Translations Signed-off-by: Samantaz Fox --- locales/zh-TW.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/locales/zh-TW.json b/locales/zh-TW.json index 584d4a0a..3b51721d 100644 --- a/locales/zh-TW.json +++ b/locales/zh-TW.json @@ -456,5 +456,9 @@ "search_filters_type_option_all": "任何類型", "search_filters_date_option_none": "任何日期", "Popular enabled: ": "已啟用人氣: ", - "error_video_not_in_playlist": "此播放清單不存在請求的影片。點擊此處檢視播放清單首頁。" + "error_video_not_in_playlist": "此播放清單不存在請求的影片。點擊此處檢視播放清單首頁。", + "channel_tab_shorts_label": "短片", + "channel_tab_playlists_label": "播放清單", + "channel_tab_channels_label": "頻道", + "channel_tab_streams_label": "直播" } From ad3c721af7e33b4b000d7e00ba668b7fc4322eac Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 23 Jan 2023 22:00:01 +0100 Subject: [PATCH 044/114] Update Czech translation Co-authored-by: Fjuro Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/invidious/translations/ Translation: Invidious/Invidious Translations Signed-off-by: Samantaz Fox --- locales/cs.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/locales/cs.json b/locales/cs.json index 466a3058..7502de0b 100644 --- a/locales/cs.json +++ b/locales/cs.json @@ -63,7 +63,7 @@ "reddit": "Reddit", "preferences_captions_label": "Výchozí titulky: ", "Fallback captions: ": "Záložní titulky: ", - "preferences_related_videos_label": "Zobrazit podobné videa: ", + "preferences_related_videos_label": "Zobrazit podobná videa: ", "preferences_annotations_label": "Zobrazovat poznámky ve výchozím nastavení: ", "preferences_extend_desc_label": "Rozšířit automaticky popis u videa: ", "preferences_category_visual": "Nastavení vzhledu", @@ -488,5 +488,9 @@ "search_filters_sort_option_relevance": "Relevantnost", "search_filters_apply_button": "Použít vybrané filtry", "Popular enabled: ": "Populární povoleno: ", - "error_video_not_in_playlist": "Požadované video v tomto playlistu neexistuje. Klikněte sem pro navštívení domovské stránky playlistu." + "error_video_not_in_playlist": "Požadované video v tomto playlistu neexistuje. Klikněte sem pro navštívení domovské stránky playlistu.", + "channel_tab_shorts_label": "Shorts", + "channel_tab_playlists_label": "Playlisty", + "channel_tab_channels_label": "Kanály", + "channel_tab_streams_label": "Živé přenosy" } From c2957dbce4a76b9a85fde9224b8c18edcb5821ba Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Tue, 24 Jan 2023 23:21:09 -0500 Subject: [PATCH 045/114] fix displaying author name #1612 --- src/invidious/channels/community.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/channels/community.cr b/src/invidious/channels/community.cr index 8e300288..76dff555 100644 --- a/src/invidious/channels/community.cr +++ b/src/invidious/channels/community.cr @@ -69,7 +69,7 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode) next if !post content_html = post["contentText"]?.try { |t| parse_content(t) } || "" - author = post["authorText"]?.try &.["simpleText"]? || "" + author = post["authorText"]["runs"]?.try &.[0]?.try &.["text"]? || "" json.object do json.field "author", author From 13bf4e9e00030161165edf45b5e7d6e2ab1b3e30 Mon Sep 17 00:00:00 2001 From: Macic Date: Thu, 26 Jan 2023 01:19:12 +0100 Subject: [PATCH 046/114] Support handles --- src/invidious/routing.cr | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/invidious/routing.cr b/src/invidious/routing.cr index 491022a5..157e6de7 100644 --- a/src/invidious/routing.cr +++ b/src/invidious/routing.cr @@ -132,6 +132,8 @@ module Invidious::Routing get "/c/:user#{path}", Routes::Channels, :brand_redirect # /user/linustechtips | Not always the same as /c/ get "/user/:user#{path}", Routes::Channels, :brand_redirect + # /@LinusTechTips | Handle + get "/@:user#{path}", Routes::Channels, :brand_redirect # /attribution_link?a=anything&u=/channel/UCZYTClx2T1of7BRZ86-8fow get "/attribution_link#{path}", Routes::Channels, :brand_redirect # /profile?user=linustechtips From 785fe5267480db83173e54423051bc528c545b0c Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Sun, 29 Jan 2023 10:28:42 -0500 Subject: [PATCH 047/114] API: Parse multiimage community posts --- src/invidious/channels/community.cr | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/invidious/channels/community.cr b/src/invidious/channels/community.cr index 76dff555..13af2d8b 100644 --- a/src/invidious/channels/community.cr +++ b/src/invidious/channels/community.cr @@ -189,6 +189,32 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode) # when .has_key?("pollRenderer") # attachment = attachment["pollRenderer"] # json.field "type", "poll" + when .has_key?("postMultiImageRenderer") + attachment = attachment["postMultiImageRenderer"] + json.field "type", "multiImage" + json.field "images" do + json.array do + attachment["images"].as_a.each do |image| + json.array do + thumbnail = image["backstageImageRenderer"]["image"]["thumbnails"][0].as_h + width = thumbnail["width"].as_i + height = thumbnail["height"].as_i + aspect_ratio = (width.to_f / height.to_f) + url = thumbnail["url"].as_s.gsub(/=w\d+-h\d+(-p)?(-nd)?(-df)?(-rwa)?/, "=s640") + + qualities = {320, 560, 640, 1280, 2000} + + qualities.each do |quality| + json.object do + json.field "url", url.gsub(/=s\d+/, "=s#{quality}") + json.field "width", quality + json.field "height", (quality / aspect_ratio).ceil.to_i + end + end + end + end + end + end else json.field "type", "unknown" json.field "error", "Unrecognized attachment type." From e7a9aeff9538903d22363d2abcee28c62dc10895 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Mon, 30 Jan 2023 10:49:23 -0500 Subject: [PATCH 048/114] Add username to auth token callback --- src/invidious/routes/account.cr | 1 + 1 file changed, 1 insertion(+) diff --git a/src/invidious/routes/account.cr b/src/invidious/routes/account.cr index 9bb73136..d01aee56 100644 --- a/src/invidious/routes/account.cr +++ b/src/invidious/routes/account.cr @@ -262,6 +262,7 @@ module Invidious::Routes::Account end query["token"] = access_token + query["username"] = user.email url.query = query.to_s env.redirect url.to_s From bf5175d1e979005f6d04c9d7639c9db4aa08fb7b Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Thu, 2 Feb 2023 11:52:31 -0500 Subject: [PATCH 049/114] Feat: Add api endpoint to resolve youtube urls --- src/invidious/routes/api/v1/misc.cr | 27 +++++++++++++++++++++++++++ src/invidious/routing.cr | 1 + 2 files changed, 28 insertions(+) diff --git a/src/invidious/routes/api/v1/misc.cr b/src/invidious/routes/api/v1/misc.cr index 43d360e6..9679b530 100644 --- a/src/invidious/routes/api/v1/misc.cr +++ b/src/invidious/routes/api/v1/misc.cr @@ -150,4 +150,31 @@ module Invidious::Routes::API::V1::Misc response end + + # resolve channel and clip urls, return the UCID + def self.resolve_url(env) + env.response.content_type = "application/json" + url = env.params.query["url"]? + + return error_json(400, "Missing URL to resolve") if !url + + begin + resolved_url = YoutubeAPI.resolve_url(url.as(String)) + endpoint = resolved_url["endpoint"] + if resolved_ucid = endpoint.dig?("watchEndpoint", "videoId") + elsif resolved_ucid = endpoint.dig?("browseEndpoint", "browseId") + elsif pageType = endpoint.dig?("commandMetadata", "webCommandMetadata", "webPageType").try &.as_s || "" + if pageType == "WEB_PAGE_TYPE_UNKNOWN" + return error_json(400, "Unknown url") + end + end + rescue ex + return error_json(500, ex) + end + JSON.build do |json| + json.object do + json.field "ucid", resolved_ucid.try &.as_s || "" + end + end + end end diff --git a/src/invidious/routing.cr b/src/invidious/routing.cr index 157e6de7..fb9851a3 100644 --- a/src/invidious/routing.cr +++ b/src/invidious/routing.cr @@ -281,6 +281,7 @@ module Invidious::Routing get "/api/v1/playlists/:plid", {{namespace}}::Misc, :get_playlist get "/api/v1/auth/playlists/:plid", {{namespace}}::Misc, :get_playlist get "/api/v1/mixes/:rdid", {{namespace}}::Misc, :mixes + get "/api/v1/resolveurl", {{namespace}}::Misc, :resolve_url {% end %} end end From c162c7ff3f27498bd374b674bf7ca9b0c0790cc8 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Thu, 2 Feb 2023 18:20:14 -0500 Subject: [PATCH 050/114] add pageType --- src/invidious/routes/api/v1/misc.cr | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/invidious/routes/api/v1/misc.cr b/src/invidious/routes/api/v1/misc.cr index 9679b530..e499f4d6 100644 --- a/src/invidious/routes/api/v1/misc.cr +++ b/src/invidious/routes/api/v1/misc.cr @@ -161,12 +161,11 @@ module Invidious::Routes::API::V1::Misc begin resolved_url = YoutubeAPI.resolve_url(url.as(String)) endpoint = resolved_url["endpoint"] + pageType = endpoint.dig?("commandMetadata", "webCommandMetadata", "webPageType").try &.as_s || "" if resolved_ucid = endpoint.dig?("watchEndpoint", "videoId") elsif resolved_ucid = endpoint.dig?("browseEndpoint", "browseId") - elsif pageType = endpoint.dig?("commandMetadata", "webCommandMetadata", "webPageType").try &.as_s || "" - if pageType == "WEB_PAGE_TYPE_UNKNOWN" - return error_json(400, "Unknown url") - end + elsif pageType == "WEB_PAGE_TYPE_UNKNOWN" + return error_json(400, "Unknown url") end rescue ex return error_json(500, ex) @@ -174,6 +173,7 @@ module Invidious::Routes::API::V1::Misc JSON.build do |json| json.object do json.field "ucid", resolved_ucid.try &.as_s || "" + json.field "pageType", pageType end end end From b2589c74bedb73a1ab6e0afe1a921b97f80c4b8e Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Thu, 2 Feb 2023 19:14:02 -0500 Subject: [PATCH 051/114] Add API for import/export --- src/invidious/routes/api/v1/authenticated.cr | 49 ++++++++++++++++++++ src/invidious/routing.cr | 3 ++ 2 files changed, 52 insertions(+) diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr index 421355bb..c6042e40 100644 --- a/src/invidious/routes/api/v1/authenticated.cr +++ b/src/invidious/routes/api/v1/authenticated.cr @@ -31,6 +31,55 @@ module Invidious::Routes::API::V1::Authenticated env.response.status_code = 204 end + def self.export_invidious(env) + env.response.content_type = "application/json" + user = env.get("user").as(User) + + playlists = Invidious::Database::Playlists.select_like_iv(user.email) + + return JSON.build do |json| + json.object do + json.field "subscriptions", user.subscriptions + json.field "watch_history", user.watched + json.field "preferences", user.preferences + json.field "playlists" do + json.array do + playlists.each do |playlist| + json.object do + json.field "title", playlist.title + json.field "description", html_to_content(playlist.description_html) + json.field "privacy", playlist.privacy.to_s + json.field "videos" do + json.array do + Invidious::Database::PlaylistVideos.select_ids(playlist.id, playlist.index, limit: 500).each do |video_id| + json.string video_id + end + end + end + end + end + end + end + end + end + end + + def self.import_invidious(env) + user = env.get("user").as(User) + + begin + if body = env.request.body + body = env.request.body.not_nil!.gets_to_end + else + body = "{}" + end + Invidious::User::Import.from_invidious(user, body) + rescue + end + + env.response.status_code = 204 + end + def self.feed(env) env.response.content_type = "application/json" diff --git a/src/invidious/routing.cr b/src/invidious/routing.cr index 157e6de7..d5766b90 100644 --- a/src/invidious/routing.cr +++ b/src/invidious/routing.cr @@ -254,6 +254,9 @@ module Invidious::Routing get "/api/v1/auth/preferences", {{namespace}}::Authenticated, :get_preferences post "/api/v1/auth/preferences", {{namespace}}::Authenticated, :set_preferences + get "/api/v1/auth/export/invidious", {{namespace}}::Authenticated, :export_invidious + post "/api/v1/auth/import/invidious", {{namespace}}::Authenticated, :import_invidious + get "/api/v1/auth/feed", {{namespace}}::Authenticated, :feed get "/api/v1/auth/subscriptions", {{namespace}}::Authenticated, :get_subscriptions From 2606decd21a84ac3cba914f327f60a8403398ed9 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Sun, 5 Feb 2023 15:00:11 -0500 Subject: [PATCH 052/114] Refactor export function --- src/invidious/routes/api/v1/authenticated.cr | 28 +--------------- src/invidious/routes/subscriptions.cr | 26 +-------------- src/invidious/user/exports.cr | 35 ++++++++++++++++++++ 3 files changed, 37 insertions(+), 52 deletions(-) create mode 100644 src/invidious/user/exports.cr diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr index c6042e40..6b935312 100644 --- a/src/invidious/routes/api/v1/authenticated.cr +++ b/src/invidious/routes/api/v1/authenticated.cr @@ -35,33 +35,7 @@ module Invidious::Routes::API::V1::Authenticated env.response.content_type = "application/json" user = env.get("user").as(User) - playlists = Invidious::Database::Playlists.select_like_iv(user.email) - - return JSON.build do |json| - json.object do - json.field "subscriptions", user.subscriptions - json.field "watch_history", user.watched - json.field "preferences", user.preferences - json.field "playlists" do - json.array do - playlists.each do |playlist| - json.object do - json.field "title", playlist.title - json.field "description", html_to_content(playlist.description_html) - json.field "privacy", playlist.privacy.to_s - json.field "videos" do - json.array do - Invidious::Database::PlaylistVideos.select_ids(playlist.id, playlist.index, limit: 500).each do |video_id| - json.string video_id - end - end - end - end - end - end - end - end - end + return Invidious::User::Export.to_invidious(user) end def self.import_invidious(env) diff --git a/src/invidious/routes/subscriptions.cr b/src/invidious/routes/subscriptions.cr index 7b1fa876..3090e026 100644 --- a/src/invidious/routes/subscriptions.cr +++ b/src/invidious/routes/subscriptions.cr @@ -106,31 +106,7 @@ module Invidious::Routes::Subscriptions env.response.headers["content-disposition"] = "attachment" playlists = Invidious::Database::Playlists.select_like_iv(user.email) - return JSON.build do |json| - json.object do - json.field "subscriptions", user.subscriptions - json.field "watch_history", user.watched - json.field "preferences", user.preferences - json.field "playlists" do - json.array do - playlists.each do |playlist| - json.object do - json.field "title", playlist.title - json.field "description", html_to_content(playlist.description_html) - json.field "privacy", playlist.privacy.to_s - json.field "videos" do - json.array do - Invidious::Database::PlaylistVideos.select_ids(playlist.id, playlist.index, limit: 500).each do |video_id| - json.string video_id - end - end - end - end - end - end - end - end - end + return Invidious::User::Export.to_invidious(user) else env.response.content_type = "application/xml" env.response.headers["content-disposition"] = "attachment" diff --git a/src/invidious/user/exports.cr b/src/invidious/user/exports.cr new file mode 100644 index 00000000..32be0ca2 --- /dev/null +++ b/src/invidious/user/exports.cr @@ -0,0 +1,35 @@ +struct Invidious::User + module Export + extend self + + def to_invidious(user : User) + playlists = Invidious::Database::Playlists.select_like_iv(user.email) + + return JSON.build do |json| + json.object do + json.field "subscriptions", user.subscriptions + json.field "watch_history", user.watched + json.field "preferences", user.preferences + json.field "playlists" do + json.array do + playlists.each do |playlist| + json.object do + json.field "title", playlist.title + json.field "description", html_to_content(playlist.description_html) + json.field "privacy", playlist.privacy.to_s + json.field "videos" do + json.array do + Invidious::Database::PlaylistVideos.select_ids(playlist.id, playlist.index, limit: 500).each do |video_id| + json.string video_id + end + end + end + end + end + end + end + end + end + end + end # module +end From 47a5b98e2554b32946864bc3320478d0dcc1daf8 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Sun, 5 Feb 2023 15:43:58 -0500 Subject: [PATCH 053/114] Remove unused db call --- src/invidious/routes/subscriptions.cr | 1 - 1 file changed, 1 deletion(-) diff --git a/src/invidious/routes/subscriptions.cr b/src/invidious/routes/subscriptions.cr index 3090e026..0704c05e 100644 --- a/src/invidious/routes/subscriptions.cr +++ b/src/invidious/routes/subscriptions.cr @@ -104,7 +104,6 @@ module Invidious::Routes::Subscriptions if format == "json" env.response.content_type = "application/json" env.response.headers["content-disposition"] = "attachment" - playlists = Invidious::Database::Playlists.select_like_iv(user.email) return Invidious::User::Export.to_invidious(user) else From c37d8e36645d23afedff2729b8ad504cc5ba0655 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Sun, 5 Feb 2023 15:49:56 -0500 Subject: [PATCH 054/114] Use CONFIG.playlist_length_limit when exporting playlists --- src/invidious/user/exports.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/user/exports.cr b/src/invidious/user/exports.cr index 32be0ca2..b52503c9 100644 --- a/src/invidious/user/exports.cr +++ b/src/invidious/user/exports.cr @@ -19,7 +19,7 @@ struct Invidious::User json.field "privacy", playlist.privacy.to_s json.field "videos" do json.array do - Invidious::Database::PlaylistVideos.select_ids(playlist.id, playlist.index, limit: 500).each do |video_id| + Invidious::Database::PlaylistVideos.select_ids(playlist.id, playlist.index, limit: CONFIG.playlist_length_limit).each do |video_id| json.string video_id end end From 28424d0e881c8595bbc5797b9ef46e98103fe6d6 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Tue, 7 Feb 2023 09:23:26 -0500 Subject: [PATCH 055/114] Ignore casing for trending type in api --- src/invidious/trending.cr | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/invidious/trending.cr b/src/invidious/trending.cr index 1f957081..d164c37f 100644 --- a/src/invidious/trending.cr +++ b/src/invidious/trending.cr @@ -4,11 +4,14 @@ def fetch_trending(trending_type, region, locale) plid = nil - if trending_type == "Music" + trending_type ||= "default" + trending_type = trending_type.downcase + + if trending_type == "music" params = "4gINGgt5dG1hX2NoYXJ0cw%3D%3D" - elsif trending_type == "Gaming" + elsif trending_type == "gaming" params = "4gIcGhpnYW1pbmdfY29ycHVzX21vc3RfcG9wdWxhcg%3D%3D" - elsif trending_type == "Movies" + elsif trending_type == "movies" params = "4gIKGgh0cmFpbGVycw%3D%3D" else # Default params = "" From 97825be10c4acf98962c9e65d63305cc77c21021 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Tue, 7 Feb 2023 21:52:53 -0500 Subject: [PATCH 056/114] add missing authorVerified to api --- src/invidious/helpers/serialized_yt_data.cr | 1 + src/invidious/routes/api/v1/channels.cr | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/invidious/helpers/serialized_yt_data.cr b/src/invidious/helpers/serialized_yt_data.cr index 635f0984..c1874780 100644 --- a/src/invidious/helpers/serialized_yt_data.cr +++ b/src/invidious/helpers/serialized_yt_data.cr @@ -74,6 +74,7 @@ struct SearchVideo json.field "author", self.author json.field "authorId", self.ucid json.field "authorUrl", "/channel/#{self.ucid}" + json.field "authorVerified", self.author_verified json.field "videoThumbnails" do Invidious::JSONify::APIv1.thumbnails(json, self.id) diff --git a/src/invidious/routes/api/v1/channels.cr b/src/invidious/routes/api/v1/channels.cr index ca2b2734..bcb4db2c 100644 --- a/src/invidious/routes/api/v1/channels.cr +++ b/src/invidious/routes/api/v1/channels.cr @@ -89,6 +89,8 @@ module Invidious::Routes::API::V1::Channels json.field "descriptionHtml", channel.description_html json.field "allowedRegions", channel.allowed_regions + json.field "tabs", channel.tabs + json.field "authorVerified", channel.verified json.field "latestVideos" do json.array do From b893bdac0d6b76a61e2cd972b29e44cf5b9c88f0 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Tue, 7 Feb 2023 22:02:35 -0500 Subject: [PATCH 057/114] parse isPinned, add support for strikethrough --- src/invidious/comments.cr | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index d691ca36..357a461c 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -181,6 +181,8 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b json.field "content", html_to_content(content_html) json.field "contentHtml", content_html + json.field "isPinned", (node_comment["pinnedCommentBadge"]? != nil) + json.field "published", published.to_unix json.field "publishedText", translate(locale, "`x` ago", recode_date(published, locale)) @@ -670,6 +672,7 @@ def content_to_comment_html(content, video_id : String? = "") end text = "#{text}" if run["bold"]? + text = "#{text}" if run["strikethrough"]? text = "#{text}" if run["italics"]? text From e0c70d34cc3f937149d5c36c76aed8d8b57b4de5 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Thu, 9 Feb 2023 17:13:21 -0500 Subject: [PATCH 058/114] Make sure pinnedCommentBadge isn't equal to false Co-authored-by: Samantaz Fox --- src/invidious/comments.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index 357a461c..41b0efa8 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -181,7 +181,7 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b json.field "content", html_to_content(content_html) json.field "contentHtml", content_html - json.field "isPinned", (node_comment["pinnedCommentBadge"]? != nil) + json.field "isPinned", (node_comment["pinnedCommentBadge"]?.try(&.as_bool) == true) json.field "published", published.to_unix json.field "publishedText", translate(locale, "`x` ago", recode_date(published, locale)) From 838cbeffcc7c8f85c83f6ab3e97362f803bd766c Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Sat, 11 Feb 2023 08:41:26 -0500 Subject: [PATCH 059/114] Use case statement for trending_type Co-Authored-By: Samantaz Fox --- src/invidious/trending.cr | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/invidious/trending.cr b/src/invidious/trending.cr index d164c37f..134eb437 100644 --- a/src/invidious/trending.cr +++ b/src/invidious/trending.cr @@ -4,14 +4,12 @@ def fetch_trending(trending_type, region, locale) plid = nil - trending_type ||= "default" - trending_type = trending_type.downcase - - if trending_type == "music" + case trending_type.try &.downcase + when "music" params = "4gINGgt5dG1hX2NoYXJ0cw%3D%3D" - elsif trending_type == "gaming" + when "gaming" params = "4gIcGhpnYW1pbmdfY29ycHVzX21vc3RfcG9wdWxhcg%3D%3D" - elsif trending_type == "movies" + when "movies" params = "4gIKGgh0cmFpbGVycw%3D%3D" else # Default params = "" From 87342e4efd4258f52d2b34f0e5af0fcf7ca09f90 Mon Sep 17 00:00:00 2001 From: Samantaz Fox Date: Sun, 12 Feb 2023 17:57:07 +0100 Subject: [PATCH 060/114] Comments: Revert "isPinned" to a nil check "pinnedCommentBadge" is not a boolean, but a complex structure. This commit fixes a wrong assumption I had during the rewiew of https://github.com/iv-org/invidious/pull/3626 --- src/invidious/comments.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index 41b0efa8..357a461c 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -181,7 +181,7 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b json.field "content", html_to_content(content_html) json.field "contentHtml", content_html - json.field "isPinned", (node_comment["pinnedCommentBadge"]?.try(&.as_bool) == true) + json.field "isPinned", (node_comment["pinnedCommentBadge"]? != nil) json.field "published", published.to_unix json.field "publishedText", translate(locale, "`x` ago", recode_date(published, locale)) From 48306564843569713cf7ccda63451946419fa376 Mon Sep 17 00:00:00 2001 From: AHOHNMYC Date: Thu, 26 Jan 2023 07:58:32 +0000 Subject: [PATCH 061/114] Update Russian translation --- locales/ru.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/locales/ru.json b/locales/ru.json index e54937a6..77057f53 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -488,5 +488,9 @@ "search_filters_duration_option_medium": "Средние (4 - 20 минут)", "search_filters_apply_button": "Применить фильтры", "Popular enabled: ": "Популярное включено: ", - "error_video_not_in_playlist": "Запрошенного видео нет в этом плейлисте. Нажмите тут, чтобы вернуться к странице плейлиста." + "error_video_not_in_playlist": "Запрошенного видео нет в этом плейлисте. Нажмите тут, чтобы вернуться к странице плейлиста.", + "channel_tab_playlists_label": "Плейлисты", + "channel_tab_channels_label": "Каналы", + "channel_tab_streams_label": "Живое вещание", + "channel_tab_shorts_label": "Shorts" } From bd00b4c730c1fd416751f74c10fe492a02f6acd2 Mon Sep 17 00:00:00 2001 From: SC Date: Thu, 26 Jan 2023 19:26:36 +0000 Subject: [PATCH 062/114] Update Portuguese translation --- locales/pt.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/locales/pt.json b/locales/pt.json index 2facba94..79a39ab6 100644 --- a/locales/pt.json +++ b/locales/pt.json @@ -472,5 +472,9 @@ "search_filters_type_option_all": "Qualquer tipo", "search_filters_duration_option_none": "Qualquer duração", "Popular enabled: ": "Página \"popular\" ativada: ", - "error_video_not_in_playlist": "O vídeo pedido não existe nesta lista de reprodução. Clique aqui para a página inicial da lista de reprodução." + "error_video_not_in_playlist": "O vídeo pedido não existe nesta lista de reprodução. Clique aqui para a página inicial da lista de reprodução.", + "channel_tab_playlists_label": "Listas de reprodução", + "channel_tab_channels_label": "Canais", + "channel_tab_shorts_label": "Curtos", + "channel_tab_streams_label": "Diretos" } From b2f93dc89c4c2271bdb3e7e52510813ee7296d88 Mon Sep 17 00:00:00 2001 From: eightyy8 Date: Tue, 31 Jan 2023 17:22:42 +0000 Subject: [PATCH 063/114] Update Russian translation --- locales/ru.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/ru.json b/locales/ru.json index 77057f53..85628d0f 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -379,7 +379,7 @@ "Turkish (auto-generated)": "Турецкий (созданы автоматически)", "Vietnamese (auto-generated)": "Вьетнамский (созданы автоматически)", "footer_documentation": "Документация", - "adminprefs_modified_source_code_url_label": "Ссылка на нашу ветку репозитория", + "adminprefs_modified_source_code_url_label": "URL-адрес репозитория измененного исходного кода", "none": "ничего", "videoinfo_watch_on_youTube": "Смотреть на YouTube", "videoinfo_youTube_embed_link": "Версия для встраивания", From f4de962dc270a399d49eb659b9fc2e30e991a6b9 Mon Sep 17 00:00:00 2001 From: maboroshin Date: Tue, 31 Jan 2023 01:16:27 +0000 Subject: [PATCH 064/114] Update Japanese translation --- locales/ja.json | 107 ++++++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 50 deletions(-) diff --git a/locales/ja.json b/locales/ja.json index a392abfe..9df1477b 100644 --- a/locales/ja.json +++ b/locales/ja.json @@ -53,12 +53,12 @@ "E-mail": "メールアドレス", "Google verification code": "Google 認証コード", "Preferences": "設定", - "preferences_category_player": "プレイヤー設定", + "preferences_category_player": "プレイヤーの設定", "preferences_video_loop_label": "常にループ: ", "preferences_autoplay_label": "自動再生: ", "preferences_continue_label": "デフォルトで次を再生: ", "preferences_continue_autoplay_label": "次の動画を自動再生: ", - "preferences_listen_label": "デフォルトでオーディオモードを使用: ", + "preferences_listen_label": "デフォルトで音声モードを使用: ", "preferences_local_label": "動画をプロキシーに通す: ", "preferences_speed_label": "デフォルトの再生速度: ", "preferences_quality_label": "優先する画質: ", @@ -73,14 +73,14 @@ "preferences_extend_desc_label": "動画の説明文を自動的に拡張: ", "preferences_vr_mode_label": "対話的な360°動画 (WebGL が必要): ", "preferences_category_visual": "外観設定", - "preferences_player_style_label": "プレイヤースタイル: ", + "preferences_player_style_label": "プレイヤーのスタイル: ", "Dark mode: ": "ダークモード: ", "preferences_dark_mode_label": "テーマ: ", "dark": "ダーク", "light": "ライト", "preferences_thin_mode_label": "最小モード: ", - "preferences_category_misc": "雑設定", - "preferences_automatic_instance_redirect_label": "自動的なインスタンスの移転(redirect.invidious.ioにフォールバック): ", + "preferences_category_misc": "ほかの設定", + "preferences_automatic_instance_redirect_label": "インスタンスの自動転送 (redirect.invidious.ioにフォールバック): ", "preferences_category_subscription": "登録チャンネル設定", "preferences_annotations_subscribed_label": "デフォルトで登録チャンネルのアノテーションを表示しますか? ", "Redirect homepage to feed: ": "ホームからフィードにリダイレクト: ", @@ -117,8 +117,8 @@ "Registration enabled: ": "登録を有効化: ", "Report statistics: ": "統計を報告: ", "Save preferences": "設定を保存", - "Subscription manager": "登録チャンネルマネージャー", - "Token manager": "トークンマネージャー", + "Subscription manager": "登録チャンネルの管理", + "Token manager": "トークンの管理", "Token": "トークン", "tokens_count_0": "{{count}} 個のトークン", "Import/export": "インポート/エクスポート", @@ -128,7 +128,7 @@ "subscriptions_unseen_notifs_count_0": "{{count}} 個の未読通知", "search": "検索", "Log out": "ログアウト", - "Released under the AGPLv3 on Github.": "GitHub 上で AGPLv3 の元で公開されています。", + "Released under the AGPLv3 on Github.": "GitHub 上で AGPLv3 の元で公開", "Source available here.": "ソースはここで閲覧可能です。", "View JavaScript license information.": "JavaScript ライセンス情報", "View privacy policy.": "プライバシーポリシー", @@ -136,24 +136,24 @@ "Public": "公開", "Unlisted": "限定公開", "Private": "非公開", - "View all playlists": "再生リストをすべて見る", + "View all playlists": "すべての再生リストを表示", "Updated `x` ago": "`x`前に更新", "Delete playlist `x`?": "再生リスト `x` を削除しますか?", "Delete playlist": "再生リストを削除", "Create playlist": "再生リストを作成", "Title": "タイトル", - "Playlist privacy": "再生リストのプライバシー", + "Playlist privacy": "再生リストの公開設定", "Editing playlist `x`": "再生リスト `x` を編集中", - "Show more": "表示を増やす", - "Show less": "表示を減らす", + "Show more": "もっと見る", + "Show less": "表示を少なく", "Watch on YouTube": "YouTube で視聴", - "Switch Invidious Instance": "Invidiousインスタンスの変更", + "Switch Invidious Instance": "Invidious インスタンスの変更", "Hide annotations": "アノテーションを隠す", "Show annotations": "アノテーションを表示", "Genre: ": "ジャンル: ", "License: ": "ライセンス: ", "Family friendly? ": "家族向け: ", - "Wilson score: ": "ウィルソンスコア: ", + "Wilson score: ": "ウィルソン得点区間: ", "Engagement: ": "エンゲージメント: ", "Whitelisted regions: ": "ホワイトリストの地域: ", "Blacklisted regions: ": "ブラックリストの地域: ", @@ -181,11 +181,11 @@ "User ID is a required field": "ユーザー ID は必須項目です", "Password is a required field": "パスワードは必須項目です", "Wrong username or password": "ユーザー名またはパスワードが間違っています", - "Please sign in using 'Log in with Google'": "'Google でログイン' を使用してログインしてください", - "Password cannot be empty": "パスワードを空にすることはできません", + "Please sign in using 'Log in with Google'": "「Google でログイン」を使用してログインしてください", + "Password cannot be empty": "パスワードは空にできません", "Password cannot be longer than 55 characters": "パスワードは55文字より長くできません", - "Please log in": "ログインをしてください", - "Invidious Private Feed for `x`": "`x` の Invidious プライベートフィード", + "Please log in": "ログインしてください", + "Invidious Private Feed for `x`": "`x` 個人の Invidious によるフィード", "channel:`x`": "チャンネル:`x`", "Deleted or invalid channel": "削除済みまたは無効なチャンネルです", "This channel does not exist.": "このチャンネルは存在しません。", @@ -194,18 +194,18 @@ "comments_view_x_replies_0": "{{count}} 件の返信を見る", "`x` ago": "`x`前", "Load more": "もっと読み込む", - "comments_points_count_0": "{{count}} ポイント", + "comments_points_count_0": "{{count}}点", "Could not create mix.": "ミックスを作成できませんでした。", "Empty playlist": "空の再生リスト", "Not a playlist.": "再生リストではありません。", "Playlist does not exist.": "再生リストが存在しません。", "Could not pull trending pages.": "急上昇ページを取得できませんでした。", - "Hidden field \"challenge\" is a required field": "非表示項目 \"challenge\" は必須項目です", - "Hidden field \"token\" is a required field": "非表示項目 \"token\" は必須項目です", + "Hidden field \"challenge\" is a required field": "非表示項目 challenge は必須項目です", + "Hidden field \"token\" is a required field": "非表示項目 token は必須項目です", "Erroneous challenge": "チャレンジが間違っています", "Erroneous token": "トークンが間違っています", "No such user": "ユーザーが存在しません", - "Token is expired, please try again": "トークンが期限切れです。再度試してください", + "Token is expired, please try again": "トークンが期限切れです。再度お試しください", "English": "英語", "English (auto-generated)": "英語 (自動生成)", "Afrikaans": "アフリカーンス語", @@ -313,7 +313,7 @@ "Yoruba": "ヨルバ語", "Zulu": "ズール語", "generic_count_years_0": "{{count}}年", - "generic_count_months_0": "{{count}}ヶ月", + "generic_count_months_0": "{{count}}か月", "generic_count_weeks_0": "{{count}}週", "generic_count_days_0": "{{count}}日", "generic_count_hours_0": "{{count}}時間", @@ -338,21 +338,21 @@ "(edited)": "(編集済み)", "YouTube comment permalink": "YouTube コメントのパーマリンク", "permalink": "パーマリンク", - "`x` marked it with a ❤": "`x` が❤を込めてマークしました", - "Audio mode": "オーディオモード", - "Video mode": "ビデオモード", + "`x` marked it with a ❤": "`x` が❤を送りました", + "Audio mode": "音声モード", + "Video mode": "動画モード", "channel_tab_videos_label": "動画", - "Playlists": "プレイリスト", + "Playlists": "再生リスト", "channel_tab_community_label": "コミュニティ", - "search_filters_sort_option_relevance": "関連", + "search_filters_sort_option_relevance": "関連度", "search_filters_sort_option_rating": "評価", - "search_filters_sort_option_date": "時刻", + "search_filters_sort_option_date": "アップロード日", "search_filters_sort_option_views": "再生回数", - "search_filters_type_label": "コンテンツの種類", + "search_filters_type_label": "種類", "search_filters_duration_label": "再生時間", - "search_filters_features_label": "機能", + "search_filters_features_label": "特徴", "search_filters_sort_label": "順番", - "search_filters_date_option_hour": "1時間前", + "search_filters_date_option_hour": "1時間以内", "search_filters_date_option_today": "今日", "search_filters_date_option_week": "今週", "search_filters_date_option_month": "今月", @@ -377,9 +377,9 @@ "search_filters_duration_option_short": "4 分未満", "footer_documentation": "文書", "footer_source_code": "ソースコード", - "footer_original_source_code": "ソースコード(元)", - "footer_modfied_source_code": "ソースコード(編集)", - "adminprefs_modified_source_code_url_label": "編集したソースコードのレポジトリーURL", + "footer_original_source_code": "ソースコード (元)", + "footer_modfied_source_code": "ソースコード (改変)", + "adminprefs_modified_source_code_url_label": "改変されたソースコードのレポジトリのURL", "search_filters_duration_option_long": "20 分以上", "preferences_region_label": "地域: ", "footer_donate_page": "寄付する", @@ -406,10 +406,10 @@ "preferences_quality_option_dash": "DASH (適応品質)", "preferences_quality_dash_option_worst": "最悪", "preferences_quality_dash_option_best": "最高", - "videoinfo_started_streaming_x_ago": "`x`分前に配信を開始", + "videoinfo_started_streaming_x_ago": "`x`前に配信を開始", "videoinfo_watch_on_youTube": "YouTube上で見る", - "user_created_playlists": "`x`が作成したプレイリスト", - "Video unavailable": "ビデオは利用できません", + "user_created_playlists": "`x`個の作成した再生リスト", + "Video unavailable": "動画は利用できません", "Chinese": "中国語", "Chinese (Taiwan)": "中国語 (台湾)", "Korean (auto-generated)": "韓国語 (自動生成)", @@ -434,24 +434,31 @@ "Vietnamese (auto-generated)": "ベトナム語 (自動生成)", "search_filters_title": "フィルタ", "search_filters_features_option_three_sixty": "360°", - "search_message_change_filters_or_query": "別のキーワードを試してみるか、検索フィルタを削除してください", - "search_message_no_results": "一致する検索結果はありませんでした", + "search_message_change_filters_or_query": "別の検索語句を試したり、検索フィルタを変更してください。", + "search_message_no_results": "一致する検索結果はありません。", "English (United States)": "英語 (アメリカ)", "search_filters_date_label": "アップロード日", "search_filters_features_option_vr180": "VR180", - "crash_page_switch_instance": "別のインスタンスを使用しようとしました", + "crash_page_switch_instance": "別のインスタンスを使用を試す", "crash_page_read_the_faq": "よくある質問 (FAQ) を読む", "Popular enabled: ": "人気動画を有効化 ", - "search_message_use_another_instance": " 別のインスタンスで検索することもできます。", + "search_message_use_another_instance": " 別のインスタンス上でも検索できます。", "search_filters_apply_button": "選択したフィルターを適用", - "user_saved_playlists": "`x` 個の保存済みプレイリスト", + "user_saved_playlists": "`x` 個の保存した再生リスト", "crash_page_you_found_a_bug": "Invidious でバグを見つけたようです。", - "crash_page_refresh": "ページを更新しようとしました", - "preferences_watch_history_label": "視聴履歴を有効化 ", - "search_filters_date_option_none": "任意の日付", - "search_filters_type_option_all": "いかなるタイプ", - "search_filters_duration_option_none": "任意の期間", - "search_filters_duration_option_medium": "ミディアム (4 ~ 20 分)", + "crash_page_refresh": "ページを更新を試す", + "preferences_watch_history_label": "再生履歴を有効化 ", + "search_filters_date_option_none": "すべて", + "search_filters_type_option_all": "すべての種類", + "search_filters_duration_option_none": "すべての長さ", + "search_filters_duration_option_medium": "4 ~ 20 分", "preferences_save_player_pos_label": "再生位置を保存: ", - "crash_page_before_reporting": "バグを報告する前に、次のことを確認してください。" + "crash_page_before_reporting": "バグを報告する前に、次のことを確認してください。", + "crash_page_report_issue": "上記が助けにならないなら、GitHub に新しい issue を作成し(英語が好ましい)、メッセージに次のテキストを含めてください(テキストは翻訳しない)。", + "crash_page_search_issue": "GitHub の既存の問題 (issue) を検索", + "channel_tab_streams_label": "ライブ", + "channel_tab_playlists_label": "再生リスト", + "error_video_not_in_playlist": "要求された動画はこの再生リスト内に存在しません。再生リストのホームへ。", + "channel_tab_shorts_label": "ショート", + "channel_tab_channels_label": "チャンネル" } From 20dc0a9e262bb3dd7d2a18314938ea497fd6e776 Mon Sep 17 00:00:00 2001 From: Mateus Date: Wed, 1 Feb 2023 03:37:53 +0000 Subject: [PATCH 065/114] Update Portuguese (Brazil) translation --- locales/pt-BR.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/locales/pt-BR.json b/locales/pt-BR.json index 112ed4b7..afd31ede 100644 --- a/locales/pt-BR.json +++ b/locales/pt-BR.json @@ -472,5 +472,9 @@ "search_filters_duration_option_medium": "Médio (4 - 20 minutos)", "search_filters_features_option_vr180": "VR180", "Popular enabled: ": "Popular habilitado: ", - "error_video_not_in_playlist": "O vídeo solicitado não existe nesta playlist. Clique aqui para acessar a página inicial da playlist." + "error_video_not_in_playlist": "O vídeo solicitado não existe nesta playlist. Clique aqui para acessar a página inicial da playlist.", + "channel_tab_channels_label": "Canais", + "channel_tab_playlists_label": "Listas de reprodução", + "channel_tab_shorts_label": "Curtos", + "channel_tab_streams_label": "Ao Vivo" } From eb7588f1a0989efd95da28a3598ee956c2a989e3 Mon Sep 17 00:00:00 2001 From: Goudarz Jafari Date: Mon, 30 Jan 2023 10:22:38 +0000 Subject: [PATCH 066/114] Update Persian translation --- locales/fa.json | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/locales/fa.json b/locales/fa.json index f2ca2745..fe72a1e8 100644 --- a/locales/fa.json +++ b/locales/fa.json @@ -408,9 +408,9 @@ "preferences_region_label": "کشور محتوا: ", "footer_documentation": "مستندات", "footer_original_source_code": "کد منبع اصلی", - "search_filters_duration_option_long": "بلند (> 20 دقیقه)", + "search_filters_duration_option_long": "بلند (> ۲۰ دقیقه)", "adminprefs_modified_source_code_url_label": "URL مخزن کد منبع ویریش شده", - "search_filters_duration_option_short": "کوتاه (< 4 دقیقه)", + "search_filters_duration_option_short": "کوتاه (< ۴ دقیقه)", "search_filters_title": "پالایه", "Chinese (Hong Kong)": "چینی (هنگ‌کنگ)", "Dutch (auto-generated)": "هلندی (تولید خودکار)", @@ -424,5 +424,26 @@ "search_message_no_results": "نتیجه‌ای یافت نشد.", "search_message_change_filters_or_query": "سعی کنید جست‌و‌جوی خود را وسیع‌تر کنید و/یا فیلترها را تغییر دهید.", "Chinese (China)": "چینی (چین)", - "German (auto-generated)": "آلمانی (تولید خودکار)" + "German (auto-generated)": "آلمانی (تولید خودکار)", + "Japanese (auto-generated)": "ژاپنی (تولید خودکار)", + "Korean (auto-generated)": "کره‌ای (تولید خودکار)", + "Portuguese (Brazil)": "پرتغالی (برزیل)", + "search_filters_apply_button": "اعمال فیلترهای انتخاب شده", + "Italian (auto-generated)": "ایتالیایی (تولید خودکار)", + "Vietnamese (auto-generated)": "ویتنامی (تولید خودکار)", + "search_filters_type_option_all": "هر نوعی", + "search_filters_duration_option_none": "هر مدت زمانی", + "search_filters_date_label": "تاریخ بارگذاری", + "search_filters_date_option_none": "هر تاریخی", + "user_created_playlists": "`x` فهرست پخش ایجاد شد", + "Interlingue": "سرخپوستی", + "Russian (auto-generated)": "روسی (تولید خودکار)", + "Spanish (auto-generated)": "اسپانیایی (تولید خودکار)", + "search_filters_duration_option_medium": "متوسط (۴ تا ۲۰ دقیقه)", + "Portuguese (auto-generated)": "پرتغالی (تولید خودکار)", + "Cantonese (Hong Kong)": "کانتونی (هنگ کنگ)", + "Spanish (Spain)": "اسپانیایی (اسپانیا)", + "Turkish (auto-generated)": "ترکی (تولید خودکار)", + "search_filters_features_option_vr180": "VR180", + "Spanish (Mexico)": "اسپانیایی (مکزیک)" } From 5534cd87f84f685b4ecb40e9102f6f6f9186a0bf Mon Sep 17 00:00:00 2001 From: Damjan Gerl Date: Sun, 29 Jan 2023 16:38:35 +0000 Subject: [PATCH 067/114] Update Slovenian translation --- locales/sl.json | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/locales/sl.json b/locales/sl.json index f27bb20d..9a4a1bde 100644 --- a/locales/sl.json +++ b/locales/sl.json @@ -206,7 +206,7 @@ "generic_count_years_2": "{{count}} leti", "generic_count_years_3": "{{count}} leti", "generic_count_days_0": "{{count}} dnevom", - "generic_count_days_1": "{{count}} dnevi", + "generic_count_days_1": "{{count}} dnevoma", "generic_count_days_2": "{{count}} dnevi", "generic_count_days_3": "{{count}} dnevi", "generic_count_hours_0": "{{count}} uro", @@ -246,10 +246,10 @@ "generic_videos_count_1": "{{count}} videa", "generic_videos_count_2": "{{count}} videi", "generic_videos_count_3": "{{count}} videov", - "generic_views_count_0": "{{count}} ogled", - "generic_views_count_1": "{{count}} ogleda", - "generic_views_count_2": "{{count}} ogledi", - "generic_views_count_3": "{{count}} ogledov", + "generic_views_count_0": "Ogledov: {{count}}", + "generic_views_count_1": "Ogledov: {{count}}", + "generic_views_count_2": "Ogledov: {{count}}", + "generic_views_count_3": "Ogledov: {{count}}", "generic_playlists_count_0": "{{count}} seznam predvajanja", "generic_playlists_count_1": "{{count}} seznama predvajanja", "generic_playlists_count_2": "{{count}} seznami predvajanja", @@ -495,7 +495,7 @@ "footer_modfied_source_code": "Spremenjena izvorna koda", "user_created_playlists": "`x` ustvarjenih seznamov predvajanja", "adminprefs_modified_source_code_url_label": "URL do shrambe spremenjene izvorne kode", - "videoinfo_youTube_embed_link": "Vdelati", + "videoinfo_youTube_embed_link": "Vdelaj", "videoinfo_invidious_embed_link": "Povezava za vdelavo", "crash_page_switch_instance": "poskušal/a uporabiti drugo instanco", "download_subtitles": "Podnapisi - `x` (.vtt)", @@ -504,5 +504,9 @@ "crash_page_search_issue": "preiskal/a obstoječe težave na GitHubu", "crash_page_report_issue": "Če nič od navedenega ni pomagalo, prosim odpri novo težavo v GitHubu (po možnosti v angleščini) in v svoje sporočilo vključi naslednje besedilo (tega besedila NE prevajaj):", "Popular enabled: ": "Priljubljeni omogočeni: ", - "error_video_not_in_playlist": "Zahtevani videoposnetek ne obstaja na tem seznamu predvajanja. Klikni tukaj za domačo stran seznama predvajanja." + "error_video_not_in_playlist": "Zahtevani videoposnetek ne obstaja na tem seznamu predvajanja. Klikni tukaj za domačo stran seznama predvajanja.", + "channel_tab_playlists_label": "Seznami predvajanja", + "channel_tab_shorts_label": "Kratki videoposnetki", + "channel_tab_channels_label": "Kanali", + "channel_tab_streams_label": "Prenosi v živo" } From 7ae9dabe3c5491f476bdbb1f9dadc7294fe1927a Mon Sep 17 00:00:00 2001 From: Matthaiks Date: Thu, 2 Feb 2023 22:31:10 +0000 Subject: [PATCH 068/114] Update Polish translation --- locales/pl.json | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/locales/pl.json b/locales/pl.json index b9c2a638..2dd3ed87 100644 --- a/locales/pl.json +++ b/locales/pl.json @@ -67,7 +67,7 @@ "preferences_annotations_label": "Domyślnie pokazuj adnotacje: ", "preferences_extend_desc_label": "Automatycznie rozwijaj opisy filmów: ", "preferences_vr_mode_label": "Interaktywne filmy 360 stopni (wymaga WebGL): ", - "preferences_category_visual": "Preferencje Wizualne", + "preferences_category_visual": "Preferencje wizualne", "preferences_player_style_label": "Styl odtwarzacza: ", "Dark mode: ": "Ciemny motyw: ", "preferences_dark_mode_label": "Motyw: ", @@ -443,7 +443,7 @@ "user_saved_playlists": "`x` zapisanych playlist", "Video unavailable": "Film niedostępny", "preferences_save_player_pos_label": "Zapisz pozycję odtwarzania: ", - "preferences_region_label": "Region zawartości: ", + "preferences_region_label": "Kraj treści: ", "Released under the AGPLv3 on Github.": "Wydany na licencji AGPLv3 na GitHub.", "search_filters_duration_option_short": "Krótka (< 4 minut)", "search_filters_duration_option_long": "Długa (> 20 minut)", @@ -481,7 +481,7 @@ "search_message_no_results": "Nie znaleziono wyników.", "preferences_watch_history_label": "Włącz historię oglądania: ", "search_filters_apply_button": "Zastosuj wybrane filtry", - "search_message_change_filters_or_query": "Spróbuj poszerzyć zapytanie i/lub zmienić filtry.", + "search_message_change_filters_or_query": "Spróbuj poszerzyć zapytanie wyszukiwania i/lub zmienić filtry.", "search_filters_date_label": "Data przesłania", "search_filters_features_option_vr180": "VR180", "search_filters_date_option_none": "Dowolna data", @@ -492,5 +492,8 @@ "channel_tab_streams_label": "Na żywo", "channel_tab_channels_label": "Kanały", "channel_tab_playlists_label": "Playlisty", - "channel_tab_shorts_label": "Shorts" + "channel_tab_shorts_label": "Shorts", + "Music in this video": "Muzyka w tym filmie", + "Artist: ": "Wykonawca: ", + "Album: ": "Album: " } From 45c99190b2c1ebf7ea47667bd2404eb5031724ab Mon Sep 17 00:00:00 2001 From: Rex_sa Date: Fri, 3 Feb 2023 06:20:45 +0000 Subject: [PATCH 069/114] Update Arabic translation --- locales/ar.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/ar.json b/locales/ar.json index 55dea5f3..181ff933 100644 --- a/locales/ar.json +++ b/locales/ar.json @@ -540,5 +540,8 @@ "channel_tab_shorts_label": "الفيديوهات القصيرة", "channel_tab_streams_label": "البث المباشر", "channel_tab_playlists_label": "قوائم التشغيل", - "channel_tab_channels_label": "القنوات" + "channel_tab_channels_label": "القنوات", + "Music in this video": "الموسيقى في هذا الفيديو", + "Album: ": "الألبوم: ", + "Artist: ": "الفنان: " } From 4ca23f2d51ea29c267cfdaaafc8cc5999aa825d4 Mon Sep 17 00:00:00 2001 From: atilluF Date: Sun, 5 Feb 2023 13:45:52 +0000 Subject: [PATCH 070/114] Update Italian translation --- locales/it.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/it.json b/locales/it.json index f47b032e..c60f760b 100644 --- a/locales/it.json +++ b/locales/it.json @@ -476,5 +476,8 @@ "channel_tab_playlists_label": "Playlist", "channel_tab_channels_label": "Canali", "channel_tab_streams_label": "Livestream", - "channel_tab_community_label": "Comunità" + "channel_tab_community_label": "Comunità", + "Music in this video": "Musica in questo video", + "Artist: ": "Artista: ", + "Album: ": "Album: " } From c82272155ed0e6bca6d3372303a771c5c9f317ad Mon Sep 17 00:00:00 2001 From: Jorge Maldonado Ventura Date: Thu, 2 Feb 2023 21:42:40 +0000 Subject: [PATCH 071/114] Update Spanish translation --- locales/es.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/es.json b/locales/es.json index 59d6b145..6cf721f3 100644 --- a/locales/es.json +++ b/locales/es.json @@ -476,5 +476,8 @@ "channel_tab_streams_label": "Directos", "channel_tab_channels_label": "Canales", "channel_tab_shorts_label": "Cortos", - "channel_tab_playlists_label": "Listas de reproducción" + "channel_tab_playlists_label": "Listas de reproducción", + "Music in this video": "Música en este vídeo", + "Artist: ": "Artista: ", + "Album: ": "Álbum: " } From c1c6f67ad30b5d34bc714a5b4b28934b3bd8cd1f Mon Sep 17 00:00:00 2001 From: Jorge Maldonado Ventura Date: Thu, 2 Feb 2023 21:44:13 +0000 Subject: [PATCH 072/114] Update Esperanto translation --- locales/eo.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/eo.json b/locales/eo.json index 56e718f2..9f37c7cb 100644 --- a/locales/eo.json +++ b/locales/eo.json @@ -476,5 +476,8 @@ "channel_tab_streams_label": "Tujelsendoj", "channel_tab_playlists_label": "Ludlistoj", "channel_tab_channels_label": "Kanaloj", - "channel_tab_shorts_label": "Mallongaj" + "channel_tab_shorts_label": "Mallongaj", + "Music in this video": "Muziko en ĉi tiu video", + "Artist: ": "Artisto: ", + "Album: ": "Albumo: " } From 054686e557b8c1b1aa708c04b5c20552eb0c7b40 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Fri, 3 Feb 2023 17:12:10 +0000 Subject: [PATCH 073/114] Update Ukrainian translation --- locales/uk.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/uk.json b/locales/uk.json index ae2fb5bd..b44d237f 100644 --- a/locales/uk.json +++ b/locales/uk.json @@ -492,5 +492,8 @@ "channel_tab_shorts_label": "Shorts", "channel_tab_streams_label": "Прямі трансляції", "channel_tab_playlists_label": "Добірки", - "channel_tab_channels_label": "Канали" + "channel_tab_channels_label": "Канали", + "Music in this video": "Музика в цьому відео", + "Artist: ": "Виконавець: ", + "Album: ": "Альбом: " } From db6d3d2191b5f499ff56b54e7e29d198c159b6d6 Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 3 Feb 2023 09:46:16 +0000 Subject: [PATCH 074/114] Update Chinese (Simplified) translation --- locales/zh-CN.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/locales/zh-CN.json b/locales/zh-CN.json index 385f16bd..aff6dd3e 100644 --- a/locales/zh-CN.json +++ b/locales/zh-CN.json @@ -456,5 +456,12 @@ "search_filters_type_option_all": "任意类型", "search_filters_features_option_vr180": "VR180", "Popular enabled: ": "已启用流行度: ", - "error_video_not_in_playlist": "此播放列表中不存在请求的视频。 单击析出查看播放列表主页。" + "error_video_not_in_playlist": "此播放列表中不存在请求的视频。 单击析出查看播放列表主页。", + "Music in this video": "此视频中的音乐", + "channel_tab_playlists_label": "播放列表", + "Artist: ": "艺术家: ", + "channel_tab_streams_label": "直播", + "Album: ": "专辑: ", + "channel_tab_shorts_label": "短视频", + "channel_tab_channels_label": "频道" } From 591f816781cfbf31f761ef6ccf59a1769c002041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Fri, 3 Feb 2023 04:25:29 +0000 Subject: [PATCH 075/114] Update Turkish translation --- locales/tr.json | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/locales/tr.json b/locales/tr.json index 76cce15a..d98e2038 100644 --- a/locales/tr.json +++ b/locales/tr.json @@ -397,8 +397,8 @@ "videoinfo_watch_on_youTube": "YouTube'da İzle", "download_subtitles": "Alt Yazılar - `x` (.vtt)", "preferences_save_player_pos_label": "Oynatma Konumunu Kaydet: ", - "generic_views_count": "{{count}} Görüntüleme", - "generic_views_count_plural": "{{count}} Görüntüleme", + "generic_views_count": "{{count}} Görüntülenme", + "generic_views_count_plural": "{{count}} Görüntülenme", "generic_subscribers_count": "{{count}} Abone", "generic_subscribers_count_plural": "{{count}} Abone", "generic_subscriptions_count": "{{count}} Abonelik", @@ -476,5 +476,8 @@ "channel_tab_channels_label": "Kanallar", "channel_tab_shorts_label": "Kısa Çekimler", "channel_tab_streams_label": "Canlı Yayınlar", - "channel_tab_playlists_label": "Oynatma Listeleri" + "channel_tab_playlists_label": "Oynatma Listeleri", + "Album: ": "Albüm: ", + "Music in this video": "Bu videodaki müzik", + "Artist: ": "Sanatçı: " } From fc5092c3992eba953903d5bf9bd206fc50e0be6b Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Fri, 3 Feb 2023 02:09:55 +0000 Subject: [PATCH 076/114] Update Chinese (Traditional) translation --- locales/zh-TW.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/zh-TW.json b/locales/zh-TW.json index 3b51721d..8aa9869a 100644 --- a/locales/zh-TW.json +++ b/locales/zh-TW.json @@ -460,5 +460,8 @@ "channel_tab_shorts_label": "短片", "channel_tab_playlists_label": "播放清單", "channel_tab_channels_label": "頻道", - "channel_tab_streams_label": "直播" + "channel_tab_streams_label": "直播", + "Artist: ": "藝術家: ", + "Album: ": "專輯: ", + "Music in this video": "此影片中的音樂" } From 58688a6311205ee7503277d802d9e63eb90f2016 Mon Sep 17 00:00:00 2001 From: maboroshin Date: Sat, 4 Feb 2023 15:10:38 +0000 Subject: [PATCH 077/114] Update Japanese translation --- locales/ja.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/ja.json b/locales/ja.json index 9df1477b..3ad4b494 100644 --- a/locales/ja.json +++ b/locales/ja.json @@ -460,5 +460,8 @@ "channel_tab_playlists_label": "再生リスト", "error_video_not_in_playlist": "要求された動画はこの再生リスト内に存在しません。再生リストのホームへ。", "channel_tab_shorts_label": "ショート", - "channel_tab_channels_label": "チャンネル" + "channel_tab_channels_label": "チャンネル", + "Music in this video": "この動画の音楽", + "Artist: ": "アーティスト: ", + "Album: ": "アルバム: " } From 256b518469d1c3aa2c73aa5552ffa404d58232c5 Mon Sep 17 00:00:00 2001 From: Milo Ivir Date: Sun, 5 Feb 2023 20:05:22 +0000 Subject: [PATCH 078/114] Update Croatian translation --- locales/hr.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/hr.json b/locales/hr.json index 7914ab16..72cd6a8e 100644 --- a/locales/hr.json +++ b/locales/hr.json @@ -492,5 +492,8 @@ "channel_tab_streams_label": "Prijenosi uživo", "channel_tab_playlists_label": "Zbirke", "channel_tab_channels_label": "Kanali", - "channel_tab_shorts_label": "Kratka videa" + "channel_tab_shorts_label": "Kratka videa", + "Music in this video": "Glazba u ovom videu", + "Album: ": "Album: ", + "Artist: ": "Izvođač: " } From f2390ed052e018c6b11fdb1f9b356891022bb822 Mon Sep 17 00:00:00 2001 From: Fjuro Date: Fri, 3 Feb 2023 15:39:21 +0000 Subject: [PATCH 079/114] Update Czech translation --- locales/cs.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/cs.json b/locales/cs.json index 7502de0b..51db1550 100644 --- a/locales/cs.json +++ b/locales/cs.json @@ -492,5 +492,8 @@ "channel_tab_shorts_label": "Shorts", "channel_tab_playlists_label": "Playlisty", "channel_tab_channels_label": "Kanály", - "channel_tab_streams_label": "Živé přenosy" + "channel_tab_streams_label": "Živé přenosy", + "Music in this video": "Hudba v tomto videu", + "Artist: ": "Umělec: ", + "Album: ": "Album: " } From 299eb9207bd3dcfc35690ae876aa740d131b7b64 Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Fri, 3 Feb 2023 13:10:19 +0000 Subject: [PATCH 080/114] Update Albanian translation --- locales/sq.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/locales/sq.json b/locales/sq.json index b8651316..15025750 100644 --- a/locales/sq.json +++ b/locales/sq.json @@ -463,5 +463,10 @@ "search_filters_duration_option_none": "Çfarëdo kohëzgjatjeje", "search_filters_duration_option_medium": "Mesatare (4 - 20 minuta)", "search_filters_features_option_vr180": "VR180", - "search_filters_apply_button": "Apliko filtrat e përzgjedhur" + "search_filters_apply_button": "Apliko filtrat e përzgjedhur", + "channel_tab_playlists_label": "Luajlista", + "Artist: ": "Artist: ", + "Album: ": "Album: ", + "channel_tab_channels_label": "Kanale", + "Music in this video": "Muzikë në këtë video" } From c5d134451140157939043d7be8aa70fad87488f8 Mon Sep 17 00:00:00 2001 From: Damjan Gerl Date: Fri, 3 Feb 2023 09:11:13 +0000 Subject: [PATCH 081/114] Update Slovenian translation --- locales/sl.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/sl.json b/locales/sl.json index 9a4a1bde..47f295e0 100644 --- a/locales/sl.json +++ b/locales/sl.json @@ -508,5 +508,8 @@ "channel_tab_playlists_label": "Seznami predvajanja", "channel_tab_shorts_label": "Kratki videoposnetki", "channel_tab_channels_label": "Kanali", - "channel_tab_streams_label": "Prenosi v živo" + "channel_tab_streams_label": "Prenosi v živo", + "Artist: ": "Umetnik/ca: ", + "Music in this video": "Glasba v tem videoposnetku", + "Album: ": "Album: " } From cb7c4a82200bc5098ed35bd736e54a35b837edc3 Mon Sep 17 00:00:00 2001 From: "Marsel J. Jonker" Date: Thu, 9 Feb 2023 01:41:14 +0100 Subject: [PATCH 082/114] Add Afrikaans translation --- locales/af.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 locales/af.json diff --git a/locales/af.json b/locales/af.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/locales/af.json @@ -0,0 +1 @@ +{} From e4d14481c5f738f86fb45275a341e2c8264cda51 Mon Sep 17 00:00:00 2001 From: SC Date: Thu, 9 Feb 2023 19:42:49 +0000 Subject: [PATCH 083/114] Update Portuguese translation --- locales/pt.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/pt.json b/locales/pt.json index 79a39ab6..b6b6c110 100644 --- a/locales/pt.json +++ b/locales/pt.json @@ -476,5 +476,8 @@ "channel_tab_playlists_label": "Listas de reprodução", "channel_tab_channels_label": "Canais", "channel_tab_shorts_label": "Curtos", - "channel_tab_streams_label": "Diretos" + "channel_tab_streams_label": "Diretos", + "Music in this video": "Música neste vídeo", + "Artist: ": "Artista: ", + "Album: ": "Álbum: " } From 9c400fd455e3282ef3444a8f28ec7943f5d37a7a Mon Sep 17 00:00:00 2001 From: AHOHNMYC Date: Sat, 11 Feb 2023 15:48:41 +0000 Subject: [PATCH 084/114] Update Russian translation --- locales/ru.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/ru.json b/locales/ru.json index 85628d0f..733e0be1 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -492,5 +492,8 @@ "channel_tab_playlists_label": "Плейлисты", "channel_tab_channels_label": "Каналы", "channel_tab_streams_label": "Живое вещание", - "channel_tab_shorts_label": "Shorts" + "channel_tab_shorts_label": "Shorts", + "Music in this video": "Музыка в этом видео", + "Artist: ": "Исполнитель: ", + "Album: ": "Альбом: " } From a95f82e44bfc77ac8fc1b7acd2159d185a4fa637 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Fri, 17 Feb 2023 12:08:05 -0500 Subject: [PATCH 085/114] Add Playlet to "Projects using Invidious" (#3640) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8d668a29..0744ac50 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,7 @@ Weblate also allows you to log-in with major SSO providers like Github, Gitlab, - [Yattee](https://github.com/yattee/yattee): Alternative YouTube frontend for iPhone, iPad, Mac and Apple TV. - [TubiTui](https://codeberg.org/777/TubiTui): A lightweight, libre, TUI-based YouTube client. - [Ytfzf](https://github.com/pystardust/ytfzf): A posix script to find and watch youtube videos from the terminal. (Without API) +- [Playlet](https://github.com/iBicha/playlet): Unofficial Youtube client for Roku TV ## Liability From b287ddc52acf43c3d3a5fc11e42a8b1b8d66e800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milien=20Devos=20=28perso=29?= Date: Sun, 19 Feb 2023 20:20:47 +0100 Subject: [PATCH 086/114] Allow to set a label for exempting from staling (#3651) --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 11168aea..a945da58 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -23,4 +23,4 @@ jobs: stale-pr-label: "stale" ascending: true # Never mark feature requests/enhancements as stale - exempt-issue-labels: "feature-request,enhancement" + exempt-issue-labels: "feature-request,enhancement,exempt-stale" From bde21d527f1fae4a84b964f1b297d7b246526ba0 Mon Sep 17 00:00:00 2001 From: Wes van der Vleuten <16665772+WesVleuten@users.noreply.github.com> Date: Sun, 19 Feb 2023 20:41:18 +0100 Subject: [PATCH 087/114] Fixed console error --- assets/js/watched_indicator.js | 24 +++++++++++++++++++++ assets/js/watched_widget.js | 24 --------------------- src/invidious/views/add_playlist_items.ecr | 2 +- src/invidious/views/channel.ecr | 2 +- src/invidious/views/edit_playlist.ecr | 2 +- src/invidious/views/feeds/playlists.ecr | 2 +- src/invidious/views/feeds/popular.ecr | 2 +- src/invidious/views/feeds/subscriptions.ecr | 3 ++- src/invidious/views/feeds/trending.ecr | 2 +- src/invidious/views/hashtag.ecr | 2 +- src/invidious/views/playlist.ecr | 2 +- src/invidious/views/search.ecr | 2 +- 12 files changed, 35 insertions(+), 34 deletions(-) create mode 100644 assets/js/watched_indicator.js diff --git a/assets/js/watched_indicator.js b/assets/js/watched_indicator.js new file mode 100644 index 00000000..e971cd80 --- /dev/null +++ b/assets/js/watched_indicator.js @@ -0,0 +1,24 @@ +'use strict'; +var save_player_pos_key = 'save_player_pos'; + +function get_all_video_times() { + return helpers.storage.get(save_player_pos_key) || {}; +} + +document.querySelectorAll('.watched-indicator').forEach(function (indicator) { + var watched_part = get_all_video_times()[indicator.dataset.id]; + var total = parseInt(indicator.dataset.length, 10); + if (watched_part === undefined) { + watched_part = total; + } + var percentage = Math.round((watched_part / total) * 100); + + if (percentage < 5) { + percentage = 5; + } + if (percentage > 90) { + percentage = 100; + } + + indicator.style.width = percentage + '%'; +}); diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js index 02537111..f1ac9cb4 100644 --- a/assets/js/watched_widget.js +++ b/assets/js/watched_widget.js @@ -32,27 +32,3 @@ function mark_unwatched(target) { } }); } - -var save_player_pos_key = 'save_player_pos'; - -function get_all_video_times() { - return helpers.storage.get(save_player_pos_key) || {}; -} - -document.querySelectorAll('.watched-indicator').forEach(function (indicator) { - var watched_part = get_all_video_times()[indicator.dataset.id]; - var total = parseInt(indicator.dataset.length, 10); - if (watched_part === undefined) { - watched_part = total; - } - var percentage = Math.round((watched_part / total) * 100); - - if (percentage < 5) { - percentage = 5; - } - if (percentage > 90) { - percentage = 100; - } - - indicator.style.width = percentage + '%'; -}); diff --git a/src/invidious/views/add_playlist_items.ecr b/src/invidious/views/add_playlist_items.ecr index 70575de3..bcba74cf 100644 --- a/src/invidious/views/add_playlist_items.ecr +++ b/src/invidious/views/add_playlist_items.ecr @@ -39,7 +39,7 @@ <% end %>
- + <% if query %> <%- query_encoded = URI.encode_www_form(query.text, space_to_plus: true) -%> diff --git a/src/invidious/views/channel.ecr b/src/invidious/views/channel.ecr index 931dd407..6e62a471 100644 --- a/src/invidious/views/channel.ecr +++ b/src/invidious/views/channel.ecr @@ -49,7 +49,7 @@ <% end %>
- +
diff --git a/src/invidious/views/edit_playlist.ecr b/src/invidious/views/edit_playlist.ecr index 100764c7..548104c8 100644 --- a/src/invidious/views/edit_playlist.ecr +++ b/src/invidious/views/edit_playlist.ecr @@ -62,7 +62,7 @@ <% end %>
- +
diff --git a/src/invidious/views/feeds/playlists.ecr b/src/invidious/views/feeds/playlists.ecr index f9064762..e52a7707 100644 --- a/src/invidious/views/feeds/playlists.ecr +++ b/src/invidious/views/feeds/playlists.ecr @@ -33,4 +33,4 @@ <% end %>
- + diff --git a/src/invidious/views/feeds/popular.ecr b/src/invidious/views/feeds/popular.ecr index 919002cd..5fbe539c 100644 --- a/src/invidious/views/feeds/popular.ecr +++ b/src/invidious/views/feeds/popular.ecr @@ -17,4 +17,4 @@ <% end %>
- + diff --git a/src/invidious/views/feeds/subscriptions.ecr b/src/invidious/views/feeds/subscriptions.ecr index d4e93240..9c69c5b0 100644 --- a/src/invidious/views/feeds/subscriptions.ecr +++ b/src/invidious/views/feeds/subscriptions.ecr @@ -54,6 +54,7 @@ }.to_pretty_json %> +
<% videos.each do |item| %> @@ -61,7 +62,7 @@ <% end %>
- +
diff --git a/src/invidious/views/feeds/trending.ecr b/src/invidious/views/feeds/trending.ecr index 76218165..7dc416c6 100644 --- a/src/invidious/views/feeds/trending.ecr +++ b/src/invidious/views/feeds/trending.ecr @@ -46,4 +46,4 @@ <% end %>
- + diff --git a/src/invidious/views/hashtag.ecr b/src/invidious/views/hashtag.ecr index 6064af74..3351c21c 100644 --- a/src/invidious/views/hashtag.ecr +++ b/src/invidious/views/hashtag.ecr @@ -24,7 +24,7 @@ <%- end -%>
- +
diff --git a/src/invidious/views/playlist.ecr b/src/invidious/views/playlist.ecr index 1df047ba..a04acf4c 100644 --- a/src/invidious/views/playlist.ecr +++ b/src/invidious/views/playlist.ecr @@ -106,7 +106,7 @@ <% end %>
- +
diff --git a/src/invidious/views/search.ecr b/src/invidious/views/search.ecr index c4960d08..a7469e36 100644 --- a/src/invidious/views/search.ecr +++ b/src/invidious/views/search.ecr @@ -37,7 +37,7 @@
<%- end -%> - +
From 8046316f200801e2e8c34ce2d43da6a16fb86fe8 Mon Sep 17 00:00:00 2001 From: Raman Date: Tue, 14 Feb 2023 07:26:13 +0000 Subject: [PATCH 088/114] Update Hindi translation --- locales/hi.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/hi.json b/locales/hi.json index e576080f..54e0fe84 100644 --- a/locales/hi.json +++ b/locales/hi.json @@ -470,5 +470,7 @@ "crash_page_switch_instance": "किसी दूसरे उदाहरण का इस्तेमाल करें", "crash_page_read_the_faq": "अक्सर पूछे जाने वाले प्रश्न (FAQ) पढ़ें", "crash_page_refresh": "पृष्ठ को एक बार साफ़ करें", - "crash_page_search_issue": "GitHub पर मौजूदा मुद्दे ढूँढ़ें" + "crash_page_search_issue": "GitHub पर मौजूदा मुद्दे ढूँढ़ें", + "Popular enabled: ": "लोकप्रिय सक्षम: ", + "Artist: ": "कलाकार: " } From 64780ce1da79ce5ea7f1619b46cb9e7137c4cc97 Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 17 Feb 2023 20:47:00 +0000 Subject: [PATCH 089/114] Update Russian translation --- locales/ru.json | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/locales/ru.json b/locales/ru.json index 733e0be1..7ca5cf1f 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -69,11 +69,11 @@ "preferences_vr_mode_label": "Интерактивные 360-градусные видео (необходим WebGL): ", "preferences_category_visual": "Настройки сайта", "preferences_player_style_label": "Стиль проигрывателя: ", - "Dark mode: ": "Тёмное оформление: ", + "Dark mode: ": "Темное оформление: ", "preferences_dark_mode_label": "Тема: ", - "dark": "тёмная", + "dark": "темная", "light": "светлая", - "preferences_thin_mode_label": "Облегчённое оформление: ", + "preferences_thin_mode_label": "Облегченное оформление: ", "preferences_category_misc": "Прочие настройки", "preferences_automatic_instance_redirect_label": "Автоматическая смена зеркала (переход на redirect.invidious.io): ", "preferences_category_subscription": "Настройки подписок", @@ -88,7 +88,7 @@ "channel name": "по названию канала", "channel name - reverse": "по названию канала в обратном порядке", "Only show latest video from channel: ": "Показывать только последние видео с каналов: ", - "Only show latest unwatched video from channel: ": "Показывать только непросмотренные видео с каналов: ", + "Only show latest unwatched video from channel: ": "Показывать только последние непросмотренные видео с канала: ", "preferences_unseen_only_label": "Показывать только непросмотренные видео: ", "preferences_notifications_only_label": "Показывать только оповещения, если они есть: ", "Enable web notifications": "Включить уведомления в браузере", @@ -147,13 +147,13 @@ "License: ": "Лицензия: ", "Family friendly? ": "Семейный просмотр: ", "Wilson score: ": "Оценка Уилсона: ", - "Engagement: ": "Вовлечённость: ", + "Engagement: ": "Вовлеченность: ", "Whitelisted regions: ": "Доступно в регионах: ", "Blacklisted regions: ": "Недоступно в регионах: ", "Shared `x`": "Опубликовано `x`", "Premieres in `x`": "Премьера через `x`", "Premieres `x`": "Премьера `x`", - "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Похоже, у вас отключён JavaScript. Нажмите сюда, чтобы увидеть комментарии. Но учтите: они могут загружаться немного медленнее.", + "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Похоже, у вас отключен JavaScript. Нажмите сюда, чтобы увидеть комментарии. Но учтите: они могут загружаться немного медленнее.", "View YouTube comments": "Показать комментарии с YouTube", "View more comments on Reddit": "Посмотреть больше комментариев на Reddit", "View `x` comments": { @@ -180,23 +180,23 @@ "Please log in": "Пожалуйста, войдите", "Invidious Private Feed for `x`": "Приватная лента Invidious для `x`", "channel:`x`": "канал: `x`", - "Deleted or invalid channel": "Канал удалён или не найден", + "Deleted or invalid channel": "Канал удален или не найден", "This channel does not exist.": "Такого канала не существует.", - "Could not get channel info.": "Не удаётся получить информацию об этом канале.", - "Could not fetch comments": "Не удаётся загрузить комментарии", + "Could not get channel info.": "Не удается получить информацию об этом канале.", + "Could not fetch comments": "Не удается загрузить комментарии", "`x` ago": "`x` назад", - "Load more": "Загрузить ещё", + "Load more": "Загрузить еще", "Could not create mix.": "Не удалось создать микс.", "Empty playlist": "Плейлист пуст", - "Not a playlist.": "Некорректный плейлист.", + "Not a playlist.": "Это не плейлист.", "Playlist does not exist.": "Плейлист не существует.", - "Could not pull trending pages.": "Не удаётся загрузить страницы «в тренде».", + "Could not pull trending pages.": "Не удается загрузить страницы «в тренде».", "Hidden field \"challenge\" is a required field": "Необходимо заполнить скрытое поле «challenge»", "Hidden field \"token\" is a required field": "Необходимо заполнить скрытое поле «токен»", "Erroneous challenge": "Неправильный ответ в «challenge»", "Erroneous token": "Неправильный токен", "No such user": "Пользователь не найден", - "Token is expired, please try again": "Срок действия токена истёк, попробуйте позже", + "Token is expired, please try again": "Срок действия токена истек, попробуйте позже", "English": "Английский", "English (auto-generated)": "Английский (созданы автоматически)", "Afrikaans": "Африкаанс", @@ -453,8 +453,8 @@ "Portuguese (Brazil)": "Португальский (Бразилия)", "footer_source_code": "Исходный код", "footer_original_source_code": "Оригинальный исходный код", - "footer_modfied_source_code": "Изменённый исходный код", - "user_saved_playlists": "`x` сохранённых плейлистов", + "footer_modfied_source_code": "Измененный исходный код", + "user_saved_playlists": "`x` сохраненных плейлистов", "crash_page_search_issue": "поискали похожую проблему на GitHub", "comments_points_count_0": "{{count}} плюс", "comments_points_count_1": "{{count}} плюса", From 7b124eec640ca601d2cafc366867e1d6cd283577 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Mon, 20 Feb 2023 16:27:16 -0500 Subject: [PATCH 090/114] Add History API --- src/invidious/routes/api/v1/authenticated.cr | 50 ++++++++++++++++++++ src/invidious/routing.cr | 5 ++ 2 files changed, 55 insertions(+) diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr index 6b935312..e670a87c 100644 --- a/src/invidious/routes/api/v1/authenticated.cr +++ b/src/invidious/routes/api/v1/authenticated.cr @@ -54,6 +54,56 @@ module Invidious::Routes::API::V1::Authenticated env.response.status_code = 204 end + def self.get_history(env) + env.response.content_type = "application/json" + user = env.get("user").as(User) + + page = env.params.query["page"]?.try &.to_i? + page ||= 1 + + 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 + + return watched.to_json + end + + def self.mark_watched(env) + user = env.get("user").as(User) + + id = env.params.url["id"]?.try &.as(String) + if !id + return error_json(400, "Invalid video id.") + end + + Invidious::Database::Users.mark_watched(user, id) + env.response.status_code = 204 + end + + def self.mark_unwatched(env) + user = env.get("user").as(User) + + id = env.params.url["id"]?.try &.as(String) + if !id + return error_json(400, "Invalid video id.") + end + + Invidious::Database::Users.mark_unwatched(user, id) + env.response.status_code = 204 + end + + def self.clear_history(env) + user = env.get("user").as(User) + + Invidious::Database::Users.clear_watch_history(user) + env.response.status_code = 204 + end + def self.feed(env) env.response.content_type = "application/json" diff --git a/src/invidious/routing.cr b/src/invidious/routing.cr index dca2f117..9e2ade3d 100644 --- a/src/invidious/routing.cr +++ b/src/invidious/routing.cr @@ -257,6 +257,11 @@ module Invidious::Routing get "/api/v1/auth/export/invidious", {{namespace}}::Authenticated, :export_invidious post "/api/v1/auth/import/invidious", {{namespace}}::Authenticated, :import_invidious + get "/api/v1/auth/history", {{namespace}}::Authenticated, :get_history + post "/api/v1/auth/history/:id", {{namespace}}::Authenticated, :mark_watched + delete "/api/v1/auth/history/:id", {{namespace}}::Authenticated, :mark_unwatched + delete "/api/v1/auth/history", {{namespace}}::Authenticated, :clear_history + get "/api/v1/auth/feed", {{namespace}}::Authenticated, :feed get "/api/v1/auth/subscriptions", {{namespace}}::Authenticated, :get_subscriptions From 15e9510ab212ac1f8b6bc2a5a3e83ebc4ba1fe90 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Mon, 20 Feb 2023 16:43:36 -0500 Subject: [PATCH 091/114] Check preferences before marking video as watched --- src/invidious/routes/api/v1/authenticated.cr | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr index e670a87c..dc86bb3c 100644 --- a/src/invidious/routes/api/v1/authenticated.cr +++ b/src/invidious/routes/api/v1/authenticated.cr @@ -76,6 +76,10 @@ module Invidious::Routes::API::V1::Authenticated def self.mark_watched(env) user = env.get("user").as(User) + if !user.preferences.watch_history + return error_json(409, "Watch history is disabled in preferences.") + end + id = env.params.url["id"]?.try &.as(String) if !id return error_json(400, "Invalid video id.") From 6ee51f460a27618d5926e9caf230a7ada2823e70 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Tue, 21 Feb 2023 15:24:25 -0500 Subject: [PATCH 092/114] encode username on callback --- src/invidious/routes/account.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/routes/account.cr b/src/invidious/routes/account.cr index d01aee56..284d5b06 100644 --- a/src/invidious/routes/account.cr +++ b/src/invidious/routes/account.cr @@ -262,7 +262,7 @@ module Invidious::Routes::Account end query["token"] = access_token - query["username"] = user.email + query["username"] = URI.encode_path_segment(user.email) url.query = query.to_s env.redirect url.to_s From 57e4312d9fabf4dc284426c74db952c3609f9987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Marcelo=20Alvarenga?= Date: Mon, 20 Feb 2023 22:56:13 +0000 Subject: [PATCH 093/114] Update Portuguese (Brazil) translation --- locales/pt-BR.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/pt-BR.json b/locales/pt-BR.json index afd31ede..079c4ea1 100644 --- a/locales/pt-BR.json +++ b/locales/pt-BR.json @@ -476,5 +476,8 @@ "channel_tab_channels_label": "Canais", "channel_tab_playlists_label": "Listas de reprodução", "channel_tab_shorts_label": "Curtos", - "channel_tab_streams_label": "Ao Vivo" + "channel_tab_streams_label": "Ao Vivo", + "Music in this video": "Música neste vídeo", + "Artist: ": "Artista: ", + "Album: ": "Álbum: " } From 596a16c085c6e3afd998273ab3c9bff3c109e07c Mon Sep 17 00:00:00 2001 From: ssantos Date: Mon, 20 Feb 2023 14:05:29 +0000 Subject: [PATCH 094/114] Update Portuguese (Portugal) translation --- locales/pt-PT.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/locales/pt-PT.json b/locales/pt-PT.json index 1788deb1..43834d70 100644 --- a/locales/pt-PT.json +++ b/locales/pt-PT.json @@ -472,5 +472,12 @@ "search_message_change_filters_or_query": "Tente alargar os termos genéricos da pesquisa e/ou alterar os filtros.", "crash_page_refresh": "tentou recarregar a página", "crash_page_switch_instance": "tentou usar outra instância", - "error_video_not_in_playlist": "O vídeo pedido não existe nesta lista de reprodução. Clique aqui para a página inicial da lista de reprodução." + "error_video_not_in_playlist": "O vídeo pedido não existe nesta lista de reprodução. Clique aqui para a página inicial da lista de reprodução.", + "Artist: ": "Artista: ", + "Album: ": "Álbum: ", + "channel_tab_streams_label": "Diretos", + "channel_tab_playlists_label": "Listas de reprodução", + "channel_tab_channels_label": "Canais", + "Music in this video": "Música neste vídeo", + "channel_tab_shorts_label": "Curtos" } From 7e0210d090b0b6141832944bba19ca9fe1170817 Mon Sep 17 00:00:00 2001 From: Saurmandal Date: Mon, 20 Feb 2023 15:39:25 +0000 Subject: [PATCH 095/114] Update Hindi translation --- locales/hi.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/locales/hi.json b/locales/hi.json index 54e0fe84..41335266 100644 --- a/locales/hi.json +++ b/locales/hi.json @@ -472,5 +472,12 @@ "crash_page_refresh": "पृष्ठ को एक बार साफ़ करें", "crash_page_search_issue": "GitHub पर मौजूदा मुद्दे ढूँढ़ें", "Popular enabled: ": "लोकप्रिय सक्षम: ", - "Artist: ": "कलाकार: " + "Artist: ": "कलाकार: ", + "Music in this video": "इस वीडियो में संगीत", + "Album: ": "एल्बम: ", + "error_video_not_in_playlist": "अनुरोधित वीडियो इस प्लेलिस्ट में मौजूद नहीं है। प्लेलिस्ट के मुखपृष्ठ पर जाने के लिए यहाँ क्लिक करें।", + "channel_tab_shorts_label": "शॉर्ट्स", + "channel_tab_streams_label": "लाइवस्ट्रीम्स", + "channel_tab_playlists_label": "प्लेलिस्ट्स", + "channel_tab_channels_label": "चैनल्स" } From 3ddcfea8faea4d6a6e4db9c52b2c54eb07625d75 Mon Sep 17 00:00:00 2001 From: Ashirg-ch Date: Thu, 23 Feb 2023 15:25:03 +0000 Subject: [PATCH 096/114] Update English (United States) translation --- locales/en-US.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/en-US.json b/locales/en-US.json index a5c16fd7..86b83a23 100644 --- a/locales/en-US.json +++ b/locales/en-US.json @@ -454,7 +454,7 @@ "footer_documentation": "Documentation", "footer_source_code": "Source code", "footer_original_source_code": "Original source code", - "footer_modfied_source_code": "Modified Source code", + "footer_modfied_source_code": "Modified source code", "adminprefs_modified_source_code_url_label": "URL to modified source code repository", "none": "none", "videoinfo_started_streaming_x_ago": "Started streaming `x` ago", From 23f1f8bde3ae838c26871eae16b1b3fbf37e11de Mon Sep 17 00:00:00 2001 From: Ashirg-ch Date: Thu, 23 Feb 2023 15:17:43 +0000 Subject: [PATCH 097/114] Update German translation --- locales/de.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/locales/de.json b/locales/de.json index 55c40905..c2941d6d 100644 --- a/locales/de.json +++ b/locales/de.json @@ -472,5 +472,12 @@ "search_filters_duration_option_none": "Beliebige Länge", "search_filters_date_label": "Upload-Datum", "search_filters_date_option_none": "Beliebiges Datum", - "error_video_not_in_playlist": "Das angeforderte Video existiert nicht in dieser Wiedergabeliste. Klicken Sie hier, um zur Startseite der Wiedergabeliste zu gelangen." + "error_video_not_in_playlist": "Das angeforderte Video existiert nicht in dieser Wiedergabeliste. Klicken Sie hier, um zur Startseite der Wiedergabeliste zu gelangen.", + "channel_tab_shorts_label": "Shorts", + "channel_tab_streams_label": "Livestreams", + "Music in this video": "Musik in diesem Video", + "Artist: ": "Künstler: ", + "Album: ": "Album: ", + "channel_tab_playlists_label": "Wiedergabelisten", + "channel_tab_channels_label": "Kanäle" } From eb3af9d4f101a5b99d26fe81b28d1789de3b4d7c Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Thu, 23 Feb 2023 17:29:11 +0000 Subject: [PATCH 098/114] Update Spanish translation --- locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/es.json b/locales/es.json index 6cf721f3..fec3a667 100644 --- a/locales/es.json +++ b/locales/es.json @@ -364,7 +364,7 @@ "footer_original_source_code": "Código fuente original", "adminprefs_modified_source_code_url_label": "URL al repositorio de código fuente modificado", "footer_source_code": "Código fuente", - "footer_modfied_source_code": "Código fuente modificado", + "footer_modfied_source_code": "Modificación del código fuente", "footer_donate_page": "Donar", "preferences_region_label": "País del contenido: ", "preferences_quality_dash_label": "Calidad de vídeo DASH preferida: ", From 0efb56238f9e75ca2d083cbd5c5701333b0bcd92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Sun, 26 Feb 2023 18:53:33 +0000 Subject: [PATCH 099/114] Update Turkish translation --- locales/tr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/tr.json b/locales/tr.json index d98e2038..b7cb3958 100644 --- a/locales/tr.json +++ b/locales/tr.json @@ -363,7 +363,7 @@ "footer_documentation": "Belgelendirme", "footer_source_code": "Kaynak Kodları", "footer_original_source_code": "Orijinal Kaynak Kodları", - "footer_modfied_source_code": "Değiştirilmiş Kaynak Kodları", + "footer_modfied_source_code": "Değiştirilmiş kaynak kodları", "adminprefs_modified_source_code_url_label": "Değiştirilmiş Kaynak Kodları Deposunun URL'si", "footer_donate_page": "Bağış Yap", "preferences_region_label": "İçerik Ülkesi: ", From 24ac873532bb562398d64afbd9e8f6cf943d283c Mon Sep 17 00:00:00 2001 From: maboroshin Date: Fri, 24 Feb 2023 05:24:09 +0000 Subject: [PATCH 100/114] Update Japanese translation --- locales/ja.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/locales/ja.json b/locales/ja.json index 3ad4b494..d08413ea 100644 --- a/locales/ja.json +++ b/locales/ja.json @@ -5,7 +5,7 @@ "generic_subscribers_count_0": "{{count}} 人の登録者", "generic_subscriptions_count_0": "{{count}} 個の登録チャンネル", "LIVE": "ライブ", - "Shared `x` ago": "`x`前に共有", + "Shared `x` ago": "`x`前に公開", "Unsubscribe": "登録解除", "Subscribe": "登録", "View channel on YouTube": "YouTube でチャンネルを見る", @@ -56,17 +56,17 @@ "preferences_category_player": "プレイヤーの設定", "preferences_video_loop_label": "常にループ: ", "preferences_autoplay_label": "自動再生: ", - "preferences_continue_label": "デフォルトで次を再生: ", + "preferences_continue_label": "次の動画を再生: ", "preferences_continue_autoplay_label": "次の動画を自動再生: ", "preferences_listen_label": "デフォルトで音声モードを使用: ", - "preferences_local_label": "動画をプロキシーに通す: ", - "preferences_speed_label": "デフォルトの再生速度: ", + "preferences_local_label": "動画視聴にプロキシーを経由: ", + "preferences_speed_label": "標準の再生速度: ", "preferences_quality_label": "優先する画質: ", "preferences_volume_label": "プレイヤーの音量: ", "preferences_comments_label": "デフォルトのコメント: ", "youtube": "YouTube", "reddit": "Reddit", - "preferences_captions_label": "デフォルトの字幕: ", + "preferences_captions_label": "優先する字幕: ", "Fallback captions: ": "フォールバック時の字幕: ", "preferences_related_videos_label": "関連動画を表示: ", "preferences_annotations_label": "デフォルトでアノテーションを表示: ", @@ -108,7 +108,7 @@ "Watch history": "再生履歴", "Delete account": "アカウントを削除", "preferences_category_admin": "管理者設定", - "preferences_default_home_label": "デフォルトのホーム: ", + "preferences_default_home_label": "ホームに表示するページ: ", "preferences_feed_menu_label": "フィードメニュー: ", "preferences_show_nick_label": "ニックネームを一番上に表示する: ", "Top enabled: ": "トップページを有効化: ", @@ -157,7 +157,7 @@ "Engagement: ": "エンゲージメント: ", "Whitelisted regions: ": "ホワイトリストの地域: ", "Blacklisted regions: ": "ブラックリストの地域: ", - "Shared `x`": "`x`に共有", + "Shared `x`": "公開日 `x`", "Premieres in `x`": "`x`後にプレミア公開", "Premieres `x`": "`x`にプレミア公開", "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "やあ!君は JavaScript を無効にしているのかな?ここをクリックしてコメントを見れるけど、読み込みには少し時間がかかることがあるのを覚えておいてね。", @@ -191,9 +191,9 @@ "This channel does not exist.": "このチャンネルは存在しません。", "Could not get channel info.": "チャンネル情報を取得できませんでした。", "Could not fetch comments": "コメントを取得できませんでした", - "comments_view_x_replies_0": "{{count}} 件の返信を見る", + "comments_view_x_replies_0": "{{count}}件の返信を表示", "`x` ago": "`x`前", - "Load more": "もっと読み込む", + "Load more": "もっと見る", "comments_points_count_0": "{{count}}点", "Could not create mix.": "ミックスを作成できませんでした。", "Empty playlist": "空の再生リスト", @@ -377,8 +377,8 @@ "search_filters_duration_option_short": "4 分未満", "footer_documentation": "文書", "footer_source_code": "ソースコード", - "footer_original_source_code": "ソースコード (元)", - "footer_modfied_source_code": "ソースコード (改変)", + "footer_original_source_code": "元のソースコード", + "footer_modfied_source_code": "改変して使用", "adminprefs_modified_source_code_url_label": "改変されたソースコードのレポジトリのURL", "search_filters_duration_option_long": "20 分以上", "preferences_region_label": "地域: ", From fdf162e318ac3dd6c38e64a47938944efc730824 Mon Sep 17 00:00:00 2001 From: Milo Ivir Date: Sat, 25 Feb 2023 19:16:10 +0000 Subject: [PATCH 101/114] Update Croatian translation --- locales/hr.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locales/hr.json b/locales/hr.json index 72cd6a8e..c626ed28 100644 --- a/locales/hr.json +++ b/locales/hr.json @@ -359,13 +359,13 @@ "next_steps_error_message_refresh": "Aktualiziraj stranicu", "next_steps_error_message_go_to_youtube": "Idi na YouTube", "footer_donate_page": "Doniraj", - "adminprefs_modified_source_code_url_label": "URL do repozitorija izmijenjenog izvornog koda", + "adminprefs_modified_source_code_url_label": "URL do repozitorija prilagođenog izvornog koda", "search_filters_duration_option_short": "Kratko (< 4 minute)", "search_filters_duration_option_long": "Dugo (> 20 minute)", "footer_source_code": "Izvorni kod", - "footer_modfied_source_code": "Izmijenjeni izvorni kod", + "footer_modfied_source_code": "Prilagođen izvorni kod", "footer_documentation": "Dokumentacija", - "footer_original_source_code": "Izvoran izvorni kod", + "footer_original_source_code": "Prvobitan izvorni kod", "preferences_region_label": "Zemlja sadržaja: ", "preferences_quality_dash_label": "Preferirana DASH videokvaliteta: ", "preferences_quality_option_dash": "DASH (adaptativna kvaliteta)", From 2974ed348cbb429ee780affa077c25d08d189995 Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Thu, 23 Feb 2023 18:03:55 +0000 Subject: [PATCH 102/114] Update Albanian translation --- locales/sq.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/locales/sq.json b/locales/sq.json index 15025750..7f29a035 100644 --- a/locales/sq.json +++ b/locales/sq.json @@ -286,7 +286,7 @@ "search_filters_type_option_show": "Shfaqe", "search_filters_duration_option_short": "E shkurtër (< 4 minuta)", "search_filters_features_option_purchased": "Të blera", - "footer_modfied_source_code": "Kod Burim i ndryshuar", + "footer_modfied_source_code": "Kod burim i ndryshuar", "adminprefs_modified_source_code_url_label": "URL e depos së ndryshuar të kodit burim", "none": "asnjë", "videoinfo_started_streaming_x_ago": "Filloi transmetimin `x` më parë", @@ -468,5 +468,7 @@ "Artist: ": "Artist: ", "Album: ": "Album: ", "channel_tab_channels_label": "Kanale", - "Music in this video": "Muzikë në këtë video" + "Music in this video": "Muzikë në këtë video", + "channel_tab_shorts_label": "Të shkurtra", + "channel_tab_streams_label": "Transmetime të drejtpërdrejta" } From 27bf4d02a185e6750cdecdc4f1c169b0723dbbf5 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Wed, 1 Mar 2023 22:08:19 -0500 Subject: [PATCH 103/114] PR nursing --- src/invidious/routes/api/v1/authenticated.cr | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr index dc86bb3c..a20d23d0 100644 --- a/src/invidious/routes/api/v1/authenticated.cr +++ b/src/invidious/routes/api/v1/authenticated.cr @@ -58,15 +58,16 @@ module Invidious::Routes::API::V1::Authenticated env.response.content_type = "application/json" user = env.get("user").as(User) - page = env.params.query["page"]?.try &.to_i? + page = env.params.query["page"]?.try &.to_i?.try &.clamp(0, Int32::MAX) page ||= 1 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] + start_index = (page - 1) * max_results + if user.watched[start_index]? + watched = user.watched.reverse[start_index, max_results] end watched ||= [] of String From 406d74d0b6c85f300b7a96f85acb0963c998f944 Mon Sep 17 00:00:00 2001 From: Samantaz Fox Date: Wed, 1 Mar 2023 21:09:00 +0000 Subject: [PATCH 104/114] Update Spanish translation --- locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/es.json b/locales/es.json index fec3a667..6cf721f3 100644 --- a/locales/es.json +++ b/locales/es.json @@ -364,7 +364,7 @@ "footer_original_source_code": "Código fuente original", "adminprefs_modified_source_code_url_label": "URL al repositorio de código fuente modificado", "footer_source_code": "Código fuente", - "footer_modfied_source_code": "Modificación del código fuente", + "footer_modfied_source_code": "Código fuente modificado", "footer_donate_page": "Donar", "preferences_region_label": "País del contenido: ", "preferences_quality_dash_label": "Calidad de vídeo DASH preferida: ", From 8c0efb3ea9e409796ae860128b16d8aac860c5c6 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Thu, 2 Mar 2023 14:45:26 -0500 Subject: [PATCH 105/114] validate video id --- src/invidious/routes/api/v1/authenticated.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr index a20d23d0..75dad6df 100644 --- a/src/invidious/routes/api/v1/authenticated.cr +++ b/src/invidious/routes/api/v1/authenticated.cr @@ -94,7 +94,7 @@ module Invidious::Routes::API::V1::Authenticated user = env.get("user").as(User) id = env.params.url["id"]?.try &.as(String) - if !id + if !id.match(/[a-zA-Z0-9_-]{11}/) return error_json(400, "Invalid video id.") end From 38f6d08be6559915262cd246b7a82988700250a5 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Thu, 2 Mar 2023 14:47:14 -0500 Subject: [PATCH 106/114] Validate id, avoid db call if not needed --- src/invidious/routes/api/v1/authenticated.cr | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr index 75dad6df..e8e7c524 100644 --- a/src/invidious/routes/api/v1/authenticated.cr +++ b/src/invidious/routes/api/v1/authenticated.cr @@ -82,7 +82,7 @@ module Invidious::Routes::API::V1::Authenticated end id = env.params.url["id"]?.try &.as(String) - if !id + if !id.match(/[a-zA-Z0-9_-]{11}/) return error_json(400, "Invalid video id.") end @@ -93,6 +93,10 @@ module Invidious::Routes::API::V1::Authenticated def self.mark_unwatched(env) user = env.get("user").as(User) + if !user.preferences.watch_history + return error_json(409, "Watch history is disabled in preferences.") + end + id = env.params.url["id"]?.try &.as(String) if !id.match(/[a-zA-Z0-9_-]{11}/) return error_json(400, "Invalid video id.") From a5cc66e060578f801371fe3f4b53bcb3d61b3ef9 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Thu, 2 Mar 2023 16:11:50 -0500 Subject: [PATCH 107/114] Fix id check --- src/invidious/routes/api/v1/authenticated.cr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr index e8e7c524..a024736c 100644 --- a/src/invidious/routes/api/v1/authenticated.cr +++ b/src/invidious/routes/api/v1/authenticated.cr @@ -81,7 +81,7 @@ module Invidious::Routes::API::V1::Authenticated return error_json(409, "Watch history is disabled in preferences.") end - id = env.params.url["id"]?.try &.as(String) + id = env.params.url["id"] if !id.match(/[a-zA-Z0-9_-]{11}/) return error_json(400, "Invalid video id.") end @@ -97,7 +97,7 @@ module Invidious::Routes::API::V1::Authenticated return error_json(409, "Watch history is disabled in preferences.") end - id = env.params.url["id"]?.try &.as(String) + id = env.params.url["id"] if !id.match(/[a-zA-Z0-9_-]{11}/) return error_json(400, "Invalid video id.") end From 03542f2f5dcf7686b8d5fd38bb0c8c0e9e4a2cb7 Mon Sep 17 00:00:00 2001 From: amogusussy <83502633+amogusussy@users.noreply.github.com> Date: Fri, 3 Mar 2023 22:28:26 +0000 Subject: [PATCH 108/114] Fix empty description boxes. If a video has no description, (without this commit) the description box will still take up 8.3em, even if there's no content in it. This fixes that issue. --- assets/css/default.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/css/default.css b/assets/css/default.css index 3deaebe1..24910610 100644 --- a/assets/css/default.css +++ b/assets/css/default.css @@ -515,7 +515,7 @@ hr { #descexpansionbutton ~ div { overflow: hidden; - height: 8.3em; + max-height: 8.3em; } #descexpansionbutton:checked ~ div { From a3ecd46b019637b9a9d926d91042bbf3603c7f7c Mon Sep 17 00:00:00 2001 From: Paul Fauchon Date: Sun, 5 Mar 2023 04:55:27 +0800 Subject: [PATCH 109/114] add new Android client to list of projects using invidious --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0744ac50..abf57e38 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,7 @@ Weblate also allows you to log-in with major SSO providers like Github, Gitlab, - [TubiTui](https://codeberg.org/777/TubiTui): A lightweight, libre, TUI-based YouTube client. - [Ytfzf](https://github.com/pystardust/ytfzf): A posix script to find and watch youtube videos from the terminal. (Without API) - [Playlet](https://github.com/iBicha/playlet): Unofficial Youtube client for Roku TV +- [Clipious](https://github.com/lamarios/clipious): Unofficial Invidious client for Android ## Liability From 3c3d9ebf84f6dbac671dd7561b72de4af45f1747 Mon Sep 17 00:00:00 2001 From: fresh Date: Sat, 4 Mar 2023 23:07:28 +0000 Subject: [PATCH 110/114] Update Greek translation --- locales/el.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/el.json b/locales/el.json index 3448a4dc..8d0c84dd 100644 --- a/locales/el.json +++ b/locales/el.json @@ -366,7 +366,7 @@ "preferences_quality_option_hd720": "HD720", "preferences_quality_option_medium": "Μεσαία", "preferences_quality_option_small": "Μικρό", - "preferences_quality_option_dash": "DASH (προσαρμοστική ποιότητα)", + "preferences_quality_option_dash": "DASH (προσαρμόσιμη ποιότητα)", "preferences_quality_dash_option_4320p": "4320p", "preferences_quality_dash_option_720p": "720p", "invidious": "Invidious", @@ -450,5 +450,5 @@ "search_filters_type_option_show": "Μπάρα προόδου διαβάσματος", "preferences_watch_history_label": "Ενεργοποίηση ιστορικού παρακολούθησης: ", "search_filters_title": "Φίλτρο", - "search_message_no_results": "Δεν" + "search_message_no_results": "Δε βρέθηκαν αποτελέσματα." } From 1f607273a87c85e65c7bfc7345984c6b7d631a5a Mon Sep 17 00:00:00 2001 From: Felipe Nogueira Date: Sun, 5 Mar 2023 02:24:43 +0000 Subject: [PATCH 111/114] Update Portuguese (Brazil) translation --- locales/pt-BR.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/pt-BR.json b/locales/pt-BR.json index 079c4ea1..ec00d46e 100644 --- a/locales/pt-BR.json +++ b/locales/pt-BR.json @@ -381,7 +381,7 @@ "footer_documentation": "Documentação", "footer_source_code": "Código fonte", "footer_original_source_code": "Código fonte original", - "footer_modfied_source_code": "Código Fonte Modificado", + "footer_modfied_source_code": "Código-fonte modificado", "preferences_quality_dash_label": "Qualidade de vídeo do painel preferida: ", "preferences_region_label": "País do conteúdo: ", "preferences_quality_dash_option_4320p": "4320p", From 9325fa79ae3ee751b52da95997cc4824742531e7 Mon Sep 17 00:00:00 2001 From: VisualPlugin Date: Mon, 6 Mar 2023 06:17:50 +0000 Subject: [PATCH 112/114] Update es.json --- locales/es.json | 106 ++++++++++++++++++++++++------------------------ 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/locales/es.json b/locales/es.json index 6cf721f3..a0d16325 100644 --- a/locales/es.json +++ b/locales/es.json @@ -52,21 +52,21 @@ "preferences_video_loop_label": "Repetir siempre: ", "preferences_autoplay_label": "Reproducción automática: ", "preferences_continue_label": "Reproducir siguiente por defecto: ", - "preferences_continue_autoplay_label": "Reproducir automáticamente el vídeo siguiente: ", + "preferences_continue_autoplay_label": "Reproducir automáticamente el video siguiente: ", "preferences_listen_label": "Activar el sonido por defecto: ", - "preferences_local_label": "¿Usar un proxy para los vídeos? ", + "preferences_local_label": "¿Usar un proxy para los videos? ", "preferences_speed_label": "Velocidad por defecto: ", - "preferences_quality_label": "Calidad de vídeo preferida: ", + "preferences_quality_label": "Calidad de video preferida: ", "preferences_volume_label": "Volumen del reproductor: ", "preferences_comments_label": "Comentarios por defecto: ", "youtube": "YouTube", "reddit": "Reddit", "preferences_captions_label": "Subtítulos por defecto: ", "Fallback captions: ": "Subtítulos alternativos: ", - "preferences_related_videos_label": "¿Mostrar vídeos relacionados? ", + "preferences_related_videos_label": "¿Mostrar videos relacionados? ", "preferences_annotations_label": "¿Mostrar anotaciones por defecto? ", - "preferences_extend_desc_label": "Extender automáticamente la descripción del vídeo: ", - "preferences_vr_mode_label": "Vídeos interactivos de 360 grados (necesita WebGL): ", + "preferences_extend_desc_label": "Extender automáticamente la descripción del video: ", + "preferences_vr_mode_label": "Videos interactivos de 360 grados (necesita WebGL): ", "preferences_category_visual": "Preferencias visuales", "preferences_player_style_label": "Estilo de reproductor: ", "Dark mode: ": "Modo oscuro: ", @@ -79,16 +79,16 @@ "preferences_category_subscription": "Preferencias de la suscripción", "preferences_annotations_subscribed_label": "¿Mostrar anotaciones por defecto para los canales suscritos? ", "Redirect homepage to feed: ": "Redirigir la página de inicio a la fuente: ", - "preferences_max_results_label": "Número de vídeos mostrados en la fuente: ", - "preferences_sort_label": "Ordenar los vídeos por: ", + "preferences_max_results_label": "Número de videos mostrados en la fuente: ", + "preferences_sort_label": "Ordenar los videos por: ", "published": "fecha de publicación", "published - reverse": "fecha de publicación: orden inverso", "alphabetically": "alfabéticamente", "alphabetically - reverse": "alfabéticamente: orden inverso", "channel name": "nombre del canal", "channel name - reverse": "nombre del canal: orden inverso", - "Only show latest video from channel: ": "Mostrar solo el último vídeo del canal: ", - "Only show latest unwatched video from channel: ": "Mostrar solo el último vídeo sin ver del canal: ", + "Only show latest video from channel: ": "Mostrar solo el último video del canal: ", + "Only show latest unwatched video from channel: ": "Mostrar solo el último video sin ver del canal: ", "preferences_unseen_only_label": "Mostrar solo los no vistos: ", "preferences_notifications_only_label": "Mostrar solo notificaciones (si hay alguna): ", "Enable web notifications": "Habilitar notificaciones web", @@ -139,7 +139,7 @@ "Editing playlist `x`": "Editando la lista de reproducción 'x'", "Show more": "Mostrar más", "Show less": "Mostrar menos", - "Watch on YouTube": "Ver el vídeo en YouTube", + "Watch on YouTube": "Ver en YouTube", "Switch Invidious Instance": "Cambiar Instancia de Invidious", "Hide annotations": "Ocultar anotaciones", "Show annotations": "Mostrar anotaciones", @@ -153,7 +153,7 @@ "Shared `x`": "Compartido `x`", "Premieres in `x`": "Se estrena en `x`", "Premieres `x`": "Estrenos `x`", - "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "¡Hola! Parece que tiene JavaScript desactivado. Haga clic aquí para ver los comentarios, pero tenga en cuenta que pueden tardar un poco más en cargarse.", + "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "¡Hola! Parece que tienes JavaScript desactivado. Haz clic aquí para ver los comentarios, pero tengas en cuenta que pueden tardar un poco más en cargarse.", "View YouTube comments": "Ver los comentarios de YouTube", "View more comments on Reddit": "Ver más comentarios en Reddit", "View `x` comments": { @@ -164,7 +164,7 @@ "Hide replies": "Ocultar las respuestas", "Show replies": "Mostrar las respuestas", "Incorrect password": "Contraseña incorrecta", - "Quota exceeded, try again in a few hours": "Cuota excedida, pruebe otra vez en unas horas", + "Quota exceeded, try again in a few hours": "Cuota excedida, prueba otra vez en unas horas", "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "No se puede iniciar sesión, asegúrese de que la autentificación de dos factores (autentificador o SMS) esté habilitada.", "Invalid TFA code": "Código TFA no válido", "Login failed. This may be because two-factor authentication is not turned on for your account.": "Error de inicio de sesion. Puede deberse a que la autentificación de dos factores no está habilitada en su cuenta.", @@ -176,7 +176,7 @@ "Wrong username or password": "Nombre o contraseña incorrecto", "Please sign in using 'Log in with Google'": "Inicie sesión con «Iniciar sesión con Google»", "Password cannot be empty": "La contraseña no puede estar en blanco", - "Password cannot be longer than 55 characters": "La contraseña no puede tener más de 55 caracteres", + "Password cannot be longer than 55 characters": "La contraseña no debe tener más de 55 caracteres", "Please log in": "Inicie sesión, por favor", "Invidious Private Feed for `x`": "Fuente privada de Invidious para `x`", "channel:`x`": "canal: `x`", @@ -198,7 +198,7 @@ "No such user": "Usuario no existe", "Token is expired, please try again": "El símbolo ha caducado, inténtelo de nuevo", "English": "Inglés", - "English (auto-generated)": "Inglés (generados automáticamente)", + "English (auto-generated)": "Inglés (generado automáticamente)", "Afrikaans": "Afrikáans", "Albanian": "Albanés", "Amharic": "Amárico", @@ -324,50 +324,51 @@ "permalink": "enlace permanente", "`x` marked it with a ❤": "`x` lo ha marcado con un ❤", "Audio mode": "Modo de audio", - "Video mode": "Modo de vídeo", - "channel_tab_videos_label": "Vídeos", + "Video mode": "Modo de video", + "channel_tab_videos_label": "Videos", "Playlists": "Listas de reproducción", "channel_tab_community_label": "Comunidad", - "search_filters_sort_option_relevance": "relevancia", - "search_filters_sort_option_rating": "valoración", - "search_filters_sort_option_date": "fecha", - "search_filters_sort_option_views": "visualizaciones", - "search_filters_type_label": "content_type", + "search_filters_sort_option_relevance": "Relevancia", + "search_filters_sort_option_rating": "Valoración", + "search_filters_sort_option_date": "Fecha de subida", + "search_filters_sort_option_views": "Visualizaciones", + "search_filters_type_label": "tipo de contenido", "search_filters_duration_label": "duración", "search_filters_features_label": "funcionalidades", "search_filters_sort_label": "ordenar", - "search_filters_date_option_hour": "hora", - "search_filters_date_option_today": "hoy", - "search_filters_date_option_week": "semana", - "search_filters_date_option_month": "mes", - "search_filters_date_option_year": "año", - "search_filters_type_option_video": "vídeo", - "search_filters_type_option_channel": "canal", - "search_filters_type_option_playlist": "lista de reproducción", - "search_filters_type_option_movie": "película", - "search_filters_type_option_show": "programa", - "search_filters_features_option_hd": "hd", - "search_filters_features_option_subtitles": "subtítulos", - "search_filters_features_option_c_commons": "creative_commons", - "search_filters_features_option_three_d": "3d", - "search_filters_features_option_live": "directo", - "search_filters_features_option_four_k": "4k", - "search_filters_features_option_location": "ubicación", - "search_filters_features_option_hdr": "hdr", + "search_filters_date_option_hour": "Última hora", + "search_filters_date_option_today": "Hoy", + "search_filters_date_option_week": "Esta semana", + "search_filters_date_option_month": "Este mes", + "search_filters_date_option_year": "Este año", + "search_filters_type_option_video": "Video", + "search_filters_type_option_channel": "Canal", + "search_filters_type_option_playlist": "Lista de reproducción", + "search_filters_type_option_movie": "Película", + "search_filters_type_option_show": "Programa", + "search_filters_features_option_hd": "HD", + "search_filters_features_option_subtitles": "Subtítulos", + "search_filters_features_option_c_commons": "Creative Commons", + "search_filters_features_option_three_d": "3D", + "search_filters_features_option_live": "En directo", + "search_filters_features_option_four_k": "4K", + "search_filters_features_option_location": "Ubicación", + "search_filters_features_option_hdr": "HDR", "Current version: ": "Versión actual: ", "next_steps_error_message": "Después de lo cual debes intentar: ", "next_steps_error_message_refresh": "Recargar la página", "next_steps_error_message_go_to_youtube": "Ir a YouTube", - "search_filters_duration_option_short": "Corto (< 4 minutos)", - "search_filters_duration_option_long": "Largo (> 20 minutos)", + "search_filters_duration_option_short": "Menos de 4 minutos", + "search_filters_duration_option_medium": "De 4 a 20 minutos", + "search_filters_duration_option_long": "Más de 20 minutos", "footer_documentation": "Documentación", "footer_original_source_code": "Código fuente original", - "adminprefs_modified_source_code_url_label": "URL al repositorio de código fuente modificado", + "adminprefs_modified_source_code_url_label": "Enlace al repositorio de código fuente modificado", "footer_source_code": "Código fuente", "footer_modfied_source_code": "Código fuente modificado", "footer_donate_page": "Donar", "preferences_region_label": "País del contenido: ", - "preferences_quality_dash_label": "Calidad de vídeo DASH preferida: ", + "preferences_quality_dash_label": "Calidad de video DASH preferida: ", "preferences_quality_option_hd720": "HD720", "preferences_quality_option_medium": "Intermedia", "preferences_quality_dash_option_auto": "Automática", @@ -376,7 +377,7 @@ "download_subtitles": "Subtítulos- `x` (.vtt)", "user_created_playlists": "`x` listas de reproducción creadas", "user_saved_playlists": "`x` listas de reproducción guardadas", - "Video unavailable": "Vídeo no disponible", + "Video unavailable": "Video no disponible", "videoinfo_youTube_embed_link": "Insertar", "preferences_quality_dash_option_2160p": "2160p", "preferences_quality_dash_option_4320p": "4320p", @@ -413,8 +414,8 @@ "generic_count_weeks_plural": "{{count}} semanas", "generic_playlists_count": "{{count}} lista de reproducción", "generic_playlists_count_plural": "{{count}} listas de reproducción", - "generic_videos_count": "{{count}} vídeo", - "generic_videos_count_plural": "{{count}} vídeos", + "generic_videos_count": "{{count}} video", + "generic_videos_count_plural": "{{count}} videos", "generic_count_months": "{{count}} mes", "generic_count_months_plural": "{{count}} meses", "comments_points_count": "{{count}} punto", @@ -433,7 +434,7 @@ "crash_page_search_issue": "buscado problemas existentes en GitHub", "crash_page_you_found_a_bug": "¡Parece que has encontrado un error en Invidious!", "crash_page_refresh": "probado a recargar la página", - "crash_page_report_issue": "Si nada de lo anterior ha sido de ayuda, por favor, abre una nueva incidencia en GitHub (preferiblemente en inglés) e incluye el siguiente texto en tu mensaje (NO traduzcas este texto):", + "crash_page_report_issue": "Si nada de lo anterior ha sido de ayuda, por favor, abre una nueva incidencia en GitHub (preferiblemente en inglés) e incluye verbatim el siguiente texto en tu mensaje:", "English (United States)": "Inglés (Estados Unidos)", "Cantonese (Hong Kong)": "Cantonés (Hong Kong)", "Dutch (auto-generated)": "Neerlandés (generados automáticamente)", @@ -461,23 +462,22 @@ "search_message_no_results": "No se han encontrado resultados.", "search_message_change_filters_or_query": "Pruebe ampliar la consulta de búsqueda y/o a cambiar los filtros.", "search_filters_title": "Filtros", - "search_filters_date_label": "Fecha de subida", + "search_filters_date_label": "fecha de subida", "search_filters_date_option_none": "Cualquier fecha", "search_filters_type_option_all": "Cualquier tipo", "search_filters_duration_option_none": "Cualquier duración", "search_filters_features_option_vr180": "VR180", - "search_filters_apply_button": "Aplicar filtros seleccionados", + "search_filters_apply_button": "Aplicar filtros", "tokens_count": "{{count}} ficha", "tokens_count_plural": "{{count}} fichas", "search_message_use_another_instance": " También puede buscar en otra instancia.", - "search_filters_duration_option_medium": "Medio (4 - 20 minutes)", "Popular enabled: ": "¿Habilitar la sección popular? ", - "error_video_not_in_playlist": "El vídeo solicitado no existe en esta lista de reproducción. Haga clic aquí para acceder a la página de inicio de la lista de reproducción.", + "error_video_not_in_playlist": "El video que solicitaste no existe en esta lista de reproducción. Haz clic aquí para acceder a la página de inicio de la lista de reproducción.", "channel_tab_streams_label": "Directos", "channel_tab_channels_label": "Canales", "channel_tab_shorts_label": "Cortos", "channel_tab_playlists_label": "Listas de reproducción", - "Music in this video": "Música en este vídeo", + "Music in this video": "Música en este video", "Artist: ": "Artista: ", "Album: ": "Álbum: " } From 548a0f26ef07a4f2beec3f5e7b7d2b667b9ff50e Mon Sep 17 00:00:00 2001 From: maboroshin Date: Sun, 5 Mar 2023 23:53:05 +0000 Subject: [PATCH 113/114] Update Japanese translation --- locales/ja.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/ja.json b/locales/ja.json index d08413ea..4d2ed5a0 100644 --- a/locales/ja.json +++ b/locales/ja.json @@ -366,7 +366,7 @@ "search_filters_features_option_subtitles": "字幕", "search_filters_features_option_c_commons": "クリエイティブ・コモンズ", "search_filters_features_option_three_d": "3D", - "search_filters_features_option_live": "生配信", + "search_filters_features_option_live": "ライブ", "search_filters_features_option_four_k": "4K", "search_filters_features_option_location": "場所", "search_filters_features_option_hdr": "HDR", From 0b17f68ebacdb54e74116cf3364c8229e896eff0 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Tue, 7 Mar 2023 13:50:02 -0500 Subject: [PATCH 114/114] Fix input validation --- src/invidious/routes/api/v1/authenticated.cr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr index a024736c..ce2ee812 100644 --- a/src/invidious/routes/api/v1/authenticated.cr +++ b/src/invidious/routes/api/v1/authenticated.cr @@ -82,7 +82,7 @@ module Invidious::Routes::API::V1::Authenticated end id = env.params.url["id"] - if !id.match(/[a-zA-Z0-9_-]{11}/) + if !id.match(/^[a-zA-Z0-9_-]{11}$/) return error_json(400, "Invalid video id.") end @@ -98,7 +98,7 @@ module Invidious::Routes::API::V1::Authenticated end id = env.params.url["id"] - if !id.match(/[a-zA-Z0-9_-]{11}/) + if !id.match(/^[a-zA-Z0-9_-]{11}$/) return error_json(400, "Invalid video id.") end