mirror of
				https://github.com/iv-org/invidious.git
				synced 2025-11-03 21:58:29 -06:00 
			
		
		
		
	Merge remote-tracking branch 'upstream/master' into side-menu
This commit is contained in:
		
						commit
						74d9bd30d0
					
				@ -322,13 +322,6 @@ img.thumbnail {
 | 
			
		||||
  object-fit: cover;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#player {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  left: 0;
 | 
			
		||||
  top: 0;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.player-dimensions.vjs-fluid {
 | 
			
		||||
  padding-top: 82vh;
 | 
			
		||||
}
 | 
			
		||||
@ -336,8 +329,6 @@ img.thumbnail {
 | 
			
		||||
#player-container {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  padding-bottom: 82vh;
 | 
			
		||||
  margin-left: 1em;
 | 
			
		||||
  margin-right: 1em;
 | 
			
		||||
  height: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -982,12 +982,11 @@ post "/login" do |env|
 | 
			
		||||
        preferences = env.get("preferences").as(Preferences)
 | 
			
		||||
        PG_DB.exec("UPDATE users SET preferences = $1 WHERE email = $2", preferences, user.email)
 | 
			
		||||
 | 
			
		||||
        login.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", value: "", expires: Time.new(1990, 1, 1),
 | 
			
		||||
          secure: secure, http_only: true)
 | 
			
		||||
        cookie = env.request.cookies["PREFS"]
 | 
			
		||||
        cookie.expires = Time.new(1990, 1, 1)
 | 
			
		||||
        env.response.cookies << cookie
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      login.cookies.add_response_headers(env.response.headers)
 | 
			
		||||
 | 
			
		||||
      env.redirect referer
 | 
			
		||||
    rescue ex
 | 
			
		||||
      error_message = translate(locale, "Login failed. This may be because two-factor authentication is not enabled on your account.")
 | 
			
		||||
@ -1099,8 +1098,9 @@ post "/login" do |env|
 | 
			
		||||
 | 
			
		||||
      # Since this user has already registered, we don't want to overwrite their preferences
 | 
			
		||||
      if env.request.cookies["PREFS"]?
 | 
			
		||||
        env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", value: "", expires: Time.new(1990, 1, 1),
 | 
			
		||||
          secure: secure, http_only: true)
 | 
			
		||||
        cookie = env.request.cookies["PREFS"]
 | 
			
		||||
        cookie.expires = Time.new(1990, 1, 1)
 | 
			
		||||
        env.response.cookies << cookie
 | 
			
		||||
      end
 | 
			
		||||
    elsif action == "register"
 | 
			
		||||
      if !config.registration_enabled
 | 
			
		||||
@ -1156,11 +1156,12 @@ post "/login" do |env|
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      if env.request.cookies["PREFS"]?
 | 
			
		||||
        preferences = env.get("preferences").as(Preferences)
 | 
			
		||||
        preferences = env.get("preferences").as(Preferences).to_json
 | 
			
		||||
        PG_DB.exec("UPDATE users SET preferences = $1 WHERE email = $2", preferences, user.email)
 | 
			
		||||
 | 
			
		||||
        env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", value: "", expires: Time.new(1990, 1, 1),
 | 
			
		||||
          secure: secure, http_only: true)
 | 
			
		||||
        cookie = env.request.cookies["PREFS"]
 | 
			
		||||
        cookie.expires = Time.new(1990, 1, 1)
 | 
			
		||||
        env.response.cookies << cookie
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@ -1193,9 +1194,8 @@ get "/signout" do |env|
 | 
			
		||||
 | 
			
		||||
    env.request.cookies.each do |cookie|
 | 
			
		||||
      cookie.expires = Time.new(1990, 1, 1)
 | 
			
		||||
      env.response.cookies << cookie
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    env.request.cookies.add_response_headers(env.response.headers)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  env.redirect referer
 | 
			
		||||
@ -1803,8 +1803,8 @@ post "/delete_account" do |env|
 | 
			
		||||
 | 
			
		||||
    env.request.cookies.each do |cookie|
 | 
			
		||||
      cookie.expires = Time.new(1990, 1, 1)
 | 
			
		||||
      env.response.cookies << cookie
 | 
			
		||||
    end
 | 
			
		||||
    env.request.cookies.add_response_headers(env.response.headers)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  env.redirect referer
 | 
			
		||||
