アプリを壊れ予防するには、APIの言語は英語に変えた

This commit is contained in:
テクニカル諏訪子 2021-08-10 10:48:56 +09:00
parent a87e94b981
commit f8d4820740
13 changed files with 23 additions and 44 deletions

View file

@ -17,17 +17,13 @@ CONFIG = Config.from_yaml(File.open("config/config.example.yml"))
describe "Helper" do
describe "#produce_channel_videos_url" do
it "correctly produces url for requesting page `x` of a channel's videos" do
#produce_channel_videos_url(ucid: "UCXuqSBlHAE6Xw-yeJA0Tunw").should eq("/browse_ajax?continuation=4qmFsgI8EhhVQ1h1cVNCbEhBRTZYdy15ZUpBMFR1bncaIEVnWjJhV1JsYjNNd0FqZ0JZQUZxQUxnQkFDQUFlZ0V4&gl=JP&hl=ja")
produce_channel_videos_url(ucid: "UCXuqSBlHAE6Xw-yeJA0Tunw").should eq("/browse_ajax?continuation=4qmFsgI8EhhVQ1h1cVNCbEhBRTZYdy15ZUpBMFR1bncaIEVnWjJhV1JsYjNNd0FqZ0JZQUZxQUxnQkFDQUFlZ0V4&gl=US&hl=en")
produce_channel_videos_url(ucid: "UCXuqSBlHAE6Xw-yeJA0Tunw").should eq("/browse_ajax?continuation=4qmFsgI8EhhVQ1h1cVNCbEhBRTZYdy15ZUpBMFR1bncaIEVnWjJhV1JsYjNNd0FqZ0JZQUZxQUxnQkFDQUFlZ0V4&gl=JP&hl=en")
#produce_channel_videos_url(ucid: "UCXuqSBlHAE6Xw-yeJA0Tunw", sort_by: "popular").should eq("/browse_ajax?continuation=4qmFsgJAEhhVQ1h1cVNCbEhBRTZYdy15ZUpBMFR1bncaJEVnWjJhV1JsYjNNd0FqZ0JZQUZxQUxnQkFDQUFlZ0V4R0FFPQ%3D%3D&gl=JP&hl=ja")
produce_channel_videos_url(ucid: "UCXuqSBlHAE6Xw-yeJA0Tunw", sort_by: "popular").should eq("/browse_ajax?continuation=4qmFsgJAEhhVQ1h1cVNCbEhBRTZYdy15ZUpBMFR1bncaJEVnWjJhV1JsYjNNd0FqZ0JZQUZxQUxnQkFDQUFlZ0V4R0FFPQ%3D%3D&gl=US&hl=en")
produce_channel_videos_url(ucid: "UCXuqSBlHAE6Xw-yeJA0Tunw", sort_by: "popular").should eq("/browse_ajax?continuation=4qmFsgJAEhhVQ1h1cVNCbEhBRTZYdy15ZUpBMFR1bncaJEVnWjJhV1JsYjNNd0FqZ0JZQUZxQUxnQkFDQUFlZ0V4R0FFPQ%3D%3D&gl=JP&hl=en")
#produce_channel_videos_url(ucid: "UCXuqSBlHAE6Xw-yeJA0Tunw", page: 20).should eq("/browse_ajax?continuation=4qmFsgJAEhhVQ1h1cVNCbEhBRTZYdy15ZUpBMFR1bncaJEVnWjJhV1JsYjNNd0FqZ0JZQUZxQUxnQkFDQUFlZ0l5TUE9PQ%3D%3D&gl=JP&hl=ja")
produce_channel_videos_url(ucid: "UCXuqSBlHAE6Xw-yeJA0Tunw", page: 20).should eq("/browse_ajax?continuation=4qmFsgJAEhhVQ1h1cVNCbEhBRTZYdy15ZUpBMFR1bncaJEVnWjJhV1JsYjNNd0FqZ0JZQUZxQUxnQkFDQUFlZ0l5TUE9PQ%3D%3D&gl=US&hl=en")
produce_channel_videos_url(ucid: "UCXuqSBlHAE6Xw-yeJA0Tunw", page: 20).should eq("/browse_ajax?continuation=4qmFsgJAEhhVQ1h1cVNCbEhBRTZYdy15ZUpBMFR1bncaJEVnWjJhV1JsYjNNd0FqZ0JZQUZxQUxnQkFDQUFlZ0l5TUE9PQ%3D%3D&gl=JP&hl=en")
#produce_channel_videos_url(ucid: "UC-9-kyTW8ZkZNDHQJ6FgpwQ", page: 20, sort_by: "popular").should eq("/browse_ajax?continuation=4qmFsgJAEhhVQy05LWt5VFc4WmtaTkRIUUo2Rmdwd1EaJEVnWjJhV1JsYjNNd0FqZ0JZQUZxQUxnQkFDQUFlZ0l5TUJnQg%3D%3D&gl=JP&hl=ja")
produce_channel_videos_url(ucid: "UC-9-kyTW8ZkZNDHQJ6FgpwQ", page: 20, sort_by: "popular").should eq("/browse_ajax?continuation=4qmFsgJAEhhVQy05LWt5VFc4WmtaTkRIUUo2Rmdwd1EaJEVnWjJhV1JsYjNNd0FqZ0JZQUZxQUxnQkFDQUFlZ0l5TUJnQg%3D%3D&gl=US&hl=en")
produce_channel_videos_url(ucid: "UC-9-kyTW8ZkZNDHQJ6FgpwQ", page: 20, sort_by: "popular").should eq("/browse_ajax?continuation=4qmFsgJAEhhVQy05LWt5VFc4WmtaTkRIUUo2Rmdwd1EaJEVnWjJhV1JsYjNNd0FqZ0JZQUZxQUxnQkFDQUFlZ0l5TUJnQg%3D%3D&gl=JP&hl=en")
end
end
@ -41,8 +37,7 @@ describe "Helper" do
describe "#produce_channel_playlists_url" do
it "correctly produces a /browse_ajax URL with the given UCID and cursor" do
produce_channel_playlists_url("UCCj956IF62FbT7Gouszaj9w", "AIOkY9EQpi_gyn1_QrFuZ1reN81_MMmI1YmlBblw8j7JHItEFG5h7qcJTNd4W9x5Quk_CVZ028gW").should eq("/browse_ajax?continuation=4qmFsgLNARIYVUNDajk1NklGNjJGYlQ3R291c3phajl3GrABRWdsd2JHRjViR2x6ZEhNd0FqZ0JZQUZxQUxnQkFIcG1VVlZzVUdFeGF6VlNWa1ozWVZZNWJtVlhOSGhZTVVaNVVtNVdZVTFZU214VWFtZDRXREF4VG1KVmEzaFhWekZ6VVcxS2MyUjZhSEZPTUhCSlUxaFNSbEpyWXpGaFJHUjRXVEJ3VlZSdFVUQldlbXcwVGxaR01XRXhPVVJXYkc5M1RXcG9ibFozSUFFWUF3PT0%3D&gl=JP&hl=ja")
produce_channel_playlists_url("UCCj956IF62FbT7Gouszaj9w", "AIOkY9EQpi_gyn1_QrFuZ1reN81_MMmI1YmlBblw8j7JHItEFG5h7qcJTNd4W9x5Quk_CVZ028gW").should eq("/browse_ajax?continuation=4qmFsgLNARIYVUNDajk1NklGNjJGYlQ3R291c3phajl3GrABRWdsd2JHRjViR2x6ZEhNd0FqZ0JZQUZxQUxnQkFIcG1VVlZzVUdFeGF6VlNWa1ozWVZZNWJtVlhOSGhZTVVaNVVtNVdZVTFZU214VWFtZDRXREF4VG1KVmEzaFhWekZ6VVcxS2MyUjZhSEZPTUhCSlUxaFNSbEpyWXpGaFJHUjRXVEJ3VlZSdFVUQldlbXcwVGxaR01XRXhPVVJXYkc5M1RXcG9ibFozSUFFWUF3PT0%3D&gl=US&hl=en")
produce_channel_playlists_url("UCCj956IF62FbT7Gouszaj9w", "AIOkY9EQpi_gyn1_QrFuZ1reN81_MMmI1YmlBblw8j7JHItEFG5h7qcJTNd4W9x5Quk_CVZ028gW").should eq("/browse_ajax?continuation=4qmFsgLNARIYVUNDajk1NklGNjJGYlQ3R291c3phajl3GrABRWdsd2JHRjViR2x6ZEhNd0FqZ0JZQUZxQUxnQkFIcG1VVlZzVUdFeGF6VlNWa1ozWVZZNWJtVlhOSGhZTVVaNVVtNVdZVTFZU214VWFtZDRXREF4VG1KVmEzaFhWekZ6VVcxS2MyUjZhSEZPTUhCSlUxaFNSbEpyWXpGaFJHUjRXVEJ3VlZSdFVUQldlbXcwVGxaR01XRXhPVVJXYkc5M1RXcG9ibFozSUFFWUF3PT0%3D&gl=JP&hl=en")
end
end

