From 35011723e6bbc6074b143c3ec297b9e473df12d8 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Sat, 13 Sep 2025 06:05:20 +0530 Subject: [PATCH 1/3] Remove LocaleCompat class --- .../extractor/localization/Localization.java | 28 +++++------- .../extractors/MediaCCCStreamExtractor.java | 6 +-- .../extractors/YoutubeStreamExtractor.java | 6 +-- .../extractor/stream/SubtitlesStream.java | 7 +-- .../newpipe/extractor/utils/LocaleCompat.java | 44 ------------------- 5 files changed, 15 insertions(+), 76 deletions(-) delete mode 100644 extractor/src/main/java/org/schabi/newpipe/extractor/utils/LocaleCompat.java diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/localization/Localization.java b/extractor/src/main/java/org/schabi/newpipe/extractor/localization/Localization.java index 5727150fe3..87dff8d45e 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/localization/Localization.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/localization/Localization.java @@ -1,17 +1,15 @@ package org.schabi.newpipe.extractor.localization; import org.schabi.newpipe.extractor.exceptions.ParsingException; -import org.schabi.newpipe.extractor.utils.LocaleCompat; import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; -import java.util.Optional; +import java.util.stream.Collectors; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -26,21 +24,15 @@ public class Localization implements Serializable { private final String countryCode; /** - * @param localizationCodeList a list of localization code, formatted like {@link - * #getLocalizationCode()} - * @throws IllegalArgumentException If any of the localizationCodeList is formatted incorrectly + * @param localizationCodes a list of localization code, formatted like + * {@link #getLocalizationCode()} * @return list of Localization objects */ @Nonnull - public static List listFrom(final String... localizationCodeList) { - final List toReturn = new ArrayList<>(); - for (final String localizationCode : localizationCodeList) { - toReturn.add(fromLocalizationCode(localizationCode) - .orElseThrow(() -> new IllegalArgumentException( - "Not a localization code: " + localizationCode - ))); - } - return Collections.unmodifiableList(toReturn); + public static List listFrom(final String... localizationCodes) { + return Arrays.stream(localizationCodes) + .map(Localization::fromLocalizationCode) + .collect(Collectors.toUnmodifiableList()); } /** @@ -48,8 +40,8 @@ public static List listFrom(final String... localizationCodeList) * @return A Localization, if the code was valid. */ @Nonnull - public static Optional fromLocalizationCode(final String localizationCode) { - return LocaleCompat.forLanguageTag(localizationCode).map(Localization::fromLocale); + public static Localization fromLocalizationCode(final String localizationCode) { + return Localization.fromLocale(Locale.forLanguageTag(localizationCode)); } public Localization(@Nonnull final String languageCode, @Nullable final String countryCode) { diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCStreamExtractor.java index 99ddf5e08c..a9e4a4b046 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCStreamExtractor.java @@ -28,7 +28,6 @@ import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.VideoStream; import org.schabi.newpipe.extractor.utils.JsonUtils; -import org.schabi.newpipe.extractor.utils.LocaleCompat; import java.io.IOException; import java.util.ArrayList; @@ -130,10 +129,7 @@ public List getAudioStreams() throws ExtractionException { // track with multiple languages, so there is no specific language for this stream // Don't set the audio language in this case if (language != null && !language.contains("-")) { - builder.setAudioLocale(LocaleCompat.forLanguageTag(language).orElseThrow(() -> - new ParsingException( - "Cannot convert this language to a locale: " + language) - )); + builder.setAudioLocale(Locale.forLanguageTag(language)); } // Not checking containsSimilarStream here, since MediaCCC does not provide enough diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java index eb050fd13e..6d230298a2 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java @@ -79,7 +79,6 @@ import org.schabi.newpipe.extractor.stream.SubtitlesStream; import org.schabi.newpipe.extractor.stream.VideoStream; import org.schabi.newpipe.extractor.utils.JsonUtils; -import org.schabi.newpipe.extractor.utils.LocaleCompat; import org.schabi.newpipe.extractor.utils.Pair; import org.schabi.newpipe.extractor.utils.Parser; import org.schabi.newpipe.extractor.utils.Utils; @@ -1412,9 +1411,8 @@ private ItagInfo buildAndAddItagInfoToList( final int audioTrackIdLastLocaleCharacter = audioTrackId.indexOf("."); if (audioTrackIdLastLocaleCharacter != -1) { // Audio tracks IDs are in the form LANGUAGE_CODE.TRACK_NUMBER - LocaleCompat.forLanguageTag( - audioTrackId.substring(0, audioTrackIdLastLocaleCharacter) - ).ifPresent(itagItem::setAudioLocale); + final String tag = audioTrackId.substring(0, audioTrackIdLastLocaleCharacter); + itagItem.setAudioLocale(Locale.forLanguageTag(tag)); } itagItem.setAudioTrackType(YoutubeParsingHelper.extractAudioTrackType(streamUrl)); } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/SubtitlesStream.java b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/SubtitlesStream.java index 08886dcac6..1b8fb67119 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/SubtitlesStream.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/SubtitlesStream.java @@ -3,7 +3,6 @@ import org.schabi.newpipe.extractor.MediaFormat; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.services.youtube.ItagItem; -import org.schabi.newpipe.extractor.utils.LocaleCompat; import java.util.Locale; @@ -230,11 +229,9 @@ private SubtitlesStream(@Nonnull final String id, @Nonnull final DeliveryMethod deliveryMethod, @Nonnull final String languageCode, final boolean autoGenerated, - @Nullable final String manifestUrl) throws ParsingException { + @Nullable final String manifestUrl) { super(id, content, isUrl, mediaFormat, deliveryMethod, manifestUrl); - this.locale = LocaleCompat.forLanguageTag(languageCode).orElseThrow( - () -> new ParsingException( - "not a valid locale language code: " + languageCode)); + this.locale = Locale.forLanguageTag(languageCode); this.code = languageCode; this.format = mediaFormat; this.autoGenerated = autoGenerated; diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/utils/LocaleCompat.java b/extractor/src/main/java/org/schabi/newpipe/extractor/utils/LocaleCompat.java deleted file mode 100644 index 082a56824c..0000000000 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/utils/LocaleCompat.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.schabi.newpipe.extractor.utils; - -import java.util.Locale; -import java.util.Optional; - -/** - * This class contains a simple implementation of {@link Locale#forLanguageTag(String)} for Android - * API levels below 21 (Lollipop). This is needed as core library desugaring does not backport that - * method as of this writing. - *
- * Relevant issue: https://issuetracker.google.com/issues/171182330 - */ -public final class LocaleCompat { - private LocaleCompat() { - } - - // Source: The AndroidX LocaleListCompat class's private forLanguageTagCompat() method. - // Use Locale.forLanguageTag() on Android API level >= 21 / Java instead. - public static Optional forLanguageTag(final String str) { - if (str.contains("-")) { - final String[] args = str.split("-", -1); - if (args.length > 2) { - return Optional.of(new Locale(args[0], args[1], args[2])); - } else if (args.length > 1) { - return Optional.of(new Locale(args[0], args[1])); - } else if (args.length == 1) { - return Optional.of(new Locale(args[0])); - } - } else if (str.contains("_")) { - final String[] args = str.split("_", -1); - if (args.length > 2) { - return Optional.of(new Locale(args[0], args[1], args[2])); - } else if (args.length > 1) { - return Optional.of(new Locale(args[0], args[1])); - } else if (args.length == 1) { - return Optional.of(new Locale(args[0])); - } - } else { - return Optional.of(new Locale(str)); - } - - return Optional.empty(); - } -} From 1f262127c0c816c3380371a2cb170363b84247fa Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Mon, 13 Oct 2025 08:43:46 +0530 Subject: [PATCH 2/3] Replace Localization with Locale --- .../schabi/newpipe/extractor/Extractor.java | 15 +- .../org/schabi/newpipe/extractor/NewPipe.java | 50 +++---- .../newpipe/extractor/StreamingService.java | 66 ++++----- .../extractor/downloader/Downloader.java | 62 ++++----- .../newpipe/extractor/downloader/Request.java | 59 ++++---- .../newpipe/extractor/kiosk/KioskList.java | 42 +++--- .../localization/ContentCountry.java | 11 +- .../extractor/localization/Localization.java | 129 ------------------ .../localization/TimeAgoPatternsManager.java | 40 +++--- .../extractors/MediaCCCConferenceKiosk.java | 2 +- .../MediaCCCLiveStreamExtractor.java | 2 +- .../extractors/MediaCCCLiveStreamKiosk.java | 2 +- .../extractors/MediaCCCParsingHelper.java | 8 +- .../extractors/MediaCCCRecentKiosk.java | 2 +- .../extractors/MediaCCCSearchExtractor.java | 2 +- .../extractors/MediaCCCStreamExtractor.java | 9 +- .../extractors/PeertubeStreamExtractor.java | 2 +- .../soundcloud/SoundcloudParsingHelper.java | 12 +- .../SoundcloudChannelExtractor.java | 2 +- .../SoundcloudPlaylistExtractor.java | 4 +- .../extractors/SoundcloudSearchExtractor.java | 4 +- .../SoundcloudSuggestionExtractor.java | 2 +- .../youtube/YoutubeChannelHelper.java | 19 ++- .../youtube/YoutubeJavaScriptExtractor.java | 8 +- .../youtube/YoutubeParsingHelper.java | 45 +++--- .../services/youtube/YoutubeService.java | 8 +- .../services/youtube/YoutubeStreamHelper.java | 51 ++++--- .../extractors/YoutubeChannelExtractor.java | 2 +- .../YoutubeChannelTabExtractor.java | 6 +- .../extractors/YoutubeCommentsExtractor.java | 17 ++- .../YoutubeCommentsInfoItemExtractor.java | 2 +- .../YoutubeMixPlaylistExtractor.java | 11 +- .../extractors/YoutubePlaylistExtractor.java | 17 ++- .../extractors/YoutubeSearchExtractor.java | 19 ++- .../extractors/YoutubeStreamExtractor.java | 45 +++--- .../YoutubeSuggestionExtractor.java | 2 +- .../YoutubeChartsBaseKioskExtractor.java | 20 ++- .../YoutubeDesktopBaseKioskExtractor.java | 6 +- .../kiosk/YoutubeTrendingExtractor.java | 4 +- .../extractor/stream/SubtitlesStream.java | 6 +- .../suggestion/SuggestionExtractor.java | 12 +- .../localization/TimeAgoParserTest.java | 18 ++- .../MediaCCCStreamExtractorTest.java | 4 +- .../peertube/PeertubeStreamExtractorTest.java | 4 +- .../YoutubeChannelLocalizationTest.java | 37 +++-- .../youtube/YoutubeCommentsExtractorTest.java | 19 +-- .../YoutubeMixPlaylistExtractorTest.java | 24 ++-- .../YoutubeSuggestionExtractorTest.java | 11 +- .../GeneratePatternClasses.java | 17 +-- .../newpipe/extractor/timeago/PatternMap.java | 18 +-- .../extractor/timeago/PatternsManager.java | 18 --- 51 files changed, 388 insertions(+), 609 deletions(-) delete mode 100644 extractor/src/main/java/org/schabi/newpipe/extractor/localization/Localization.java delete mode 100644 timeago-parser/src/main/java/org/schabi/newpipe/extractor/timeago/PatternsManager.java diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/Extractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/Extractor.java index e973b44167..2f9fbb4ffa 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/Extractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/Extractor.java @@ -5,13 +5,12 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.linkhandler.LinkHandler; import org.schabi.newpipe.extractor.localization.ContentCountry; -import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.localization.TimeAgoParser; import javax.annotation.Nonnull; import javax.annotation.Nullable; - import java.io.IOException; +import java.util.Locale; import java.util.Objects; public abstract class Extractor { @@ -24,7 +23,7 @@ public abstract class Extractor { private final LinkHandler linkHandler; @Nullable - private Localization forcedLocalization = null; + private Locale forcedLocale = null; @Nullable private ContentCountry forcedContentCountry = null; @@ -128,8 +127,8 @@ public Downloader getDownloader() { // Localization //////////////////////////////////////////////////////////////////////////*/ - public void forceLocalization(final Localization localization) { - this.forcedLocalization = localization; + public void forceLocale(final Locale locale) { + this.forcedLocale = locale; } public void forceContentCountry(final ContentCountry contentCountry) { @@ -137,8 +136,8 @@ public void forceContentCountry(final ContentCountry contentCountry) { } @Nonnull - public Localization getExtractorLocalization() { - return forcedLocalization == null ? getService().getLocalization() : forcedLocalization; + public Locale getExtractorLocale() { + return forcedLocale == null ? getService().getLocale() : forcedLocale; } @Nonnull @@ -149,6 +148,6 @@ public ContentCountry getExtractorContentCountry() { @Nonnull public TimeAgoParser getTimeAgoParser() { - return getService().getTimeAgoParser(getExtractorLocalization()); + return getService().getTimeAgoParser(getExtractorLocale()); } } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/NewPipe.java b/extractor/src/main/java/org/schabi/newpipe/extractor/NewPipe.java index 7dfa4c4cde..50e057e8cb 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/NewPipe.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/NewPipe.java @@ -23,36 +23,34 @@ import org.schabi.newpipe.extractor.downloader.Downloader; import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.localization.ContentCountry; -import org.schabi.newpipe.extractor.localization.Localization; - -import java.util.List; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.List; +import java.util.Locale; /** * Provides access to streaming services supported by NewPipe. */ public final class NewPipe { private static Downloader downloader; - private static Localization preferredLocalization; + private static Locale preferredLocale; private static ContentCountry preferredContentCountry; private NewPipe() { } public static void init(final Downloader d) { - init(d, Localization.DEFAULT); + init(d, Locale.UK); } - public static void init(final Downloader d, final Localization l) { - init(d, l, l.getCountryCode().isEmpty() - ? ContentCountry.DEFAULT : new ContentCountry(l.getCountryCode())); + public static void init(final Downloader d, final Locale l) { + init(d, l, ContentCountry.fromLocale(l)); } - public static void init(final Downloader d, final Localization l, final ContentCountry c) { + public static void init(final Downloader d, final Locale l, final ContentCountry c) { downloader = d; - preferredLocalization = l; + preferredLocale = l; preferredContentCountry = c; } @@ -97,31 +95,23 @@ public static StreamingService getServiceByUrl(final String url) throws Extracti // Localization //////////////////////////////////////////////////////////////////////////*/ - public static void setupLocalization(final Localization thePreferredLocalization) { - setupLocalization(thePreferredLocalization, null); + public static void setupLocalization(final Locale locale) { + setupLocalization(locale, null); } - public static void setupLocalization( - final Localization thePreferredLocalization, - @Nullable final ContentCountry thePreferredContentCountry) { - NewPipe.preferredLocalization = thePreferredLocalization; - - if (thePreferredContentCountry != null) { - NewPipe.preferredContentCountry = thePreferredContentCountry; - } else { - NewPipe.preferredContentCountry = thePreferredLocalization.getCountryCode().isEmpty() - ? ContentCountry.DEFAULT - : new ContentCountry(thePreferredLocalization.getCountryCode()); - } + public static void setupLocalization(final Locale locale, + @Nullable final ContentCountry country) { + preferredLocale = locale; + preferredContentCountry = country != null ? country : ContentCountry.fromLocale(locale); } @Nonnull - public static Localization getPreferredLocalization() { - return preferredLocalization == null ? Localization.DEFAULT : preferredLocalization; + public static Locale getPreferredLocale() { + return preferredLocale == null ? Locale.UK : preferredLocale; } - public static void setPreferredLocalization(final Localization preferredLocalization) { - NewPipe.preferredLocalization = preferredLocalization; + public static void setPreferredLocale(final Locale locale) { + preferredLocale = locale; } @Nonnull @@ -129,7 +119,7 @@ public static ContentCountry getPreferredContentCountry() { return preferredContentCountry == null ? ContentCountry.DEFAULT : preferredContentCountry; } - public static void setPreferredContentCountry(final ContentCountry preferredContentCountry) { - NewPipe.preferredContentCountry = preferredContentCountry; + public static void setPreferredContentCountry(final ContentCountry contentCountry) { + preferredContentCountry = contentCountry; } } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/StreamingService.java b/extractor/src/main/java/org/schabi/newpipe/extractor/StreamingService.java index e7d88c2379..c6449f3ab6 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/StreamingService.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/StreamingService.java @@ -14,7 +14,6 @@ import org.schabi.newpipe.extractor.linkhandler.SearchQueryHandler; import org.schabi.newpipe.extractor.linkhandler.SearchQueryHandlerFactory; import org.schabi.newpipe.extractor.localization.ContentCountry; -import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.localization.TimeAgoParser; import org.schabi.newpipe.extractor.localization.TimeAgoPatternsManager; import org.schabi.newpipe.extractor.playlist.PlaylistExtractor; @@ -27,6 +26,7 @@ import javax.annotation.Nullable; import java.util.Collections; import java.util.List; +import java.util.Locale; /* * Copyright (C) 2018 Christian Schabesberger @@ -344,44 +344,38 @@ public final LinkType getLinkTypeByUrl(final String url) throws ParsingException /** * Returns a list of localizations that this service supports. */ - public List getSupportedLocalizations() { - return Collections.singletonList(Localization.DEFAULT); + public List getSupportedLocales() { + return List.of(Locale.UK); } /** * Returns a list of countries that this service supports.
*/ public List getSupportedCountries() { - return Collections.singletonList(ContentCountry.DEFAULT); + return List.of(ContentCountry.DEFAULT); } /** - * Returns the localization that should be used in this service. It will get which localization - * the user prefer (using {@link NewPipe#getPreferredLocalization()}), then it will: + * Returns the localization that should be used in this service. It will get which locale + * the user prefers (using {@link NewPipe#getPreferredLocale()}), then it will: *
    - *
  • Check if the exactly localization is supported by this service.
  • + *
  • Check if the exact locale is supported by this service.
  • *
  • If not, check if a less specific localization is available, using only the language * code.
  • - *
  • Fallback to the {@link Localization#DEFAULT default} localization.
  • + *
  • Fallback to the {@link Locale#UK default} locale.
  • *
*/ - public Localization getLocalization() { - final Localization preferredLocalization = NewPipe.getPreferredLocalization(); - - // Check the localization's language and country - if (getSupportedLocalizations().contains(preferredLocalization)) { - return preferredLocalization; - } - - // Fallback to the first supported language that matches the preferred language - for (final Localization supportedLanguage : getSupportedLocalizations()) { - if (supportedLanguage.getLanguageCode() - .equals(preferredLocalization.getLanguageCode())) { - return supportedLanguage; - } - } - - return Localization.DEFAULT; + public Locale getLocale() { + final var preferredLocale = NewPipe.getPreferredLocale(); + return getSupportedLocales().stream() + .filter(locale -> { + // Check the localization's language and country + return preferredLocale.equals(locale) + // Fallback to the first supported language that matches the preferred + // language + || preferredLocale.getLanguage().equals(locale.getLanguage()); + }) + .findFirst().orElse(Locale.UK); } /** @@ -405,32 +399,18 @@ public ContentCountry getContentCountry() { /** * Get an instance of the time ago parser using the patterns related to the passed localization. *

- * Just like {@link #getLocalization()}, it will also try to fallback to a less specific + * Just like {@link #getLocale()}, it will also try to fallback to a less specific * localization if the exact one is not available/supported. * * @throws IllegalArgumentException if the localization is not supported (parsing patterns are * not present). */ - public TimeAgoParser getTimeAgoParser(final Localization localization) { - final TimeAgoParser targetParser = TimeAgoPatternsManager.getTimeAgoParserFor(localization); - + public TimeAgoParser getTimeAgoParser(final Locale locale) { + final var targetParser = TimeAgoPatternsManager.getTimeAgoParserFor(locale); if (targetParser != null) { return targetParser; } - - if (!localization.getCountryCode().isEmpty()) { - final Localization lessSpecificLocalization - = new Localization(localization.getLanguageCode()); - final TimeAgoParser lessSpecificParser - = TimeAgoPatternsManager.getTimeAgoParserFor(lessSpecificLocalization); - - if (lessSpecificParser != null) { - return lessSpecificParser; - } - } - - throw new IllegalArgumentException( - "Localization is not supported (\"" + localization + "\")"); + throw new IllegalArgumentException("Locale is not supported (\"" + locale + "\")"); } } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/downloader/Downloader.java b/extractor/src/main/java/org/schabi/newpipe/extractor/downloader/Downloader.java index aa7987156d..f72764628d 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/downloader/Downloader.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/downloader/Downloader.java @@ -2,14 +2,13 @@ import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.exceptions.ReCaptchaException; -import org.schabi.newpipe.extractor.localization.Localization; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.io.IOException; -import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; /** @@ -21,7 +20,7 @@ public abstract class Downloader { /** * Do a GET request to get the resource that the url is pointing to.
*
- * This method calls {@link #get(String, Map, Localization)} with the default preferred + * This method calls {@link #get(String, Map, Locale)} with the default preferred * localization. It should only be used when the resource that will be fetched won't be affected * by the localization. * @@ -29,21 +28,21 @@ public abstract class Downloader { * @return the result of the GET request */ public Response get(final String url) throws IOException, ReCaptchaException { - return get(url, null, NewPipe.getPreferredLocalization()); + return get(url, null, NewPipe.getPreferredLocale()); } /** * Do a GET request to get the resource that the url is pointing to.
*
- * It will set the {@code Accept-Language} header to the language of the localization parameter. + * It will set the {@code Accept-Language} header to the language of the locale parameter. * * @param url the URL that is pointing to the wanted resource - * @param localization the source of the value of the {@code Accept-Language} header + * @param locale the source of the value of the {@code Accept-Language} header * @return the result of the GET request */ - public Response get(final String url, final Localization localization) + public Response get(final String url, final Locale locale) throws IOException, ReCaptchaException { - return get(url, null, localization); + return get(url, null, locale); } /** @@ -56,7 +55,7 @@ public Response get(final String url, final Localization localization) */ public Response get(final String url, @Nullable final Map> headers) throws IOException, ReCaptchaException { - return get(url, headers, NewPipe.getPreferredLocalization()); + return get(url, headers, NewPipe.getPreferredLocale()); } /** @@ -67,17 +66,17 @@ public Response get(final String url, @Nullable final Map> * @param url the URL that is pointing to the wanted resource * @param headers a list of headers that will be used in the request. * Any default headers should be overridden by these. - * @param localization the source of the value of the {@code Accept-Language} header + * @param locale the source of the value of the {@code Accept-Language} header * @return the result of the GET request */ public Response get(final String url, @Nullable final Map> headers, - final Localization localization) + final Locale locale) throws IOException, ReCaptchaException { return execute(Request.newBuilder() .get(url) .headers(headers) - .localization(localization) + .locale(locale) .build()); } @@ -120,7 +119,7 @@ public Response post(final String url, @Nullable final Map> headers, @Nullable final byte[] dataToSend) throws IOException, ReCaptchaException { - return post(url, headers, dataToSend, NewPipe.getPreferredLocalization()); + return post(url, headers, dataToSend, NewPipe.getPreferredLocale()); } /** @@ -132,47 +131,47 @@ public Response post(final String url, * @param headers a list of headers that will be used in the request. * Any default headers should be overridden by these. * @param dataToSend byte array that will be sent when doing the request. - * @param localization the source of the value of the {@code Accept-Language} header + * @param locale the source of the value of the {@code Accept-Language} header * @return the result of the POST request */ public Response post(final String url, @Nullable final Map> headers, @Nullable final byte[] dataToSend, - final Localization localization) + final Locale locale) throws IOException, ReCaptchaException { return execute(Request.newBuilder() .post(url, dataToSend) .headers(headers) - .localization(localization) + .locale(locale) .build()); } /** * Convenient method to send a POST request using the specified value of the - * {@code Content-Type} header with a given {@link Localization}. + * {@code Content-Type} header with a given {@link Locale}. * * @param url the URL that is pointing to the wanted resource * @param headers a list of headers that will be used in the request. * Any default headers should be overridden by these. * @param dataToSend byte array that will be sent when doing the request. - * @param localization the source of the value of the {@code Accept-Language} header + * @param locale the source of the value of the {@code Accept-Language} header * @param contentType the mime type of the body sent, which will be set as the value of the * {@code Content-Type} header * @return the result of the POST request - * @see #post(String, Map, byte[], Localization) + * @see #post(String, Map, byte[], Locale) */ public Response postWithContentType(final String url, @Nullable final Map> headers, @Nullable final byte[] dataToSend, - final Localization localization, + final Locale locale, final String contentType) throws IOException, ReCaptchaException { final Map> actualHeaders = new HashMap<>(); if (headers != null) { actualHeaders.putAll(headers); } - actualHeaders.put("Content-Type", Collections.singletonList(contentType)); - return post(url, actualHeaders, dataToSend, localization); + actualHeaders.put("Content-Type", List.of(contentType)); + return post(url, actualHeaders, dataToSend, locale); } /** @@ -186,35 +185,35 @@ public Response postWithContentType(final String url, * @param contentType the mime type of the body sent, which will be set as the value of the * {@code Content-Type} header * @return the result of the POST request - * @see #post(String, Map, byte[], Localization) + * @see #post(String, Map, byte[], Locale) */ public Response postWithContentType(final String url, @Nullable final Map> headers, @Nullable final byte[] dataToSend, final String contentType) throws IOException, ReCaptchaException { - return postWithContentType(url, headers, dataToSend, NewPipe.getPreferredLocalization(), + return postWithContentType(url, headers, dataToSend, NewPipe.getPreferredLocale(), contentType); } /** * Convenient method to send a POST request the JSON mime type as the value of the - * {@code Content-Type} header with a given {@link Localization}. + * {@code Content-Type} header with a given {@link Locale}. * * @param url the URL that is pointing to the wanted resource * @param headers a list of headers that will be used in the request. * Any default headers should be overridden by these. * @param dataToSend byte array that will be sent when doing the request. - * @param localization the source of the value of the {@code Accept-Language} header + * @param locale the source of the value of the {@code Accept-Language} header * @return the result of the POST request - * @see #post(String, Map, byte[], Localization) + * @see #post(String, Map, byte[], Locale) */ public Response postWithContentTypeJson(final String url, @Nullable final Map> headers, @Nullable final byte[] dataToSend, - final Localization localization) + final Locale locale) throws IOException, ReCaptchaException { - return postWithContentType(url, headers, dataToSend, localization, "application/json"); + return postWithContentType(url, headers, dataToSend, locale, "application/json"); } /** @@ -226,14 +225,13 @@ public Response postWithContentTypeJson(final String url, * Any default headers should be overridden by these. * @param dataToSend byte array that will be sent when doing the request. * @return the result of the POST request - * @see #post(String, Map, byte[], Localization) + * @see #post(String, Map, byte[], Locale) */ public Response postWithContentTypeJson(final String url, @Nullable final Map> headers, @Nullable final byte[] dataToSend) throws IOException, ReCaptchaException { - return postWithContentTypeJson(url, headers, dataToSend, - NewPipe.getPreferredLocalization()); + return postWithContentTypeJson(url, headers, dataToSend, NewPipe.getPreferredLocale()); } /** diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/downloader/Request.java b/extractor/src/main/java/org/schabi/newpipe/extractor/downloader/Request.java index 5beb57007a..3f0f5b51b1 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/downloader/Request.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/downloader/Request.java @@ -1,18 +1,16 @@ package org.schabi.newpipe.extractor.downloader; -import org.schabi.newpipe.extractor.localization.Localization; - +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Objects; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - /** * An object that holds request information used when {@link Downloader#execute(Request) executing} * a request. @@ -24,33 +22,33 @@ public class Request { @Nullable private final byte[] dataToSend; @Nullable - private final Localization localization; + private final Locale locale; public Request(final String httpMethod, final String url, @Nullable final Map> headers, @Nullable final byte[] dataToSend, - @Nullable final Localization localization, + @Nullable final Locale locale, final boolean automaticLocalizationHeader) { this.httpMethod = Objects.requireNonNull(httpMethod, "Request's httpMethod is null"); this.url = Objects.requireNonNull(url, "Request's url is null"); this.dataToSend = dataToSend; - this.localization = localization; + this.locale = locale; final Map> actualHeaders = new LinkedHashMap<>(); if (headers != null) { actualHeaders.putAll(headers); } - if (automaticLocalizationHeader && localization != null) { - actualHeaders.putAll(getHeadersFromLocalization(localization)); + if (automaticLocalizationHeader && locale != null) { + actualHeaders.putAll(getHeadersFromLocale(locale)); } this.headers = Collections.unmodifiableMap(actualHeaders); } private Request(final Builder builder) { - this(builder.httpMethod, builder.url, builder.headers, builder.dataToSend, - builder.localization, builder.automaticLocalizationHeader); + this(builder.httpMethod, builder.url, builder.headers, builder.dataToSend, builder.locale, + builder.automaticLocalizationHeader); } /** @@ -91,11 +89,11 @@ public byte[] dataToSend() { * A localization object that should be used when executing a request.
*
* Usually the {@code Accept-Language} will be set to this value (a helper - * method to do this easily: {@link Request#getHeadersFromLocalization(Localization)}). + * method to do this easily: {@link Request#getHeadersFromLocale(Locale)}). */ @Nullable - public Localization localization() { - return localization; + public Locale locale() { + return locale; } public static Builder newBuilder() { @@ -107,7 +105,7 @@ public static final class Builder { private String url; private final Map> headers = new LinkedHashMap<>(); private byte[] dataToSend; - private Localization localization; + private Locale locale; private boolean automaticLocalizationHeader = true; public Builder() { @@ -158,10 +156,10 @@ public Builder dataToSend(final byte[] dataToSendToSet) { * A localization object that should be used when executing a request.
*
* Usually the {@code Accept-Language} will be set to this value (a helper - * method to do this easily: {@link Request#getHeadersFromLocalization(Localization)}). + * method to do this easily: {@link Request#getHeadersFromLocale(Locale)}). */ - public Builder localization(final Localization localizationToSet) { - this.localization = localizationToSet; + public Builder locale(final Locale localeToSet) { + this.locale = localeToSet; return this; } @@ -236,19 +234,16 @@ public Builder addHeader(final String headerName, final String headerValue) { // Utils //////////////////////////////////////////////////////////////////////////*/ - @SuppressWarnings("WeakerAccess") @Nonnull - public static Map> getHeadersFromLocalization( - @Nullable final Localization localization) { - if (localization == null) { - return Collections.emptyMap(); + public static Map> getHeadersFromLocale(@Nullable final Locale locale) { + if (locale == null) { + return Map.of(); } - - final String languageCode = localization.getLanguageCode(); - final List languageCodeList = Collections.singletonList( - localization.getCountryCode().isEmpty() ? languageCode - : localization.getLocalizationCode() + ", " + languageCode + ";q=0.9"); - return Collections.singletonMap("Accept-Language", languageCodeList); + String headerValue = locale.toLanguageTag(); + if (!headerValue.equals(locale.getLanguage())) { + headerValue += ", " + locale.getLanguage() + ";q=0.9"; + } + return Map.of("Accept-Language", List.of(headerValue)); } /*////////////////////////////////////////////////////////////////////////// @@ -268,12 +263,12 @@ public boolean equals(final Object o) { && url.equals(request.url) && headers.equals(request.headers) && Arrays.equals(dataToSend, request.dataToSend) - && Objects.equals(localization, request.localization); + && Objects.equals(locale, request.locale); } @Override public int hashCode() { - int result = Objects.hash(httpMethod, url, headers, localization); + int result = Objects.hash(httpMethod, url, headers, locale); result = 31 * result + Arrays.hashCode(dataToSend); return result; } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/kiosk/KioskList.java b/extractor/src/main/java/org/schabi/newpipe/extractor/kiosk/KioskList.java index 358e03c9c2..7667dc3a5b 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/kiosk/KioskList.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/kiosk/KioskList.java @@ -1,21 +1,20 @@ package org.schabi.newpipe.extractor.kiosk; -import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; - import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.Page; import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory; import org.schabi.newpipe.extractor.localization.ContentCountry; -import org.schabi.newpipe.extractor.localization.Localization; +import javax.annotation.Nullable; import java.io.IOException; import java.util.HashMap; +import java.util.Locale; import java.util.Map; import java.util.Set; -import javax.annotation.Nullable; +import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; public class KioskList { @@ -31,7 +30,7 @@ KioskExtractor createNewKiosk(StreamingService streamingService, private String defaultKiosk = null; @Nullable - private Localization forcedLocalization; + private Locale forcedLocale; @Nullable private ContentCountry forcedContentCountry; @@ -70,19 +69,18 @@ public KioskExtractor getDefaultKioskExtractor() public KioskExtractor getDefaultKioskExtractor(final Page nextPage) throws ExtractionException, IOException { - return getDefaultKioskExtractor(nextPage, NewPipe.getPreferredLocalization()); + return getDefaultKioskExtractor(nextPage, NewPipe.getPreferredLocale()); } - public KioskExtractor getDefaultKioskExtractor(final Page nextPage, - final Localization localization) + public KioskExtractor getDefaultKioskExtractor(final Page nextPage, final Locale locale) throws ExtractionException, IOException { if (!isNullOrEmpty(defaultKiosk)) { - return getExtractorById(defaultKiosk, nextPage, localization); + return getExtractorById(defaultKiosk, nextPage, locale); } else { final String first = kioskList.keySet().stream().findAny().orElse(null); if (first != null) { // if not set get any entry - return getExtractorById(first, nextPage, localization); + return getExtractorById(first, nextPage, locale); } else { return null; } @@ -95,12 +93,11 @@ public String getDefaultKioskId() { public KioskExtractor getExtractorById(final String kioskId, final Page nextPage) throws ExtractionException, IOException { - return getExtractorById(kioskId, nextPage, NewPipe.getPreferredLocalization()); + return getExtractorById(kioskId, nextPage, NewPipe.getPreferredLocale()); } - public KioskExtractor getExtractorById(final String kioskId, - final Page nextPage, - final Localization localization) + public KioskExtractor getExtractorById(final String kioskId, final Page nextPage, + final Locale locale) throws ExtractionException, IOException { final KioskEntry ke = kioskList.get(kioskId); if (ke == null) { @@ -109,8 +106,8 @@ public KioskExtractor getExtractorById(final String kioskId, final KioskExtractor kioskExtractor = ke.extractorFactory.createNewKiosk(service, ke.handlerFactory.fromId(kioskId).getUrl(), kioskId); - if (forcedLocalization != null) { - kioskExtractor.forceLocalization(forcedLocalization); + if (forcedLocale != null) { + kioskExtractor.forceLocale(forcedLocale); } if (forcedContentCountry != null) { kioskExtractor.forceContentCountry(forcedContentCountry); @@ -126,17 +123,16 @@ public Set getAvailableKiosks() { public KioskExtractor getExtractorByUrl(final String url, final Page nextPage) throws ExtractionException, IOException { - return getExtractorByUrl(url, nextPage, NewPipe.getPreferredLocalization()); + return getExtractorByUrl(url, nextPage, NewPipe.getPreferredLocale()); } - public KioskExtractor getExtractorByUrl(final String url, - final Page nextPage, - final Localization localization) + public KioskExtractor getExtractorByUrl(final String url, final Page nextPage, + final Locale locale) throws ExtractionException, IOException { for (final Map.Entry e : kioskList.entrySet()) { final KioskEntry ke = e.getValue(); if (ke.handlerFactory.acceptUrl(url)) { - return getExtractorById(ke.handlerFactory.getId(url), nextPage, localization); + return getExtractorById(ke.handlerFactory.getId(url), nextPage, locale); } } throw new ExtractionException("Could not find a kiosk that fits to the url: " + url); @@ -146,8 +142,8 @@ public ListLinkHandlerFactory getListLinkHandlerFactoryByType(final String type) return kioskList.get(type).handlerFactory; } - public void forceLocalization(@Nullable final Localization localization) { - this.forcedLocalization = localization; + public void forceLocale(@Nullable final Locale locale) { + this.forcedLocale = locale; } public void forceContentCountry(@Nullable final ContentCountry contentCountry) { diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/localization/ContentCountry.java b/extractor/src/main/java/org/schabi/newpipe/extractor/localization/ContentCountry.java index 89baf11ea2..444d267ae5 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/localization/ContentCountry.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/localization/ContentCountry.java @@ -1,11 +1,11 @@ package org.schabi.newpipe.extractor.localization; import javax.annotation.Nonnull; - import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Locale; /** * Represents a country that should be used when fetching content. @@ -15,8 +15,7 @@ *

*/ public class ContentCountry implements Serializable { - public static final ContentCountry DEFAULT = - new ContentCountry(Localization.DEFAULT.getCountryCode()); + public static final ContentCountry DEFAULT = new ContentCountry("GB"); @Nonnull private final String countryCode; @@ -61,4 +60,10 @@ public boolean equals(final Object o) { public int hashCode() { return countryCode.hashCode(); } + + @Nonnull + public static ContentCountry fromLocale(@Nonnull final Locale locale) { + final String country = locale.getCountry(); + return country.isEmpty() ? ContentCountry.DEFAULT : new ContentCountry(country); + } } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/localization/Localization.java b/extractor/src/main/java/org/schabi/newpipe/extractor/localization/Localization.java deleted file mode 100644 index 87dff8d45e..0000000000 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/localization/Localization.java +++ /dev/null @@ -1,129 +0,0 @@ -package org.schabi.newpipe.extractor.localization; - -import org.schabi.newpipe.extractor.exceptions.ParsingException; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - - -public class Localization implements Serializable { - public static final Localization DEFAULT = new Localization("en", "GB"); - - @Nonnull - private final String languageCode; - @Nullable - private final String countryCode; - - /** - * @param localizationCodes a list of localization code, formatted like - * {@link #getLocalizationCode()} - * @return list of Localization objects - */ - @Nonnull - public static List listFrom(final String... localizationCodes) { - return Arrays.stream(localizationCodes) - .map(Localization::fromLocalizationCode) - .collect(Collectors.toUnmodifiableList()); - } - - /** - * @param localizationCode a localization code, formatted like {@link #getLocalizationCode()} - * @return A Localization, if the code was valid. - */ - @Nonnull - public static Localization fromLocalizationCode(final String localizationCode) { - return Localization.fromLocale(Locale.forLanguageTag(localizationCode)); - } - - public Localization(@Nonnull final String languageCode, @Nullable final String countryCode) { - this.languageCode = languageCode; - this.countryCode = countryCode; - } - - public Localization(@Nonnull final String languageCode) { - this(languageCode, null); - } - - @Nonnull - public String getLanguageCode() { - return languageCode; - } - - @Nonnull - public String getCountryCode() { - return countryCode == null ? "" : countryCode; - } - - public static Localization fromLocale(@Nonnull final Locale locale) { - return new Localization(locale.getLanguage(), locale.getCountry()); - } - - /** - * Return a formatted string in the form of: {@code language-Country}, or - * just {@code language} if country is {@code null}. - * - * @return A correctly formatted localizationCode for this localization. - */ - public String getLocalizationCode() { - return languageCode + (countryCode == null ? "" : "-" + countryCode); - } - - @Override - public String toString() { - return "Localization[" + getLocalizationCode() + "]"; - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (!(o instanceof Localization)) { - return false; - } - - final Localization that = (Localization) o; - - return languageCode.equals(that.languageCode) - && Objects.equals(countryCode, that.countryCode); - } - - @Override - public int hashCode() { - int result = languageCode.hashCode(); - result = 31 * result + Objects.hashCode(countryCode); - return result; - } - - /** - * Converts a three letter language code (ISO 639-2/T) to a Locale - * because limits of Java Locale class. - * - * @param code a three letter language code - * @return the Locale corresponding - */ - public static Locale getLocaleFromThreeLetterCode(@Nonnull final String code) - throws ParsingException { - final String[] languages = Locale.getISOLanguages(); - final Map localeMap = new HashMap<>(languages.length); - for (final String language : languages) { - final Locale locale = new Locale(language); - localeMap.put(locale.getISO3Language(), locale); - } - if (localeMap.containsKey(code)) { - return localeMap.get(code); - } else { - throw new ParsingException( - "Could not get Locale from this three letter language code" + code); - } - } -} diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/localization/TimeAgoPatternsManager.java b/extractor/src/main/java/org/schabi/newpipe/extractor/localization/TimeAgoPatternsManager.java index 47889a5d32..aaf988b61f 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/localization/TimeAgoPatternsManager.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/localization/TimeAgoPatternsManager.java @@ -1,44 +1,36 @@ package org.schabi.newpipe.extractor.localization; +import org.schabi.newpipe.extractor.timeago.PatternMap; import org.schabi.newpipe.extractor.timeago.PatternsHolder; -import org.schabi.newpipe.extractor.timeago.PatternsManager; - -import java.time.OffsetDateTime; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.time.OffsetDateTime; +import java.util.Locale; public final class TimeAgoPatternsManager { private TimeAgoPatternsManager() { } @Nullable - private static PatternsHolder getPatternsFor(@Nonnull final Localization localization) { - return PatternsManager.getPatterns(localization.getLanguageCode(), - localization.getCountryCode()); + private static PatternsHolder getPatternsFor(@Nonnull final Locale locale) { + final var holder = PatternMap.getPattern(locale.toLanguageTag()); + if (holder != null) { + return holder; + } + return PatternMap.getPattern(locale.getLanguage()); } @Nullable - public static TimeAgoParser getTimeAgoParserFor(@Nonnull final Localization localization) { - final PatternsHolder holder = getPatternsFor(localization); - - if (holder == null) { - return null; - } - - return new TimeAgoParser(holder); + public static TimeAgoParser getTimeAgoParserFor(@Nonnull final Locale locale) { + final var holder = getPatternsFor(locale); + return holder == null ? null : new TimeAgoParser(holder); } @Nullable - public static TimeAgoParser getTimeAgoParserFor( - @Nonnull final Localization localization, - @Nonnull final OffsetDateTime now) { - final PatternsHolder holder = getPatternsFor(localization); - - if (holder == null) { - return null; - } - - return new TimeAgoParser(holder, now); + public static TimeAgoParser getTimeAgoParserFor(@Nonnull final Locale locale, + @Nonnull final OffsetDateTime now) { + final var holder = getPatternsFor(locale); + return holder == null ? null : new TimeAgoParser(holder, now); } } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCConferenceKiosk.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCConferenceKiosk.java index 3ce00ac431..68a5f5bb08 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCConferenceKiosk.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCConferenceKiosk.java @@ -52,7 +52,7 @@ public InfoItemsPage getPage(final Page page) { @Override public void onFetchPage(@Nonnull final Downloader downloader) throws IOException, ExtractionException { - final String site = downloader.get(getLinkHandler().getUrl(), getExtractorLocalization()) + final String site = downloader.get(getLinkHandler().getUrl(), getExtractorLocale()) .responseBody(); try { doc = JsonParser.object().from(site); diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCLiveStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCLiveStreamExtractor.java index 4c3edbd06c..23597fdc86 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCLiveStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCLiveStreamExtractor.java @@ -48,7 +48,7 @@ public MediaCCCLiveStreamExtractor(final StreamingService service, public void onFetchPage(@Nonnull final Downloader downloader) throws IOException, ExtractionException { final JsonArray doc = MediaCCCParsingHelper.getLiveStreams(downloader, - getExtractorLocalization()); + getExtractorLocale()); // Find the correct room for (int c = 0; c < doc.size(); c++) { final JsonObject conferenceObject = doc.getObject(c); diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCLiveStreamKiosk.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCLiveStreamKiosk.java index 2d34d011a6..28efa79858 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCLiveStreamKiosk.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCLiveStreamKiosk.java @@ -29,7 +29,7 @@ public MediaCCCLiveStreamKiosk(final StreamingService streamingService, @Override public void onFetchPage(@Nonnull final Downloader downloader) throws IOException, ExtractionException { - doc = MediaCCCParsingHelper.getLiveStreams(downloader, getExtractorLocalization()); + doc = MediaCCCParsingHelper.getLiveStreams(downloader, getExtractorLocale()); } @Nonnull diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCParsingHelper.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCParsingHelper.java index 2a4ea6a9f8..9412d53531 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCParsingHelper.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCParsingHelper.java @@ -10,7 +10,6 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ReCaptchaException; -import org.schabi.newpipe.extractor.localization.Localization; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -20,6 +19,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Locale; import java.util.regex.Pattern; import static org.schabi.newpipe.extractor.Image.HEIGHT_UNKNOWN; @@ -59,19 +59,19 @@ public static boolean isLiveStreamId(final String id) { * Use this method to cache requests, because they can get quite big. * TODO: implement better caching policy (max-age: 3 min) * @param downloader The downloader to use for making the request - * @param localization The localization to be used. Will most likely be ignored. + * @param locale The localization to be used. Will most likely be ignored. * @return {@link JsonArray} containing current conferences and info about their rooms and * streams. * @throws ExtractionException if the data could not be fetched or the retrieved data could not * be parsed to a {@link JsonArray} */ public static JsonArray getLiveStreams(final Downloader downloader, - final Localization localization) + final Locale locale) throws ExtractionException { if (liveStreams == null) { try { final String site = downloader.get("https://streaming.media.ccc.de/streams/v2.json", - localization).responseBody(); + locale).responseBody(); liveStreams = JsonParser.array().from(site); } catch (final IOException | ReCaptchaException e) { throw new ExtractionException("Could not get live stream JSON.", e); diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCRecentKiosk.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCRecentKiosk.java index d38d65fd53..59a8967fe9 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCRecentKiosk.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCRecentKiosk.java @@ -37,7 +37,7 @@ public MediaCCCRecentKiosk(final StreamingService streamingService, public void onFetchPage(@Nonnull final Downloader downloader) throws IOException, ExtractionException { final String site = downloader.get("https://api.media.ccc.de/public/events/recent", - getExtractorLocalization()).responseBody(); + getExtractorLocale()).responseBody(); try { doc = JsonParser.object().from(site); } catch (final JsonParserException jpe) { diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCSearchExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCSearchExtractor.java index e72d26cb22..1658497561 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCSearchExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCSearchExtractor.java @@ -107,7 +107,7 @@ public void onFetchPage(@Nonnull final Downloader downloader) || getLinkHandler().getContentFilters().isEmpty()) { final String site; final String url = getUrl(); - site = downloader.get(url, getExtractorLocalization()).responseBody(); + site = downloader.get(url, getExtractorLocale()).responseBody(); try { doc = JsonParser.object().from(site); } catch (final JsonParserException jpe) { diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCStreamExtractor.java index a9e4a4b046..267f20964d 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCStreamExtractor.java @@ -19,7 +19,6 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.linkhandler.LinkHandler; import org.schabi.newpipe.extractor.localization.DateWrapper; -import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.MediaCCCConferenceLinkHandlerFactory; import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.MediaCCCStreamLinkHandlerFactory; import org.schabi.newpipe.extractor.stream.AudioStream; @@ -31,6 +30,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Locale; @@ -213,7 +213,12 @@ public String getOriginalUrl() { @Override public Locale getLanguageInfo() throws ParsingException { - return Localization.getLocaleFromThreeLetterCode(data.getString("original_language")); + final String language = data.getString("original_language"); + return Arrays.stream(Locale.getAvailableLocales()) + .filter(locale -> locale.getISO3Language().equals(language)) + .findFirst() + .orElseThrow(() -> new ParsingException("Could not get Locale from this three " + + "letter language code" + language)); } @Nonnull diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeStreamExtractor.java index 5406368854..7863fbc8c4 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeStreamExtractor.java @@ -781,7 +781,7 @@ public String getLicence() throws ParsingException { @Override public Locale getLanguageInfo() { try { - return new Locale(JsonUtils.getString(json, "language.id")); + return Locale.forLanguageTag(JsonUtils.getString(json, "language.id")); } catch (final ParsingException e) { return null; } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudParsingHelper.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudParsingHelper.java index ae8fd77d6d..e4992597e3 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudParsingHelper.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudParsingHelper.java @@ -160,7 +160,7 @@ public static JsonObject resolveFor(@Nonnull final Downloader downloader, final + "&client_id=" + clientId(); try { - final String response = downloader.get(apiUrl, SoundCloud.getLocalization()) + final String response = downloader.get(apiUrl, SoundCloud.getLocale()) .responseBody(); return JsonParser.object().from(response); } catch (final JsonParserException e) { @@ -178,7 +178,7 @@ public static String resolveUrlWithEmbedPlayer(final String apiUrl) throws IOExc ReCaptchaException { final String response = NewPipe.getDownloader().get("https://w.soundcloud.com/player/?url=" - + Utils.encodeUrlUtf8(apiUrl), SoundCloud.getLocalization()).responseBody(); + + Utils.encodeUrlUtf8(apiUrl), SoundCloud.getLocale()).responseBody(); return Jsoup.parse(response).select("link[rel=\"canonical\"]").first() .attr("abs:href"); @@ -225,7 +225,7 @@ public static String resolveIdWithWidgetApi(final String urlString) throws IOExc + Utils.encodeUrlUtf8(url.toString()) + "&format=json&client_id=" + SoundcloudParsingHelper.clientId(); final String response = NewPipe.getDownloader().get(widgetUrl, - SoundCloud.getLocalization()).responseBody(); + SoundCloud.getLocale()).responseBody(); final JsonObject o = JsonParser.object().from(response); return String.valueOf(JsonUtils.getValue(o, "id")); } catch (final JsonParserException e) { @@ -267,7 +267,7 @@ public static String getUsersFromApiMinItems(final int minItems, public static String getUsersFromApi(final ChannelInfoItemsCollector collector, final String apiUrl) throws IOException, ReCaptchaException, ParsingException { - final String response = NewPipe.getDownloader().get(apiUrl, SoundCloud.getLocalization()) + final String response = NewPipe.getDownloader().get(apiUrl, SoundCloud.getLocale()) .responseBody(); final JsonObject responseObject; @@ -321,7 +321,7 @@ public static String getStreamsFromApi(final StreamInfoItemsCollector collector, final boolean charts) throws IOException, ReCaptchaException, ParsingException { final Response response = NewPipe.getDownloader().get(apiUrl, SoundCloud - .getLocalization()); + .getLocale()); if (response.responseCode() >= 400) { throw new IOException("Could not get streams from API, HTTP " + response .responseCode()); @@ -368,7 +368,7 @@ public static String getStreamsFromApi(final StreamInfoItemsCollector collector, public static String getInfoItemsFromApi(final MultiInfoItemsCollector collector, final String apiUrl) throws ReCaptchaException, ParsingException, IOException { - final Response response = NewPipe.getDownloader().get(apiUrl, SoundCloud.getLocalization()); + final Response response = NewPipe.getDownloader().get(apiUrl, SoundCloud.getLocale()); if (response.responseCode() >= 400) { throw new IOException("Could not get streams from API, HTTP " + response.responseCode()); diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudChannelExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudChannelExtractor.java index 3cad8782b1..b4c3f0d931 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudChannelExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudChannelExtractor.java @@ -42,7 +42,7 @@ public void onFetchPage(@Nonnull final Downloader downloader) throws IOException final String apiUrl = USERS_ENDPOINT + userId + "?client_id=" + SoundcloudParsingHelper.clientId(); - final String response = downloader.get(apiUrl, getExtractorLocalization()).responseBody(); + final String response = downloader.get(apiUrl, getExtractorLocale()).responseBody(); try { user = JsonParser.object().from(response); } catch (final JsonParserException e) { diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudPlaylistExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudPlaylistExtractor.java index 46bba0a0d9..fcc594fef2 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudPlaylistExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudPlaylistExtractor.java @@ -50,7 +50,7 @@ public void onFetchPage(@Nonnull final Downloader downloader) throws IOException final String apiUrl = SOUNDCLOUD_API_V2_URL + "playlists/" + playlistId + "?client_id=" + SoundcloudParsingHelper.clientId() + "&representation=compact"; - final String response = downloader.get(apiUrl, getExtractorLocalization()).responseBody(); + final String response = downloader.get(apiUrl, getExtractorLocale()).responseBody(); try { playlist = JsonParser.object().from(response); } catch (final JsonParserException e) { @@ -181,7 +181,7 @@ public InfoItemsPage getPage(final Page page) throws IOException final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId()); final String response = NewPipe.getDownloader().get(currentPageUrl, - getExtractorLocalization()).responseBody(); + getExtractorLocale()).responseBody(); try { final JsonArray tracks = JsonParser.array().from(response); diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudSearchExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudSearchExtractor.java index b26728873d..e2f9ef3528 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudSearchExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudSearchExtractor.java @@ -83,7 +83,7 @@ public InfoItemsPage getPage(final Page page) throws IOException, final JsonArray searchCollection; final int totalResults; try { - final String response = dl.get(page.getUrl(), getExtractorLocalization()) + final String response = dl.get(page.getUrl(), getExtractorLocale()) .responseBody(); final JsonObject result = JsonParser.object().from(response); searchCollection = result.getArray(COLLECTION); @@ -106,7 +106,7 @@ public void onFetchPage(@Nonnull final Downloader downloader) throws IOException final Downloader dl = getDownloader(); final String url = getUrl(); try { - final String response = dl.get(url, getExtractorLocalization()).responseBody(); + final String response = dl.get(url, getExtractorLocale()).responseBody(); initialSearchObject = JsonParser.object().from(response); } catch (final JsonParserException e) { throw new ParsingException("Could not parse json response", e); diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudSuggestionExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudSuggestionExtractor.java index 59614b6e21..c6591744ef 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudSuggestionExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudSuggestionExtractor.java @@ -34,7 +34,7 @@ public List suggestionList(final String query) throws IOException, final String url = SOUNDCLOUD_API_V2_URL + "search/queries?q=" + Utils.encodeUrlUtf8(query) + "&client_id=" + SoundcloudParsingHelper.clientId() + "&limit=10"; - final String response = dl.get(url, getExtractorLocalization()).responseBody(); + final String response = dl.get(url, getExtractorLocale()).responseBody(); try { final JsonArray collection = JsonParser.object().from(response).getArray("collection"); diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelHelper.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelHelper.java index c3faf673f8..3b6f0a3ff0 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelHelper.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelHelper.java @@ -14,11 +14,11 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.localization.ContentCountry; -import org.schabi.newpipe.extractor.localization.Localization; import java.io.IOException; import java.io.Serializable; import java.nio.charset.StandardCharsets; +import java.util.Locale; import java.util.Optional; import javax.annotation.Nonnull; @@ -82,13 +82,13 @@ public static String resolveChannelId(@Nonnull final String idOrPath) urlToResolve != null && tries < 3; tries++) { final byte[] body = JsonWriter.string( - prepareDesktopJsonBuilder(Localization.DEFAULT, ContentCountry.DEFAULT) + prepareDesktopJsonBuilder(Locale.UK, ContentCountry.DEFAULT) .value("url", urlToResolve) .done()) .getBytes(StandardCharsets.UTF_8); final JsonObject jsonResponse = getJsonPostResponse( - "navigation/resolve_url", body, Localization.DEFAULT); + "navigation/resolve_url", body, Locale.UK); checkIfChannelResponseIsValid(jsonResponse); @@ -127,8 +127,8 @@ public static String resolveChannelId(@Nonnull final String idOrPath) } /** - * Response data object for {@link #getChannelResponse(String, String, Localization, - * ContentCountry)}, after any redirection in the allowed redirects count ({@code 3}). + * Response data object for {@link #getChannelResponse(String, String, Locale, ContentCountry)}, + * after any redirection in the allowed redirects count ({@code 3}). */ public static final class ChannelResponseData { @@ -165,7 +165,7 @@ private ChannelResponseData(@Nonnull final JsonObject jsonResponse, * @param channelId a valid YouTube channel ID * @param parameters the parameters to specify the YouTube channel tab; if invalid ones are * specified, YouTube should return the {@code Home} tab - * @param localization the {@link Localization} to use + * @param locale the {@link Locale} to use * @param country the {@link ContentCountry} to use * @return a {@link ChannelResponseData channel response data} * @throws IOException if a channel request failed @@ -174,7 +174,7 @@ private ChannelResponseData(@Nonnull final JsonObject jsonResponse, @Nonnull public static ChannelResponseData getChannelResponse(@Nonnull final String channelId, @Nonnull final String parameters, - @Nonnull final Localization localization, + @Nonnull final Locale locale, @Nonnull final ContentCountry country) throws ExtractionException, IOException { String id = channelId; @@ -182,15 +182,14 @@ public static ChannelResponseData getChannelResponse(@Nonnull final String chann int level = 0; while (level < 3) { - final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder( - localization, country) + final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder(locale, country) .value(BROWSE_ID, id) .value("params", parameters) .done()) .getBytes(StandardCharsets.UTF_8); final JsonObject jsonResponse = getJsonPostResponse( - "browse", body, localization); + "browse", body, locale); checkIfChannelResponseIsValid(jsonResponse); diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeJavaScriptExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeJavaScriptExtractor.java index 5902a66df9..540efb52a7 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeJavaScriptExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeJavaScriptExtractor.java @@ -6,12 +6,12 @@ import org.jsoup.select.Elements; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.exceptions.ParsingException; -import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.utils.Parser; import javax.annotation.Nonnull; import java.net.MalformedURLException; import java.net.URL; +import java.util.Locale; import java.util.regex.Pattern; /** @@ -84,7 +84,7 @@ static String extractJavaScriptUrlWithIframeResource() throws ParsingException { try { iframeUrl = "https://www.youtube.com/iframe_api"; iframeContent = NewPipe.getDownloader() - .get(iframeUrl, Localization.DEFAULT) + .get(iframeUrl, Locale.UK) .responseBody(); } catch (final Exception e) { throw new ParsingException("Could not fetch IFrame resource", e); @@ -108,7 +108,7 @@ static String extractJavaScriptUrlWithEmbedWatchPage(@Nonnull final String video try { embedUrl = "https://www.youtube.com/embed/" + videoId; embedPageContent = NewPipe.getDownloader() - .get(embedUrl, Localization.DEFAULT) + .get(embedUrl, Locale.UK) .responseBody(); } catch (final Exception e) { throw new ParsingException("Could not fetch embedded watch page", e); @@ -155,7 +155,7 @@ private static String downloadJavaScriptCode(@Nonnull final String javaScriptPla throws ParsingException { try { return NewPipe.getDownloader() - .get(javaScriptPlayerUrl, Localization.DEFAULT) + .get(javaScriptPlayerUrl, Locale.UK) .responseBody(); } catch (final Exception e) { throw new ParsingException("Could not get JavaScript base player's code", e); diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java index 70aac8d2b5..4c43a5f806 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java @@ -55,7 +55,6 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ReCaptchaException; import org.schabi.newpipe.extractor.localization.ContentCountry; -import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.playlist.PlaylistInfo; import org.schabi.newpipe.extractor.stream.AudioTrackType; import org.schabi.newpipe.extractor.utils.JsonUtils; @@ -1019,19 +1018,19 @@ public static String getValidJsonResponseBody(@Nonnull final Response response) public static JsonObject getJsonPostResponse(@Nonnull final String endpoint, final byte[] body, - @Nonnull final Localization localization) + @Nonnull final Locale locale) throws IOException, ExtractionException { final var headers = getYouTubeHeaders(); return JsonUtils.toJsonObject(getValidJsonResponseBody( getDownloader().postWithContentTypeJson(YOUTUBEI_V1_URL + endpoint + "?" - + DISABLE_PRETTY_PRINT_PARAMETER, headers, body, localization))); + + DISABLE_PRETTY_PRINT_PARAMETER, headers, body, locale))); } public static JsonObject getJsonPostResponse(@Nonnull final String endpoint, @Nonnull final List queryParameters, final byte[] body, - @Nonnull final Localization localization) + @Nonnull final Locale locale) throws IOException, ExtractionException { final var headers = getYouTubeHeaders(); @@ -1045,18 +1044,18 @@ public static JsonObject getJsonPostResponse(@Nonnull final String endpoint, return JsonUtils.toJsonObject(getValidJsonResponseBody( getDownloader().postWithContentTypeJson(YOUTUBEI_V1_URL + endpoint - + queryParametersString, headers, body, localization))); + + queryParametersString, headers, body, locale))); } @Nonnull public static JsonBuilder prepareDesktopJsonBuilder( - @Nonnull final Localization localization, + @Nonnull final Locale locale, @Nonnull final ContentCountry contentCountry) throws IOException, ExtractionException { // @formatter:off return JsonObject.builder() .object("context") .object("client") - .value("hl", localization.getLocalizationCode()) + .value("hl", locale.toLanguageTag()) .value("gl", contentCountry.getCountryCode()) .value("clientName", WEB_CLIENT_NAME) .value("clientVersion", getClientVersion()) @@ -1083,19 +1082,19 @@ public static JsonBuilder prepareDesktopJsonBuilder( * client. * *

- * If the {@link Localization} provided is {@code null}, fallbacks to - * {@link Localization#DEFAULT the default one}. + * If the {@link Locale} provided is {@code null}, fallbacks to + * {@link Locale#UK the default one}. *

* - * @param localization the {@link Localization} to set in the user-agent + * @param locale the {@link Locale} to set in the user-agent * @return the Android user-agent used for InnerTube requests with the Android client, - * depending on the {@link Localization} provided + * depending on the {@link Locale} provided */ @Nonnull - public static String getAndroidUserAgent(@Nullable final Localization localization) { + public static String getAndroidUserAgent(@Nullable final Locale locale) { return "com.google.android.youtube/" + ANDROID_CLIENT_VERSION + " (Linux; U; Android 15; " - + (localization != null ? localization : Localization.DEFAULT).getCountryCode() + + (locale != null ? locale : Locale.UK).getCountry() + ") gzip"; } @@ -1104,19 +1103,19 @@ public static String getAndroidUserAgent(@Nullable final Localization localizati * client. * *

- * If the {@link Localization} provided is {@code null}, fallbacks to - * {@link Localization#DEFAULT the default one}. + * If the {@link Locale} provided is {@code null}, fallbacks to + * {@link Locale#UK the default one}. *

* - * @param localization the {@link Localization} to set in the user-agent + * @param locale the {@link Locale} to set in the user-agent * @return the iOS user-agent used for InnerTube requests with the iOS client, depending on the - * {@link Localization} provided + * {@link Locale} provided */ @Nonnull - public static String getIosUserAgent(@Nullable final Localization localization) { + public static String getIosUserAgent(@Nullable final Locale locale) { return "com.google.ios.youtube/" + IOS_CLIENT_VERSION + "(" + IOS_DEVICE_MODEL + "; U; CPU iOS " + IOS_USER_AGENT_VERSION + " like Mac OS X; " - + (localization != null ? localization : Localization.DEFAULT).getCountryCode() + + (locale != null ? locale : Locale.UK).getCountry() + ")"; } @@ -1496,14 +1495,14 @@ public static AudioTrackType extractAudioTrackType(final String streamUrl) { @Nonnull public static String getVisitorDataFromInnertube( @Nonnull final InnertubeClientRequestInfo innertubeClientRequestInfo, - @Nonnull final Localization localization, + @Nonnull final Locale locale, @Nonnull final ContentCountry contentCountry, @Nonnull final Map> httpHeaders, @Nonnull final String innertubeDomainAndVersionEndpoint, @Nullable final String embedUrl, final boolean useGuideEndpoint) throws IOException, ExtractionException { final JsonBuilder builder = prepareJsonBuilder( - localization, contentCountry, innertubeClientRequestInfo, embedUrl); + locale, contentCountry, innertubeClientRequestInfo, embedUrl); final byte[] body = JsonWriter.string(builder.done()) .getBytes(StandardCharsets.UTF_8); @@ -1526,7 +1525,7 @@ public static String getVisitorDataFromInnertube( @Nonnull public static JsonBuilder prepareJsonBuilder( - @Nonnull final Localization localization, + @Nonnull final Locale locale, @Nonnull final ContentCountry contentCountry, @Nonnull final InnertubeClientRequestInfo innertubeClientRequestInfo, @Nullable final String embedUrl) { @@ -1565,7 +1564,7 @@ public static JsonBuilder prepareJsonBuilder( innertubeClientRequestInfo.deviceInfo.androidSdkVersion); } - builder.value("hl", localization.getLocalizationCode()) + builder.value("hl", locale.toLanguageTag()) .value("gl", contentCountry.getCountryCode()) .value("utcOffsetMinutes", 0) .end(); diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeService.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeService.java index 128fbfdb91..cb0f00d972 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeService.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeService.java @@ -21,7 +21,6 @@ import org.schabi.newpipe.extractor.linkhandler.SearchQueryHandler; import org.schabi.newpipe.extractor.linkhandler.SearchQueryHandlerFactory; import org.schabi.newpipe.extractor.localization.ContentCountry; -import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.playlist.PlaylistExtractor; import org.schabi.newpipe.extractor.search.SearchExtractor; import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeChannelExtractor; @@ -58,6 +57,7 @@ import org.schabi.newpipe.extractor.suggestion.SuggestionExtractor; import java.util.List; +import java.util.Locale; import javax.annotation.Nonnull; @@ -263,8 +263,8 @@ public CommentsExtractor getCommentsExtractor(final ListLinkHandler urlIdHandler //////////////////////////////////////////////////////////////////////////*/ // https://www.youtube.com/picker_ajax?action_language_json=1 - private static final List SUPPORTED_LANGUAGES = Localization.listFrom( - "en-GB" + private static final List SUPPORTED_LANGUAGES = List.of( + Locale.UK // en-GB /*"af", "am", "ar", "az", "be", "bg", "bn", "bs", "ca", "cs", "da", "de", "el", "en", "en-GB", "es", "es-419", "es-US", "et", "eu", "fa", "fi", "fil", "fr", "fr-CA", "gl", "gu", "hi", "hr", "hu", "hy", "id", "is", "it", "iw", "ja", @@ -287,7 +287,7 @@ public CommentsExtractor getCommentsExtractor(final ListLinkHandler urlIdHandler ); @Override - public List getSupportedLocalizations() { + public List getSupportedLocales() { return SUPPORTED_LANGUAGES; } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamHelper.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamHelper.java index aef5c2444f..0fcc50b3a5 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamHelper.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamHelper.java @@ -5,7 +5,6 @@ import com.grack.nanojson.JsonWriter; import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.localization.ContentCountry; -import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.utils.JsonUtils; import javax.annotation.Nonnull; @@ -14,6 +13,7 @@ import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import static org.schabi.newpipe.extractor.NewPipe.getDownloader; @@ -48,7 +48,7 @@ private YoutubeStreamHelper() { @Nonnull public static JsonObject getWebMetadataPlayerResponse( - @Nonnull final Localization localization, + @Nonnull final Locale locale, @Nonnull final ContentCountry contentCountry, @Nonnull final String videoId) throws IOException, ExtractionException { final InnertubeClientRequestInfo innertubeClientRequestInfo = @@ -61,9 +61,9 @@ public static JsonObject getWebMetadataPlayerResponse( // got from YouTube innertubeClientRequestInfo.clientInfo.visitorData = YoutubeParsingHelper.getVisitorDataFromInnertube(innertubeClientRequestInfo, - localization, contentCountry, headers, YOUTUBEI_V1_URL, null, false); + locale, contentCountry, headers, YOUTUBEI_V1_URL, null, false); - final JsonBuilder builder = prepareJsonBuilder(localization, contentCountry, + final JsonBuilder builder = prepareJsonBuilder(locale, contentCountry, innertubeClientRequestInfo, null); addVideoIdCpnAndOkChecks(builder, videoId, null); @@ -76,12 +76,12 @@ public static JsonObject getWebMetadataPlayerResponse( return JsonUtils.toJsonObject(getValidJsonResponseBody( getDownloader().postWithContentTypeJson( - url, headers, body, localization))); + url, headers, body, locale))); } @Nonnull public static JsonObject getWebEmbeddedPlayerResponse( - @Nonnull final Localization localization, + @Nonnull final Locale locale, @Nonnull final ContentCountry contentCountry, @Nonnull final String videoId, @Nonnull final String cpn, @@ -100,10 +100,10 @@ public static JsonObject getWebEmbeddedPlayerResponse( // got from YouTube innertubeClientRequestInfo.clientInfo.visitorData = webEmbeddedPoTokenResult == null ? YoutubeParsingHelper.getVisitorDataFromInnertube(innertubeClientRequestInfo, - localization, contentCountry, headers, YOUTUBEI_V1_URL, embedUrl, false) + locale, contentCountry, headers, YOUTUBEI_V1_URL, embedUrl, false) : webEmbeddedPoTokenResult.visitorData; - final JsonBuilder builder = prepareJsonBuilder(localization, contentCountry, + final JsonBuilder builder = prepareJsonBuilder(locale, contentCountry, innertubeClientRequestInfo, embedUrl); addVideoIdCpnAndOkChecks(builder, videoId, cpn); @@ -119,12 +119,12 @@ public static JsonObject getWebEmbeddedPlayerResponse( final String url = YOUTUBEI_V1_URL + PLAYER + "?" + DISABLE_PRETTY_PRINT_PARAMETER; return JsonUtils.toJsonObject(getValidJsonResponseBody( - getDownloader().postWithContentTypeJson(url, headers, body, localization))); + getDownloader().postWithContentTypeJson(url, headers, body, locale))); } public static JsonObject getAndroidPlayerResponse( @Nonnull final ContentCountry contentCountry, - @Nonnull final Localization localization, + @Nonnull final Locale locale, @Nonnull final String videoId, @Nonnull final String cpn, @Nonnull final PoTokenResult androidPoTokenResult) @@ -134,9 +134,9 @@ public static JsonObject getAndroidPlayerResponse( innertubeClientRequestInfo.clientInfo.visitorData = androidPoTokenResult.visitorData; final Map> headers = - getMobileClientHeaders(getAndroidUserAgent(localization)); + getMobileClientHeaders(getAndroidUserAgent(locale)); - final JsonBuilder builder = prepareJsonBuilder(localization, contentCountry, + final JsonBuilder builder = prepareJsonBuilder(locale, contentCountry, innertubeClientRequestInfo, null); addVideoIdCpnAndOkChecks(builder, videoId, cpn); @@ -150,27 +150,24 @@ public static JsonObject getAndroidPlayerResponse( + "&t=" + generateTParameter() + "&id=" + videoId; return JsonUtils.toJsonObject(getValidJsonResponseBody( - getDownloader().postWithContentTypeJson(url, headers, body, localization))); + getDownloader().postWithContentTypeJson(url, headers, body, locale))); } public static JsonObject getAndroidReelPlayerResponse( @Nonnull final ContentCountry contentCountry, - @Nonnull final Localization localization, + @Nonnull final Locale locale, @Nonnull final String videoId, @Nonnull final String cpn) throws IOException, ExtractionException { - final InnertubeClientRequestInfo innertubeClientRequestInfo = - InnertubeClientRequestInfo.ofAndroidClient(); - - final Map> headers = - getMobileClientHeaders(getAndroidUserAgent(localization)); + final var innertubeClientRequestInfo = InnertubeClientRequestInfo.ofAndroidClient(); + final var headers = getMobileClientHeaders(getAndroidUserAgent(locale)); // We must always pass a valid visitorData to get valid player responses, which needs to be // got from YouTube innertubeClientRequestInfo.clientInfo.visitorData = YoutubeParsingHelper.getVisitorDataFromInnertube(innertubeClientRequestInfo, - localization, contentCountry, headers, YOUTUBEI_V1_GAPIS_URL, null, false); + locale, contentCountry, headers, YOUTUBEI_V1_GAPIS_URL, null, false); - final JsonBuilder builder = prepareJsonBuilder(localization, contentCountry, + final JsonBuilder builder = prepareJsonBuilder(locale, contentCountry, innertubeClientRequestInfo, null); builder.object("playerRequest"); @@ -186,12 +183,12 @@ public static JsonObject getAndroidReelPlayerResponse( + "&$fields=playerResponse"; return JsonUtils.toJsonObject(getValidJsonResponseBody( - getDownloader().postWithContentTypeJson(url, headers, body, localization))) + getDownloader().postWithContentTypeJson(url, headers, body, locale))) .getObject("playerResponse"); } public static JsonObject getIosPlayerResponse(@Nonnull final ContentCountry contentCountry, - @Nonnull final Localization localization, + @Nonnull final Locale locale, @Nonnull final String videoId, @Nonnull final String cpn, @Nullable final PoTokenResult iosPoTokenResult) @@ -200,16 +197,16 @@ public static JsonObject getIosPlayerResponse(@Nonnull final ContentCountry cont InnertubeClientRequestInfo.ofIosClient(); final Map> headers = - getMobileClientHeaders(getIosUserAgent(localization)); + getMobileClientHeaders(getIosUserAgent(locale)); // We must always pass a valid visitorData to get valid player responses, which needs to be // got from YouTube innertubeClientRequestInfo.clientInfo.visitorData = iosPoTokenResult == null ? YoutubeParsingHelper.getVisitorDataFromInnertube(innertubeClientRequestInfo, - localization, contentCountry, headers, YOUTUBEI_V1_URL, null, false) + locale, contentCountry, headers, YOUTUBEI_V1_URL, null, false) : iosPoTokenResult.visitorData; - final JsonBuilder builder = prepareJsonBuilder(localization, contentCountry, + final JsonBuilder builder = prepareJsonBuilder(locale, contentCountry, innertubeClientRequestInfo, null); addVideoIdCpnAndOkChecks(builder, videoId, cpn); @@ -225,7 +222,7 @@ public static JsonObject getIosPlayerResponse(@Nonnull final ContentCountry cont + "&t=" + generateTParameter() + "&id=" + videoId; return JsonUtils.toJsonObject(getValidJsonResponseBody( - getDownloader().postWithContentTypeJson(url, headers, body, localization))); + getDownloader().postWithContentTypeJson(url, headers, body, locale))); } private static void addVideoIdCpnAndOkChecks(@Nonnull final JsonBuilder builder, diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeChannelExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeChannelExtractor.java index 147345526a..e91ebe1816 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeChannelExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeChannelExtractor.java @@ -102,7 +102,7 @@ public void onFetchPage(@Nonnull final Downloader downloader) final String id = resolveChannelId(channelPath); // Fetch Videos tab final YoutubeChannelHelper.ChannelResponseData data = getChannelResponse(id, - "EgZ2aWRlb3PyBgQKAjoA", getExtractorLocalization(), getExtractorContentCountry()); + "EgZ2aWRlb3PyBgQKAjoA", getExtractorLocale(), getExtractorContentCountry()); jsonResponse = data.jsonResponse; channelHeader = YoutubeChannelHelper.getChannelHeader(jsonResponse); diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeChannelTabExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeChannelTabExtractor.java index 1a1f7fbbb3..a1e5df8b92 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeChannelTabExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeChannelTabExtractor.java @@ -80,7 +80,7 @@ public void onFetchPage(@Nonnull final Downloader downloader) throws IOException final String params = getChannelTabsParameters(); final YoutubeChannelHelper.ChannelResponseData data = getChannelResponse(channelIdFromId, - params, getExtractorLocalization(), getExtractorContentCountry()); + params, getExtractorLocale(), getExtractorContentCountry()); jsonResponse = data.jsonResponse; channelHeader = YoutubeChannelHelper.getChannelHeader(jsonResponse); @@ -179,7 +179,7 @@ public InfoItemsPage getPage(final Page page) final MultiInfoItemsCollector collector = new MultiInfoItemsCollector(getServiceId()); final JsonObject ajaxJson = getJsonPostResponse("browse", page.getBody(), - getExtractorLocalization()); + getExtractorLocale()); final JsonObject sectionListContinuation = ajaxJson.getArray("onResponseReceivedActions") .stream() @@ -510,7 +510,7 @@ private Page getNextPageFrom(final JsonObject continuations, final String continuation = continuationEndpoint.getObject("continuationCommand") .getString("token"); - final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder(getExtractorLocalization(), + final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder(getExtractorLocale(), getExtractorContentCountry()) .value("continuation", continuation) .done()) diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeCommentsExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeCommentsExtractor.java index 8667768a4b..3bab534ca9 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeCommentsExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeCommentsExtractor.java @@ -12,7 +12,6 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; -import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.localization.TimeAgoParser; import org.schabi.newpipe.extractor.utils.JsonUtils; import org.schabi.newpipe.extractor.utils.Utils; @@ -202,16 +201,16 @@ public InfoItemsPage getPage(final Page page) throw new IllegalArgumentException("Page doesn't have the continuation."); } - final Localization localization = getExtractorLocalization(); + final var locale = getExtractorLocale(); // @formatter:off final byte[] body = JsonWriter.string( - prepareDesktopJsonBuilder(localization, getExtractorContentCountry()) + prepareDesktopJsonBuilder(locale, getExtractorContentCountry()) .value("continuation", page.getId()) .done()) .getBytes(StandardCharsets.UTF_8); // @formatter:on - final JsonObject jsonObject = getJsonPostResponse("next", body, localization); + final JsonObject jsonObject = getJsonPostResponse("next", body, locale); return extractComments(jsonObject); } @@ -342,17 +341,17 @@ private void collectCommentItem(@Nonnull final JsonArray mutations, @Override public void onFetchPage(@Nonnull final Downloader downloader) throws IOException, ExtractionException { - final Localization localization = getExtractorLocalization(); + final var locale = getExtractorLocale(); // @formatter:off final byte[] body = JsonWriter.string( - prepareDesktopJsonBuilder(localization, getExtractorContentCountry()) + prepareDesktopJsonBuilder(locale, getExtractorContentCountry()) .value("videoId", getId()) .done()) .getBytes(StandardCharsets.UTF_8); // @formatter:on final String initialToken = - findInitialCommentsToken(getJsonPostResponse("next", body, localization)); + findInitialCommentsToken(getJsonPostResponse("next", body, locale)); if (initialToken == null) { return; @@ -360,13 +359,13 @@ public void onFetchPage(@Nonnull final Downloader downloader) // @formatter:off final byte[] ajaxBody = JsonWriter.string( - prepareDesktopJsonBuilder(localization, getExtractorContentCountry()) + prepareDesktopJsonBuilder(locale, getExtractorContentCountry()) .value("continuation", initialToken) .done()) .getBytes(StandardCharsets.UTF_8); // @formatter:on - ajaxJson = getJsonPostResponse("next", ajaxBody, localization); + ajaxJson = getJsonPostResponse("next", ajaxBody, locale); } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeCommentsInfoItemExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeCommentsInfoItemExtractor.java index ddc7b7bcc0..510640b09e 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeCommentsInfoItemExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeCommentsInfoItemExtractor.java @@ -102,7 +102,7 @@ public DateWrapper getUploadDate() throws ParsingException { *
  • More than 1k likes will result in an inaccurate number
  • *
  • This will fail for other languages than English. However as long as the Extractor * only uses "en-GB" (as seen in {@link - * org.schabi.newpipe.extractor.services.youtube.YoutubeService#getSupportedLocalizations}) + * org.schabi.newpipe.extractor.services.youtube.YoutubeService#getSupportedLocales}) * , everything will work fine.
  • * *
    diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMixPlaylistExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMixPlaylistExtractor.java index 1df90f967f..0df844bce2 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMixPlaylistExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMixPlaylistExtractor.java @@ -27,7 +27,6 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; -import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.localization.TimeAgoParser; import org.schabi.newpipe.extractor.playlist.PlaylistExtractor; import org.schabi.newpipe.extractor.playlist.PlaylistInfo; @@ -81,13 +80,13 @@ public YoutubeMixPlaylistExtractor(final StreamingService service, @Override public void onFetchPage(@Nonnull final Downloader downloader) throws IOException, ExtractionException { - final Localization localization = getExtractorLocalization(); + final var locale = getExtractorLocale(); final URL url = stringToURL(getUrl()); final String mixPlaylistId = getId(); final String videoId = getQueryValue(url, "v"); final String playlistIndexString = getQueryValue(url, "index"); - final JsonBuilder jsonBody = prepareDesktopJsonBuilder(localization, + final JsonBuilder jsonBody = prepareDesktopJsonBuilder(locale, getExtractorContentCountry()).value("playlistId", mixPlaylistId); if (videoId != null) { jsonBody.value("videoId", videoId); @@ -103,7 +102,7 @@ public void onFetchPage(@Nonnull final Downloader downloader) final Response response = getDownloader().postWithContentTypeJson( YOUTUBEI_V1_URL + "next?" + DISABLE_PRETTY_PRINT_PARAMETER, headers, body, - localization); + locale); initialData = JsonUtils.toJsonObject(getValidJsonResponseBody(response)); playlistData = initialData @@ -215,7 +214,7 @@ private Page getNextPageFrom(@Nonnull final JsonObject playlistJson, final String videoId = watchEndpoint.getString("videoId"); final int index = watchEndpoint.getInt("index"); final String params = watchEndpoint.getString("params"); - final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder(getExtractorLocalization(), + final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder(getExtractorLocale(), getExtractorContentCountry()) .value("videoId", videoId) .value("playlistId", playlistId) @@ -243,7 +242,7 @@ public InfoItemsPage getPage(final Page page) throws IOException final var headers = getYouTubeHeaders(); final Response response = getDownloader().postWithContentTypeJson(page.getUrl(), headers, - page.getBody(), getExtractorLocalization()); + page.getBody(), getExtractorLocale()); final JsonObject ajaxJson = JsonUtils.toJsonObject(getValidJsonResponseBody(response)); final JsonObject playlistJson = ajaxJson.getObject("contents") .getObject("twoColumnWatchNextResults").getObject("playlist").getObject("playlist"); diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubePlaylistExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubePlaylistExtractor.java index 3e2fd89d5e..21733cabb9 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubePlaylistExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubePlaylistExtractor.java @@ -23,7 +23,6 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; -import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.localization.TimeAgoParser; import org.schabi.newpipe.extractor.playlist.PlaylistExtractor; import org.schabi.newpipe.extractor.playlist.PlaylistInfo; @@ -72,8 +71,8 @@ public void onFetchPage(@Nonnull final Downloader downloader) throws IOException ExtractionException { final String playlistId = getId(); - final Localization localization = getExtractorLocalization(); - final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder(localization, + final var locale = getExtractorLocale(); + final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder(locale, getExtractorContentCountry()) .value("browseId", "VL" + playlistId) .value("params", "wgYCCAA%3D") // Show unavailable videos @@ -83,12 +82,12 @@ public void onFetchPage(@Nonnull final Downloader downloader) throws IOException browseMetadataResponse = getJsonPostResponse("browse", List.of("$fields=" + SIDEBAR + "," + HEADER + "," + MICROFORMAT + ",alerts"), body, - localization); + locale); YoutubeParsingHelper.defaultAlertsCheck(browseMetadataResponse); isNewPlaylistInterface = checkIfResponseIsNewPlaylistInterface(); - final PlaylistContinuation playlistContinuation = PlaylistContinuation.newBuilder() + final var playlistContinuation = PlaylistContinuation.newBuilder() .setParameters(ContinuationParams.newBuilder() .setBrowseId("VL" + playlistId) .setPlaylistId(playlistId) @@ -97,13 +96,13 @@ public void onFetchPage(@Nonnull final Downloader downloader) throws IOException .build(); initialBrowseContinuationResponse = getJsonPostResponse("browse", - JsonWriter.string(prepareDesktopJsonBuilder(localization, + JsonWriter.string(prepareDesktopJsonBuilder(locale, getExtractorContentCountry()) .value("continuation", Utils.encodeUrlUtf8(Base64.getUrlEncoder() .encodeToString(playlistContinuation.toByteArray()))) .done()) .getBytes(StandardCharsets.UTF_8), - localization); + locale); } /** @@ -353,7 +352,7 @@ public InfoItemsPage getPage(final Page page) throws IOException final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId()); final JsonObject ajaxJson = getJsonPostResponse("browse", page.getBody(), - getExtractorLocalization()); + getExtractorLocale()); final JsonArray continuation = ajaxJson.getArray("onResponseReceivedActions") .getObject(0) @@ -406,7 +405,7 @@ private Page getNextPageFrom(final JsonArray contents) } final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder( - getExtractorLocalization(), getExtractorContentCountry()) + getExtractorLocale(), getExtractorContentCountry()) .value("continuation", continuation) .done()) .getBytes(StandardCharsets.UTF_8); diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSearchExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSearchExtractor.java index e888787cf9..a5df12f84a 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSearchExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSearchExtractor.java @@ -26,7 +26,6 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.linkhandler.SearchQueryHandler; -import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.localization.TimeAgoParser; import org.schabi.newpipe.extractor.search.SearchExtractor; import org.schabi.newpipe.extractor.services.youtube.YoutubeMetaInfoHelper; @@ -90,10 +89,10 @@ public YoutubeSearchExtractor(final StreamingService service, public void onFetchPage(@Nonnull final Downloader downloader) throws IOException, ExtractionException { final String query = super.getSearchString(); - final Localization localization = getExtractorLocalization(); + final var locale = getExtractorLocale(); final String params = getSearchParameter(searchType); - final JsonBuilder jsonBody = prepareDesktopJsonBuilder(localization, + final JsonBuilder jsonBody = prepareDesktopJsonBuilder(locale, getExtractorContentCountry()) .value("query", query); if (!isNullOrEmpty(params)) { @@ -102,7 +101,7 @@ public void onFetchPage(@Nonnull final Downloader downloader) throws IOException final byte[] body = JsonWriter.string(jsonBody.done()).getBytes(StandardCharsets.UTF_8); - initialData = getJsonPostResponse("search", body, localization); + initialData = getJsonPostResponse("search", body, locale); } @Nonnull @@ -194,25 +193,25 @@ public InfoItemsPage getPage(final Page page) throws IOException, throw new IllegalArgumentException("Page doesn't contain an URL"); } - final Localization localization = getExtractorLocalization(); - final MultiInfoItemsCollector collector = new MultiInfoItemsCollector(getServiceId()); + final var locale = getExtractorLocale(); + final var collector = new MultiInfoItemsCollector(getServiceId()); // @formatter:off - final byte[] json = JsonWriter.string(prepareDesktopJsonBuilder(localization, + final byte[] json = JsonWriter.string(prepareDesktopJsonBuilder(locale, getExtractorContentCountry()) .value("continuation", page.getId()) .done()) .getBytes(StandardCharsets.UTF_8); // @formatter:on - final JsonObject ajaxJson = getJsonPostResponse("search", json, localization); + final var ajaxJson = getJsonPostResponse("search", json, locale); - final JsonArray continuationItems = ajaxJson.getArray("onResponseReceivedCommands") + final var continuationItems = ajaxJson.getArray("onResponseReceivedCommands") .getObject(0) .getObject("appendContinuationItemsAction") .getArray("continuationItems"); - final JsonArray contents = continuationItems.getObject(0) + final var contents = continuationItems.getObject(0) .getObject("itemSectionRenderer") .getArray("contents"); collectStreamsFrom(collector, contents); diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java index 6d230298a2..52ee848678 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java @@ -57,7 +57,6 @@ import org.schabi.newpipe.extractor.linkhandler.LinkHandler; import org.schabi.newpipe.extractor.localization.ContentCountry; import org.schabi.newpipe.extractor.localization.DateWrapper; -import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.localization.TimeAgoParser; import org.schabi.newpipe.extractor.localization.TimeAgoPatternsManager; import org.schabi.newpipe.extractor.services.youtube.ItagItem; @@ -195,9 +194,8 @@ public String getTextualUploadDate() throws ParsingException { final String time = videoPrimaryInfoRendererDateText.substring(13); try { // Premiered 20 hours ago - final TimeAgoParser timeAgoParser = TimeAgoPatternsManager.getTimeAgoParserFor( - new Localization("en")); - final OffsetDateTime parsedTime = timeAgoParser.parse(time).offsetDateTime(); + final var parser = TimeAgoPatternsManager.getTimeAgoParserFor(Locale.ENGLISH); + final OffsetDateTime parsedTime = parser.parse(time).offsetDateTime(); return DateTimeFormatter.ISO_LOCAL_DATE.format(parsedTime); } catch (final Exception ignored) { } @@ -814,35 +812,35 @@ public void onFetchPage(@Nonnull final Downloader downloader) throws IOException, ExtractionException { final String videoId = getId(); - final Localization localization = getExtractorLocalization(); - final ContentCountry contentCountry = getExtractorContentCountry(); + final var locale = getExtractorLocale(); + final var contentCountry = getExtractorContentCountry(); final PoTokenProvider poTokenProviderInstance = poTokenProvider; final boolean noPoTokenProviderSet = poTokenProviderInstance == null; - fetchHtml5Client(localization, contentCountry, videoId, poTokenProviderInstance); + fetchHtml5Client(locale, contentCountry, videoId, poTokenProviderInstance); setStreamType(); final PoTokenResult androidPoTokenResult = noPoTokenProviderSet ? null : poTokenProviderInstance.getAndroidClientPoToken(videoId); - fetchAndroidClient(localization, contentCountry, videoId, androidPoTokenResult); + fetchAndroidClient(locale, contentCountry, videoId, androidPoTokenResult); if (fetchIosClient) { final PoTokenResult iosPoTokenResult = noPoTokenProviderSet ? null : poTokenProviderInstance.getIosClientPoToken(videoId); - fetchIosClient(localization, contentCountry, videoId, iosPoTokenResult); + fetchIosClient(locale, contentCountry, videoId, iosPoTokenResult); } final byte[] nextBody = JsonWriter.string( - prepareDesktopJsonBuilder(localization, contentCountry) + prepareDesktopJsonBuilder(locale, contentCountry) .value(VIDEO_ID, videoId) .value(CONTENT_CHECK_OK, true) .value(RACY_CHECK_OK, true) .done()) .getBytes(StandardCharsets.UTF_8); - nextResponse = getJsonPostResponse(NEXT, nextBody, localization); + nextResponse = getJsonPostResponse(NEXT, nextBody, locale); } private static void checkPlayabilityStatus(@Nonnull final JsonObject playabilityStatus) @@ -911,7 +909,7 @@ private static void checkPlayabilityStatus(@Nonnull final JsonObject playability throw new ContentNotAvailableException("Got error " + status + ": \"" + reason + "\""); } - private void fetchHtml5Client(@Nonnull final Localization localization, + private void fetchHtml5Client(@Nonnull final Locale locale, @Nonnull final ContentCountry contentCountry, @Nonnull final String videoId, @Nullable final PoTokenProvider poTokenProviderInstance) @@ -919,7 +917,7 @@ private void fetchHtml5Client(@Nonnull final Localization localization, html5Cpn = generateContentPlaybackNonce(); final JsonObject webPlayerResponse = YoutubeStreamHelper.getWebMetadataPlayerResponse( - localization, contentCountry, videoId); + locale, contentCountry, videoId); throwExceptionIfPlayerResponseNotValid(webPlayerResponse, videoId); @@ -935,7 +933,7 @@ private void fetchHtml5Client(@Nonnull final Localization localization, final JsonObject playabilityStatus = webPlayerResponse.getObject(PLAYABILITY_STATUS); if (isVideoAgeRestricted(playabilityStatus)) { - fetchHtml5EmbedClient(localization, contentCountry, videoId, + fetchHtml5EmbedClient(locale, contentCountry, videoId, poTokenProviderInstance == null ? null : poTokenProviderInstance.getWebEmbedClientPoToken(videoId)); } else { @@ -957,7 +955,7 @@ private static void throwExceptionIfPlayerResponseNotValid( } } - private void fetchHtml5EmbedClient(@Nonnull final Localization localization, + private void fetchHtml5EmbedClient(@Nonnull final Locale locale, @Nonnull final ContentCountry contentCountry, @Nonnull final String videoId, @Nullable final PoTokenResult webEmbedPoTokenResult) @@ -965,7 +963,7 @@ private void fetchHtml5EmbedClient(@Nonnull final Localization localization, html5Cpn = generateContentPlaybackNonce(); final JsonObject webEmbeddedPlayerResponse = - YoutubeStreamHelper.getWebEmbeddedPlayerResponse(localization, contentCountry, + YoutubeStreamHelper.getWebEmbeddedPlayerResponse(locale, contentCountry, videoId, html5Cpn, webEmbedPoTokenResult, YoutubeJavaScriptPlayerManager.getSignatureTimestamp(videoId)); @@ -989,7 +987,7 @@ private void fetchHtml5EmbedClient(@Nonnull final Localization localization, } } - private void fetchAndroidClient(@Nonnull final Localization localization, + private void fetchAndroidClient(@Nonnull final Locale locale, @Nonnull final ContentCountry contentCountry, @Nonnull final String videoId, @Nullable final PoTokenResult androidPoTokenResult) { @@ -999,10 +997,10 @@ private void fetchAndroidClient(@Nonnull final Localization localization, final JsonObject androidPlayerResponse; if (androidPoTokenResult == null) { androidPlayerResponse = YoutubeStreamHelper.getAndroidReelPlayerResponse( - contentCountry, localization, videoId, androidCpn); + contentCountry, locale, videoId, androidCpn); } else { androidPlayerResponse = YoutubeStreamHelper.getAndroidPlayerResponse( - contentCountry, localization, videoId, androidCpn, + contentCountry, locale, videoId, androidCpn, androidPoTokenResult); } @@ -1025,7 +1023,7 @@ private void fetchAndroidClient(@Nonnull final Localization localization, } } - private void fetchIosClient(@Nonnull final Localization localization, + private void fetchIosClient(@Nonnull final Locale locale, @Nonnull final ContentCountry contentCountry, @Nonnull final String videoId, @Nullable final PoTokenResult iosPoTokenResult) { @@ -1033,7 +1031,7 @@ private void fetchIosClient(@Nonnull final Localization localization, iosCpn = generateContentPlaybackNonce(); final JsonObject iosPlayerResponse = YoutubeStreamHelper.getIosPlayerResponse( - contentCountry, localization, videoId, iosCpn, iosPoTokenResult); + contentCountry, locale, videoId, iosCpn, iosPoTokenResult); if (!isPlayerResponseNotValid(iosPlayerResponse, videoId)) { iosStreamingData = iosPlayerResponse.getObject(STREAMING_DATA); @@ -1551,11 +1549,6 @@ public String getLicence() throws ParsingException { : "YouTube licence"; } - @Override - public Locale getLanguageInfo() { - return null; - } - @Nonnull @Override public List getTags() { diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSuggestionExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSuggestionExtractor.java index 5304ed713f..b459954c70 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSuggestionExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSuggestionExtractor.java @@ -62,7 +62,7 @@ public List suggestionList(final String query) throws IOException, Extra headers.put("Referer", Collections.singletonList("https://www.youtube.com")); final Response response = NewPipe.getDownloader() - .get(url, headers, getExtractorLocalization()); + .get(url, headers, getExtractorLocale()); final String contentTypeHeader = response.getHeader("Content-Type"); if (isNullOrEmpty(contentTypeHeader) || !contentTypeHeader.contains("application/json")) { diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/kiosk/YoutubeChartsBaseKioskExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/kiosk/YoutubeChartsBaseKioskExtractor.java index 3ede87619e..9d0b09b59e 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/kiosk/YoutubeChartsBaseKioskExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/kiosk/YoutubeChartsBaseKioskExtractor.java @@ -11,9 +11,7 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.kiosk.KioskExtractor; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; -import org.schabi.newpipe.extractor.localization.ContentCountry; import org.schabi.newpipe.extractor.localization.DateWrapper; -import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.services.youtube.InnertubeClientRequestInfo; import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelLinkHandlerFactory; import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeStreamLinkHandlerFactory; @@ -84,14 +82,12 @@ protected YoutubeChartsBaseKioskExtractor(final StreamingService streamingServic @Override public void onFetchPage(@Nonnull final Downloader downloader) throws IOException, ExtractionException { - final Localization localization = getExtractorLocalization(); - final ContentCountry contentCountry = getExtractorContentCountry(); + final var locale = getExtractorLocale(); + final var contentCountry = getExtractorContentCountry(); + final var requestInfo = InnertubeClientRequestInfo.ofWebMusicAnalyticsChartsClient(); - final InnertubeClientRequestInfo innertubeClientRequestInfo = - InnertubeClientRequestInfo.ofWebMusicAnalyticsChartsClient(); - - final byte[] body = JsonWriter.string(prepareJsonBuilder(getExtractorLocalization(), - contentCountry, innertubeClientRequestInfo, null) + final byte[] body = JsonWriter.string(prepareJsonBuilder(getExtractorLocale(), + contentCountry, requestInfo, null) .value("browseId", "FEmusic_analytics_charts_home") .value("query", "perspective=CHART_DETAILS&chart_params_country_code=" + contentCountry.getCountryCode() + "&chart_params_chart_type=" @@ -100,12 +96,12 @@ public void onFetchPage(@Nonnull final Downloader downloader) .getBytes(StandardCharsets.UTF_8); final var headers = new HashMap<>(getOriginReferrerHeaders("https://charts.youtube.com")); - headers.putAll(getClientHeaders(innertubeClientRequestInfo.clientInfo.clientId, - innertubeClientRequestInfo.clientInfo.clientVersion)); + headers.putAll(getClientHeaders(requestInfo.clientInfo.clientId, + requestInfo.clientInfo.clientVersion)); browseResponse = JsonUtils.toJsonObject(getValidJsonResponseBody( getDownloader().postWithContentTypeJson( - YT_CHARTS_ENDPOINT, headers, body, localization))); + YT_CHARTS_ENDPOINT, headers, body, locale))); } @Nonnull diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/kiosk/YoutubeDesktopBaseKioskExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/kiosk/YoutubeDesktopBaseKioskExtractor.java index 7f1c7390da..1d2fd821bf 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/kiosk/YoutubeDesktopBaseKioskExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/kiosk/YoutubeDesktopBaseKioskExtractor.java @@ -55,7 +55,7 @@ public void onFetchPage(@Nonnull final Downloader downloader) responseData = YoutubeChannelHelper.getChannelResponse( browseId, params, - getExtractorLocalization(), + getExtractorLocale(), getExtractorContentCountry()); } @@ -110,7 +110,7 @@ public InfoItemsPage getPage(final Page page) } final JsonObject continuationResponse = getJsonPostResponse("browse", page.getBody(), - getExtractorLocalization()); + getExtractorLocale()); final JsonArray continuationItems = continuationResponse.getArray("onResponseReceivedActions") @@ -193,7 +193,7 @@ private Page getNextPageFrom(@Nullable final JsonObject continuation, webClientRequestInfo.clientInfo.clientVersion = getClientVersion(); webClientRequestInfo.clientInfo.visitorData = visitorData; - final byte[] body = JsonWriter.string(prepareJsonBuilder(getExtractorLocalization(), + final byte[] body = JsonWriter.string(prepareJsonBuilder(getExtractorLocale(), getExtractorContentCountry(), webClientRequestInfo, null) diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/kiosk/YoutubeTrendingExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/kiosk/YoutubeTrendingExtractor.java index 4dd3c04355..5cfd1292a3 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/kiosk/YoutubeTrendingExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/kiosk/YoutubeTrendingExtractor.java @@ -64,7 +64,7 @@ public YoutubeTrendingExtractor(final StreamingService service, public void onFetchPage(@Nonnull final Downloader downloader) throws IOException, ExtractionException { // @formatter:off - final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder(getExtractorLocalization(), + final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder(getExtractorLocale(), getExtractorContentCountry()) .value("browseId", "FEtrending") .value("params", VIDEOS_TAB_PARAMS) @@ -72,7 +72,7 @@ public void onFetchPage(@Nonnull final Downloader downloader) .getBytes(StandardCharsets.UTF_8); // @formatter:on - initialData = getJsonPostResponse("browse", body, getExtractorLocalization()); + initialData = getJsonPostResponse("browse", body, getExtractorLocale()); } @Override diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/SubtitlesStream.java b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/SubtitlesStream.java index 1b8fb67119..759adb3e4c 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/SubtitlesStream.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/SubtitlesStream.java @@ -13,7 +13,6 @@ public final class SubtitlesStream extends Stream { private final MediaFormat format; private final Locale locale; private final boolean autoGenerated; - private final String code; /** * Class to build {@link SubtitlesStream} objects. @@ -232,7 +231,6 @@ private SubtitlesStream(@Nonnull final String id, @Nullable final String manifestUrl) { super(id, content, isUrl, mediaFormat, deliveryMethod, manifestUrl); this.locale = Locale.forLanguageTag(languageCode); - this.code = languageCode; this.format = mediaFormat; this.autoGenerated = autoGenerated; } @@ -265,7 +263,7 @@ public boolean isAutoGenerated() { public boolean equalStats(final Stream cmp) { return super.equalStats(cmp) && cmp instanceof SubtitlesStream - && code.equals(((SubtitlesStream) cmp).code) + && locale.equals(((SubtitlesStream) cmp).locale) && autoGenerated == ((SubtitlesStream) cmp).autoGenerated; } @@ -284,7 +282,7 @@ public String getDisplayLanguageName() { * @return the language tag of the subtitles */ public String getLanguageTag() { - return code; + return locale.toLanguageTag(); } /** diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/suggestion/SuggestionExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/suggestion/SuggestionExtractor.java index 171fa0bd75..3d8f108ddb 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/suggestion/SuggestionExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/suggestion/SuggestionExtractor.java @@ -3,16 +3,16 @@ import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.localization.ContentCountry; -import org.schabi.newpipe.extractor.localization.Localization; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.io.IOException; import java.util.List; +import java.util.Locale; public abstract class SuggestionExtractor { private final StreamingService service; - @Nullable private Localization forcedLocalization; + @Nullable private Locale forcedLocale; @Nullable private ContentCountry forcedContentCountry; public SuggestionExtractor(final StreamingService service) { @@ -32,8 +32,8 @@ public StreamingService getService() { // TODO: Create a more general Extractor class - public void forceLocalization(@Nullable final Localization localization) { - this.forcedLocalization = localization; + public void forceLocale(@Nullable final Locale locale) { + this.forcedLocale = locale; } public void forceContentCountry(@Nullable final ContentCountry contentCountry) { @@ -41,8 +41,8 @@ public void forceContentCountry(@Nullable final ContentCountry contentCountry) { } @Nonnull - public Localization getExtractorLocalization() { - return forcedLocalization == null ? getService().getLocalization() : forcedLocalization; + public Locale getExtractorLocale() { + return forcedLocale == null ? getService().getLocale() : forcedLocale; } @Nonnull diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/localization/TimeAgoParserTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/localization/TimeAgoParserTest.java index db45e807b9..7c80967ed9 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/localization/TimeAgoParserTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/localization/TimeAgoParserTest.java @@ -1,10 +1,5 @@ package org.schabi.newpipe.extractor.localization; -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.schabi.newpipe.extractor.localization.TimeAgoParserTest.ParseTimeAgoTestData.greaterThanDay; -import static org.schabi.newpipe.extractor.localization.TimeAgoParserTest.ParseTimeAgoTestData.lessThanDay; - import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -14,10 +9,15 @@ import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.time.temporal.ChronoUnit; -import java.util.Objects; +import java.util.Locale; import java.util.function.Function; import java.util.stream.Stream; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.schabi.newpipe.extractor.localization.TimeAgoParserTest.ParseTimeAgoTestData.greaterThanDay; +import static org.schabi.newpipe.extractor.localization.TimeAgoParserTest.ParseTimeAgoTestData.lessThanDay; + class TimeAgoParserTest { public static Stream parseTimeAgo() { return Stream.of( @@ -44,10 +44,8 @@ void parseTimeAgo(final ParseTimeAgoTestData testData) { final OffsetDateTime now = OffsetDateTime.of( LocalDateTime.of(2020, 1, 1, 1, 1, 1), ZoneOffset.UTC); - final TimeAgoParser parser = Objects.requireNonNull( - TimeAgoPatternsManager.getTimeAgoParserFor(Localization.DEFAULT, now)); - - final OffsetDateTime expected = testData.getExpectedApplyToNow().apply(now); + final var parser = TimeAgoPatternsManager.getTimeAgoParserFor(Locale.UK, now); + final var expected = testData.getExpectedApplyToNow().apply(now); assertAll( Stream.of( diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCStreamExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCStreamExtractorTest.java index caabff883f..0c33f5cb3e 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCStreamExtractorTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCStreamExtractorTest.java @@ -56,7 +56,7 @@ protected StreamExtractor createExtractor() throws Exception { @Override public boolean expectedHasFrames() { return false; } @Override public List expectedTags() { return Arrays.asList("gpn18", "105"); } @Override public int expectedStreamSegmentsCount() { return 0; } - @Override public Locale expectedLanguageInfo() { return new Locale("de"); } + @Override public Locale expectedLanguageInfo() { return Locale.forLanguageTag("de-IT"); } @Override @Test @@ -168,7 +168,7 @@ public void testAudioStreams() throws Exception { @Override public Locale expectedLanguageInfo() { - return new Locale("en"); + return Locale.forLanguageTag("en-NU"); } } } diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeStreamExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeStreamExtractorTest.java index 18252899c0..326b36bfec 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeStreamExtractorTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeStreamExtractorTest.java @@ -41,7 +41,7 @@ protected StreamExtractor createExtractor() throws Exception { @Test public void testGetLanguageInformation() throws ParsingException { - assertEquals(new Locale("en"), extractor().getLanguageInfo()); + assertEquals(Locale.ENGLISH, extractor().getLanguageInfo()); } @Override public StreamingService expectedService() { return PeerTube; } @@ -84,7 +84,7 @@ public void testGetLanguageInformation() throws ParsingException { @Override public String expectedHost() { return "framatube.org"; } @Override public String expectedCategory() { return "Science & Technology"; } @Override public String expectedLicence() { return "Attribution - Share Alike"; } - @Override public Locale expectedLanguageInfo() { return Locale.forLanguageTag("en"); } + @Override public Locale expectedLanguageInfo() { return Locale.ENGLISH; } @Override public List expectedTags() { return Arrays.asList("framasoft", "peertube"); } } diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelLocalizationTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelLocalizationTest.java index 6633a76f89..b77bf64cba 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelLocalizationTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelLocalizationTest.java @@ -1,25 +1,25 @@ package org.schabi.newpipe.extractor.services.youtube; -import static org.junit.jupiter.api.Assertions.fail; -import static org.schabi.newpipe.extractor.ServiceList.YouTube; -import static org.schabi.newpipe.extractor.services.DefaultTests.defaultTestRelatedItems; - import org.junit.jupiter.api.Test; import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.channel.ChannelExtractor; import org.schabi.newpipe.extractor.channel.tabs.ChannelTabExtractor; import org.schabi.newpipe.extractor.localization.DateWrapper; -import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.stream.Collectors; +import static org.junit.jupiter.api.Assertions.fail; +import static org.schabi.newpipe.extractor.ServiceList.YouTube; +import static org.schabi.newpipe.extractor.services.DefaultTests.defaultTestRelatedItems; + /** * A class that tests multiple channels and ranges of "time ago". */ @@ -37,17 +37,16 @@ public void testAllSupportedLocalizations() throws Exception { private void testLocalizationsFor(final String channelUrl) throws Exception { - final List supportedLocalizations = YouTube.getSupportedLocalizations(); - // final List supportedLocalizations = Arrays.asList(Localization.DEFAULT, new Localization("sr")); - final Map> results = new LinkedHashMap<>(); + final var supportedLocalizations = YouTube.getSupportedLocales(); + final Map> results = new LinkedHashMap<>(); - for (final Localization currentLocalization : supportedLocalizations) { - if (DEBUG) System.out.println("Testing localization = " + currentLocalization); + for (final var locale : supportedLocalizations) { + if (DEBUG) System.out.println("Testing localization = " + locale); final ListExtractor.InfoItemsPage itemsPage; try { final ChannelExtractor extractor = YouTube.getChannelExtractor(channelUrl); - extractor.forceLocalization(currentLocalization); + extractor.forceLocale(locale); extractor.fetchPage(); // Use Videos tab only @@ -56,7 +55,7 @@ private void testLocalizationsFor(final String channelUrl) throws Exception { tabExtractor.fetchPage(); itemsPage = defaultTestRelatedItems(tabExtractor); } catch (final Throwable e) { - System.out.println("[!] " + currentLocalization + " → failed"); + System.out.println("[!] " + locale + " → failed"); throw e; } @@ -69,7 +68,7 @@ private void testLocalizationsFor(final String channelUrl) throws Exception { final StreamInfoItem item = items.get(i); String debugMessage = "[" + String.format("%02d", i) + "] " - + currentLocalization.getLocalizationCode() + " → " + item.getName() + + locale.toLanguageTag() + " → " + item.getName() + "\n:::: " + item.getStreamType() + ", views = " + item.getViewCount(); final DateWrapper uploadDate = item.getUploadDate(); if (uploadDate != null) { @@ -79,23 +78,23 @@ private void testLocalizationsFor(final String channelUrl) throws Exception { } if (DEBUG) System.out.println(debugMessage + "\n"); } - results.put(currentLocalization, items); + results.put(locale, items); if (DEBUG) System.out.println("\n===============================\n"); } // Check results - final List referenceList = results.get(Localization.DEFAULT); + final List referenceList = results.get(Locale.UK); boolean someFail = false; - for (final Map.Entry> currentResultEntry : results.entrySet()) { - if (currentResultEntry.getKey().equals(Localization.DEFAULT)) { + for (final var currentResultEntry : results.entrySet()) { + if (currentResultEntry.getKey().equals(Locale.UK)) { continue; } - final String currentLocalizationCode = currentResultEntry.getKey().getLocalizationCode(); - final String referenceLocalizationCode = Localization.DEFAULT.getLocalizationCode(); + final String currentLocalizationCode = currentResultEntry.getKey().toLanguageTag(); + final String referenceLocalizationCode = Locale.UK.toLanguageTag(); if (DEBUG) { System.out.println("Comparing " + referenceLocalizationCode + " with " + currentLocalizationCode); diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeCommentsExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeCommentsExtractorTest.java index 4374d39f0e..1c00a8e101 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeCommentsExtractorTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeCommentsExtractorTest.java @@ -1,22 +1,11 @@ package org.schabi.newpipe.extractor.services.youtube; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.schabi.newpipe.extractor.ExtractorAsserts.assertContains; -import static org.schabi.newpipe.extractor.ExtractorAsserts.assertGreater; -import static org.schabi.newpipe.extractor.ServiceList.YouTube; -import static org.schabi.newpipe.extractor.comments.CommentsInfoItem.UNKNOWN_REPLY_COUNT; - import org.junit.jupiter.api.Test; import org.schabi.newpipe.extractor.ListExtractor.InfoItemsPage; import org.schabi.newpipe.extractor.Page; import org.schabi.newpipe.extractor.comments.CommentsInfo; import org.schabi.newpipe.extractor.comments.CommentsInfoItem; import org.schabi.newpipe.extractor.exceptions.ExtractionException; -import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.services.DefaultSimpleExtractorTest; import org.schabi.newpipe.extractor.services.DefaultTests; import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeCommentsExtractor; @@ -26,6 +15,12 @@ import java.util.List; import java.util.Locale; +import static org.junit.jupiter.api.Assertions.*; +import static org.schabi.newpipe.extractor.ExtractorAsserts.assertContains; +import static org.schabi.newpipe.extractor.ExtractorAsserts.assertGreater; +import static org.schabi.newpipe.extractor.ServiceList.YouTube; +import static org.schabi.newpipe.extractor.comments.CommentsInfoItem.UNKNOWN_REPLY_COUNT; + public class YoutubeCommentsExtractorTest { abstract static class Base extends DefaultSimpleExtractorTest @@ -271,7 +266,7 @@ protected String extractorUrl() { @Override protected void fetchExtractor(final YoutubeCommentsExtractor extractor) throws Exception { // Force non english local here - extractor.forceLocalization(Localization.fromLocale(Locale.GERMANY)); + extractor.forceLocale(Locale.GERMANY); super.fetchExtractor(extractor); } diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeMixPlaylistExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeMixPlaylistExtractorTest.java index b347bcbb44..fceaf1ee01 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeMixPlaylistExtractorTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeMixPlaylistExtractorTest.java @@ -1,16 +1,6 @@ package org.schabi.newpipe.extractor.services.youtube; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.schabi.newpipe.extractor.ServiceList.YouTube; -import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.DISABLE_PRETTY_PRINT_PARAMETER; -import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.YOUTUBEI_V1_URL; -import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.prepareDesktopJsonBuilder; - import com.grack.nanojson.JsonWriter; - import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.schabi.newpipe.extractor.ExtractorAsserts; @@ -30,6 +20,10 @@ import java.util.Map; import java.util.Set; +import static org.junit.jupiter.api.Assertions.*; +import static org.schabi.newpipe.extractor.ServiceList.YouTube; +import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.*; + @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection", "NewClassNamingConvention"}) public class YoutubeMixPlaylistExtractorTest { @@ -91,7 +85,7 @@ void getInitialPage() throws Exception { @Test void getPage() throws Exception { final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder( - NewPipe.getPreferredLocalization(), NewPipe.getPreferredContentCountry()) + NewPipe.getPreferredLocale(), NewPipe.getPreferredContentCountry()) .value("videoId", VIDEO_ID) .value("playlistId", "RD" + VIDEO_ID) .value("params", "OAE%3D") @@ -174,7 +168,7 @@ void getInitialPage() throws Exception { @Test void getPage() throws Exception { final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder( - NewPipe.getPreferredLocalization(), NewPipe.getPreferredContentCountry()) + NewPipe.getPreferredLocale(), NewPipe.getPreferredContentCountry()) .value("videoId", VIDEO_ID) .value("playlistId", "RD" + VIDEO_ID) .value("playlistIndex", INDEX) @@ -258,7 +252,7 @@ void getInitialPage() throws Exception { @Test void getPage() throws Exception { final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder( - NewPipe.getPreferredLocalization(), NewPipe.getPreferredContentCountry()) + NewPipe.getPreferredLocale(), NewPipe.getPreferredContentCountry()) .value("videoId", VIDEO_ID) .value("playlistId", "RDMM" + VIDEO_ID) .value("params", "OAE%3D") @@ -375,7 +369,7 @@ void getInitialPage() throws Exception { @Test void getPage() throws Exception { final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder( - NewPipe.getPreferredLocalization(), NewPipe.getPreferredContentCountry()) + NewPipe.getPreferredLocale(), NewPipe.getPreferredContentCountry()) .value("videoId", VIDEO_ID) .value("playlistId", "RD" + VIDEO_ID) .value("params", "OAE%3D") @@ -459,7 +453,7 @@ void getInitialPage() throws Exception { @Test void getPage() throws Exception { final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder( - NewPipe.getPreferredLocalization(), NewPipe.getPreferredContentCountry()) + NewPipe.getPreferredLocale(), NewPipe.getPreferredContentCountry()) .value("videoId", VIDEO_ID) .value("playlistId", "RD" + VIDEO_ID) .value("params", "OAE%3D") diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeSuggestionExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeSuggestionExtractorTest.java index 54c76b7119..ec2515869f 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeSuggestionExtractorTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeSuggestionExtractorTest.java @@ -20,19 +20,19 @@ package org.schabi.newpipe.extractor.services.youtube; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.schabi.newpipe.extractor.ServiceList.YouTube; - import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.schabi.newpipe.downloader.DownloaderFactory; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.exceptions.ExtractionException; -import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeSuggestionExtractor; import org.schabi.newpipe.extractor.suggestion.SuggestionExtractor; import java.io.IOException; +import java.util.Locale; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.schabi.newpipe.extractor.ServiceList.YouTube; /** * Test for {@link YoutubeSuggestionExtractor} @@ -44,7 +44,8 @@ class YoutubeSuggestionExtractorTest { @BeforeAll public static void setUp() throws Exception { YoutubeTestsUtils.ensureStateless(); - NewPipe.init(DownloaderFactory.getDownloader(YoutubeSuggestionExtractorTest.class), new Localization("de", "DE")); + NewPipe.init(DownloaderFactory.getDownloader(YoutubeSuggestionExtractorTest.class), + Locale.GERMANY); suggestionExtractor = YouTube.getSuggestionExtractor(); } diff --git a/timeago-generator/src/main/java/org/schabi/newpipe/timeago_generator/GeneratePatternClasses.java b/timeago-generator/src/main/java/org/schabi/newpipe/timeago_generator/GeneratePatternClasses.java index a2ef2ffa4f..dd1a6062ca 100644 --- a/timeago-generator/src/main/java/org/schabi/newpipe/timeago_generator/GeneratePatternClasses.java +++ b/timeago-generator/src/main/java/org/schabi/newpipe/timeago_generator/GeneratePatternClasses.java @@ -27,7 +27,8 @@ public static void main(String[] args) throws FileNotFoundException, JsonParserE final StringBuilder patternMapEntries = new StringBuilder(); for (Map.Entry entry : map.entrySet()) { - final String languageCode = entry.getKey().replace('-', '_'); + final String languageCode = entry.getKey(); + final String formattedCode = languageCode.replace('-', '_'); final Map unitsList = (Map) entry.getValue(); final String wordSeparator = (String) unitsList.get("word_separator"); @@ -54,14 +55,14 @@ public static void main(String[] args) throws FileNotFoundException, JsonParserE try (final FileWriter fileOut = new FileWriter( "timeago-parser/src/main/java/org/schabi/newpipe/extractor/timeago/patterns/" + - languageCode + ".java")) { + formattedCode + ".java")) { final String test = INFO_CLASS_GENERATED + "\n" + "\n" + "package org.schabi.newpipe.extractor.timeago.patterns;\n\n" + "import org.schabi.newpipe.extractor.timeago.PatternsHolder;\n" + (specialCasesString.length() > 0 ? "\nimport java.time.temporal.ChronoUnit;\n" : "") + "\n" + - "public class " + languageCode + " extends PatternsHolder {\n" + + "public class " + formattedCode + " extends PatternsHolder {\n" + " private static final String WORD_SEPARATOR = \"" + wordSeparator + "\";\n" + " private static final String[]\n" + " SECONDS /**/ = {" + join(seconds) + "},\n" + @@ -72,15 +73,15 @@ public static void main(String[] args) throws FileNotFoundException, JsonParserE " MONTHS /**/ = {" + join(months) + "},\n" + " YEARS /**/ = {" + join(years) + "};\n" + "\n" + - " private static final " + languageCode + " INSTANCE = new " + languageCode + "();\n" + + " private static final " + formattedCode + " INSTANCE = new " + formattedCode + "();\n" + "\n" + - " public static " + languageCode + " getInstance() {\n" + + " public static " + formattedCode + " getInstance() {\n" + " return INSTANCE;\n" + " }\n" + "\n" + - " private " + languageCode + "() {\n" + + " private " + formattedCode + "() {\n" + " super(WORD_SEPARATOR, SECONDS, MINUTES, HOURS, DAYS, WEEKS, MONTHS, YEARS);\n" + - specialCasesString.toString() + + specialCasesString + " }\n" + "}"; fileOut.write(test); @@ -90,7 +91,7 @@ public static void main(String[] args) throws FileNotFoundException, JsonParserE patternMapEntries.append(" patternMap.put(\"") .append(languageCode).append("\", ") - .append(languageCode).append(".getInstance());\n"); + .append(formattedCode).append(".getInstance());\n"); } try (final FileWriter fileOut = new FileWriter( diff --git a/timeago-parser/src/main/java/org/schabi/newpipe/extractor/timeago/PatternMap.java b/timeago-parser/src/main/java/org/schabi/newpipe/extractor/timeago/PatternMap.java index 7f721656ec..84171369ab 100644 --- a/timeago-parser/src/main/java/org/schabi/newpipe/extractor/timeago/PatternMap.java +++ b/timeago-parser/src/main/java/org/schabi/newpipe/extractor/timeago/PatternMap.java @@ -26,17 +26,17 @@ public class PatternMap { patternMap.put("de", de.getInstance()); patternMap.put("el", el.getInstance()); patternMap.put("en", en.getInstance()); - patternMap.put("en_GB", en_GB.getInstance()); + patternMap.put("en-GB", en_GB.getInstance()); patternMap.put("es", es.getInstance()); - patternMap.put("es_419", es_419.getInstance()); - patternMap.put("es_US", es_US.getInstance()); + patternMap.put("es-419", es_419.getInstance()); + patternMap.put("es-US", es_US.getInstance()); patternMap.put("et", et.getInstance()); patternMap.put("eu", eu.getInstance()); patternMap.put("fa", fa.getInstance()); patternMap.put("fi", fi.getInstance()); patternMap.put("fil", fil.getInstance()); patternMap.put("fr", fr.getInstance()); - patternMap.put("fr_CA", fr_CA.getInstance()); + patternMap.put("fr-CA", fr_CA.getInstance()); patternMap.put("gl", gl.getInstance()); patternMap.put("gu", gu.getInstance()); patternMap.put("hi", hi.getInstance()); @@ -69,7 +69,7 @@ public class PatternMap { patternMap.put("pa", pa.getInstance()); patternMap.put("pl", pl.getInstance()); patternMap.put("pt", pt.getInstance()); - patternMap.put("pt_PT", pt_PT.getInstance()); + patternMap.put("pt-PT", pt_PT.getInstance()); patternMap.put("ro", ro.getInstance()); patternMap.put("ru", ru.getInstance()); patternMap.put("si", si.getInstance()); @@ -77,7 +77,7 @@ public class PatternMap { patternMap.put("sl", sl.getInstance()); patternMap.put("sq", sq.getInstance()); patternMap.put("sr", sr.getInstance()); - patternMap.put("sr_Latn", sr_Latn.getInstance()); + patternMap.put("sr-Latn", sr_Latn.getInstance()); patternMap.put("sv", sv.getInstance()); patternMap.put("sw", sw.getInstance()); patternMap.put("ta", ta.getInstance()); @@ -88,9 +88,9 @@ public class PatternMap { patternMap.put("ur", ur.getInstance()); patternMap.put("uz", uz.getInstance()); patternMap.put("vi", vi.getInstance()); - patternMap.put("zh_CN", zh_CN.getInstance()); - patternMap.put("zh_HK", zh_HK.getInstance()); - patternMap.put("zh_TW", zh_TW.getInstance()); + patternMap.put("zh-CN", zh_CN.getInstance()); + patternMap.put("zh-HK", zh_HK.getInstance()); + patternMap.put("zh-TW", zh_TW.getInstance()); patternMap.put("zu", zu.getInstance()); } diff --git a/timeago-parser/src/main/java/org/schabi/newpipe/extractor/timeago/PatternsManager.java b/timeago-parser/src/main/java/org/schabi/newpipe/extractor/timeago/PatternsManager.java deleted file mode 100644 index 537fe4b707..0000000000 --- a/timeago-parser/src/main/java/org/schabi/newpipe/extractor/timeago/PatternsManager.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.schabi.newpipe.extractor.timeago; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -public class PatternsManager { - /** - * Return an holder object containing all the patterns array. - * - * @return an object containing the patterns. If not existent, {@code null}. - */ - @Nullable - public static PatternsHolder getPatterns(@Nonnull String languageCode, @Nullable String countryCode) { - final String targetLocalizationClassName = languageCode + - (countryCode == null || countryCode.isEmpty() ? "" : "_" + countryCode); - return PatternMap.getPattern(targetLocalizationClassName); - } -} From 2ad0b1e5dbbbc081b5dafbecfdbf77a71965e168 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Sun, 19 Oct 2025 10:47:51 +0530 Subject: [PATCH 3/3] Improve locale lookup --- .../newpipe/extractor/StreamingService.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/StreamingService.java b/extractor/src/main/java/org/schabi/newpipe/extractor/StreamingService.java index c6449f3ab6..92e72f7957 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/StreamingService.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/StreamingService.java @@ -367,15 +367,17 @@ public List getSupportedCountries() { */ public Locale getLocale() { final var preferredLocale = NewPipe.getPreferredLocale(); - return getSupportedLocales().stream() - .filter(locale -> { - // Check the localization's language and country - return preferredLocale.equals(locale) - // Fallback to the first supported language that matches the preferred - // language - || preferredLocale.getLanguage().equals(locale.getLanguage()); - }) - .findFirst().orElse(Locale.UK); + final var supportedLocales = getSupportedLocales(); + if (supportedLocales.contains(preferredLocale)) { + return preferredLocale; + } else { + return supportedLocales.stream() + // Fallback to the first supported language that matches the preferred + // language + .filter(locale -> + preferredLocale.getLanguage().equals(locale.getLanguage())) + .findFirst().orElse(Locale.UK); + } } /**