forked from MarmadileManteater/FreeTubeAndroid
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/improve-responsiveness-when-chan…
…nel-names-are-long' into development # Conflicts: # package.json # src/renderer/components/player-settings/player-settings.js # src/renderer/helpers/utils.js # src/renderer/store/modules/settings.js # src/renderer/views/Channel/Channel.js # static/locales/en-US.yaml # yarn.lock
- Loading branch information
Showing
170 changed files
with
1,877 additions
and
8,222 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
/** | ||
* This script updates the files in static/geolocations with the available locations on YouTube. | ||
* | ||
* It tries to map every active FreeTube language (static/locales/activelocales.json) | ||
* to it's equivalent on YouTube. | ||
* | ||
* It then uses those language mappings, | ||
* to scrape the location selection menu on the YouTube website, in every mapped language. | ||
* | ||
* All languages it couldn't find on YouTube, that don't have manually added mapping, | ||
* get logged to the console, as well as all unmapped YouTube languages. | ||
*/ | ||
|
||
import { mkdirSync, readFileSync, rmSync, writeFileSync } from 'fs' | ||
import { dirname } from 'path' | ||
import { fileURLToPath } from 'url' | ||
import { Innertube, Misc } from 'youtubei.js' | ||
|
||
const STATIC_DIRECTORY = `${dirname(fileURLToPath(import.meta.url))}/../static` | ||
|
||
const activeLanguagesPath = `${STATIC_DIRECTORY}/locales/activeLocales.json` | ||
/** @type {string[]} */ | ||
const activeLanguages = JSON.parse(readFileSync(activeLanguagesPath, { encoding: 'utf8' })) | ||
|
||
// en-US is en on YouTube | ||
const initialResponse = await scrapeLanguage('en') | ||
|
||
// Scrape language menu in en-US | ||
|
||
/** @type {string[]} */ | ||
const youTubeLanguages = initialResponse.data.actions[0].openPopupAction.popup.multiPageMenuRenderer.sections[1].multiPageMenuSectionRenderer.items[1].compactLinkRenderer.serviceEndpoint.signalServiceEndpoint.actions[0].getMultiPageMenuAction.menu.multiPageMenuRenderer.sections[0].multiPageMenuSectionRenderer.items | ||
.map(({ compactLinkRenderer }) => { | ||
return compactLinkRenderer.serviceEndpoint.signalServiceEndpoint.actions[0].selectLanguageCommand.hl | ||
}) | ||
|
||
// map FreeTube languages to their YouTube equivalents | ||
|
||
const foundLanguageNames = ['en-US'] | ||
const unusedYouTubeLanguageNames = [] | ||
const languagesToScrape = [] | ||
|
||
for (const language of youTubeLanguages) { | ||
if (activeLanguages.includes(language)) { | ||
foundLanguageNames.push(language) | ||
languagesToScrape.push({ | ||
youTube: language, | ||
freeTube: language | ||
}) | ||
} else if (activeLanguages.includes(language.replace('-', '_'))) { | ||
const withUnderScore = language.replace('-', '_') | ||
foundLanguageNames.push(withUnderScore) | ||
languagesToScrape.push({ | ||
youTube: language, | ||
freeTube: withUnderScore | ||
}) | ||
} | ||
// special cases | ||
else if (language === 'de') { | ||
foundLanguageNames.push('de-DE') | ||
languagesToScrape.push({ | ||
youTube: 'de', | ||
freeTube: 'de-DE' | ||
}) | ||
} else if (language === 'fr') { | ||
foundLanguageNames.push('fr-FR') | ||
languagesToScrape.push({ | ||
youTube: 'fr', | ||
freeTube: 'fr-FR' | ||
}) | ||
} else if (language === 'no') { | ||
// according to https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes | ||
// "no" is the macro language for "nb" and "nn" | ||
foundLanguageNames.push('nb_NO', 'nn') | ||
languagesToScrape.push({ | ||
youTube: 'no', | ||
freeTube: 'nb_NO' | ||
}) | ||
languagesToScrape.push({ | ||
youTube: 'no', | ||
freeTube: 'nn' | ||
}) | ||
} else if (language !== 'en') { | ||
unusedYouTubeLanguageNames.push(language) | ||
} | ||
} | ||
|
||
console.log("Active FreeTube languages that aren't available on YouTube:") | ||
console.log(activeLanguages.filter(lang => !foundLanguageNames.includes(lang)).sort()) | ||
|
||
console.log("YouTube languages that don't have an equivalent active FreeTube language:") | ||
console.log(unusedYouTubeLanguageNames.sort()) | ||
|
||
// Scrape the location menu in various languages and write files to the file system | ||
|
||
rmSync(`${STATIC_DIRECTORY}/geolocations`, { recursive: true }) | ||
mkdirSync(`${STATIC_DIRECTORY}/geolocations`) | ||
|
||
processGeolocations('en-US', 'en', initialResponse) | ||
|
||
for (const { youTube, freeTube } of languagesToScrape) { | ||
const response = await scrapeLanguage(youTube) | ||
|
||
processGeolocations(freeTube, youTube, response) | ||
} | ||
|
||
|
||
|
||
async function scrapeLanguage(youTubeLanguageCode) { | ||
const session = await Innertube.create({ | ||
retrieve_player: false, | ||
generate_session_locally: true, | ||
lang: youTubeLanguageCode | ||
}) | ||
|
||
return await session.actions.execute('/account/account_menu') | ||
} | ||
|
||
function processGeolocations(freeTubeLanguage, youTubeLanguage, response) { | ||
const geolocations = response.data.actions[0].openPopupAction.popup.multiPageMenuRenderer.sections[1].multiPageMenuSectionRenderer.items[3].compactLinkRenderer.serviceEndpoint.signalServiceEndpoint.actions[0].getMultiPageMenuAction.menu.multiPageMenuRenderer.sections[0].multiPageMenuSectionRenderer.items | ||
.map(({ compactLinkRenderer }) => { | ||
return { | ||
name: new Misc.Text(compactLinkRenderer.title).toString().trim(), | ||
code: compactLinkRenderer.serviceEndpoint.signalServiceEndpoint.actions[0].selectCountryCommand.gl | ||
} | ||
}) | ||
|
||
const normalisedFreeTubeLanguage = freeTubeLanguage.replace('_', '-') | ||
|
||
// give Intl.Collator 4 locales, in the hopes that it supports one of them | ||
// deduplicate the list so it doesn't have to do duplicate work | ||
const localeSet = new Set() | ||
localeSet.add(normalisedFreeTubeLanguage) | ||
localeSet.add(youTubeLanguage) | ||
localeSet.add(normalisedFreeTubeLanguage.split('-')[0]) | ||
localeSet.add(youTubeLanguage.split('-')[0]) | ||
|
||
const locales = Array.from(localeSet) | ||
|
||
// only sort if node supports sorting the language, otherwise hope that YouTube's sorting was correct | ||
// node 20.3.1 doesn't support sorting `eu` | ||
if (Intl.Collator.supportedLocalesOf(locales).length > 0) { | ||
const collator = new Intl.Collator(locales) | ||
|
||
geolocations.sort((a, b) => collator.compare(a.name, b.name)) | ||
} | ||
|
||
writeFileSync(`${STATIC_DIRECTORY}/geolocations/${freeTubeLanguage}.json`, JSON.stringify(geolocations)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.