View file

@ -813,8 +813,7 @@ post "/data_control" do |env|
if match = channel["url"].as_s.match(/\/channel\/(?<channel>UC[a-zA-Z0-9_-]{22})/)
next match["channel"]
elsif match = channel["url"].as_s.match(/\/user\/(?<user>.+)/)
response = YT_POOL.client &.get("/user/#{match["user"]}?disable_polymer=1&hl=ja&gl=JP")
#response = YT_POOL.client &.get("/user/#{match["user"]}?disable_polymer=1&hl=en&gl=US")
response = YT_POOL.client &.get("/user/#{match["user"]}?disable_polymer=1&hl=en&gl=JP")
html = XML.parse_html(response.body)
ucid = html.xpath_node(%q(//link[@rel="canonical"])).try &.["href"].split("/")[-1]
next ucid if ucid

View file

@ -29,11 +29,9 @@ struct AboutRelatedChannel
end
def get_about_info(ucid, locale)
#result = YT_POOL.client &.get("/channel/#{ucid}/about?gl=JP&hl=ja")
result = YT_POOL.client &.get("/channel/#{ucid}/about?gl=US&hl=en")
result = YT_POOL.client &.get("/channel/#{ucid}/about?gl=JP&hl=en")
if result.status_code != 200
#result = YT_POOL.client &.get("/user/#{ucid}/about?gl=JP&hl=ja")
result = YT_POOL.client &.get("/user/#{ucid}/about?gl=US&hl=en")
result = YT_POOL.client &.get("/user/#{ucid}/about?gl=JP&hl=en")
end
if md = result.headers["location"]?.try &.match(/\/channel\/(?<ucid>UC[a-zA-Z0-9_-]{22})/)

View file

@ -1,10 +1,8 @@
# TODO: Add "sort_by"
def fetch_channel_community(ucid, continuation, locale, format, thin_mode)
response = YT_POOL.client &.get("/channel/#{ucid}/community?gl=JP&hl=ja")
#response = YT_POOL.client &.get("/channel/#{ucid}/community?gl=US&hl=en")
response = YT_POOL.client &.get("/channel/#{ucid}/community?gl=JP&hl=en")
if response.status_code != 200
response = YT_POOL.client &.get("/user/#{ucid}/community?gl=JP&hl=ja")
#response = YT_POOL.client &.get("/user/#{ucid}/community?gl=US&hl=en")
response = YT_POOL.client &.get("/user/#{ucid}/community?gl=JP&hl=en")
end
if response.status_code != 200
@ -33,8 +31,7 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode)
session_token: session_token,
}
response = YT_POOL.client &.post("/comment_service_ajax?action_get_comments=1&ctoken=#{continuation}&continuation=#{continuation}&hl=ja&gl=JP", headers, form: post_req)
#response = YT_POOL.client &.post("/comment_service_ajax?action_get_comments=1&ctoken=#{continuation}&continuation=#{continuation}&hl=en&gl=US", headers, form: post_req)
response = YT_POOL.client &.post("/comment_service_ajax?action_get_comments=1&ctoken=#{continuation}&continuation=#{continuation}&hl=en&gl=JP", headers, form: post_req)
body = JSON.parse(response.body)
body = body["response"]["continuationContents"]["itemSectionContinuation"]? ||

