Merge pull request #409 from Bartoshr/bugfix/short-channel-urls
Support short custom YouTube channel URLs
This commit is contained in:
commit
8026304a0a
|
@ -1,5 +1,6 @@
|
||||||
package org.schabi.newpipe.extractor.services.youtube.linkHandler;
|
package org.schabi.newpipe.extractor.services.youtube.linkHandler;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
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.services.youtube.YoutubeParsingHelper;
|
import org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper;
|
||||||
|
@ -32,6 +33,9 @@ public class YoutubeChannelLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||||
|
|
||||||
private static final YoutubeChannelLinkHandlerFactory instance = new YoutubeChannelLinkHandlerFactory();
|
private static final YoutubeChannelLinkHandlerFactory instance = new YoutubeChannelLinkHandlerFactory();
|
||||||
|
|
||||||
|
private static final Pattern excludedSegments =
|
||||||
|
Pattern.compile("playlist|watch|attribution_link|watch_popup|embed|feed|select_site");
|
||||||
|
|
||||||
public static YoutubeChannelLinkHandlerFactory getInstance() {
|
public static YoutubeChannelLinkHandlerFactory getInstance() {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
@ -48,11 +52,22 @@ public class YoutubeChannelLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||||
public String getUrl(String id, List<String> contentFilters, String searchFilter) {
|
public String getUrl(String id, List<String> contentFilters, String searchFilter) {
|
||||||
return "https://www.youtube.com/" + id;
|
return "https://www.youtube.com/" + id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if path conform to
|
||||||
|
* custom short channel URLs like youtube.com/yourcustomname
|
||||||
|
*
|
||||||
|
* @param splitPath path segments array
|
||||||
|
* @return true - if value conform to short channel URL, false - not
|
||||||
|
*/
|
||||||
|
private boolean isCustomShortChannelUrl(final String[] splitPath) {
|
||||||
|
return splitPath.length == 1 && !excludedSegments.matcher(splitPath[0]).matches();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId(String url) throws ParsingException {
|
public String getId(String url) throws ParsingException {
|
||||||
try {
|
try {
|
||||||
URL urlObj = Utils.stringToURL(url);
|
final URL urlObj = Utils.stringToURL(url);
|
||||||
String path = urlObj.getPath();
|
String path = urlObj.getPath();
|
||||||
|
|
||||||
if (!Utils.isHTTP(urlObj) || !(YoutubeParsingHelper.isYoutubeURL(urlObj) ||
|
if (!Utils.isHTTP(urlObj) || !(YoutubeParsingHelper.isYoutubeURL(urlObj) ||
|
||||||
|
@ -60,15 +75,21 @@ public class YoutubeChannelLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||||
throw new ParsingException("the URL given is not a Youtube-URL");
|
throw new ParsingException("the URL given is not a Youtube-URL");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!path.startsWith("/user/") && !path.startsWith("/channel/") && !path.startsWith("/c/")) {
|
// remove leading "/"
|
||||||
|
path = path.substring(1);
|
||||||
|
String[] splitPath = path.split("/");
|
||||||
|
|
||||||
|
// Handle custom short channel URLs like youtube.com/yourcustomname
|
||||||
|
if (isCustomShortChannelUrl(splitPath)) {
|
||||||
|
path = "c/" + path;
|
||||||
|
splitPath = path.split("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!path.startsWith("user/") && !path.startsWith("channel/") && !path.startsWith("c/")) {
|
||||||
throw new ParsingException("the URL given is neither a channel nor an user");
|
throw new ParsingException("the URL given is neither a channel nor an user");
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove leading "/"
|
final String id = splitPath[1];
|
||||||
path = path.substring(1);
|
|
||||||
|
|
||||||
String[] splitPath = path.split("/");
|
|
||||||
String id = splitPath[1];
|
|
||||||
|
|
||||||
if (id == null || !id.matches("[A-Za-z0-9_-]+")) {
|
if (id == null || !id.matches("[A-Za-z0-9_-]+")) {
|
||||||
throw new ParsingException("The given id is not a Youtube-Video-ID");
|
throw new ParsingException("The given id is not a Youtube-Video-ID");
|
||||||
|
|
|
@ -8,6 +8,7 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||||
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelLinkHandlerFactory;
|
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelLinkHandlerFactory;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,6 +31,8 @@ public class YoutubeChannelLinkHandlerFactoryTest {
|
||||||
|
|
||||||
assertTrue(linkHandler.acceptUrl("https://www.youtube.com/c/creatoracademy"));
|
assertTrue(linkHandler.acceptUrl("https://www.youtube.com/c/creatoracademy"));
|
||||||
|
|
||||||
|
assertTrue(linkHandler.acceptUrl("https://youtube.com/DIMENSI0N"));
|
||||||
|
|
||||||
assertTrue(linkHandler.acceptUrl("https://www.youtube.com/channel/UClq42foiSgl7sSpLupnugGA"));
|
assertTrue(linkHandler.acceptUrl("https://www.youtube.com/channel/UClq42foiSgl7sSpLupnugGA"));
|
||||||
assertTrue(linkHandler.acceptUrl("https://www.youtube.com/channel/UClq42foiSgl7sSpLupnugGA/videos?disable_polymer=1"));
|
assertTrue(linkHandler.acceptUrl("https://www.youtube.com/channel/UClq42foiSgl7sSpLupnugGA/videos?disable_polymer=1"));
|
||||||
|
|
||||||
|
@ -44,6 +47,18 @@ public class YoutubeChannelLinkHandlerFactoryTest {
|
||||||
|
|
||||||
assertTrue(linkHandler.acceptUrl("https://invidio.us/channel/UClq42foiSgl7sSpLupnugGA"));
|
assertTrue(linkHandler.acceptUrl("https://invidio.us/channel/UClq42foiSgl7sSpLupnugGA"));
|
||||||
assertTrue(linkHandler.acceptUrl("https://invidio.us/channel/UClq42foiSgl7sSpLupnugGA/videos?disable_polymer=1"));
|
assertTrue(linkHandler.acceptUrl("https://invidio.us/channel/UClq42foiSgl7sSpLupnugGA/videos?disable_polymer=1"));
|
||||||
|
assertTrue(linkHandler.acceptUrl("https://www.youtube.com/watchismo"));
|
||||||
|
|
||||||
|
|
||||||
|
// do not accept URLs which are not channels
|
||||||
|
assertFalse(linkHandler.acceptUrl("https://www.youtube.com/watch?v=jZViOEv90dI&t=100"));
|
||||||
|
assertFalse(linkHandler.acceptUrl("http://www.youtube.com/watch_popup?v=uEJuoEs1UxY"));
|
||||||
|
assertFalse(linkHandler.acceptUrl("http://www.youtube.com/attribution_link?a=JdfC0C9V6ZI&u=%2Fwatch%3Fv%3DEhxJLojIE_o%26feature%3Dshare"));
|
||||||
|
assertFalse(linkHandler.acceptUrl("https://www.youtube.com/playlist?list=PLW5y1tjAOzI3orQNF1yGGVL5x-pR2K1d"));
|
||||||
|
assertFalse(linkHandler.acceptUrl("https://www.youtube.com/embed/jZViOEv90dI"));
|
||||||
|
assertFalse(linkHandler.acceptUrl("https://www.youtube.com/feed/subscriptions?list=PLz8YL4HVC87WJQDzVoY943URKQCsHS9XV"));
|
||||||
|
assertFalse(linkHandler.acceptUrl("https://www.youtube.com/?app=desktop&persist_app=1"));
|
||||||
|
assertFalse(linkHandler.acceptUrl("https://m.youtube.com/select_site"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue