Skip to content

Commit 45636b0

Browse files
authored
Merge pull request #986 from Isira-Seneviratne/Static_maps
Use immutable Map factory methods.
2 parents 259de3c + 219c5c5 commit 45636b0

6 files changed

Lines changed: 100 additions & 114 deletions

File tree

extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/linkHandler/PeertubeTrendingLinkHandlerFactory.java

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
import org.schabi.newpipe.extractor.exceptions.ParsingException;
55
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
66

7-
import java.util.Collections;
8-
import java.util.HashMap;
97
import java.util.List;
108
import java.util.Map;
119

@@ -14,27 +12,16 @@ public final class PeertubeTrendingLinkHandlerFactory extends ListLinkHandlerFac
1412
private static final PeertubeTrendingLinkHandlerFactory INSTANCE
1513
= new PeertubeTrendingLinkHandlerFactory();
1614

17-
public static final Map<String, String> KIOSK_MAP;
18-
public static final Map<String, String> REVERSE_KIOSK_MAP;
1915
public static final String KIOSK_TRENDING = "Trending";
2016
public static final String KIOSK_MOST_LIKED = "Most liked";
2117
public static final String KIOSK_RECENT = "Recently added";
2218
public static final String KIOSK_LOCAL = "Local";
2319

24-
static {
25-
final Map<String, String> map = new HashMap<>();
26-
map.put(KIOSK_TRENDING, "%s/api/v1/videos?sort=-trending");
27-
map.put(KIOSK_MOST_LIKED, "%s/api/v1/videos?sort=-likes");
28-
map.put(KIOSK_RECENT, "%s/api/v1/videos?sort=-publishedAt");
29-
map.put(KIOSK_LOCAL, "%s/api/v1/videos?sort=-publishedAt&filter=local");
30-
KIOSK_MAP = Collections.unmodifiableMap(map);
31-
32-
final Map<String, String> reverseMap = new HashMap<>();
33-
for (final Map.Entry<String, String> entry : KIOSK_MAP.entrySet()) {
34-
reverseMap.put(entry.getValue(), entry.getKey());
35-
}
36-
REVERSE_KIOSK_MAP = Collections.unmodifiableMap(reverseMap);
37-
}
20+
public static final Map<String, String> KIOSK_MAP = Map.of(
21+
KIOSK_TRENDING, "%s/api/v1/videos?sort=-trending",
22+
KIOSK_MOST_LIKED, "%s/api/v1/videos?sort=-likes",
23+
KIOSK_RECENT, "%s/api/v1/videos?sort=-publishedAt",
24+
KIOSK_LOCAL, "%s/api/v1/videos?sort=-publishedAt&filter=local");
3825

3926
public static PeertubeTrendingLinkHandlerFactory getInstance() {
4027
return INSTANCE;
@@ -66,10 +53,12 @@ public String getId(final String url) throws ParsingException {
6653
return KIOSK_RECENT;
6754
} else if (cleanUrl.contains("/videos/local")) {
6855
return KIOSK_LOCAL;
69-
} else if (REVERSE_KIOSK_MAP.containsKey(cleanUrl)) {
70-
return REVERSE_KIOSK_MAP.get(cleanUrl);
7156
} else {
72-
throw new ParsingException("no id found for this url");
57+
return KIOSK_MAP.entrySet().stream()
58+
.filter(entry -> cleanUrl.equals(entry.getValue()))
59+
.findFirst()
60+
.map(Map.Entry::getKey)
61+
.orElseThrow(() -> new ParsingException("no id found for this url"));
7362
}
7463
}
7564

extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudParsingHelper.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ public static synchronized String clientId() throws ExtractionException, IOExcep
6464
// The one containing the client id will likely be the last one
6565
Collections.reverse(possibleScripts);
6666

67-
final Map<String, List<String>> headers = Collections.singletonMap("Range",
68-
Collections.singletonList("bytes=0-50000"));
67+
final var headers = Map.of("Range", List.of("bytes=0-50000"));
6968

