From 0352659e2b0b3113538e710226dc95faaeea004f Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Fri, 29 Nov 2024 05:16:08 +0530 Subject: [PATCH 1/4] Use BufferedReader#lines() --- .../YoutubeSubscriptionExtractor.java | 81 +++++-------------- 1 file changed, 18 insertions(+), 63 deletions(-) diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSubscriptionExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSubscriptionExtractor.java index 403151f07..7293a37d5 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSubscriptionExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSubscriptionExtractor.java @@ -14,9 +14,11 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.UncheckedIOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; @@ -110,7 +112,7 @@ public class YoutubeSubscriptionExtractor extends SubscriptionExtractor { // Return it only if it has items (it exits early if it's the wrong file // format), otherwise try the next file - if (csvItems.size() > 0) { + if (!csvItems.isEmpty()) { return csvItems; } } catch (final ExtractionException e) { @@ -138,69 +140,22 @@ public class YoutubeSubscriptionExtractor extends SubscriptionExtractor { // The first line is always a header // Header names are different based on the locale // Fortunately the data is always the same order no matter what locale + try (var reader = new BufferedReader(new InputStreamReader(contentInputStream))) { + return reader.lines() + .skip(1) // ignore header and skip first line + .map(line -> line.split(",")) + .filter(values -> values.length >= 3) + .map(values -> { + // Channel URL from second entry + final String channelUrl = values[1].replace("http://", "https://"); + // Channel title from third entry + final String title = values[2]; - int currentLine = 0; - String line = ""; - - try (BufferedReader br = new BufferedReader(new InputStreamReader(contentInputStream))) { - final List subscriptionItems = new ArrayList<>(); - - // ignore header and skip first line - currentLine = 1; - line = br.readLine(); - - while ((line = br.readLine()) != null) { - currentLine++; - - // Exit early if we've read the first few lines and we haven't added any items - // It's likely we're in the wrong file - if (currentLine > 5 && subscriptionItems.size() == 0) { - break; - } - - // First comma - final int i1 = line.indexOf(","); - if (i1 == -1) { - continue; - } - - // Second comma - final int i2 = line.indexOf(",", i1 + 1); - if (i2 == -1) { - continue; - } - - // Third comma or line length - int i3 = line.indexOf(",", i2 + 1); - if (i3 == -1) { - i3 = line.length(); - } - - // Channel URL from second entry - final String channelUrl = line - .substring(i1 + 1, i2) - .replace("http://", "https://"); - if (!channelUrl.startsWith(BASE_CHANNEL_URL)) { - continue; - } - - // Channel title from third entry - final String channelTitle = line.substring(i2 + 1, i3); - - final SubscriptionItem newItem - = new SubscriptionItem(service.getServiceId(), channelUrl, channelTitle); - subscriptionItems.add(newItem); - } - - return subscriptionItems; - } catch (final IOException e) { - if (line == null) { - line = ""; - } else if (line.length() > 10) { - line = line.substring(0, 10) + "..."; - } - throw new InvalidSourceException("Error reading CSV file on line = \"" + line - + "\", line number = " + currentLine, e); + return new SubscriptionItem(service.getServiceId(), channelUrl, title); + }) + .collect(Collectors.toUnmodifiableList()); + } catch (final UncheckedIOException | IOException e) { + throw new InvalidSourceException("Error reading CSV file", e); } } } From e475b2971b283d0da3ca519f57a0b4368f3f9789 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Sat, 7 Dec 2024 11:15:01 +0530 Subject: [PATCH 2/4] Restore URL check --- .../extractors/YoutubeSubscriptionExtractor.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSubscriptionExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSubscriptionExtractor.java index 7293a37d5..f07b1047c 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSubscriptionExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSubscriptionExtractor.java @@ -18,6 +18,7 @@ import java.io.UncheckedIOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; @@ -148,11 +149,15 @@ public class YoutubeSubscriptionExtractor extends SubscriptionExtractor { .map(values -> { // Channel URL from second entry final String channelUrl = values[1].replace("http://", "https://"); - // Channel title from third entry - final String title = values[2]; - - return new SubscriptionItem(service.getServiceId(), channelUrl, title); + if (!channelUrl.startsWith(BASE_CHANNEL_URL)) { + return null; + } else { + // Channel title from third entry + final String title = values[2]; + return new SubscriptionItem(service.getServiceId(), channelUrl, title); + } }) + .filter(Objects::nonNull) .collect(Collectors.toUnmodifiableList()); } catch (final UncheckedIOException | IOException e) { throw new InvalidSourceException("Error reading CSV file", e); From 625e9f96d21ff4e0777840931560df8a745e8f45 Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Mon, 27 Jan 2025 22:24:15 +0100 Subject: [PATCH 3/4] Remove public modifier from tests --- .../YoutubeSubscriptionExtractorTest.java | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeSubscriptionExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeSubscriptionExtractorTest.java index 8224f991f..55afef360 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeSubscriptionExtractorTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeSubscriptionExtractorTest.java @@ -26,8 +26,7 @@ import java.util.List; /** * Test for {@link YoutubeSubscriptionExtractor} */ -public class YoutubeSubscriptionExtractorTest { - +class YoutubeSubscriptionExtractorTest { private static YoutubeSubscriptionExtractor subscriptionExtractor; private static LinkHandlerFactory urlHandler; @@ -41,7 +40,7 @@ public class YoutubeSubscriptionExtractorTest { } @Test - public void testFromInputStream() throws Exception { + void testFromInputStream() throws Exception { final List subscriptionItems = subscriptionExtractor.fromInputStream( new FileInputStream(resolveTestResource("youtube_takeout_import_test.json"))); assertEquals(7, subscriptionItems.size()); @@ -55,14 +54,14 @@ public class YoutubeSubscriptionExtractorTest { } @Test - public void testEmptySourceException() throws Exception { + void testEmptySourceException() throws Exception { final List items = subscriptionExtractor.fromInputStream( new ByteArrayInputStream("[]".getBytes(StandardCharsets.UTF_8))); assertTrue(items.isEmpty()); } @Test - public void testSubscriptionWithEmptyTitleInSource() throws Exception { + void testSubscriptionWithEmptyTitleInSource() throws Exception { final String source = "[{\"snippet\":{\"resourceId\":{\"channelId\":\"UCEOXxzW2vU0P-0THehuIIeg\"}}}]"; final List items = subscriptionExtractor.fromInputStream( new ByteArrayInputStream(source.getBytes(StandardCharsets.UTF_8))); @@ -74,7 +73,7 @@ public class YoutubeSubscriptionExtractorTest { } @Test - public void testSubscriptionWithInvalidUrlInSource() throws Exception { + void testSubscriptionWithInvalidUrlInSource() throws Exception { final String source = "[{\"snippet\":{\"resourceId\":{\"channelId\":\"gibberish\"},\"title\":\"name1\"}}," + "{\"snippet\":{\"resourceId\":{\"channelId\":\"UCEOXxzW2vU0P-0THehuIIeg\"},\"title\":\"name2\"}}]"; final List items = subscriptionExtractor.fromInputStream( @@ -87,8 +86,8 @@ public class YoutubeSubscriptionExtractorTest { } @Test - public void testInvalidSourceException() { - List invalidList = Arrays.asList( + void testInvalidSourceException() { + final List invalidList = Arrays.asList( "", "", "{\"a\":\"b\"}", @@ -100,13 +99,14 @@ public class YoutubeSubscriptionExtractorTest { "\uD83D\uDC28\uD83D\uDC28\uD83D\uDC28", "gibberish"); - for (String invalidContent : invalidList) { + for (final String invalidContent : invalidList) { try { - byte[] bytes = invalidContent.getBytes(StandardCharsets.UTF_8); + final byte[] bytes = invalidContent.getBytes(StandardCharsets.UTF_8); subscriptionExtractor.fromInputStream(new ByteArrayInputStream(bytes)); fail("Extracting from \"" + invalidContent + "\" didn't throw an exception"); } catch (final Exception e) { - boolean correctType = e instanceof SubscriptionExtractor.InvalidSourceException; + final boolean correctType = + e instanceof SubscriptionExtractor.InvalidSourceException; if (!correctType) { e.printStackTrace(); } @@ -117,7 +117,7 @@ public class YoutubeSubscriptionExtractorTest { private static void assertSubscriptionItems(final List subscriptionItems) throws Exception { - assertTrue(subscriptionItems.size() > 0); + assertTrue(!subscriptionItems.isEmpty()); for (final SubscriptionItem item : subscriptionItems) { assertNotNull(item.getName()); @@ -128,7 +128,7 @@ public class YoutubeSubscriptionExtractorTest { } @Test - public void fromZipInputStream() throws Exception { + void fromZipInputStream() throws Exception { final List zipPaths = Arrays.asList( "youtube_takeout_import_test_1.zip", "youtube_takeout_import_test_2.zip" @@ -144,13 +144,13 @@ public class YoutubeSubscriptionExtractorTest { } @Test - public void fromCsvInputStream() throws Exception { + void fromCsvInputStream() throws Exception { final List csvPaths = Arrays.asList( "youtube_takeout_import_test_1.csv", "youtube_takeout_import_test_2.csv" ); - for (String path : csvPaths) + for (final String path : csvPaths) { final File file = resolveTestResource(path); final FileInputStream fileInputStream = new FileInputStream(file); From 222d869efcaea49eb5455cac23a2d93ec8550008 Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Mon, 27 Jan 2025 22:32:01 +0100 Subject: [PATCH 4/4] Polish: Use ternary instead of if --- .../extractors/YoutubeSubscriptionExtractor.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSubscriptionExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSubscriptionExtractor.java index f07b1047c..852d4ebf1 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSubscriptionExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSubscriptionExtractor.java @@ -149,13 +149,12 @@ public class YoutubeSubscriptionExtractor extends SubscriptionExtractor { .map(values -> { // Channel URL from second entry final String channelUrl = values[1].replace("http://", "https://"); - if (!channelUrl.startsWith(BASE_CHANNEL_URL)) { - return null; - } else { - // Channel title from third entry - final String title = values[2]; - return new SubscriptionItem(service.getServiceId(), channelUrl, title); - } + return channelUrl.startsWith(BASE_CHANNEL_URL) + ? new SubscriptionItem( + service.getServiceId(), + channelUrl, + values[2]) // Channel title from third entry + : null; }) .filter(Objects::nonNull) .collect(Collectors.toUnmodifiableList());