forked from midou/invidious
commit
c2f74879da
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
|||||||
- name: Install Crystal
|
- name: Install Crystal
|
||||||
uses: oprypin/install-crystal@v1.2.4
|
uses: oprypin/install-crystal@v1.2.4
|
||||||
with:
|
with:
|
||||||
crystal: 0.35.1
|
crystal: 0.36.0
|
||||||
|
|
||||||
- name: Cache Shards
|
- name: Cache Shards
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM crystallang/crystal:0.35.1-alpine AS builder
|
FROM crystallang/crystal:0.36.0-alpine AS builder
|
||||||
RUN apk add --no-cache curl sqlite-static
|
RUN apk add --no-cache curl sqlite-static
|
||||||
WORKDIR /invidious
|
WORKDIR /invidious
|
||||||
COPY ./shard.yml ./shard.yml
|
COPY ./shard.yml ./shard.yml
|
||||||
|
@ -29,6 +29,6 @@ dependencies:
|
|||||||
github: iv-org/lsquic.cr
|
github: iv-org/lsquic.cr
|
||||||
version: ~> 2.18.1-1
|
version: ~> 2.18.1-1
|
||||||
|
|
||||||
crystal: 0.35.1
|
crystal: 0.36.0
|
||||||
|
|
||||||
license: AGPLv3
|
license: AGPLv3
|
||||||
|
@ -1428,9 +1428,9 @@ get "/feed/playlist/:plid" do |env|
|
|||||||
node.attributes.each do |attribute|
|
node.attributes.each do |attribute|
|
||||||
case attribute.name
|
case attribute.name
|
||||||
when "url", "href"
|
when "url", "href"
|
||||||
full_path = URI.parse(node[attribute.name]).full_path
|
request_target = URI.parse(node[attribute.name]).request_target
|
||||||
query_string_opt = full_path.starts_with?("/watch?v=") ? "&#{params}" : ""
|
query_string_opt = request_target.starts_with?("/watch?v=") ? "&#{params}" : ""
|
||||||
node[attribute.name] = "#{HOST_URL}#{full_path}#{query_string_opt}"
|
node[attribute.name] = "#{HOST_URL}#{request_target}#{query_string_opt}"
|
||||||
else nil # Skip
|
else nil # Skip
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1439,7 +1439,7 @@ get "/feed/playlist/:plid" do |env|
|
|||||||
document = document.to_xml(options: XML::SaveOptions::NO_DECL)
|
document = document.to_xml(options: XML::SaveOptions::NO_DECL)
|
||||||
|
|
||||||
document.scan(/<uri>(?<url>[^<]+)<\/uri>/).each do |match|
|
document.scan(/<uri>(?<url>[^<]+)<\/uri>/).each do |match|
|
||||||
content = "#{HOST_URL}#{URI.parse(match["url"]).full_path}"
|
content = "#{HOST_URL}#{URI.parse(match["url"]).request_target}"
|
||||||
document = document.gsub(match[0], "<uri>#{content}</uri>")
|
document = document.gsub(match[0], "<uri>#{content}</uri>")
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1634,7 +1634,7 @@ end
|
|||||||
|
|
||||||
get "/attribution_link" do |env|
|
get "/attribution_link" do |env|
|
||||||
if query = env.params.query["u"]?
|
if query = env.params.query["u"]?
|
||||||
url = URI.parse(query).full_path
|
url = URI.parse(query).request_target
|
||||||
else
|
else
|
||||||
url = "/"
|
url = "/"
|
||||||
end
|
end
|
||||||
@ -1978,7 +1978,7 @@ get "/api/v1/captions/:id" do |env|
|
|||||||
caption = caption[0]
|
caption = caption[0]
|
||||||
end
|
end
|
||||||
|
|
||||||
url = URI.parse("#{caption.baseUrl}&tlang=#{tlang}").full_path
|
url = URI.parse("#{caption.baseUrl}&tlang=#{tlang}").request_target
|
||||||
|
|
||||||
# Auto-generated captions often have cues that aren't aligned properly with the video,
|
# Auto-generated captions often have cues that aren't aligned properly with the video,
|
||||||
# as well as some other markup that makes it cumbersome, so we try to fix that here
|
# as well as some other markup that makes it cumbersome, so we try to fix that here
|
||||||
@ -3184,7 +3184,7 @@ get "/api/manifest/dash/id/:id" do |env|
|
|||||||
end
|
end
|
||||||
|
|
||||||
if dashmpd = video.dash_manifest_url
|
if dashmpd = video.dash_manifest_url
|
||||||
manifest = YT_POOL.client &.get(URI.parse(dashmpd).full_path).body
|
manifest = YT_POOL.client &.get(URI.parse(dashmpd).request_target).body
|
||||||
|
|
||||||
manifest = manifest.gsub(/<BaseURL>[^<]+<\/BaseURL>/) do |baseurl|
|
manifest = manifest.gsub(/<BaseURL>[^<]+<\/BaseURL>/) do |baseurl|
|
||||||
url = baseurl.lchop("<BaseURL>")
|
url = baseurl.lchop("<BaseURL>")
|
||||||
@ -3192,7 +3192,7 @@ get "/api/manifest/dash/id/:id" do |env|
|
|||||||
|
|
||||||
if local
|
if local
|
||||||
uri = URI.parse(url)
|
uri = URI.parse(url)
|
||||||
url = "#{uri.full_path}host/#{uri.host}/"
|
url = "#{uri.request_target}host/#{uri.host}/"
|
||||||
end
|
end
|
||||||
|
|
||||||
"<BaseURL>#{url}</BaseURL>"
|
"<BaseURL>#{url}</BaseURL>"
|
||||||
@ -3205,7 +3205,7 @@ get "/api/manifest/dash/id/:id" do |env|
|
|||||||
|
|
||||||
if local
|
if local
|
||||||
adaptive_fmts.each do |fmt|
|
adaptive_fmts.each do |fmt|
|
||||||
fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path)
|
fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -3403,7 +3403,7 @@ get "/latest_version" do |env|
|
|||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
url = URI.parse(url).full_path.not_nil! if local
|
url = URI.parse(url).request_target.not_nil! if local
|
||||||
url = "#{url}&title=#{title}" if title
|
url = "#{url}&title=#{title}" if title
|
||||||
|
|
||||||
env.redirect url
|
env.redirect url
|
||||||
@ -3515,7 +3515,7 @@ get "/videoplayback" do |env|
|
|||||||
client = make_client(URI.parse(new_host), region)
|
client = make_client(URI.parse(new_host), region)
|
||||||
end
|
end
|
||||||
|
|
||||||
url = "#{location.full_path}&host=#{location.host}#{region ? "®ion=#{region}" : ""}"
|
url = "#{location.request_target}&host=#{location.host}#{region ? "®ion=#{region}" : ""}"
|
||||||
else
|
else
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
@ -3555,7 +3555,7 @@ get "/videoplayback" do |env|
|
|||||||
|
|
||||||
if location = response.headers["Location"]?
|
if location = response.headers["Location"]?
|
||||||
location = URI.parse(location)
|
location = URI.parse(location)
|
||||||
location = "#{location.full_path}&host=#{location.host}"
|
location = "#{location.request_target}&host=#{location.host}"
|
||||||
|
|
||||||
if region
|
if region
|
||||||
location += "®ion=#{region}"
|
location += "®ion=#{region}"
|
||||||
@ -3619,7 +3619,7 @@ get "/videoplayback" do |env|
|
|||||||
|
|
||||||
if location = response.headers["Location"]?
|
if location = response.headers["Location"]?
|
||||||
location = URI.parse(location)
|
location = URI.parse(location)
|
||||||
location = "#{location.full_path}&host=#{location.host}#{region ? "®ion=#{region}" : ""}"
|
location = "#{location.request_target}&host=#{location.host}#{region ? "®ion=#{region}" : ""}"
|
||||||
|
|
||||||
env.redirect location
|
env.redirect location
|
||||||
break
|
break
|
||||||
@ -3859,7 +3859,7 @@ end
|
|||||||
get "/watch_videos" do |env|
|
get "/watch_videos" do |env|
|
||||||
response = YT_POOL.client &.get(env.request.resource)
|
response = YT_POOL.client &.get(env.request.resource)
|
||||||
if url = response.headers["Location"]?
|
if url = response.headers["Location"]?
|
||||||
url = URI.parse(url).full_path
|
url = URI.parse(url).request_target
|
||||||
next env.redirect url
|
next env.redirect url
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -3874,7 +3874,7 @@ error 404 do |env|
|
|||||||
response = YT_POOL.client &.get("/#{item}")
|
response = YT_POOL.client &.get("/#{item}")
|
||||||
|
|
||||||
if response.status_code == 301
|
if response.status_code == 301
|
||||||
response = YT_POOL.client &.get(URI.parse(response.headers["Location"]).full_path)
|
response = YT_POOL.client &.get(URI.parse(response.headers["Location"]).request_target)
|
||||||
end
|
end
|
||||||
|
|
||||||
if response.body.empty?
|
if response.body.empty?
|
||||||
|
@ -294,7 +294,7 @@ def template_youtube_comments(comments, locale, thin_mode)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if !thin_mode
|
if !thin_mode
|
||||||
author_thumbnail = "/ggpht#{URI.parse(child["authorThumbnails"][-1]["url"].as_s).full_path}"
|
author_thumbnail = "/ggpht#{URI.parse(child["authorThumbnails"][-1]["url"].as_s).request_target}"
|
||||||
else
|
else
|
||||||
author_thumbnail = ""
|
author_thumbnail = ""
|
||||||
end
|
end
|
||||||
@ -322,7 +322,7 @@ def template_youtube_comments(comments, locale, thin_mode)
|
|||||||
html << <<-END_HTML
|
html << <<-END_HTML
|
||||||
<div class="pure-g">
|
<div class="pure-g">
|
||||||
<div class="pure-u-1 pure-u-md-1-2">
|
<div class="pure-u-1 pure-u-md-1-2">
|
||||||
<img style="width:100%" src="/ggpht#{URI.parse(attachment["url"].as_s).full_path}">
|
<img style="width:100%" src="/ggpht#{URI.parse(attachment["url"].as_s).request_target}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
END_HTML
|
END_HTML
|
||||||
@ -375,7 +375,7 @@ def template_youtube_comments(comments, locale, thin_mode)
|
|||||||
|
|
||||||
if child["creatorHeart"]?
|
if child["creatorHeart"]?
|
||||||
if !thin_mode
|
if !thin_mode
|
||||||
creator_thumbnail = "/ggpht#{URI.parse(child["creatorHeart"]["creatorThumbnail"].as_s).full_path}"
|
creator_thumbnail = "/ggpht#{URI.parse(child["creatorHeart"]["creatorThumbnail"].as_s).request_target}"
|
||||||
else
|
else
|
||||||
creator_thumbnail = ""
|
creator_thumbnail = ""
|
||||||
end
|
end
|
||||||
@ -473,7 +473,7 @@ def replace_links(html)
|
|||||||
params = HTTP::Params.parse(url.query.not_nil!)
|
params = HTTP::Params.parse(url.query.not_nil!)
|
||||||
anchor["href"] = params["q"]?
|
anchor["href"] = params["q"]?
|
||||||
else
|
else
|
||||||
anchor["href"] = url.full_path
|
anchor["href"] = url.request_target
|
||||||
end
|
end
|
||||||
elsif url.to_s == "#"
|
elsif url.to_s == "#"
|
||||||
begin
|
begin
|
||||||
@ -544,7 +544,7 @@ def content_to_comment_html(content)
|
|||||||
if url.path == "/redirect"
|
if url.path == "/redirect"
|
||||||
url = HTTP::Params.parse(url.query.not_nil!)["q"]
|
url = HTTP::Params.parse(url.query.not_nil!)["q"]
|
||||||
else
|
else
|
||||||
url = url.full_path
|
url = url.request_target
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -71,14 +71,14 @@ end
|
|||||||
class HTTPClient < HTTP::Client
|
class HTTPClient < HTTP::Client
|
||||||
def set_proxy(proxy : HTTPProxy)
|
def set_proxy(proxy : HTTPProxy)
|
||||||
begin
|
begin
|
||||||
@socket = proxy.open(host: @host, port: @port, tls: @tls, connection_options: proxy_connection_options)
|
@io = proxy.open(host: @host, port: @port, tls: @tls, connection_options: proxy_connection_options)
|
||||||
rescue IO::Error
|
rescue IO::Error
|
||||||
@socket = nil
|
@io = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def unset_proxy
|
def unset_proxy
|
||||||
@socket = nil
|
@io = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def proxy_connection_options
|
def proxy_connection_options
|
||||||
|
@ -329,7 +329,7 @@ def get_referer(env, fallback = "/", unroll = true)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
referer = referer.full_path
|
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
|
if referer == env.request.path
|
||||||
|
@ -60,7 +60,7 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob
|
|||||||
elsif response.headers["Location"]?.try &.includes?("/sorry/index")
|
elsif response.headers["Location"]?.try &.includes?("/sorry/index")
|
||||||
location = response.headers["Location"].try { |u| URI.parse(u) }
|
location = response.headers["Location"].try { |u| URI.parse(u) }
|
||||||
headers = HTTP::Headers{":authority" => location.host.not_nil!}
|
headers = HTTP::Headers{":authority" => location.host.not_nil!}
|
||||||
response = YT_POOL.client &.get(location.full_path, headers)
|
response = YT_POOL.client &.get(location.request_target, headers)
|
||||||
|
|
||||||
html = XML.parse_html(response.body)
|
html = XML.parse_html(response.body)
|
||||||
form = html.xpath_node(%(//form[@action="index"])).not_nil!
|
form = html.xpath_node(%(//form[@action="index"])).not_nil!
|
||||||
|
@ -144,8 +144,8 @@ class Invidious::Routes::Embed < Invidious::Routes::BaseRoute
|
|||||||
adaptive_fmts = video.adaptive_fmts
|
adaptive_fmts = video.adaptive_fmts
|
||||||
|
|
||||||
if params.local
|
if params.local
|
||||||
fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) }
|
fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target) }
|
||||||
adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) }
|
adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target) }
|
||||||
end
|
end
|
||||||
|
|
||||||
video_streams = video.video_streams
|
video_streams = video.video_streams
|
||||||
|
@ -255,7 +255,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute
|
|||||||
traceback << "Unhandled dialog /b/0/SmsAuthInterstitial."
|
traceback << "Unhandled dialog /b/0/SmsAuthInterstitial."
|
||||||
end
|
end
|
||||||
|
|
||||||
login = client.get(location.full_path, headers)
|
login = client.get(location.request_target, headers)
|
||||||
|
|
||||||
headers = login.cookies.add_request_headers(headers)
|
headers = login.cookies.add_request_headers(headers)
|
||||||
location = login.headers["Location"]?.try { |u| URI.parse(u) }
|
location = login.headers["Location"]?.try { |u| URI.parse(u) }
|
||||||
|
@ -126,8 +126,8 @@ class Invidious::Routes::Watch < Invidious::Routes::BaseRoute
|
|||||||
adaptive_fmts = video.adaptive_fmts
|
adaptive_fmts = video.adaptive_fmts
|
||||||
|
|
||||||
if params.local
|
if params.local
|
||||||
fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) }
|
fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target) }
|
||||||
adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) }
|
adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target) }
|
||||||
end
|
end
|
||||||
|
|
||||||
video_streams = video.video_streams
|
video_streams = video.video_streams
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<% if channel.banner %>
|
<% if channel.banner %>
|
||||||
<div class="h-box">
|
<div class="h-box">
|
||||||
<img style="width:100%" src="/ggpht<%= URI.parse(channel.banner.not_nil!.gsub("=w1060-", "=w1280-")).full_path %>">
|
<img style="width:100%" src="/ggpht<%= URI.parse(channel.banner.not_nil!.gsub("=w1060-", "=w1280-")).request_target %>">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="h-box">
|
<div class="h-box">
|
||||||
@ -16,7 +16,7 @@
|
|||||||
<div class="pure-g h-box">
|
<div class="pure-g h-box">
|
||||||
<div class="pure-u-2-3">
|
<div class="pure-u-2-3">
|
||||||
<div class="channel-profile">
|
<div class="channel-profile">
|
||||||
<img src="/ggpht<%= URI.parse(channel.author_thumbnail).full_path %>">
|
<img src="/ggpht<%= URI.parse(channel.author_thumbnail).request_target %>">
|
||||||
<span><%= channel.author %></span>
|
<span><%= channel.author %></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<% if channel.banner %>
|
<% if channel.banner %>
|
||||||
<div class="h-box">
|
<div class="h-box">
|
||||||
<img style="width:100%" src="/ggpht<%= URI.parse(channel.banner.not_nil!.gsub("=w1060-", "=w1280-")).full_path %>">
|
<img style="width:100%" src="/ggpht<%= URI.parse(channel.banner.not_nil!.gsub("=w1060-", "=w1280-")).request_target %>">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="h-box">
|
<div class="h-box">
|
||||||
@ -15,7 +15,7 @@
|
|||||||
<div class="pure-g h-box">
|
<div class="pure-g h-box">
|
||||||
<div class="pure-u-2-3">
|
<div class="pure-u-2-3">
|
||||||
<div class="channel-profile">
|
<div class="channel-profile">
|
||||||
<img src="/ggpht<%= URI.parse(channel.author_thumbnail).full_path %>">
|
<img src="/ggpht<%= URI.parse(channel.author_thumbnail).request_target %>">
|
||||||
<span><%= channel.author %></span>
|
<span><%= channel.author %></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<a style="width:100%" href="/channel/<%= item.ucid %>">
|
<a style="width:100%" href="/channel/<%= item.ucid %>">
|
||||||
<% if !env.get("preferences").as(Preferences).thin_mode %>
|
<% if !env.get("preferences").as(Preferences).thin_mode %>
|
||||||
<center>
|
<center>
|
||||||
<img style="width:56.25%" src="/ggpht<%= URI.parse(item.author_thumbnail).full_path %>"/>
|
<img style="width:56.25%" src="/ggpht<%= URI.parse(item.author_thumbnail).request_target %>"/>
|
||||||
</center>
|
</center>
|
||||||
<% end %>
|
<% end %>
|
||||||
<p><%= item.author %></p>
|
<p><%= item.author %></p>
|
||||||
@ -15,7 +15,7 @@
|
|||||||
<h5><%= item.description_html %></h5>
|
<h5><%= item.description_html %></h5>
|
||||||
<% when SearchPlaylist, InvidiousPlaylist %>
|
<% when SearchPlaylist, InvidiousPlaylist %>
|
||||||
<% if item.id.starts_with? "RD" %>
|
<% if item.id.starts_with? "RD" %>
|
||||||
<% url = "/mix?list=#{item.id}&continuation=#{URI.parse(item.thumbnail || "/vi/-----------").full_path.split("/")[2]}" %>
|
<% url = "/mix?list=#{item.id}&continuation=#{URI.parse(item.thumbnail || "/vi/-----------").request_target.split("/")[2]}" %>
|
||||||
<% else %>
|
<% else %>
|
||||||
<% url = "/playlist?list=#{item.id}" %>
|
<% url = "/playlist?list=#{item.id}" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
@ -23,7 +23,7 @@
|
|||||||
<a style="width:100%" href="<%= url %>">
|
<a style="width:100%" href="<%= url %>">
|
||||||
<% if !env.get("preferences").as(Preferences).thin_mode %>
|
<% if !env.get("preferences").as(Preferences).thin_mode %>
|
||||||
<div class="thumbnail">
|
<div class="thumbnail">
|
||||||
<img class="thumbnail" src="<%= URI.parse(item.thumbnail || "/").full_path %>"/>
|
<img class="thumbnail" src="<%= URI.parse(item.thumbnail || "/").request_target %>"/>
|
||||||
<p class="length"><%= number_with_separator(item.video_count) %> videos</p>
|
<p class="length"><%= number_with_separator(item.video_count) %> videos</p>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<% if params.video_loop %>loop<% end %>
|
<% if params.video_loop %>loop<% end %>
|
||||||
<% if params.controls %>controls<% end %>>
|
<% if params.controls %>controls<% end %>>
|
||||||
<% if (hlsvp = video.hls_manifest_url) && !CONFIG.disabled?("livestreams") %>
|
<% if (hlsvp = video.hls_manifest_url) && !CONFIG.disabled?("livestreams") %>
|
||||||
<source src="<%= URI.parse(hlsvp).full_path %><% if params.local %>?local=true<% end %>" type="application/x-mpegURL" label="livestream">
|
<source src="<%= URI.parse(hlsvp).request_target %><% if params.local %>?local=true<% end %>" type="application/x-mpegURL" label="livestream">
|
||||||
<% else %>
|
<% else %>
|
||||||
<% if params.listen %>
|
<% if params.listen %>
|
||||||
<% audio_streams.each_with_index do |fmt, i| %>
|
<% audio_streams.each_with_index do |fmt, i| %>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<% if channel.banner %>
|
<% if channel.banner %>
|
||||||
<div class="h-box">
|
<div class="h-box">
|
||||||
<img style="width:100%" src="/ggpht<%= URI.parse(channel.banner.not_nil!.gsub("=w1060-", "=w1280-")).full_path %>">
|
<img style="width:100%" src="/ggpht<%= URI.parse(channel.banner.not_nil!.gsub("=w1060-", "=w1280-")).request_target %>">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="h-box">
|
<div class="h-box">
|
||||||
@ -15,7 +15,7 @@
|
|||||||
<div class="pure-g h-box">
|
<div class="pure-g h-box">
|
||||||
<div class="pure-u-2-3">
|
<div class="pure-u-2-3">
|
||||||
<div class="channel-profile">
|
<div class="channel-profile">
|
||||||
<img src="/ggpht<%= URI.parse(channel.author_thumbnail).full_path %>">
|
<img src="/ggpht<%= URI.parse(channel.author_thumbnail).request_target %>">
|
||||||
<span><%= channel.author %></span>
|
<span><%= channel.author %></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -203,7 +203,7 @@
|
|||||||
<a href="/channel/<%= video.ucid %>" style="display:block;width:fit-content;width:-moz-fit-content">
|
<a href="/channel/<%= video.ucid %>" style="display:block;width:fit-content;width:-moz-fit-content">
|
||||||
<div class="channel-profile">
|
<div class="channel-profile">
|
||||||
<% if !video.author_thumbnail.empty? %>
|
<% if !video.author_thumbnail.empty? %>
|
||||||
<img src="/ggpht<%= URI.parse(video.author_thumbnail).full_path %>">
|
<img src="/ggpht<%= URI.parse(video.author_thumbnail).request_target %>">
|
||||||
<% end %>
|
<% end %>
|
||||||
<span id="channel-name"><%= video.author %></span>
|
<span id="channel-name"><%= video.author %></span>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user