View file

@ -89,6 +89,5 @@ def produce_channel_playlists_url(ucid, cursor, sort = "newest", auto_generated
.try { |i| Base64.urlsafe_encode(i) }
.try { |i| URI.encode_www_form(i) }
#return "/browse_ajax?continuation=#{continuation}&gl=JP&hl=ja"
return "/browse_ajax?continuation=#{continuation}&gl=US&hl=en"
return "/browse_ajax?continuation=#{continuation}&gl=JP&hl=en"
end

View file

@ -85,5 +85,5 @@ end
# Used in bypass_captcha_job.cr
def produce_channel_videos_url(ucid, page = 1, auto_generated = nil, sort_by = "newest", v2 = false)
continuation = produce_channel_videos_continuation(ucid, page, auto_generated, sort_by, v2)
return "/browse_ajax?continuation=#{continuation}&gl=JP&hl=ja"
return "/browse_ajax?continuation=#{continuation}&gl=JP&hl=en"
end

View file

@ -88,8 +88,7 @@ def fetch_youtube_comments(id, db, cursor, format, locale, thin_mode, region, so
"cookie" => video.cookie,
}
#response = YT_POOL.client(region, &.post("/comment_service_ajax?#{action}=1&hl=ja&gl=JP&pbj=1", headers, form: post_req))
response = YT_POOL.client(region, &.post("/comment_service_ajax?#{action}=1&hl=en&gl=US&pbj=1", headers, form: post_req))
response = YT_POOL.client(region, &.post("/comment_service_ajax?#{action}=1&hl=en&gl=JP&pbj=1", headers, form: post_req))
response = JSON.parse(response.body)
# For some reason youtube puts it in an array for comment_replies but otherwise it's the same

View file

@ -36,8 +36,7 @@ struct ConfigPreferences
property latest_only : Bool = false
property listen : Bool = false
property local : Bool = false
#property locale : String = "ja-JP"
property locale : String = "en-US"
property locale : String = "ja-JP"
property max_results : Int32 = 40
property notifications_only : Bool = false
property player_style : String = "invidious"
@ -220,10 +219,8 @@ def login_req(f_req)
"pstMsg" => "1",
"checkConnection" => "youtube",
"checkedDomains" => "youtube",
#"hl" => "ja",
#"deviceinfo" => %|[null,null,null,[],null,"JP",null,null,[],"GlifWebSignIn",null,[null,null,[]]]|,
"hl" => "en",
"deviceinfo" => %|[null,null,null,[],null,"US",null,null,[],"GlifWebSignIn",null,[null,null,[]]]|,
"deviceinfo" => %|[null,null,null,[],null,"JP",null,null,[],"GlifWebSignIn",null,[null,null,[]]]|,
"f.req" => f_req,
"flowName" => "GlifWebSignIn",
"flowEntry" => "ServiceLogin",

View file

@ -12,7 +12,7 @@ struct DecryptFunction
end
private def fetch_decrypt_function(id = "CvFH_6DNRCY")
document = YT_POOL.client &.get("/watch?v=#{id}&gl=JP&hl=ja").body
document = YT_POOL.client &.get("/watch?v=#{id}&gl=JP&hl=en").body
url = document.match(/src="(?<url>\/s\/player\/[^\/]+\/player_ias[^\/]+\/ja_JP\/base.js)"/).not_nil!["url"]
player = YT_POOL.client &.get(url).body

View file

@ -6,7 +6,7 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob
if !random_video
random_video = {id: "zj82_v2R6ts", ucid: "UCK87Lox575O_HCHBWaBSyGA"}
end
{"/watch?v=#{random_video["id"]}&gl=JP&hl=ja&has_verified=1&bpctr=9999999999", produce_channel_videos_url(ucid: random_video["ucid"])}.each do |path|
{"/watch?v=#{random_video["id"]}&gl=JP&hl=en&has_verified=1&bpctr=9999999999", produce_channel_videos_url(ucid: random_video["ucid"])}.each do |path|
response = YT_POOL.client &.get(path)
if response.body.includes?("To continue with your YouTube experience, please fill out the form below.")
html = XML.parse_html(response.body)

View file

@ -26,7 +26,7 @@ def fetch_mix(rdid, video_id, cookies = nil, locale = nil)
end
video_id = "CvFH_6DNRCY" if rdid.starts_with? "OLAK5uy_"
response = YT_POOL.client &.get("/watch?v=#{video_id}&list=#{rdid}&gl=JP&hl=ja", headers)
response = YT_POOL.client &.get("/watch?v=#{video_id}&list=#{rdid}&gl=JP&hl=en", headers)
initial_data = extract_initial_data(response.body)
if !initial_data["contents"]["twoColumnWatchNextResults"]["playlist"]?

View file

@ -58,8 +58,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute
headers = login_page.cookies.add_request_headers(headers)
lookup_req = {
#email, nil, [] of String, nil, "JP", nil, nil, 2, false, true,
email, nil, [] of String, nil, "US", nil, nil, 2, false, true,
email, nil, [] of String, nil, "JP", nil, nil, 2, false, true,
{nil, nil,
{2, 1, nil, 1,
"https://accounts.google.com/ServiceLogin?passive=true&continue=https%3A%2F%2Fwww.youtube.com%2Fsignin%3Fnext%3D%252F%26action_handle_signin%3Dtrue%26hl%3Den%26app%3Ddesktop%26feature%3Dsign_in_button&hl=en&service=youtube&uilel=3&requestPath=%2FServiceLogin&Page=PasswordSeparationSignIn",

View file

@ -968,8 +968,7 @@ def get_video(id, db, refresh = true, region = nil, force_refresh = false)
end
def fetch_video(id, region)
#response = YT_POOL.client(region, &.get("/watch?v=#{id}&gl=JP&hl=ja&has_verified=1&bpctr=9999999999"))
response = YT_POOL.client(region, &.get("/watch?v=#{id}&gl=US&hl=en&has_verified=1&bpctr=9999999999"))
response = YT_POOL.client(region, &.get("/watch?v=#{id}&gl=JP&hl=en&has_verified=1&bpctr=9999999999"))
if md = response.headers["location"]?.try &.match(/v=(?<id>[a-zA-Z0-9_-]{11})/)
raise VideoRedirect.new(video_id: md["id"])
@ -984,8 +983,7 @@ def fetch_video(id, region)
bypass_regions = PROXY_LIST.keys & allowed_regions
if !bypass_regions.empty?
region = bypass_regions[rand(bypass_regions.size)]
#response = YT_POOL.client(region, &.get("/watch?v=#{id}&gl=JP&hl=ja&has_verified=1&bpctr=9999999999"))
response = YT_POOL.client(region, &.get("/watch?v=#{id}&gl=US&hl=en&has_verified=1&bpctr=9999999999"))
response = YT_POOL.client(region, &.get("/watch?v=#{id}&gl=JP&hl=en&has_verified=1&bpctr=9999999999"))
region_info = extract_polymer_config(response.body)
region_info["region"] = JSON::Any.new(region) if region
@ -1000,9 +998,7 @@ def fetch_video(id, region)
"video_id" => id,
"eurl" => "https://youtube.googleapis.com/v/#{id}",
"html5" => "1",
#"gl" => "JP",
#"hl" => "ja",
"gl" => "US",
"gl" => "JP",
"hl" => "en",
}
if info["reason"].as_s.includes?("inappropriate")