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 16050445..5beb5700 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 @@ -42,7 +42,7 @@ public class Request { actualHeaders.putAll(headers); } if (automaticLocalizationHeader && localization != null) { - actualHeaders.putAll(headersFromLocalization(localization)); + actualHeaders.putAll(getHeadersFromLocalization(localization)); } this.headers = Collections.unmodifiableMap(actualHeaders); @@ -91,7 +91,7 @@ public class Request { * 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#headersFromLocalization(Localization)}). + * method to do this easily: {@link Request#getHeadersFromLocalization(Localization)}). */ @Nullable public Localization localization() { @@ -158,7 +158,7 @@ public class Request { * 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#headersFromLocalization(Localization)}). + * method to do this easily: {@link Request#getHeadersFromLocalization(Localization)}). */ public Builder localization(final Localization localizationToSet) { this.localization = localizationToSet; @@ -238,23 +238,17 @@ public class Request { @SuppressWarnings("WeakerAccess") @Nonnull - public static Map> headersFromLocalization( + public static Map> getHeadersFromLocalization( @Nullable final Localization localization) { if (localization == null) { return Collections.emptyMap(); } - final Map> headers = new LinkedHashMap<>(); - if (!localization.getCountryCode().isEmpty()) { - headers.put("Accept-Language", - Collections.singletonList(localization.getLocalizationCode() - + ", " + localization.getLanguageCode() + ";q=0.9")); - } else { - headers.put("Accept-Language", - Collections.singletonList(localization.getLanguageCode())); - } - - return headers; + 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); } /*////////////////////////////////////////////////////////////////////////// diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampStreamExtractor.java index 4b5d9d12..bf551769 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampStreamExtractor.java @@ -31,7 +31,6 @@ import org.schabi.newpipe.extractor.utils.Utils; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.io.IOException; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -149,8 +148,7 @@ public class BandcampStreamExtractor extends StreamExtractor { @Override public List getAudioStreams() { - final List audioStreams = new ArrayList<>(); - audioStreams.add(new AudioStream.Builder() + return Collections.singletonList(new AudioStream.Builder() .setId("mp3-128") .setContent(albumJson.getArray("trackinfo") .getObject(0) @@ -159,7 +157,6 @@ public class BandcampStreamExtractor extends StreamExtractor { .setMediaFormat(MediaFormat.MP3) .setAverageBitrate(128) .build()); - return audioStreams; } @Override 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 80e7adc1..73df2b40 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 @@ -5,7 +5,6 @@ import static org.schabi.newpipe.extractor.utils.Utils.EMPTY_STRING; import static org.schabi.newpipe.extractor.utils.Utils.UTF_8; import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; import static org.schabi.newpipe.extractor.utils.Utils.replaceHttpWithHttps; -import static java.util.Collections.singletonList; import com.grack.nanojson.JsonArray; import com.grack.nanojson.JsonObject; @@ -39,8 +38,8 @@ import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.Collections; -import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.annotation.Nonnull; @@ -68,8 +67,8 @@ public final class SoundcloudParsingHelper { // The one containing the client id will likely be the last one Collections.reverse(possibleScripts); - final HashMap> headers = new HashMap<>(); - headers.put("Range", singletonList("bytes=0-50000")); + final Map> headers = Collections.singletonMap("Range", + Collections.singletonList("bytes=0-50000")); for (final Element element : possibleScripts) { final String srcUrl = element.attr("src"); 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 566da521..a31586ee 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 @@ -28,6 +28,8 @@ import static org.schabi.newpipe.extractor.utils.Utils.UTF_8; import static org.schabi.newpipe.extractor.utils.Utils.getStringResultFromRegexArray; import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; +import static java.util.Collections.singletonList; + import com.grack.nanojson.JsonArray; import com.grack.nanojson.JsonBuilder; import com.grack.nanojson.JsonObject; @@ -63,7 +65,6 @@ import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.time.format.DateTimeParseException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -595,9 +596,9 @@ public final class YoutubeParsingHelper { // @formatter:on final Map> headers = new HashMap<>(); - headers.put("X-YouTube-Client-Name", Collections.singletonList("1")); + headers.put("X-YouTube-Client-Name", singletonList("1")); headers.put("X-YouTube-Client-Version", - Collections.singletonList(HARDCODED_CLIENT_VERSION)); + singletonList(HARDCODED_CLIENT_VERSION)); // This endpoint is fetched by the YouTube website to get the items of its main menu and is // pretty lightweight (around 30kB) @@ -619,8 +620,8 @@ public final class YoutubeParsingHelper { } final String url = "https://www.youtube.com/sw.js"; final Map> headers = new HashMap<>(); - headers.put("Origin", Collections.singletonList("https://www.youtube.com")); - headers.put("Referer", Collections.singletonList("https://www.youtube.com")); + headers.put("Origin", singletonList("https://www.youtube.com")); + headers.put("Referer", singletonList("https://www.youtube.com")); final String response = getDownloader().get(url, headers).responseBody(); try { clientVersion = getStringResultFromRegexArray(response, @@ -641,9 +642,7 @@ public final class YoutubeParsingHelper { } // Don't provide a search term in order to have a smaller response final String url = "https://www.youtube.com/results?search_query=&ucbcb=1"; - final Map> headers = new HashMap<>(); - addCookieHeader(headers); - final String html = getDownloader().get(url, headers).responseBody(); + final String html = getDownloader().get(url, getCookieHeader()).responseBody(); final JsonObject initialData = getInitialData(html); final JsonArray serviceTrackingParams = initialData.getObject("responseContext") .getArray("serviceTrackingParams"); @@ -821,13 +820,13 @@ public final class YoutubeParsingHelper { // @formatter:on final Map> headers = new HashMap<>(); - headers.put("X-YouTube-Client-Name", Collections.singletonList( + headers.put("X-YouTube-Client-Name", singletonList( HARDCODED_YOUTUBE_MUSIC_KEY[1])); - headers.put("X-YouTube-Client-Version", Collections.singletonList( + headers.put("X-YouTube-Client-Version", singletonList( HARDCODED_YOUTUBE_MUSIC_KEY[2])); - headers.put("Origin", Collections.singletonList("https://music.youtube.com")); - headers.put("Referer", Collections.singletonList("music.youtube.com")); - headers.put("Content-Type", Collections.singletonList("application/json")); + headers.put("Origin", singletonList("https://music.youtube.com")); + headers.put("Referer", singletonList("music.youtube.com")); + headers.put("Content-Type", singletonList("application/json")); final Response response = getDownloader().post(url, headers, json); // Ensure to have a valid response @@ -851,8 +850,8 @@ public final class YoutubeParsingHelper { try { final String url = "https://music.youtube.com/sw.js"; final Map> headers = new HashMap<>(); - headers.put("Origin", Collections.singletonList("https://music.youtube.com")); - headers.put("Referer", Collections.singletonList("https://music.youtube.com")); + headers.put("Origin", singletonList("https://music.youtube.com")); + headers.put("Referer", singletonList("https://music.youtube.com")); final String response = getDownloader().get(url, headers).responseBody(); musicClientVersion = getStringResultFromRegexArray(response, INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES, 1); @@ -860,9 +859,7 @@ public final class YoutubeParsingHelper { musicClientName = Parser.matchGroup1(INNERTUBE_CLIENT_NAME_REGEX, response); } catch (final Exception e) { final String url = "https://music.youtube.com/?ucbcb=1"; - final Map> headers = new HashMap<>(); - addCookieHeader(headers); - final String html = getDownloader().get(url, headers).responseBody(); + final String html = getDownloader().get(url, getCookieHeader()).responseBody(); musicKey = getStringResultFromRegexArray(html, INNERTUBE_API_KEY_REGEXES, 1); musicClientVersion = getStringResultFromRegexArray(html, @@ -1066,7 +1063,7 @@ public final class YoutubeParsingHelper { throws IOException, ExtractionException { final Map> headers = new HashMap<>(); addClientInfoHeaders(headers); - headers.put("Content-Type", Collections.singletonList("application/json")); + headers.put("Content-Type", singletonList("application/json")); final Response response = getDownloader().post(YOUTUBEI_V1_URL + endpoint + "?key=" + getKey() + DISABLE_PRETTY_PRINT_PARAMETER, headers, body, localization); @@ -1100,9 +1097,9 @@ public final class YoutubeParsingHelper { @Nonnull final String innerTubeApiKey, @Nullable final String endPartOfUrlRequest) throws IOException, ExtractionException { final Map> headers = new HashMap<>(); - headers.put("Content-Type", Collections.singletonList("application/json")); - headers.put("User-Agent", Collections.singletonList(userAgent)); - headers.put("X-Goog-Api-Format-Version", Collections.singletonList("2")); + headers.put("Content-Type", singletonList("application/json")); + headers.put("User-Agent", singletonList(userAgent)); + headers.put("X-Goog-Api-Format-Version", singletonList("2")); final String baseEndpointUrl = YOUTUBEI_V1_GAPIS_URL + endpoint + "?key=" + innerTubeApiKey + DISABLE_PRETTY_PRINT_PARAMETER; @@ -1306,25 +1303,30 @@ public final class YoutubeParsingHelper { */ public static void addClientInfoHeaders(@Nonnull final Map> headers) throws IOException, ExtractionException { - headers.computeIfAbsent("Origin", k -> Collections.singletonList( - "https://www.youtube.com")); - headers.computeIfAbsent("Referer", k -> Collections.singletonList( - "https://www.youtube.com")); - headers.computeIfAbsent("X-YouTube-Client-Name", k -> Collections.singletonList("1")); + headers.computeIfAbsent("Origin", k -> singletonList("https://www.youtube.com")); + headers.computeIfAbsent("Referer", k -> singletonList("https://www.youtube.com")); + headers.computeIfAbsent("X-YouTube-Client-Name", k -> singletonList("1")); if (headers.get("X-YouTube-Client-Version") == null) { - headers.put("X-YouTube-Client-Version", Collections.singletonList(getClientVersion())); + headers.put("X-YouTube-Client-Version", singletonList(getClientVersion())); } } + /** + * Create a map with the required cookie header. + * @return A singleton map containing the header. + */ + public static Map> getCookieHeader() { + return Collections.singletonMap("Cookie", singletonList(generateConsentCookie())); + } + /** * Add the CONSENT cookie to prevent redirect to consent.youtube.com * @see #CONSENT_COOKIE * @param headers the headers which should be completed */ - @SuppressWarnings("ArraysAsListWithZeroOrOneArgument") public static void addCookieHeader(@Nonnull final Map> headers) { if (headers.get("Cookie") == null) { - headers.put("Cookie", Arrays.asList(generateConsentCookie())); + headers.put("Cookie", Collections.singletonList(generateConsentCookie())); } else { headers.get("Cookie").add(generateConsentCookie()); } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/dashmanifestcreators/YoutubeDashManifestCreatorsUtils.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/dashmanifestcreators/YoutubeDashManifestCreatorsUtils.java index 5c45f65d..045e5dda 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/dashmanifestcreators/YoutubeDashManifestCreatorsUtils.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/dashmanifestcreators/YoutubeDashManifestCreatorsUtils.java @@ -584,10 +584,9 @@ public final class YoutubeDashManifestCreatorsUtils { } } else if (isAndroidStreamingUrl || isIosStreamingUrl) { try { - final Map> headers = new HashMap<>(); - headers.put("User-Agent", Collections.singletonList( - isAndroidStreamingUrl ? getAndroidUserAgent(null) - : getIosUserAgent(null))); + final Map> headers = Collections.singletonMap("User-Agent", + Collections.singletonList(isAndroidStreamingUrl + ? getAndroidUserAgent(null) : getIosUserAgent(null))); final byte[] emptyBody = "".getBytes(StandardCharsets.UTF_8); return downloader.post(baseStreamingUrl, headers, emptyBody); } catch (final IOException | ExtractionException e) { 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 70789d45..f25fea05 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 @@ -1,6 +1,6 @@ package org.schabi.newpipe.extractor.services.youtube.extractors; -import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.addCookieHeader; +import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getCookieHeader; import static org.schabi.newpipe.extractor.utils.Utils.UTF_8; import com.grack.nanojson.JsonArray; @@ -17,9 +17,7 @@ import org.schabi.newpipe.extractor.suggestion.SuggestionExtractor; import java.io.IOException; import java.net.URLEncoder; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; /* * Created by Christian Schabesberger on 28.09.16. @@ -59,10 +57,7 @@ public class YoutubeSuggestionExtractor extends SuggestionExtractor { + "&gl=" + URLEncoder.encode(getExtractorContentCountry().getCountryCode(), UTF_8) + "&q=" + URLEncoder.encode(query, UTF_8); - final Map> headers = new HashMap<>(); - addCookieHeader(headers); - - String response = dl.get(url, headers, getExtractorLocalization()).responseBody(); + String response = dl.get(url, getCookieHeader(), getExtractorLocalization()).responseBody(); // trim JSONP part "JP(...)" response = response.substring(3, response.length() - 1); try {