7069
for (final Element element : possibleScripts) {
7170
final String srcUrl = element.attr("src");

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java

Lines changed: 61 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import static org.schabi.newpipe.extractor.utils.Utils.HTTPS;
2626
import static org.schabi.newpipe.extractor.utils.Utils.getStringResultFromRegexArray;
2727
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
28-
import static java.util.Collections.singletonList;
2928

3029
import com.grack.nanojson.JsonArray;
3130
import com.grack.nanojson.JsonBuilder;
@@ -61,7 +60,6 @@
6160
import java.time.ZoneOffset;
6261
import java.time.format.DateTimeParseException;
6362
import java.util.ArrayList;
64-
import java.util.Collections;
6563
import java.util.HashMap;
6664
import java.util.List;
6765
import java.util.Locale;
@@ -92,6 +90,11 @@ private YoutubeParsingHelper() {
9290
public static final String YOUTUBEI_V1_GAPIS_URL =
9391
"https://youtubei.googleapis.com/youtubei/v1/";
9492

93+
/**
94+
* The base URL of YouTube Music.
95+
*/
96+
private static final String YOUTUBE_MUSIC_URL = "https://music.youtube.com";
97+
9598
/**
9699
* A parameter to disable pretty-printed response of InnerTube requests, to reduce response
97100
* sizes.
@@ -554,9 +557,7 @@ public static boolean areHardcodedClientVersionAndKeyValid()
554557
.end().done().getBytes(StandardCharsets.UTF_8);
555558
// @formatter:on
556559

557-
final Map<String, List<String>> headers = new HashMap<>();
558-
headers.put("X-YouTube-Client-Name", singletonList("1"));
559-
headers.put("X-YouTube-Client-Version", singletonList(HARDCODED_CLIENT_VERSION));
560+
final var headers = getClientHeaders("1", HARDCODED_CLIENT_VERSION);
560561

561562
// This endpoint is fetched by the YouTube website to get the items of its main menu and is
562563
// pretty lightweight (around 30kB)
@@ -578,9 +579,7 @@ private static void extractClientVersionAndKeyFromSwJs()
578579
return;
579580
}
580581
final String url = "https://www.youtube.com/sw.js";
581-
final Map<String, List<String>> headers = new HashMap<>();
582-
headers.put("Origin", singletonList("https://www.youtube.com"));
583-
headers.put("Referer", singletonList("https://www.youtube.com"));
582+
final var headers = getOriginReferrerHeaders("https://www.youtube.com");
584583
final String response = getDownloader().get(url, headers).responseBody();
585584
try {
586585
clientVersion = getStringResultFromRegexArray(response,
@@ -799,11 +798,9 @@ public static boolean isHardcodedYoutubeMusicKeyValid() throws IOException,
799798
.end().done().getBytes(StandardCharsets.UTF_8);
800799
// @formatter:on
801800

802-
final Map<String, List<String>> headers = new HashMap<>();
803-
headers.put("X-YouTube-Client-Name", singletonList(HARDCODED_YOUTUBE_MUSIC_KEY[1]));
804-
headers.put("X-YouTube-Client-Version", singletonList(HARDCODED_YOUTUBE_MUSIC_KEY[2]));
805-
headers.put("Origin", singletonList("https://music.youtube.com"));
806-
headers.put("Referer", singletonList("https://music.youtube.com"));
801+
final var headers = new HashMap<>(getOriginReferrerHeaders(YOUTUBE_MUSIC_URL));
802+
headers.putAll(getClientHeaders(HARDCODED_YOUTUBE_MUSIC_KEY[1],
803+
HARDCODED_YOUTUBE_MUSIC_KEY[2]));
807804

808805
final Response response = getDownloader().postWithContentTypeJson(url, headers, json);
809806
// Ensure to have a valid response
@@ -826,14 +823,12 @@ public static String[] getYoutubeMusicKey()
826823

827824
try {
828825
final String url = "https://music.youtube.com/sw.js";
829-
final Map<String, List<String>> headers = new HashMap<>();
830-
headers.put("Origin", singletonList("https://music.youtube.com"));
831-
headers.put("Referer", singletonList("https://music.youtube.com"));
826+
final var headers = getOriginReferrerHeaders("https://music.youtube.com");
832827
final String response = getDownloader().get(url, headers).responseBody();
833-
musicClientVersion = getStringResultFromRegexArray(response,
834-
INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES, 1);
835-
musicKey = getStringResultFromRegexArray(response, INNERTUBE_API_KEY_REGEXES, 1);
836-
musicClientName = Parser.matchGroup1(INNERTUBE_CLIENT_NAME_REGEX, response);
828+
musicClientVersion = getStringResultFromRegexArray(response,
829+
INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES, 1);
830+
musicKey = getStringResultFromRegexArray(response, INNERTUBE_API_KEY_REGEXES, 1);
831+
musicClientName = Parser.matchGroup1(INNERTUBE_CLIENT_NAME_REGEX, response);
837832
} catch (final Exception e) {
838833
final String url = "https://music.youtube.com/?ucbcb=1";
839834
final String html = getDownloader().get(url, getCookieHeader()).responseBody();
@@ -1176,8 +1171,7 @@ public static JsonObject getJsonPostResponse(final String endpoint,
11761171
final byte[] body,
11771172
final Localization localization)
11781173
throws IOException, ExtractionException {
1179-
final Map<String, List<String>> headers = new HashMap<>();
1180-
addYouTubeHeaders(headers);
1174+
final var headers = getYouTubeHeaders();
11811175

11821176
return JsonUtils.toJsonObject(getValidJsonResponseBody(
11831177
getDownloader().postWithContentTypeJson(YOUTUBEI_V1_URL + endpoint + "?key="
@@ -1209,9 +1203,8 @@ private static JsonObject getMobilePostResponse(
12091203
@Nonnull final String userAgent,
12101204
@Nonnull final String innerTubeApiKey,
12111205
@Nullable final String endPartOfUrlRequest) throws IOException, ExtractionException {
1212-
final Map<String, List<String>> headers = new HashMap<>();
1213-
headers.put("User-Agent", singletonList(userAgent));
1214-
headers.put("X-Goog-Api-Format-Version", singletonList("2"));
1206+
final var headers = Map.of("User-Agent", List.of(userAgent),
1207+
"X-Goog-Api-Format-Version", List.of("2"));
12151208

12161209
final String baseEndpointUrl = YOUTUBEI_V1_GAPIS_URL + endpoint + "?key=" + innerTubeApiKey
12171210
+ DISABLE_PRETTY_PRINT_PARAMETER;
@@ -1423,60 +1416,68 @@ public static String getIosUserAgent(@Nullable final Localization localization)
14231416
+ ")";
14241417
}
14251418

1419+
/**
1420+
* Returns a {@link Map} containing the required YouTube Music headers.
1421+
*/
14261422
@Nonnull
14271423
public static Map<String, List<String>> getYoutubeMusicHeaders() {
1428-
final Map<String, List<String>> headers = new HashMap<>();
1429-
headers.put("X-YouTube-Client-Name", Collections.singletonList(youtubeMusicKey[1]));
1430-
headers.put("X-YouTube-Client-Version", Collections.singletonList(youtubeMusicKey[2]));
1431-
headers.put("Origin", Collections.singletonList("https://music.youtube.com"));
1432-
headers.put("Referer", Collections.singletonList("https://music.youtube.com"));
1424+
final var headers = new HashMap<>(getOriginReferrerHeaders(YOUTUBE_MUSIC_URL));
1425+
headers.putAll(getClientHeaders(youtubeMusicKey[1], youtubeMusicKey[2]));
14331426
return headers;
14341427
}
14351428

14361429
/**
1437-
* Add required headers and cookies to an existing headers Map.
1438-
* @see #addClientInfoHeaders(Map)
1439-
* @see #addCookieHeader(Map)
1430+
* Returns a {@link Map} containing the required YouTube headers, including the
1431+
* <code>CONSENT</code> cookie to prevent redirects to <code>consent.youtube.com</code>
14401432
*/
1441-
public static void addYouTubeHeaders(final Map<String, List<String>> headers)
1442-
throws IOException, ExtractionException {
1443-
addClientInfoHeaders(headers);
1444-
addCookieHeader(headers);
1433+
public static Map<String, List<String>> getYouTubeHeaders()
1434+
throws ExtractionException, IOException {
1435+
final var headers = getClientInfoHeaders();
1436+
headers.put("Cookie", List.of(generateConsentCookie()));
1437+
return headers;
14451438
}
14461439

14471440
/**
1448-
* Add the <code>X-YouTube-Client-Name</code>, <code>X-YouTube-Client-Version</code>,
1449-
* <code>Origin</code>, and <code>Referer</code> headers.
1450-
* @param headers The headers which should be completed
1441+
* Returns a {@link Map} containing the {@code X-YouTube-Client-Name},
1442+
* {@code X-YouTube-Client-Version}, {@code Origin}, and {@code Referer} headers.
14511443
*/
1452-
public static void addClientInfoHeaders(@Nonnull final Map<String, List<String>> headers)
1453-
throws IOException, ExtractionException {
1454-
headers.computeIfAbsent("Origin", k -> singletonList("https://www.youtube.com"));
1455-
headers.computeIfAbsent("Referer", k -> singletonList("https://www.youtube.com"));
1456-
headers.computeIfAbsent("X-YouTube-Client-Name", k -> singletonList("1"));
1457-
if (headers.get("X-YouTube-Client-Version") == null) {
1458-
headers.put("X-YouTube-Client-Version", singletonList(getClientVersion()));
1459-
}
1444+
public static Map<String, List<String>> getClientInfoHeaders()
1445+
throws ExtractionException, IOException {
1446+
final var headers = new HashMap<>(getOriginReferrerHeaders("https://www.youtube.com"));
1447+
headers.putAll(getClientHeaders("1", getClientVersion()));
1448+
return headers;
14601449
}
14611450

14621451
/**
1463-
* Create a map with the required cookie header.
1464-
* @return A singleton map containing the header.
1452+
* Returns an unmodifiable {@link Map} containing the {@code Origin} and {@code Referer}
1453+
* headers set to the given URL.
1454+
*
1455+
* @param url The URL to be set as the origin and referrer.
14651456
*/
1466-
public static Map<String, List<String>> getCookieHeader() {
1467-
return Collections.singletonMap("Cookie", singletonList(generateConsentCookie()));
1457+
private static Map<String, List<String>> getOriginReferrerHeaders(@Nonnull final String url) {
1458+
final var urlList = List.of(url);
1459+
return Map.of("Origin", urlList, "Referer", urlList);
14681460
}
14691461

14701462
/**
1471-
* Add the <code>CONSENT</code> cookie to prevent redirect to <code>consent.youtube.com</code>
1472-
* @param headers the headers which should be completed
1463+
* Returns an unmodifiable {@link Map} containing the {@code X-YouTube-Client-Name} and
1464+
* {@code X-YouTube-Client-Version} headers.
1465+
*
1466+
* @param name The X-YouTube-Client-Name value.
1467+
* @param version X-YouTube-Client-Version value.
14731468
*/
1474-
public static void addCookieHeader(@Nonnull final Map<String, List<String>> headers) {
1475-
if (headers.get("Cookie") == null) {
1476-
headers.put("Cookie", Collections.singletonList(generateConsentCookie()));
1477-
} else {
1478-
headers.get("Cookie").add(generateConsentCookie());
1479-
}
1469+
private static Map<String, List<String>> getClientHeaders(@Nonnull final String name,
1470+
@Nonnull final String version) {
1471+
return Map.of("X-YouTube-Client-Name", List.of(name),
1472+
"X-YouTube-Client-Version", List.of(version));
1473+
}
1474+
1475+
/**
1476+
* Create a map with the required cookie header.
1477+
* @return A singleton map containing the header.
1478+
*/
1479+
public static Map<String, List<String>> getCookieHeader() {
1480+
return Map.of("Cookie", List.of(generateConsentCookie()));
14801481
}
14811482

14821483
@Nonnull

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/dashmanifestcreators/YoutubeDashManifestCreatorsUtils.java

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
package org.schabi.newpipe.extractor.services.youtube.dashmanifestcreators;
22

3+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getAndroidUserAgent;
4+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getClientInfoHeaders;
5+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getIosUserAgent;
6+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isAndroidStreamingUrl;
7+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isIosStreamingUrl;
8+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isTvHtml5SimplyEmbeddedPlayerStreamingUrl;
9+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isWebStreamingUrl;
10+
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
11+
312
import org.schabi.newpipe.extractor.MediaFormat;
413
import org.schabi.newpipe.extractor.NewPipe;
514
import org.schabi.newpipe.extractor.downloader.Downloader;
@@ -13,6 +22,14 @@
1322
import org.w3c.dom.Document;
1423
import org.w3c.dom.Element;
1524

25+
import java.io.IOException;
26+
import java.io.StringWriter;
27+
import java.nio.charset.StandardCharsets;
28+
import java.util.List;
29+
import java.util.Locale;
30+
import java.util.Map;
31+
import java.util.Objects;
32+
1633
import javax.annotation.Nonnull;
1734
import javax.xml.XMLConstants;
1835
import javax.xml.parsers.DocumentBuilder;
@@ -25,24 +42,6 @@
2542
import javax.xml.transform.dom.DOMSource;
2643
import javax.xml.transform.stream.StreamResult;
2744

28-
import java.io.IOException;
29-
import java.io.StringWriter;
30-
import java.nio.charset.StandardCharsets;
31-
import java.util.Collections;
32-
import java.util.HashMap;
33-
import java.util.List;
34-
import java.util.Locale;
35-
import java.util.Map;
36-
import java.util.Objects;
37-
38-
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getAndroidUserAgent;
39-
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getIosUserAgent;
40-
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isAndroidStreamingUrl;
41-
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isIosStreamingUrl;
42-
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isTvHtml5SimplyEmbeddedPlayerStreamingUrl;
43-
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isWebStreamingUrl;
44-
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
45-
4645
/**
4746
* Utilities and constants for YouTube DASH manifest creators.
4847
*
@@ -583,9 +582,9 @@ public static Response getInitializationResponse(@Nonnull String baseStreamingUr
583582
}
584583
} else if (isAndroidStreamingUrl || isIosStreamingUrl) {
585584
try {
586-
final Map<String, List<String>> headers = Collections.singletonMap("User-Agent",
587-
Collections.singletonList(isAndroidStreamingUrl
588-
? getAndroidUserAgent(null) : getIosUserAgent(null)));
585+
final var headers = Map.of("User-Agent",
586+
List.of(isAndroidStreamingUrl ? getAndroidUserAgent(null)
587+
: getIosUserAgent(null)));
589588
final byte[] emptyBody = "".getBytes(StandardCharsets.UTF_8);
590589
return downloader.post(baseStreamingUrl, headers, emptyBody);
591590
} catch (final IOException | ExtractionException e) {
@@ -705,9 +704,7 @@ private static Response getStreamingWebUrlWithoutRedirects(
705704
@Nonnull final String responseMimeTypeExpected)
706705
throws CreationException {
707706
try {
708-
final Map<String, List<String>> headers = new HashMap<>();
709-
headers.put("Origin", Collections.singletonList("https://www.youtube.com"));
710-
headers.put("Referer", Collections.singletonList("https://www.youtube.com"));
707+
final var headers = getClientInfoHeaders();
711708

712709
String responseMimeType = "";
713710

0 commit comments

Comments
 (0)