[PeerTube] Fix parsing id for instances whose domain ends with a or c

The pattern to detect the channel ID was faulty and e.g. the ID detected for "https://kolektiva.media/video-channels/documentary_channel" was "a/video-channels" which is wrong.  A new pattern is added to distinguish between URLs and potential IDs because IDs must not start with a "/" while IDs inside an URL must.

Fixes TeamNewPipe/NewPipe#11369
This commit is contained in:
TobiGr 2024-08-02 18:04:41 +02:00
parent 6963385176
commit bcacfc53c5
3 changed files with 128 additions and 7 deletions

View File

@ -5,6 +5,7 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
import org.schabi.newpipe.extractor.utils.Parser; import org.schabi.newpipe.extractor.utils.Parser;
import javax.annotation.Nonnull;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.List; import java.util.List;
@ -14,6 +15,7 @@ public final class PeertubeChannelLinkHandlerFactory extends ListLinkHandlerFact
private static final PeertubeChannelLinkHandlerFactory INSTANCE private static final PeertubeChannelLinkHandlerFactory INSTANCE
= new PeertubeChannelLinkHandlerFactory(); = new PeertubeChannelLinkHandlerFactory();
private static final String ID_PATTERN = "((accounts|a)|(video-channels|c))/([^/?&#]*)"; private static final String ID_PATTERN = "((accounts|a)|(video-channels|c))/([^/?&#]*)";
private static final String ID_URL_PATTERN = "/((accounts|a)|(video-channels|c))/([^/?&#]*)";
public static final String API_ENDPOINT = "/api/v1/"; public static final String API_ENDPOINT = "/api/v1/";
private PeertubeChannelLinkHandlerFactory() { private PeertubeChannelLinkHandlerFactory() {
@ -25,7 +27,7 @@ public final class PeertubeChannelLinkHandlerFactory extends ListLinkHandlerFact
@Override @Override
public String getId(final String url) throws ParsingException, UnsupportedOperationException { public String getId(final String url) throws ParsingException, UnsupportedOperationException {
return fixId(Parser.matchGroup(ID_PATTERN, url, 0)); return fixId(Parser.matchGroup(ID_URL_PATTERN, url, 0));
} }
@Override @Override
@ -74,12 +76,13 @@ public final class PeertubeChannelLinkHandlerFactory extends ListLinkHandlerFact
* @param id the id to fix * @param id the id to fix
* @return the fixed id * @return the fixed id
*/ */
private String fixId(final String id) { private String fixId(@Nonnull final String id) {
if (id.startsWith("a/")) { final String cleanedId = id.startsWith("/") ? id.substring(1) : id;
return "accounts" + id.substring(1); if (cleanedId.startsWith("a/")) {
} else if (id.startsWith("c/")) { return "accounts" + cleanedId.substring(1);
return "video-channels" + id.substring(1); } else if (cleanedId.startsWith("c/")) {
return "video-channels" + cleanedId.substring(1);
} }
return id; return cleanedId;
} }
} }

View File

