Fix bugs and present some in the future

This commit is contained in:
Coffeemakr 2017-11-25 01:10:04 +01:00
parent 775011db77
commit dc109d78f8
No known key found for this signature in database
GPG key ID: 3F35676D8FF6E743
33 changed files with 182 additions and 88 deletions

View file

@ -13,7 +13,7 @@ dependencies {
implementation 'com.grack:nanojson:1.1' implementation 'com.grack:nanojson:1.1'
implementation 'org.jsoup:jsoup:1.9.2' implementation 'org.jsoup:jsoup:1.9.2'
implementation 'org.mozilla:rhino:1.7.7.1' implementation 'org.mozilla:rhino:1.7.7.1'
implementation 'com.github.spotbugs:spotbugs:3.1.0'
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
} }

View file

@ -3,6 +3,8 @@ package org.schabi.newpipe.extractor;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException; import java.io.IOException;
public abstract class Extractor { public abstract class Extractor {
@ -29,6 +31,7 @@ public abstract class Extractor {
* <p> * <p>
* Is lazily-cleaned by calling {@link #getCleanUrl()} * Is lazily-cleaned by calling {@link #getCleanUrl()}
*/ */
@Nullable
private String cleanUrl; private String cleanUrl;
public Extractor(StreamingService service, String url) throws ExtractionException { public Extractor(StreamingService service, String url) throws ExtractionException {
@ -41,6 +44,7 @@ public abstract class Extractor {
/** /**
* @return a {@link UrlIdHandler} of the current extractor type (e.g. a ChannelExtractor should return a channel url handler). * @return a {@link UrlIdHandler} of the current extractor type (e.g. a ChannelExtractor should return a channel url handler).
*/ */
@Nonnull
protected abstract UrlIdHandler getUrlIdHandler() throws ParsingException; protected abstract UrlIdHandler getUrlIdHandler() throws ParsingException;
/** /**
@ -48,9 +52,18 @@ public abstract class Extractor {
*/ */
public abstract void fetchPage() throws IOException, ExtractionException; public abstract void fetchPage() throws IOException, ExtractionException;
@Nonnull
public abstract String getId() throws ParsingException; public abstract String getId() throws ParsingException;
/**
* Get the name
* @return the name
* @throws ParsingException if the name cannot be extracted
*/
@Nonnull
public abstract String getName() throws ParsingException; public abstract String getName() throws ParsingException;
@Nonnull
public String getOriginalUrl() { public String getOriginalUrl() {
return originalUrl; return originalUrl;
} }
@ -59,6 +72,7 @@ public abstract class Extractor {
* Get a clean url and as a fallback the original url. * Get a clean url and as a fallback the original url.
* @return the clean url or the original url * @return the clean url or the original url
*/ */
@Nonnull
public String getCleanUrl() { public String getCleanUrl() {
if (cleanUrl != null && !cleanUrl.isEmpty()) return cleanUrl; if (cleanUrl != null && !cleanUrl.isEmpty()) return cleanUrl;
@ -72,6 +86,7 @@ public abstract class Extractor {
return cleanUrl; return cleanUrl;
} }
@Nonnull
public StreamingService getService() { public StreamingService getService() {
return service; return service;
} }

View file

@ -6,6 +6,7 @@ import org.schabi.newpipe.extractor.UrlIdHandler;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
/* /*
@ -34,6 +35,7 @@ public abstract class ChannelExtractor extends ListExtractor {
super(service, url, nextStreamsUrl); super(service, url, nextStreamsUrl);
} }
@Nonnull
@Override @Override
protected UrlIdHandler getUrlIdHandler() throws ParsingException { protected UrlIdHandler getUrlIdHandler() throws ParsingException {
return getService().getChannelUrlIdHandler(); return getService().getChannelUrlIdHandler();

View file

@ -7,11 +7,9 @@ import org.schabi.newpipe.extractor.ServiceList;
import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.stream.StreamInfoItemCollector;
import org.schabi.newpipe.extractor.utils.ExtractorHelper; import org.schabi.newpipe.extractor.utils.ExtractorHelper;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
/* /*
* Created by Christian Schabesberger on 31.07.16. * Created by Christian Schabesberger on 31.07.16.

View file

@ -25,6 +25,7 @@ import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
public abstract class KioskExtractor extends ListExtractor { public abstract class KioskExtractor extends ListExtractor {
@ -51,6 +52,7 @@ public abstract class KioskExtractor extends ListExtractor {
} }
@Nonnull
@Override @Override
public String getId() throws ParsingException { public String getId() throws ParsingException {
return id; return id;
@ -64,6 +66,7 @@ public abstract class KioskExtractor extends ListExtractor {
* @return the tranlsated version of id * @return the tranlsated version of id
* @throws ParsingException * @throws ParsingException
*/ */
@Nonnull
@Override @Override
public abstract String getName() throws ParsingException; public abstract String getName() throws ParsingException;

View file

@ -1,16 +1,13 @@
package org.schabi.newpipe.extractor.kiosk; package org.schabi.newpipe.extractor.kiosk;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.ServiceList;
import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.UrlIdHandler; import org.schabi.newpipe.extractor.UrlIdHandler;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import java.io.IOError;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Random;
import java.util.Set; import java.util.Set;
public class KioskList { public class KioskList {

View file

@ -6,6 +6,7 @@ import org.schabi.newpipe.extractor.UrlIdHandler;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
public abstract class PlaylistExtractor extends ListExtractor { public abstract class PlaylistExtractor extends ListExtractor {
@ -14,6 +15,7 @@ public abstract class PlaylistExtractor extends ListExtractor {
super(service, url, nextStreamsUrl); super(service, url, nextStreamsUrl);
} }
@Nonnull
@Override @Override
protected UrlIdHandler getUrlIdHandler() throws ParsingException { protected UrlIdHandler getUrlIdHandler() throws ParsingException {
return getService().getPlaylistUrlIdHandler(); return getService().getPlaylistUrlIdHandler();

View file

@ -4,7 +4,6 @@ import org.schabi.newpipe.extractor.*;
import org.schabi.newpipe.extractor.ListExtractor.NextItemsResult; import org.schabi.newpipe.extractor.ListExtractor.NextItemsResult;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.utils.ExtractorHelper;
import java.io.IOException; import java.io.IOException;

View file

@ -3,9 +3,9 @@ package org.schabi.newpipe.extractor.search;
import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -32,7 +32,9 @@ import java.util.List;
public class SearchResult { public class SearchResult {
private final int serviceId; private final int serviceId;
public final String suggestion; public final String suggestion;
@Nonnull
public final List<InfoItem> resultList; public final List<InfoItem> resultList;
@Nonnull
public final List<Throwable> errors; public final List<Throwable> errors;
public SearchResult(int serviceId, String suggestion, List<InfoItem> results, List<Throwable> errors) { public SearchResult(int serviceId, String suggestion, List<InfoItem> results, List<Throwable> errors) {
@ -66,10 +68,12 @@ public class SearchResult {
} }
@Nonnull
public List<InfoItem> getResults() { public List<InfoItem> getResults() {
return Collections.unmodifiableList(resultList); return Collections.unmodifiableList(resultList);
} }
@Nonnull
public List<Throwable> getErrors() { public List<Throwable> getErrors() {
return errors; return errors;
} }

View file

@ -11,6 +11,7 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.stream.StreamInfoItemCollector; import org.schabi.newpipe.extractor.stream.StreamInfoItemCollector;
import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
@ -38,16 +39,19 @@ public class SoundcloudChannelExtractor extends ChannelExtractor {
} }
} }
@Nonnull
@Override @Override
public String getCleanUrl() { public String getCleanUrl() {
return user.isString("permalink_url") ? user.getString("permalink_url") : getOriginalUrl(); return user.isString("permalink_url") ? user.getString("permalink_url") : getOriginalUrl();
} }
@Nonnull
@Override @Override
public String getId() { public String getId() {
return userId; return userId;
} }
@Nonnull
@Override @Override
public String getName() { public String getName() {
return user.getString("username"); return user.getString("username");

View file

@ -11,6 +11,8 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.kiosk.KioskExtractor; import org.schabi.newpipe.extractor.kiosk.KioskExtractor;
import org.schabi.newpipe.extractor.stream.StreamInfoItemCollector; import org.schabi.newpipe.extractor.stream.StreamInfoItemCollector;
import javax.annotation.Nonnull;
public class SoundcloudChartsExtractor extends KioskExtractor { public class SoundcloudChartsExtractor extends KioskExtractor {
private String url; private String url;
@ -24,11 +26,13 @@ public class SoundcloudChartsExtractor extends KioskExtractor {
public void fetchPage() { public void fetchPage() {
} }
@Nonnull
@Override @Override
public String getName() throws ParsingException { public String getName() throws ParsingException {
return "< Implement me (♥_♥) >"; return "< Implement me (♥_♥) >";
} }
@Nonnull
@Override @Override
public UrlIdHandler getUrlIdHandler() { public UrlIdHandler getUrlIdHandler() {
return new SoundcloudChartsUrlIdHandler(); return new SoundcloudChartsUrlIdHandler();

View file

@ -11,6 +11,7 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.playlist.PlaylistExtractor; import org.schabi.newpipe.extractor.playlist.PlaylistExtractor;
import org.schabi.newpipe.extractor.stream.StreamInfoItemCollector; import org.schabi.newpipe.extractor.stream.StreamInfoItemCollector;
import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
@ -39,16 +40,19 @@ public class SoundcloudPlaylistExtractor extends PlaylistExtractor {
} }
} }
@Nonnull
@Override @Override
public String getCleanUrl() { public String getCleanUrl() {
return playlist.isString("permalink_url") ? playlist.getString("permalink_url") : getOriginalUrl(); return playlist.isString("permalink_url") ? playlist.getString("permalink_url") : getOriginalUrl();
} }
@Nonnull
@Override @Override
public String getId() { public String getId() {
return playlistId; return playlistId;
} }
@Nonnull
@Override @Override
public String getName() { public String getName() {
return playlist.getString("title"); return playlist.getString("title");

View file

@ -11,6 +11,7 @@ import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
import org.schabi.newpipe.extractor.stream.*; import org.schabi.newpipe.extractor.stream.*;
import org.schabi.newpipe.extractor.utils.Parser; import org.schabi.newpipe.extractor.utils.Parser;
import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
@ -19,6 +20,7 @@ public class SoundcloudStreamExtractor extends StreamExtractor {
public SoundcloudStreamExtractor(StreamingService service, String url) throws IOException, ExtractionException { public SoundcloudStreamExtractor(StreamingService service, String url) throws IOException, ExtractionException {
super(service, url); super(service, url);
fetchPage();
} }
@Override @Override
@ -31,31 +33,37 @@ public class SoundcloudStreamExtractor extends StreamExtractor {
} }
} }
@Nonnull
@Override @Override
public String getCleanUrl() { public String getCleanUrl() {
return track.isString("permalink_url") ? track.getString("permalink_url") : getOriginalUrl(); return track.isString("permalink_url") ? track.getString("permalink_url") : getOriginalUrl();
} }
@Nonnull
@Override @Override
public String getId() { public String getId() {
return track.getInt("id") + ""; return track.getInt("id") + "";
} }
@Nonnull
@Override @Override
public String getName() { public String getName() {
return track.getString("title"); return track.getString("title");
} }
@Nonnull
@Override @Override
public String getUploadDate() throws ParsingException { public String getUploadDate() throws ParsingException {
return SoundcloudParsingHelper.toDateString(track.getString("created_at")); return SoundcloudParsingHelper.toDateString(track.getString("created_at"));
} }
@Nonnull
@Override @Override
public String getThumbnailUrl() { public String getThumbnailUrl() {
return track.getString("artwork_url", ""); return track.getString("artwork_url", "");
} }
@Nonnull
@Override @Override
public String getDescription() { public String getDescription() {
return track.getString("description"); return track.getString("description");
@ -91,16 +99,19 @@ public class SoundcloudStreamExtractor extends StreamExtractor {
return -1; return -1;
} }
@Nonnull
@Override @Override
public String getUploaderUrl() { public String getUploaderUrl() {
return track.getObject("user").getString("permalink_url", ""); return track.getObject("user").getString("permalink_url", "");
} }
@Nonnull
@Override @Override
public String getUploaderName() { public String getUploaderName() {
return track.getObject("user").getString("username", ""); return track.getObject("user").getString("username", "");
} }
@Nonnull
@Override @Override
public String getUploaderAvatarUrl() { public String getUploaderAvatarUrl() {
return track.getObject("user", new JsonObject()).getString("avatar_url", ""); return track.getObject("user", new JsonObject()).getString("avatar_url", "");

View file

@ -18,6 +18,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfoItemCollector;
import org.schabi.newpipe.extractor.utils.Parser; import org.schabi.newpipe.extractor.utils.Parser;
import org.schabi.newpipe.extractor.utils.Utils; import org.schabi.newpipe.extractor.utils.Utils;
import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
/* /*
@ -79,6 +80,7 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
return true; return true;
} }
@Nonnull
@Override @Override
public String getCleanUrl() { public String getCleanUrl() {
try { try {
@ -88,6 +90,7 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
} }
} }
@Nonnull
@Override @Override
public String getId() throws ParsingException { public String getId() throws ParsingException {
try { try {
@ -100,6 +103,7 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
} }
} }
@Nonnull
@Override @Override
public String getName() throws ParsingException { public String getName() throws ParsingException {
try { try {

View file

@ -19,6 +19,7 @@ import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.extractor.utils.Parser; import org.schabi.newpipe.extractor.utils.Parser;
import org.schabi.newpipe.extractor.utils.Utils; import org.schabi.newpipe.extractor.utils.Utils;
import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
@ -45,6 +46,7 @@ public class YoutubePlaylistExtractor extends PlaylistExtractor {
nextStreamsAjax = null; nextStreamsAjax = null;
} }
@Nonnull
@Override @Override
public String getId() throws ParsingException { public String getId() throws ParsingException {
try { try {
@ -54,6 +56,7 @@ public class YoutubePlaylistExtractor extends PlaylistExtractor {
} }
} }
@Nonnull
@Override @Override
public String getName() throws ParsingException { public String getName() throws ParsingException {
try { try {

View file

@ -22,6 +22,8 @@ import org.schabi.newpipe.extractor.stream.*;
import org.schabi.newpipe.extractor.utils.Parser; import org.schabi.newpipe.extractor.utils.Parser;
import org.schabi.newpipe.extractor.utils.Utils; import org.schabi.newpipe.extractor.utils.Utils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -75,19 +77,23 @@ public class YoutubeStreamExtractor extends StreamExtractor {
/*//////////////////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////////////////////*/
private Document doc; private Document doc;
@Nullable
private JsonObject playerArgs; private JsonObject playerArgs;
private Map<String, String> videoInfoPage; @Nonnull
private final Map<String, String> videoInfoPage = new HashMap<>();
private boolean isAgeRestricted; private boolean isAgeRestricted;
public YoutubeStreamExtractor(StreamingService service, String url) throws IOException, ExtractionException { public YoutubeStreamExtractor(StreamingService service, String url) throws IOException, ExtractionException {
super(service, url); super(service, url);
fetchPage();
} }
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
// Impl // Impl
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
@Nonnull
@Override @Override
public String getId() throws ParsingException { public String getId() throws ParsingException {
try { try {
@ -97,28 +103,25 @@ public class YoutubeStreamExtractor extends StreamExtractor {
} }
} }
@Nonnull
@Override @Override
public String getName() throws ParsingException { public String getName() throws ParsingException {
try { String name = getStringFromMetaData("title");
return playerArgs.getString("title"); if(name == null) {
} catch (Exception ignored) {
// Try other method...
}
try {
return videoInfoPage.get("title");
} catch (Exception ignored) {
// Try other method...
}
try {
// Fallback to HTML method // Fallback to HTML method
return doc.select("meta[name=title]").attr(CONTENT); try {
} catch (Exception e) { name = doc.select("meta[name=title]").attr(CONTENT);
throw new ParsingException("Could not get the title", e); } catch (Exception e) {
throw new ParsingException("Could not get the title", e);
}
} }
if(name == null || name.isEmpty()) {
throw new ParsingException("Could not get the title");
}
return name;
} }
@Nonnull
@Override @Override
public String getUploadDate() throws ParsingException { public String getUploadDate() throws ParsingException {
try { try {
@ -128,6 +131,7 @@ public class YoutubeStreamExtractor extends StreamExtractor {
} }
} }
@Nonnull
@Override @Override
public String getThumbnailUrl() throws ParsingException { public String getThumbnailUrl() throws ParsingException {
// Try to get high resolution thumbnail first, if it fails, use low res from the player instead // Try to get high resolution thumbnail first, if it fails, use low res from the player instead
@ -138,7 +142,7 @@ public class YoutubeStreamExtractor extends StreamExtractor {
} }
try { try {
if (playerArgs.isString("thumbnail_url")) return playerArgs.getString("thumbnail_url"); if (playerArgs != null && playerArgs.isString("thumbnail_url")) return playerArgs.getString("thumbnail_url");
} catch (Exception ignored) { } catch (Exception ignored) {
// Try other method... // Try other method...
} }
@ -150,6 +154,7 @@ public class YoutubeStreamExtractor extends StreamExtractor {
} }
} }
@Nonnull
@Override @Override
public String getDescription() throws ParsingException { public String getDescription() throws ParsingException {
try { try {
@ -174,23 +179,27 @@ public class YoutubeStreamExtractor extends StreamExtractor {
@Override @Override
public long getLength() throws ParsingException { public long getLength() throws ParsingException {
if(playerArgs != null) {
try {
long returnValue = Long.parseLong(playerArgs.get("length_seconds") + "");
if (returnValue >= 0) return returnValue;
} catch (Exception ignored) {
// Try other method...
}
}
String lengthString = videoInfoPage.get("length_seconds");
try { try {
long returnValue = Long.parseLong(playerArgs.get("length_seconds") + ""); return Long.parseLong(lengthString);
if (returnValue >= 0) return returnValue;
} catch (Exception ignored) {
// Try other method...
}
try {
return Long.parseLong(videoInfoPage.get("length_seconds"));
} catch (Exception ignored) { } catch (Exception ignored) {
// Try other method... // Try other method...
} }
// TODO: 25.11.17 Implement a way to get the length for age restricted videos #44
try { try {
// Fallback to HTML method // Fallback to HTML method
return Long.parseLong(doc.select("div[class~=\"ytp-progress-bar\"][role=\"slider\"]") return Long.parseLong(doc.select("div[class~=\"ytp-progress-bar\"][role=\"slider\"]").first()
.first().attr("aria-valuemax")); .attr("aria-valuemax"));
} catch (Exception e) { } catch (Exception e) {
throw new ParsingException("Could not get video length", e); throw new ParsingException("Could not get video length", e);
} }
@ -253,6 +262,7 @@ public class YoutubeStreamExtractor extends StreamExtractor {
} }
} }
@Nonnull
@Override @Override
public String getUploaderUrl() throws ParsingException { public String getUploaderUrl() throws ParsingException {
try { try {
@ -263,28 +273,41 @@ public class YoutubeStreamExtractor extends StreamExtractor {
} }
} }
@Override
public String getUploaderName() throws ParsingException {
try {
return playerArgs.getString("author");
} catch (Exception ignored) {
// Try other method...
}
try { @Nullable
return videoInfoPage.get("author"); private String getStringFromMetaData(String field) {
} catch (Exception ignored) { String value = null;
// Try other method... if(playerArgs != null) {
// This can not fail
value = playerArgs.getString(field);
} }
if(value == null) {
try { // This can not fail too
// Fallback to HTML method value = videoInfoPage.get(field);
return doc.select("div.yt-user-info").first().text();
} catch (Exception e) {
throw new ParsingException("Could not get uploader name", e);
} }
return value;
} }
@Nonnull
@Override
public String getUploaderName() throws ParsingException {
String name = getStringFromMetaData("author");
if(name == null) {
try {
// Fallback to HTML method
name = doc.select("div.yt-user-info").first().text();
} catch (Exception e) {
throw new ParsingException("Could not get uploader name", e);
}
}
if(name == null || name.isEmpty()) {
throw new ParsingException("Could not get uploader name");
}
return name;
}
@Nonnull
@Override @Override
public String getUploaderAvatarUrl() throws ParsingException { public String getUploaderAvatarUrl() throws ParsingException {
try { try {
@ -300,9 +323,9 @@ public class YoutubeStreamExtractor extends StreamExtractor {
public String getDashMpdUrl() throws ParsingException { public String getDashMpdUrl() throws ParsingException {
try { try {
String dashManifestUrl; String dashManifestUrl;
if (videoInfoPage != null && videoInfoPage.containsKey("dashmpd")) { if (videoInfoPage.containsKey("dashmpd")) {
dashManifestUrl = videoInfoPage.get("dashmpd"); dashManifestUrl = videoInfoPage.get("dashmpd");
} else if (playerArgs.isString("dashmpd")) { } else if (playerArgs != null && playerArgs.isString("dashmpd")) {
dashManifestUrl = playerArgs.getString("dashmpd", ""); dashManifestUrl = playerArgs.getString("dashmpd", "");
} else { } else {
return ""; return "";
@ -521,7 +544,7 @@ public class YoutubeStreamExtractor extends StreamExtractor {
// Check if the video is age restricted // Check if the video is age restricted
if (pageContent.contains("<meta property=\"og:restrictions:age")) { if (pageContent.contains("<meta property=\"og:restrictions:age")) {
String infoPageResponse = dl.download(String.format(GET_VIDEO_INFO_URL, getId())); String infoPageResponse = dl.download(String.format(GET_VIDEO_INFO_URL, getId()));
videoInfoPage = Parser.compatParseMap(infoPageResponse); videoInfoPage.putAll(Parser.compatParseMap(infoPageResponse));
playerUrl = getPlayerUrlFromRestrictedVideo(); playerUrl = getPlayerUrlFromRestrictedVideo();
isAgeRestricted = true; isAgeRestricted = true;
} else { } else {
@ -694,7 +717,7 @@ public class YoutubeStreamExtractor extends StreamExtractor {
String encodedUrlMap = ""; String encodedUrlMap = "";
if (playerArgs != null && playerArgs.isString(encodedUrlMapKey)) { if (playerArgs != null && playerArgs.isString(encodedUrlMapKey)) {
encodedUrlMap = playerArgs.getString(encodedUrlMapKey, ""); encodedUrlMap = playerArgs.getString(encodedUrlMapKey, "");
} else if (videoInfoPage != null && videoInfoPage.containsKey(encodedUrlMapKey)) { } else if (videoInfoPage.containsKey(encodedUrlMapKey)) {
encodedUrlMap = videoInfoPage.get(encodedUrlMapKey); encodedUrlMap = videoInfoPage.get(encodedUrlMapKey);
} }

View file

@ -29,6 +29,7 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.kiosk.KioskExtractor; import org.schabi.newpipe.extractor.kiosk.KioskExtractor;
import org.schabi.newpipe.extractor.stream.StreamInfoItemCollector; import org.schabi.newpipe.extractor.stream.StreamInfoItemCollector;
import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
public class YoutubeTrendingExtractor extends KioskExtractor { public class YoutubeTrendingExtractor extends KioskExtractor {
@ -54,6 +55,7 @@ public class YoutubeTrendingExtractor extends KioskExtractor {
doc = Jsoup.parse(pageContent, url); doc = Jsoup.parse(pageContent, url);
} }
@Nonnull
@Override @Override
public UrlIdHandler getUrlIdHandler() { public UrlIdHandler getUrlIdHandler() {
return new YoutubeTrendingUrlIdHandler(); return new YoutubeTrendingUrlIdHandler();
@ -64,6 +66,7 @@ public class YoutubeTrendingExtractor extends KioskExtractor {
return null; return null;
} }
@Nonnull
@Override @Override
public String getName() throws ParsingException { public String getName() throws ParsingException {
try { try {

View file

@ -30,6 +30,7 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException; import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
import org.schabi.newpipe.extractor.utils.Parser; import org.schabi.newpipe.extractor.utils.Parser;
import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
@ -40,16 +41,19 @@ public abstract class StreamExtractor extends Extractor {
public StreamExtractor(StreamingService service, String url) throws IOException, ExtractionException { public StreamExtractor(StreamingService service, String url) throws IOException, ExtractionException {
super(service, url); super(service, url);
fetchPage();
} }
@Nonnull
@Override @Override
protected UrlIdHandler getUrlIdHandler() throws ParsingException { protected UrlIdHandler getUrlIdHandler() throws ParsingException {
return getService().getStreamUrlIdHandler(); return getService().getStreamUrlIdHandler();
} }
@Nonnull
public abstract String getUploadDate() throws ParsingException; public abstract String getUploadDate() throws ParsingException;
@Nonnull
public abstract String getThumbnailUrl() throws ParsingException; public abstract String getThumbnailUrl() throws ParsingException;
@Nonnull
public abstract String getDescription() throws ParsingException; public abstract String getDescription() throws ParsingException;
public abstract int getAgeLimit() throws ParsingException; public abstract int getAgeLimit() throws ParsingException;
@ -104,10 +108,18 @@ public abstract class StreamExtractor extends Extractor {
public abstract long getLikeCount() throws ParsingException; public abstract long getLikeCount() throws ParsingException;
public abstract long getDislikeCount() throws ParsingException; public abstract long getDislikeCount() throws ParsingException;
@Nonnull
public abstract String getUploaderUrl() throws ParsingException; public abstract String getUploaderUrl() throws ParsingException;
@Nonnull
public abstract String getUploaderName() throws ParsingException; public abstract String getUploaderName() throws ParsingException;
@Nonnull
public abstract String getUploaderAvatarUrl() throws ParsingException; public abstract String getUploaderAvatarUrl() throws ParsingException;
/**
* Get the dash mpd url
* @return the url as a string or an empty string
* @throws ParsingException if an error occurs while reading
*/
public abstract String getDashMpdUrl() throws ParsingException; public abstract String getDashMpdUrl() throws ParsingException;
public abstract List<AudioStream> getAudioStreams() throws IOException, ExtractionException; public abstract List<AudioStream> getAudioStreams() throws IOException, ExtractionException;
public abstract List<VideoStream> getVideoStreams() throws IOException, ExtractionException; public abstract List<VideoStream> getVideoStreams() throws IOException, ExtractionException;

View file

@ -7,7 +7,6 @@ import org.schabi.newpipe.extractor.utils.DashMpdParser;
import org.schabi.newpipe.extractor.utils.ExtractorHelper; import org.schabi.newpipe.extractor.utils.ExtractorHelper;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;

View file

@ -89,10 +89,8 @@ public class Downloader implements org.schabi.newpipe.extractor.Downloader {
public String download(String siteUrl, Map<String, String> customProperties) throws IOException, ReCaptchaException { public String download(String siteUrl, Map<String, String> customProperties) throws IOException, ReCaptchaException {
URL url = new URL(siteUrl); URL url = new URL(siteUrl);
HttpsURLConnection con = (HttpsURLConnection) url.openConnection(); HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
Iterator it = customProperties.entrySet().iterator(); for (Map.Entry<String, String> pair: customProperties.entrySet()) {
while (it.hasNext()) { con.setRequestProperty(pair.getKey(), pair.getValue());
Map.Entry pair = (Map.Entry) it.next();
con.setRequestProperty((String) pair.getKey(), (String) pair.getValue());
} }
return dl(con); return dl(con);
} }

View file

@ -10,13 +10,10 @@ import org.junit.Before;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.schabi.newpipe.Downloader; import org.schabi.newpipe.Downloader;
import org.schabi.newpipe.extractor.InfoItemCollector;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.kiosk.KioskExtractor; import org.schabi.newpipe.extractor.kiosk.KioskExtractor;
import org.schabi.newpipe.extractor.stream.StreamInfoItemCollector; import org.schabi.newpipe.extractor.stream.StreamInfoItemCollector;
import java.util.List;
/** /**
* Test for {@link SoundcloudChartsUrlIdHandler} * Test for {@link SoundcloudChartsUrlIdHandler}
*/ */

View file

@ -9,6 +9,7 @@ import org.schabi.newpipe.extractor.search.SearchEngine;
import org.schabi.newpipe.extractor.search.SearchResult; import org.schabi.newpipe.extractor.search.SearchResult;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.schabi.newpipe.extractor.ServiceList.SoundCloud; import static org.schabi.newpipe.extractor.ServiceList.SoundCloud;
@ -36,8 +37,9 @@ public class SoundcloudSearchEngineAllTest {
@Test @Test
public void testResultErrors() { public void testResultErrors() {
assertNotNull(result.errors);
if (!result.errors.isEmpty()) for (Throwable error : result.errors) error.printStackTrace(); if (!result.errors.isEmpty()) for (Throwable error : result.errors) error.printStackTrace();
assertTrue(result.errors == null || result.errors.isEmpty()); assertTrue(result.errors.isEmpty());
} }
@Ignore @Ignore

View file

@ -43,8 +43,9 @@ public class SoundcloudSearchEngineChannelTest {
@Test @Test
public void testResultErrors() { public void testResultErrors() {
assertNotNull(result.errors);
if (!result.errors.isEmpty()) for (Throwable error : result.errors) error.printStackTrace(); if (!result.errors.isEmpty()) for (Throwable error : result.errors) error.printStackTrace();
assertTrue(result.errors == null || result.errors.isEmpty()); assertTrue(result.errors.isEmpty());
} }
@Ignore @Ignore

View file

@ -63,8 +63,9 @@ public class SoundcloudSearchEnginePlaylistTest {
@Test @Test
public void testResultErrors() { public void testResultErrors() {
assertNotNull(result.errors);
if (!result.errors.isEmpty()) for (Throwable error : result.errors) error.printStackTrace(); if (!result.errors.isEmpty()) for (Throwable error : result.errors) error.printStackTrace();
assertTrue(result.errors == null || result.errors.isEmpty()); assertTrue(result.errors.isEmpty());
} }
@Ignore @Ignore

View file

@ -43,8 +43,9 @@ public class SoundcloudSearchEngineStreamTest {
@Test @Test
public void testResultErrors() { public void testResultErrors() {
assertNotNull(result.errors);
if (!result.errors.isEmpty()) for (Throwable error : result.errors) error.printStackTrace(); if (!result.errors.isEmpty()) for (Throwable error : result.errors) error.printStackTrace();
assertTrue(result.errors == null || result.errors.isEmpty()); assertTrue(result.errors.isEmpty());
} }
@Ignore @Ignore

View file

@ -1,6 +1,5 @@
package org.schabi.newpipe.extractor.services.youtube; package org.schabi.newpipe.extractor.services.youtube;
import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
@ -11,7 +10,6 @@ import org.schabi.newpipe.extractor.search.SearchResult;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.schabi.newpipe.extractor.ServiceList.YouTube;
/* /*
* Created by Christian Schabesberger on 29.12.15. * Created by Christian Schabesberger on 29.12.15.

View file

@ -64,8 +64,9 @@ public class YoutubeSearchEngineChannelTest {
@Test @Test
public void testResultErrors() { public void testResultErrors() {
assertNotNull(result.errors);
if (!result.errors.isEmpty()) for (Throwable error : result.errors) error.printStackTrace(); if (!result.errors.isEmpty()) for (Throwable error : result.errors) error.printStackTrace();
assertTrue(result.errors == null || result.errors.isEmpty()); assertTrue(result.errors.isEmpty());
} }
@Ignore @Ignore

View file

@ -64,8 +64,9 @@ public class YoutubeSearchEnginePlaylistTest {
@Test @Test
public void testResultErrors() { public void testResultErrors() {
assertNotNull(result.errors);
if (!result.errors.isEmpty()) for (Throwable error : result.errors) error.printStackTrace(); if (!result.errors.isEmpty()) for (Throwable error : result.errors) error.printStackTrace();
assertTrue(result.errors == null || result.errors.isEmpty()); assertTrue(result.errors.isEmpty());
} }
@Ignore @Ignore

View file

@ -64,8 +64,9 @@ public class YoutubeSearchEngineStreamTest {
@Test @Test
public void testResultErrors() { public void testResultErrors() {
assertNotNull(result.errors);
if (!result.errors.isEmpty()) for (Throwable error : result.errors) error.printStackTrace(); if (!result.errors.isEmpty()) for (Throwable error : result.errors) error.printStackTrace();
assertTrue(result.errors == null || result.errors.isEmpty()); assertTrue(result.errors.isEmpty());
} }
@Ignore @Ignore

View file

@ -26,7 +26,6 @@ import org.schabi.newpipe.Downloader;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.kiosk.KioskList; import org.schabi.newpipe.extractor.kiosk.KioskList;
import org.schabi.newpipe.extractor.search.SearchEngine;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;

View file

@ -67,14 +67,17 @@ public class YoutubeStreamExtractorDefaultTest {
@Test @Test
public void testGetDescription() throws ParsingException { public void testGetDescription() throws ParsingException {
assertTrue(extractor.getDescription() != null); assertNotNull(extractor.getDescription());
assertFalse(extractor.getDescription().isEmpty());
} }
@Test @Test
public void testGetUploaderName() throws ParsingException { public void testGetUploaderName() throws ParsingException {
assertTrue(!extractor.getUploaderName().isEmpty()); assertNotNull(extractor.getUploaderName());
assertFalse(extractor.getUploaderName().isEmpty());
} }
@Test @Test
public void testGetLength() throws ParsingException { public void testGetLength() throws ParsingException {
assertTrue(extractor.getLength() > 0); assertTrue(extractor.getLength() > 0);

View file

@ -2,6 +2,7 @@ package org.schabi.newpipe.extractor.services.youtube;
import com.grack.nanojson.JsonParserException; import com.grack.nanojson.JsonParserException;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.schabi.newpipe.Downloader; import org.schabi.newpipe.Downloader;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
@ -13,8 +14,7 @@ import org.schabi.newpipe.extractor.stream.VideoStream;
import java.io.IOException; import java.io.IOException;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.*;
import static org.junit.Assert.assertTrue;
import static org.schabi.newpipe.extractor.ServiceList.YouTube; import static org.schabi.newpipe.extractor.ServiceList.YouTube;
/** /**
@ -22,12 +22,12 @@ import static org.schabi.newpipe.extractor.ServiceList.YouTube;
*/ */
public class YoutubeStreamExtractorRestrictedTest { public class YoutubeStreamExtractorRestrictedTest {
public static final String HTTPS = "https://"; public static final String HTTPS = "https://";
private StreamExtractor extractor; private YoutubeStreamExtractor extractor;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
NewPipe.init(Downloader.getInstance()); NewPipe.init(Downloader.getInstance());
extractor = YouTube.getService() extractor = (YoutubeStreamExtractor) YouTube.getService()
.getStreamExtractor("https://www.youtube.com/watch?v=i6JTvzrpBy0"); .getStreamExtractor("https://www.youtube.com/watch?v=i6JTvzrpBy0");
} }
@ -48,20 +48,24 @@ public class YoutubeStreamExtractorRestrictedTest {
} }
@Test @Test
public void testGetTitle() throws ParsingException { public void testGetName() throws ParsingException {
assertTrue(!extractor.getName().isEmpty()); assertNotNull("name is null", extractor.getName());
assertFalse("name is empty", extractor.getName().isEmpty());
} }
@Test @Test
public void testGetDescription() throws ParsingException { public void testGetDescription() throws ParsingException {
assertTrue(extractor.getDescription() != null); assertNotNull(extractor.getDescription());
assertFalse(extractor.getDescription().isEmpty());
} }
@Test @Test
public void testGetUploaderName() throws ParsingException { public void testGetUploaderName() throws ParsingException {
assertTrue(!extractor.getUploaderName().isEmpty()); assertNotNull(extractor.getUploaderName());
assertFalse(extractor.getUploaderName().isEmpty());
} }
@Ignore // Currently there is no way get the length from restricted videos
@Test @Test
public void testGetLength() throws ParsingException { public void testGetLength() throws ParsingException {
assertTrue(extractor.getLength() > 0); assertTrue(extractor.getLength() > 0);
@ -89,9 +93,10 @@ public class YoutubeStreamExtractorRestrictedTest {
extractor.getUploaderAvatarUrl().contains(HTTPS)); extractor.getUploaderAvatarUrl().contains(HTTPS));
} }
// FIXME: 25.11.17 Are there no streams or are they not listed?
@Test @Test
public void testGetAudioStreams() throws IOException, ExtractionException { public void testGetAudioStreams() throws IOException, ExtractionException {
// audiostream not always necessary // audio streams are not always necessary
assertTrue(!extractor.getAudioStreams().isEmpty()); assertTrue(!extractor.getAudioStreams().isEmpty());
} }

View file

@ -23,7 +23,6 @@ package org.schabi.newpipe.extractor.services.youtube;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.schabi.newpipe.Downloader; import org.schabi.newpipe.Downloader;
import org.schabi.newpipe.extractor.InfoItemCollector;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.kiosk.KioskExtractor; import org.schabi.newpipe.extractor.kiosk.KioskExtractor;
import org.schabi.newpipe.extractor.stream.StreamInfoItemCollector; import org.schabi.newpipe.extractor.stream.StreamInfoItemCollector;