Skip to content

Commit 7753556

Browse files
committed
Adress the last requested changes + update YoutubeCommentsExtractor mocks
1 parent 2320aec commit 7753556

22 files changed

Lines changed: 157 additions & 144 deletions

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

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ private YoutubeParsingHelper() {
7878
private static String[] youtubeMusicKey;
7979

8080
private static boolean keyAndVersionExtracted = false;
81-
private static Boolean areHardcodedClientVersionAndKeyValidValue = null;
81+
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
82+
private static Optional<Boolean> hardcodedClientVersionAndKeyValid = Optional.empty();
8283

8384
private static Random numberGenerator = new Random();
8485

@@ -308,10 +309,10 @@ public static JsonObject getInitialData(final String html) throws ParsingExcepti
308309
}
309310
}
310311

311-
public static boolean areHardcodedClientVersionAndKeyValid()
312+
public static Optional<Boolean> areHardcodedClientVersionAndKeyValid()
312313
throws IOException, ExtractionException {
313-
if (areHardcodedClientVersionAndKeyValidValue != null) {
314-
return areHardcodedClientVersionAndKeyValidValue;
314+
if (hardcodedClientVersionAndKeyValid.isPresent()) {
315+
return hardcodedClientVersionAndKeyValid;
315316
}
316317
// @formatter:off
317318
final byte[] body = JsonWriter.string()
@@ -343,12 +344,12 @@ public static boolean areHardcodedClientVersionAndKeyValid()
343344
final String responseBody = response.responseBody();
344345
final int responseCode = response.responseCode();
345346

346-
return areHardcodedClientVersionAndKeyValidValue = responseBody.length() > 5000
347-
&& responseCode == 200; // Ensure to have a valid response
347+
return hardcodedClientVersionAndKeyValid = Optional.of(responseBody.length() > 5000
348+
&& responseCode == 200); // Ensure to have a valid response
348349
}
349350

350351
private static void extractClientVersionAndKey() throws IOException, ExtractionException {
351-
// Don't extract the client version and the innertube key if it has been already extracted
352+
// Don't extract the client version and the InnerTube key if it has been already extracted
352353
if (keyAndVersionExtracted) return;
353354
// Don't provide a search term in order to have a smaller response
354355
final String url = "https://www.youtube.com/results?search_query=&ucbcb=1";
@@ -424,7 +425,7 @@ private static void extractClientVersionAndKey() throws IOException, ExtractionE
424425
*/
425426
public static String getClientVersion() throws IOException, ExtractionException {
426427
if (!isNullOrEmpty(clientVersion)) return clientVersion;
427-
if (areHardcodedClientVersionAndKeyValid()) {
428+
if (areHardcodedClientVersionAndKeyValid().orElse(false)) {
428429
return clientVersion = HARDCODED_CLIENT_VERSION;
429430
}
430431

@@ -437,7 +438,7 @@ public static String getClientVersion() throws IOException, ExtractionException
437438
*/
438439
public static String getKey() throws IOException, ExtractionException {
439440
if (!isNullOrEmpty(key)) return key;
440-
if (areHardcodedClientVersionAndKeyValid()) {
441+
if (areHardcodedClientVersionAndKeyValid().orElse(false)) {
441442
return key = HARDCODED_KEY;
442443
}
443444

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeChannelExtractor.java

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -81,30 +81,31 @@ public YoutubeChannelExtractor(final StreamingService service,
8181
@Override
8282
public void onFetchPage(@Nonnull final Downloader downloader) throws IOException,
8383
ExtractionException {
84-
final String channel_path = super.getId();
85-
final String[] channelInfo = channel_path.split("/");
84+
final String channelPath = super.getId();
85+
final String[] channelId = channelPath.split("/");
8686
String id = "";
8787
// If the url is an URL which is not a /channel URL, we need to use the
88-
// navigation/resolve_url endpoint of the youtubei API to get the channel id. Otherwise, we
89-
// couldn't get information about the channel associated with this URL, if there is one.
90-
if (!channelInfo[0].equals("channel")) {
88+
// navigation/resolve_url endpoint of the InnerTube API to get the channel id. Otherwise,
89+
// we couldn't get information about the channel associated with this URL, if there is one.
90+
if (!channelId[0].equals("channel")) {
9191
final byte[] body = JsonWriter.string(prepareJsonBuilder(getExtractorLocalization(),
9292
getExtractorContentCountry())
93-
.value("url", "https://www.youtube.com/" + channel_path)
93+
.value("url", "https://www.youtube.com/" + channelPath)
9494
.done())
9595
.getBytes(UTF_8);
9696

9797
final JsonObject jsonResponse = getJsonPostResponse("navigation/resolve_url",
9898
body, getExtractorLocalization());
9999

100-
if (jsonResponse.has("error")) {
101-
if (jsonResponse.getInt("code") == 404) {
102-
throw new ContentNotAvailableException(
103-
"No channel associated with this user exists");
100+
if (!isNullOrEmpty(jsonResponse.getObject("error"))) {
101+
final JsonObject errorJsonObject = jsonResponse.getObject("error");
102+
final int errorCode = errorJsonObject.getInt("code");
103+
if (errorCode == 404) {
104+
throw new ContentNotAvailableException("This channel doesn't exist.");
104105
} else {
105106
throw new ContentNotAvailableException("Got error:\""
106-
+ jsonResponse.getString("status") + "\": "
107-
+ jsonResponse.getString("message"));
107+
+ errorJsonObject.getString("status") + "\": "
108+
+ errorJsonObject.getString("message"));
108109
}
109110
}
110111

@@ -128,7 +129,7 @@ public void onFetchPage(@Nonnull final Downloader downloader) throws IOException
128129
redirectedChannelId = browseId;
129130
}
130131
} else {
131-
id = channelInfo[1];
132+
id = channelId[1];
132133
}
133134
JsonObject ajaxJson = null;
134135

@@ -145,13 +146,14 @@ public void onFetchPage(@Nonnull final Downloader downloader) throws IOException
145146
getExtractorLocalization());
146147

147148
if (!isNullOrEmpty(jsonResponse.getObject("error"))) {
148-
final int errorCode = jsonResponse.getObject("error").getInt("code");
149-
if (errorCode == 400) {
149+
final JsonObject errorJsonObject = jsonResponse.getObject("error");
150+
final int errorCode = errorJsonObject.getInt("code");
151+
if (errorCode == 404) {
150152
throw new ContentNotAvailableException("This channel doesn't exist.");
151153
} else {
152154
throw new ContentNotAvailableException("Got error:\""
153-
+ jsonResponse.getString("status") + "\": "
154-
+ jsonResponse.getString("message"));
155+
+ errorJsonObject.getString("status") + "\": "
156+
+ errorJsonObject.getString("message"));
155157
}
156158
}
157159

@@ -330,13 +332,13 @@ public InfoItemsPage<StreamInfoItem> getInitialPage() throws IOException, Extrac
330332
.getArray("contents").getObject(0).getObject("itemSectionRenderer")
331333
.getArray("contents").getObject(0).getObject("gridRenderer");
332334

333-
final List<String> channelInfo = new ArrayList<>();
334-
channelInfo.add(getName());
335-
channelInfo.add(getUrl());
335+
final List<String> channelIds = new ArrayList<>();
336+
channelIds.add(getName());
337+
channelIds.add(getUrl());
336338
final JsonObject continuation = collectStreamsFrom(collector, gridRenderer
337-
.getArray("items"), channelInfo);
339+
.getArray("items"), channelIds);
338340

339-
nextPage = getNextPageFrom(continuation, channelInfo);
341+
nextPage = getNextPageFrom(continuation, channelIds);
340342
}
341343

342344
return new InfoItemsPage<>(collector, nextPage);
@@ -349,7 +351,7 @@ public InfoItemsPage<StreamInfoItem> getPage(final Page page) throws IOException
349351
throw new IllegalArgumentException("Page doesn't contain an URL");
350352
}
351353

352-
final List<String> channelInfos = page.getIds();
354+
final List<String> channelIds = page.getIds();
353355

354356
final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
355357
final Map<String, List<String>> headers = new HashMap<>();
@@ -365,14 +367,14 @@ public InfoItemsPage<StreamInfoItem> getPage(final Page page) throws IOException
365367
.getObject("appendContinuationItemsAction");
366368

367369
final JsonObject continuation = collectStreamsFrom(collector, sectionListContinuation
368-
.getArray("continuationItems"), channelInfos);
370+
.getArray("continuationItems"), channelIds);
369371

370-
return new InfoItemsPage<>(collector, getNextPageFrom(continuation, channelInfos));
372+
return new InfoItemsPage<>(collector, getNextPageFrom(continuation, channelIds));
371373
}
372374

373375
@Nullable
374376
private Page getNextPageFrom(final JsonObject continuations,
375-
final List<String> channelInfo) throws IOException,
377+
final List<String> channelIds) throws IOException,
376378
ExtractionException {
377379
if (isNullOrEmpty(continuations)) {
378380
return null;
@@ -388,23 +390,24 @@ private Page getNextPageFrom(final JsonObject continuations,
388390
.done())
389391
.getBytes(UTF_8);
390392

391-
return new Page(YOUTUBEI_V1_URL + "browse?key=" + getKey(), null, channelInfo, null, body);
393+
return new Page(YOUTUBEI_V1_URL + "browse?key=" + getKey(), null, channelIds, null, body);
392394
}
393395

394396
/**
395397
* Collect streams from an array of items
396398
*
397-
* @param collector the collector where videos will be commited
398-
* @param videos the array to get videos from
399+
* @param collector the collector where videos will be committed
400+
* @param videos the array to get videos from
401+
* @param channelIds the ids of the channel, which are its name and its URL
399402
* @return the continuation object
400403
*/
401404
private JsonObject collectStreamsFrom(@Nonnull final StreamInfoItemsCollector collector,
402405
@Nonnull final JsonArray videos,
403-
@Nonnull final List<String> channelInfo) {
406+
@Nonnull final List<String> channelIds) {
404407
collector.reset();
405408

406-
final String uploaderName = channelInfo.get(0);
407-
final String uploaderUrl = channelInfo.get(1);
409+
final String uploaderName = channelIds.get(0);
410+
final String uploaderUrl = channelIds.get(1);
408411
final TimeAgoParser timeAgoParser = getTimeAgoParser();
409412

410413
JsonObject continuation = null;

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeCommentsExtractor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ private void collectCommentsFrom(final CommentsInfoItemsCollector collector, fin
189189
public void onFetchPage(@Nonnull final Downloader downloader) throws IOException, ExtractionException {
190190
final Map<String, List<String>> requestHeaders = new HashMap<>();
191191
requestHeaders.put("User-Agent", singletonList(USER_AGENT));
192-
final Response response = downloader.get(getUrl() + "&ucbcb=1", requestHeaders, getExtractorLocalization());
192+
final Response response = downloader.get(getUrl(), requestHeaders, getExtractorLocalization());
193193
responseBody = YoutubeParsingHelper.unescapeDocument(response.responseBody());
194194
ytClientVersion = findValue(responseBody, "INNERTUBE_CONTEXT_CLIENT_VERSION\":\"", "\"");
195195
ytClientName = Parser.matchGroup1(YT_CLIENT_NAME_PATTERN, responseBody);

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMixPlaylistExtractor.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ public void onFetchPage(@Nonnull final Downloader downloader)
8585
if (isNullOrEmpty(playlistData)) throw new ExtractionException(
8686
"Could not get playlistData");
8787
cookieValue = extractCookieValue(COOKIE_NAME, response);
88-
8988
}
9089

9190
@Nonnull

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -962,7 +962,8 @@ private boolean isCipherProtectedContent() {
962962
}
963963
}
964964
}
965-
} else if (streamingData.has("formats")) {
965+
}
966+
if (streamingData.has("formats")) {
966967
final JsonArray formats = streamingData.getArray("formats");
967968
if (!isNullOrEmpty(formats)) {
968969
for (final Object format : formats) {

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/linkHandler/YoutubeSearchQueryHandlerFactory.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import org.schabi.newpipe.extractor.exceptions.ParsingException;
44
import org.schabi.newpipe.extractor.linkhandler.SearchQueryHandlerFactory;
55

6+
import javax.annotation.Nonnull;
67
import java.io.UnsupportedEncodingException;
78
import java.net.URLEncoder;
89
import java.util.List;
@@ -26,24 +27,31 @@ public class YoutubeSearchQueryHandlerFactory extends SearchQueryHandlerFactory
2627
private static final String SEARCH_URL = "https://www.youtube.com/results?search_query=";
2728
private static final String MUSIC_SEARCH_URL = "https://music.youtube.com/search?q=";
2829

30+
@Nonnull
2931
public static YoutubeSearchQueryHandlerFactory getInstance() {
3032
return new YoutubeSearchQueryHandlerFactory();
3133
}
3234

3335
@Override
34-
public String getUrl(String searchString, List<String> contentFilters, String sortFilter) throws ParsingException {
36+
public String getUrl(final String searchString,
37+
@Nonnull final List<String> contentFilters,
38+
final String sortFilter) throws ParsingException {
3539
try {
3640
if (!contentFilters.isEmpty()) {
37-
switch (contentFilters.get(0)) {
41+
final String contentFilter = contentFilters.get(0);
42+
switch (contentFilter) {
3843
case ALL:
3944
default:
4045
break;
4146
case VIDEOS:
42-
return SEARCH_URL + URLEncoder.encode(searchString, UTF_8) + "&sp=EgIQAQ%253D%253D";
47+
return SEARCH_URL + URLEncoder.encode(searchString, UTF_8)
48+
+ "&sp=EgIQAQ%253D%253D";
4349
case CHANNELS:
44-
return SEARCH_URL + URLEncoder.encode(searchString, UTF_8) + "&sp=EgIQAg%253D%253D";
50+
return SEARCH_URL + URLEncoder.encode(searchString, UTF_8)
51+
+ "&sp=EgIQAg%253D%253D";
4552
case PLAYLISTS:
46-
return SEARCH_URL + URLEncoder.encode(searchString, UTF_8) + "&sp=EgIQAw%253D%253D";
53+
return SEARCH_URL + URLEncoder.encode(searchString, UTF_8)
54+
+ "&sp=EgIQAw%253D%253D";
4755
case MUSIC_SONGS:
4856
case MUSIC_VIDEOS:
4957
case MUSIC_ALBUMS:
@@ -54,7 +62,7 @@ public String getUrl(String searchString, List<String> contentFilters, String so
5462
}
5563

5664
return SEARCH_URL + URLEncoder.encode(searchString, UTF_8);
57-
} catch (UnsupportedEncodingException e) {
65+
} catch (final UnsupportedEncodingException e) {
5866
throw new ParsingException("Could not encode query", e);
5967
}
6068
}
@@ -70,10 +78,11 @@ public String[] getAvailableContentFilter() {
7078
MUSIC_VIDEOS,
7179
MUSIC_ALBUMS,
7280
MUSIC_PLAYLISTS
73-
// MUSIC_ARTISTS
81+
// MUSIC_ARTISTS
7482
};
7583
}
7684

85+
@Nonnull
7786
public static String getSearchParameter(final String contentFilter) {
7887
if (isNullOrEmpty(contentFilter)) return "";
7988
switch (contentFilter) {

extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelperTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public static void setUp() throws IOException {
2727
@Test
2828
public void testAreHardcodedClientVersionAndKeyValid() throws IOException, ExtractionException {
2929
assertTrue("Hardcoded client version and key are not valid anymore",
30-
YoutubeParsingHelper.areHardcodedClientVersionAndKeyValid());
30+
YoutubeParsingHelper.areHardcodedClientVersionAndKeyValid().orElse(false));
3131
}
3232

3333
@Test
@@ -44,7 +44,7 @@ public void testParseDurationString() throws ParsingException {
4444
}
4545

4646
@Test
47-
public void testConvertFromGoogleCacheUrl() throws ParsingException {
47+
public void testConvertFromGoogleCacheUrl() {
4848
assertEquals("https://mohfw.gov.in/",
4949
YoutubeParsingHelper.extractCachedUrlIfNeeded("https://webcache.googleusercontent.com/search?q=cache:https://mohfw.gov.in/"));
5050
assertEquals("https://www.infektionsschutz.de/coronavirus-sars-cov-2.html",

extractor/src/test/resources/org/schabi/newpipe/extractor/services/youtube/extractor/comments/empty/generated_mock_0.json

Lines changed: 5 additions & 5 deletions
Large diffs are not rendered by default.

extractor/src/test/resources/org/schabi/newpipe/extractor/services/youtube/extractor/comments/empty/generated_mock_1.json

Lines changed: 7 additions & 7 deletions
Large diffs are not rendered by default.

extractor/src/test/resources/org/schabi/newpipe/extractor/services/youtube/extractor/comments/hearted/generated_mock_0.json

Lines changed: 5 additions & 5 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)