@ -234,4 +234,111 @@ public class PeertubeChannelExtractorTest {
assertTrue(extractor.getTags().isEmpty()); assertTrue(extractor.getTags().isEmpty());
} }
} }
public static class DocumentaryChannel implements BaseChannelExtractorTest {
// https://github.com/TeamNewPipe/NewPipe/issues/11369
private static PeertubeChannelExtractor extractor;
@BeforeAll
public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance());
// setting instance might break test when running in parallel
PeerTube.setInstance(new PeertubeInstance("https://kolektiva.media", "kolektiva.media"));
extractor = (PeertubeChannelExtractor) PeerTube
.getChannelExtractor("https://kolektiva.media/video-channels/documentary_channel");
extractor.fetchPage();
}
/*//////////////////////////////////////////////////////////////////////////
// Extractor
//////////////////////////////////////////////////////////////////////////*/
@Test
public void testServiceId() {
assertEquals(PeerTube.getServiceId(), extractor.getServiceId());
}
@Test
public void testName() throws ParsingException {
assertEquals("Documentary Channel", extractor.getName());
}
@Test
public void testId() throws ParsingException {
assertEquals("video-channels/documentary_channel", extractor.getId());
}
@Test
public void testUrl() throws ParsingException {
assertEquals("https://kolektiva.media/video-channels/documentary_channel", extractor.getUrl());
}
@Test
public void testOriginalUrl() throws ParsingException {
assertEquals("https://kolektiva.media/video-channels/documentary_channel", extractor.getOriginalUrl());
}
/*//////////////////////////////////////////////////////////////////////////
// ChannelExtractor
//////////////////////////////////////////////////////////////////////////*/
@Test
public void testDescription() {
assertNotNull(extractor.getDescription());
}
@Test
void testParentChannelName() throws ParsingException {
assertEquals("consumedmind", extractor.getParentChannelName());
}
@Test
void testParentChannelUrl() throws ParsingException {
assertEquals("https://kolektiva.media/accounts/consumedmind", extractor.getParentChannelUrl());
}
@Test
void testParentChannelAvatars() {
defaultTestImageCollection(extractor.getParentChannelAvatars());
}
@Test
public void testAvatars() {
defaultTestImageCollection(extractor.getAvatars());
}
@Test
public void testBanners() throws ParsingException {
assertGreaterOrEqual(1, extractor.getBanners().size());
}
@Test
public void testFeedUrl() throws ParsingException {
assertEquals("https://kolektiva.media/feeds/videos.xml?videoChannelId=2994", extractor.getFeedUrl());
}
@Test
public void testSubscriberCount() {
assertGreaterOrEqual(25, extractor.getSubscriberCount());
}
@Test
@Override
public void testVerified() throws Exception {
assertFalse(extractor.isVerified());
}
@Test
@Override
public void testTabs() throws Exception {
assertTabsContain(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.PLAYLISTS);
}
@Test
@Override
public void testTags() throws Exception {
assertTrue(extractor.getTags().isEmpty());
}
}
} }

View File

@ -33,6 +33,7 @@ public class PeertubeChannelLinkHandlerFactoryTest {
assertTrue(linkHandler.acceptUrl("https://peertube.stream/video-channels/kranti_channel@videos.squat.net/videos")); assertTrue(linkHandler.acceptUrl("https://peertube.stream/video-channels/kranti_channel@videos.squat.net/videos"));
assertTrue(linkHandler.acceptUrl("https://peertube.stream/c/kranti_channel@videos.squat.net/videos")); assertTrue(linkHandler.acceptUrl("https://peertube.stream/c/kranti_channel@videos.squat.net/videos"));
assertTrue(linkHandler.acceptUrl("https://peertube.stream/api/v1/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa")); assertTrue(linkHandler.acceptUrl("https://peertube.stream/api/v1/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa"));
assertTrue(linkHandler.acceptUrl("https://kolektiva.media/video-channels/documentary_channel"));
assertDoNotAcceptNonURLs(linkHandler); assertDoNotAcceptNonURLs(linkHandler);
} }
@ -60,6 +61,16 @@ public class PeertubeChannelLinkHandlerFactoryTest {
linkHandler.fromUrl("https://peertube.stream/c/kranti_channel@videos.squat.net/video-playlists").getId()); linkHandler.fromUrl("https://peertube.stream/c/kranti_channel@videos.squat.net/video-playlists").getId());
assertEquals("video-channels/kranti_channel@videos.squat.net", assertEquals("video-channels/kranti_channel@videos.squat.net",
linkHandler.fromUrl("https://peertube.stream/api/v1/video-channels/kranti_channel@videos.squat.net").getId()); linkHandler.fromUrl("https://peertube.stream/api/v1/video-channels/kranti_channel@videos.squat.net").getId());
// instance URL ending with an "a": https://kolektiva.media
assertEquals("video-channels/documentary_channel",
linkHandler.fromUrl("https://kolektiva.media/video-channels/documentary_channel/videos").getId());
assertEquals("video-channels/documentary_channel",
linkHandler.fromUrl("https://kolektiva.media/c/documentary_channel/videos").getId());
assertEquals("video-channels/documentary_channel",
linkHandler.fromUrl("https://kolektiva.media/c/documentary_channel/video-playlists").getId());
assertEquals("video-channels/documentary_channel",
linkHandler.fromUrl("https://kolektiva.media/api/v1/video-channels/documentary_channel").getId());
} }
@Test @Test