@ -2471,7 +2471,14 @@ get "/channel/:ucid" do |env|
 | 
			
		||||
    sort_by ||= "last"
 | 
			
		||||
 | 
			
		||||
    items, continuation = fetch_channel_playlists(ucid, author, auto_generated, continuation, sort_by)
 | 
			
		||||
    items.select! { |item| item.is_a?(SearchPlaylist) && !item.videos.empty? }
 | 
			
		||||
    items.uniq! do |item|
 | 
			
		||||
      if item.responds_to?(:title)
 | 
			
		||||
        item.title
 | 
			
		||||
      elsif item.responds_to?(:author)
 | 
			
		||||
        item.author
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    items.select! { |item| item.responds_to?(:thumbnail_id) && item.thumbnail_id }
 | 
			
		||||
    items = items.map { |item| item.as(SearchPlaylist) }
 | 
			
		||||
    items.each { |item| item.author = "" }
 | 
			
		||||
  else
 | 
			
		||||
 | 
			
		||||
@ -232,13 +232,22 @@ def extract_items(nodeset, ucid = nil, author_name = nil)
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      playlist_thumbnail = node.xpath_node(%q(.//div/span/img)).try &.["data-thumb"]?
 | 
			
		||||
      playlist_thumbnail ||= node.xpath_node(%q(.//div/span/img)).try &.["src"]
 | 
			
		||||
      if !playlist_thumbnail || playlist_thumbnail.empty?
 | 
			
		||||
        thumbnail_id = videos[0]?.try &.id
 | 
			
		||||
      else
 | 
			
		||||
        thumbnail_id = playlist_thumbnail.match(/\/vi\/(?<video_id>[a-zA-Z0-9_-]{11})\/\w+\.jpg/).try &.["video_id"]
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      items << SearchPlaylist.new(
 | 
			
		||||
        title,
 | 
			
		||||
        plid,
 | 
			
		||||
        author,
 | 
			
		||||
        author_id,
 | 
			
		||||
        video_count,
 | 
			
		||||
        videos
 | 
			
		||||
        videos,
 | 
			
		||||
        thumbnail_id
 | 
			
		||||
      )
 | 
			
		||||
    when .includes? "yt-lockup-channel"
 | 
			
		||||
      author = title.strip
 | 
			
		||||
@ -399,13 +408,28 @@ def extract_shelf_items(nodeset, ucid = nil, author_name = nil)
 | 
			
		||||
        playlist_title ||= ""
 | 
			
		||||
        plid ||= ""
 | 
			
		||||
 | 
			
		||||
        playlist_thumbnail = child_node.xpath_node(%q(.//span/img)).try &.["data-thumb"]?
 | 
			
		||||
        playlist_thumbnail ||= child_node.xpath_node(%q(.//span/img)).try &.["src"]
 | 
			
		||||
        if !playlist_thumbnail || playlist_thumbnail.empty?
 | 
			
		||||
          thumbnail_id = videos[0]?.try &.id
 | 
			
		||||
        else
 | 
			
		||||
          thumbnail_id = playlist_thumbnail.match(/\/vi\/(?<video_id>[a-zA-Z0-9_-]{11})\/\w+\.jpg/).try &.["video_id"]
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        video_count_label = child_node.xpath_node(%q(.//span[@class="formatted-video-count-label"]))
 | 
			
		||||
        if video_count_label
 | 
			
		||||
          video_count = video_count_label.content.strip.match(/^\d+/).try &.[0].to_i?
 | 
			
		||||
        end
 | 
			
		||||
        video_count ||= 50
 | 
			
		||||
 | 
			
		||||
        items << SearchPlaylist.new(
 | 
			
		||||
          playlist_title,
 | 
			
		||||
          plid,
 | 
			
		||||
          author_name,
 | 
			
		||||
          ucid,
 | 
			
		||||
          50,
 | 
			
		||||
          Array(SearchPlaylistVideo).new
 | 
			
		||||
          video_count,
 | 
			
		||||
          Array(SearchPlaylistVideo).new,
 | 
			
		||||
          thumbnail_id
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
@ -419,7 +443,8 @@ def extract_shelf_items(nodeset, ucid = nil, author_name = nil)
 | 
			
		||||
        author_name,
 | 
			
		||||
        ucid,
 | 
			
		||||
        videos.size,
 | 
			
		||||
        videos
 | 
			
		||||
        videos,
 | 
			
		||||
        videos[0].try &.id
 | 
			
		||||
      )
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -162,6 +162,23 @@ def number_with_separator(number)
 | 
			
		||||
  number.to_s.reverse.gsub(/(\d{3})(?=\d)/, "\\1,").reverse
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
def short_text_to_number(short_text)
 | 
			
		||||
  case short_text
 | 
			
		||||
  when .ends_with? "M"
 | 
			
		||||
    number = short_text.rstrip(" mM").to_f
 | 
			
		||||
    number *= 1000000
 | 
			
		||||
  when .ends_with? "K"
 | 
			
		||||
    number = short_text.rstrip(" kK").to_f
 | 
			
		||||
    number *= 1000
 | 
			
		||||
  else
 | 
			
		||||
    number = short_text.rstrip(" ")
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  number = number.to_i
 | 
			
		||||
 | 
			
		||||
  return number
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
def number_to_short_text(number)
 | 
			
		||||
  seperated = number_with_separator(number).gsub(",", ".").split("")
 | 
			
		||||
  text = seperated.first(2).join
 | 
			
		||||
 | 
			
		||||
@ -25,12 +25,13 @@ end
 | 
			
		||||
 | 
			
		||||
class SearchPlaylist
 | 
			
		||||
  add_mapping({
 | 
			
		||||
    title:       String,
 | 
			
		||||
    id:          String,
 | 
			
		||||
    author:      String,
 | 
			
		||||
    ucid:        String,
 | 
			
		||||
    video_count: Int32,
 | 
			
		||||
    videos:      Array(SearchPlaylistVideo),
 | 
			
		||||
    title:        String,
 | 
			
		||||
    id:           String,
 | 
			
		||||
    author:       String,
 | 
			
		||||
    ucid:         String,
 | 
			
		||||
    video_count:  Int32,
 | 
			
		||||
    videos:       Array(SearchPlaylistVideo),
 | 
			
		||||
    thumbnail_id: String?,
 | 
			
		||||
  })
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@
 | 
			
		||||
        <h5><%= item.description_html %></h5>
 | 
			
		||||
    <% when SearchPlaylist %>
 | 
			
		||||
        <% if item.id.starts_with? "RD" %>
 | 
			
		||||
        <% url = "/mix?list=#{item.id}&continuation=#{item.videos[0]?.try &.id}" %>
 | 
			
		||||
        <% url = "/mix?list=#{item.id}&continuation=#{item.thumbnail_id}" %>
 | 
			
		||||
        <% else %>
 | 
			
		||||
        <% url = "/playlist?list=#{item.id}" %>
 | 
			
		||||
        <% end %>
 | 
			
		||||
@ -24,7 +24,7 @@
 | 
			
		||||
            <% if env.get?("user") && env.get("user").as(User).preferences.thin_mode %>
 | 
			
		||||
            <% else %>
 | 
			
		||||
            <div class="thumbnail">
 | 
			
		||||
                <img class="thumbnail" src="/vi/<%= item.videos[0]?.try &.id %>/mqdefault.jpg"/>
 | 
			
		||||
                <img class="thumbnail" src="/vi/<%= item.thumbnail_id %>/mqdefault.jpg"/>
 | 
			
		||||
                <p class="length"><%= number_with_separator(item.video_count) %> videos</p>
 | 
			
		||||
            </div>
 | 
			
		||||
            <% end %>
 | 
			
		||||
 | 
			
		||||
@ -79,9 +79,9 @@ var player = videojs("player", options, function() {
 | 
			
		||||
    seekStep: 5,
 | 
			
		||||
    enableModifiersForNumbers: false,
 | 
			
		||||
    customKeys: {
 | 
			
		||||
      // Toggle play with K Key
 | 
			
		||||
      play: {
 | 
			
		||||
        key: function(e) {
 | 
			
		||||
          // Toggle play with K Key
 | 
			
		||||
          return e.which === 75;
 | 
			
		||||
        },
 | 
			
		||||
        handler: function(player, options, e) {
 | 
			
		||||
@ -92,23 +92,45 @@ var player = videojs("player", options, function() {
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      // Go backward 5 seconds
 | 
			
		||||
      backward: {
 | 
			
		||||
        key: function(e) {
 | 
			
		||||
          // Go backward 5 seconds
 | 
			
		||||
          return e.which === 74;
 | 
			
		||||
        },
 | 
			
		||||
        handler: function(player, options, e) {
 | 
			
		||||
          player.currentTime(player.currentTime() - 5);
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      // Go forward 5 seconds
 | 
			
		||||
      forward: {
 | 
			
		||||
        key: function(e) {
 | 
			
		||||
          // Go forward 5 seconds
 | 
			
		||||
          return e.which === 76;
 | 
			
		||||
        },
 | 
			
		||||
        handler: function(player, options, e) {
 | 
			
		||||
          player.currentTime(player.currentTime() + 5);
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      // Increase speed
 | 
			
		||||
      increase_speed: {
 | 
			
		||||
        key: function(e) {
 | 
			
		||||
          return e.which === 190;
 | 
			
		||||
        },
 | 
			
		||||
        handler: function(player, _, e) {
 | 
			
		||||
          size = options.playbackRates.length;
 | 
			
		||||
          index = options.playbackRates.indexOf(player.playbackRate());
 | 
			
		||||
          player.playbackRate(options.playbackRates[(index + 1) % size]);
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      // Decrease speed
 | 
			
		||||
      decrease_speed: {
 | 
			
		||||
        key: function(e) {
 | 
			
		||||
          return e.which === 188;
 | 
			
		||||
        },
 | 
			
		||||
        handler: function(player, _, e) {
 | 
			
		||||
          size = options.playbackRates.length;
 | 
			
		||||
          index = options.playbackRates.indexOf(player.playbackRate());
 | 
			
		||||
          player.playbackRate(options.playbackRates[(size + index - 1) % size]);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@ -9,8 +9,7 @@
 | 
			
		||||
  <link rel="stylesheet" href="/css/default.css">
 | 
			
		||||
  <title><%= HTML.escape(video.title) %> - Invidious</title>
 | 
			
		||||
  <style>
 | 
			
		||||
  video, #my_video, .video-js, .vjs-default-skin
 | 
			
		||||
  {
 | 
			
		||||
  #player {
 | 
			
		||||
    position: fixed; 
 | 
			
		||||
    right: 0; 
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
 | 
			
		||||
@ -59,17 +59,17 @@
 | 
			
		||||
                    <label for="download_widget"><%= translate(locale, "Download as: ") %></label>
 | 
			
		||||
                    <select style="width:100%" name="download_widget" id="download_widget">
 | 
			
		||||
                    <% video_streams.each do |option| %>
 | 
			
		||||
                        <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= URI.escape(video.title) %>-<%= video.id %>.mp4"}'>
 | 
			
		||||
                        <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= URI.escape(video.title) %>-<%= video.id %>.<%= option["type"].split("/")[1].split(";")[0] %>"}'>
 | 
			
		||||
                            <%= option["quality_label"] %> - <%= option["type"].split(";")[0] %> @ <%= option["fps"] %>fps - video only
 | 
			
		||||
                        </option>
 | 
			
		||||
                    <% end %>
 | 
			
		||||
                    <% audio_streams.each do |option| %>
 | 
			
		||||
                        <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= URI.escape(video.title) %>-<%= video.id %>.mp4"}'>
 | 
			
		||||
                        <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= URI.escape(video.title) %>-<%= video.id %>.<%= option["type"].split("/")[1].split(";")[0] %>"}'>
 | 
			
		||||
                            <%= option["type"].split(";")[0] %> @ <%= option["bitrate"] %>k - audio only
 | 
			
		||||
                        </option>
 | 
			
		||||
                    <% end %>
 | 
			
		||||
                    <% fmt_stream.each do |option| %>
 | 
			
		||||
                        <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= URI.escape(video.title) %>-<%= video.id %>.mp4"}'>
 | 
			
		||||
                        <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= URI.escape(video.title) %>-<%= video.id %>.<%= option["type"].split("/")[1].split(";")[0] %>"}'>
 | 
			
		||||
                            <%= itag_to_metadata?(option["itag"]).try &.["height"]? || "~240" %>p - <%= option["type"].split(";")[0] %>
 | 
			
		||||
                        </option>
 | 
			
		||||
                    <% end %>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user