Skip to content

Commit cfc2b9b

Browse files
Merge pull request #19 from mauriciocolli/refactor
Refactor and improvements
2 parents 731102b + ea5b08d commit cfc2b9b

61 files changed

Lines changed: 1444 additions & 843 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,8 @@ dependencies {
1010
implementation 'org.mozilla:rhino:1.7.7.1'
1111

1212
testImplementation 'junit:junit:4.12'
13+
14+
sourceCompatibility = 1.7
15+
targetCompatibility = 1.7
1316
}
1417

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,73 @@
11
package org.schabi.newpipe.extractor;
22

3-
import org.schabi.newpipe.extractor.stream.StreamInfoItemCollector;
3+
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
4+
import org.schabi.newpipe.extractor.exceptions.ParsingException;
45

5-
import java.io.Serializable;
6+
import java.io.IOException;
67

7-
public abstract class Extractor implements Serializable {
8-
private final int serviceId;
9-
private final String url;
10-
private final UrlIdHandler urlIdHandler;
11-
private final StreamInfoItemCollector previewInfoCollector;
8+
public abstract class Extractor {
9+
/**
10+
* {@link StreamingService} currently related to this extractor.<br/>
11+
* Useful for getting other things from a service (like the url handlers for cleaning/accepting/get id from urls).
12+
*/
13+
private final StreamingService service;
1214

13-
public Extractor(UrlIdHandler urlIdHandler, int serviceId, String url) {
14-
this.urlIdHandler = urlIdHandler;
15-
this.serviceId = serviceId;
16-
this.url = url;
17-
this.previewInfoCollector = new StreamInfoItemCollector(serviceId);
15+
/**
16+
* Dirty/original url that was passed in the constructor.
17+
* <p>
18+
* What makes a url "dirty" or not is, for example, the additional parameters
19+
* (not important as—in this case—the id):
20+
* <pre>
21+
* https://www.youtube.com/watch?v=a9Zf_258aTI<i>&t=4s</i> → <i><b>&t=4s</b></i>
22+
* </pre>
23+
* But as you can imagine, the time parameter is very important when calling, for example, {@link org.schabi.newpipe.extractor.stream.StreamExtractor#getTimeStamp()}.
24+
*/
25+
private final String originalUrl;
26+
27+
/**
28+
* The cleaned url, result of passing the {@link #originalUrl} to the associated urlIdHandler ({@link #getUrlIdHandler()}).
29+
* <p>
30+
* Is lazily-cleaned by calling {@link #getCleanUrl()}
31+
*/
32+
private String cleanUrl;
33+
34+
public Extractor(StreamingService service, String url) throws ExtractionException {
35+
this.service = service;
36+
this.originalUrl = url;
1837
}
1938

20-
public String getUrl() {
21-
return url;
39+
/**
40+
* @return a {@link UrlIdHandler} of the current extractor type (e.g. a ChannelExtractor should return a channel url handler).
41+
*/
42+
protected abstract UrlIdHandler getUrlIdHandler() throws ParsingException;
43+
44+
/**
45+
* Fetch the current page.
46+
*/
47+
public abstract void fetchPage() throws IOException, ExtractionException;
48+
49+
public String getOriginalUrl() {
50+
return originalUrl;
2251
}
2352

24-
public UrlIdHandler getUrlIdHandler() {
25-
return urlIdHandler;
53+
public String getCleanUrl() {
54+
if (cleanUrl != null && !cleanUrl.isEmpty()) return cleanUrl;
55+
56+
try {
57+
cleanUrl = getUrlIdHandler().cleanUrl(originalUrl);
58+
} catch (Exception e) {
59+
cleanUrl = null;
60+
// Fallback to the original url
61+
return originalUrl;
62+
}
63+
return cleanUrl;
2664
}
2765

28-
public int getServiceId() {
29-
return serviceId;
66+
public StreamingService getService() {
67+
return service;
3068
}
3169

32-
protected StreamInfoItemCollector getStreamPreviewInfoCollector() {
33-
return previewInfoCollector;
70+
public int getServiceId() {
71+
return service.getServiceId();
3472
}
3573
}

src/main/java/org/schabi/newpipe/extractor/Info.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package org.schabi.newpipe.extractor;
22

33
import java.io.Serializable;
4+
import java.util.ArrayList;
45
import java.util.List;
5-
import java.util.Vector;
66

77
public abstract class Info implements Serializable {
88

@@ -15,5 +15,5 @@ public abstract class Info implements Serializable {
1515
public String url;
1616
public String name;
1717

18-
public List<Throwable> errors = new Vector<>();
18+
public List<Throwable> errors = new ArrayList<>();
1919
}

src/main/java/org/schabi/newpipe/extractor/InfoItemCollector.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
44

5+
import java.util.ArrayList;
56
import java.util.List;
6-
import java.util.Vector;
77

88
/*
99
* Created by Christian Schabesberger on 12.02.17.
@@ -26,8 +26,8 @@
2626
*/
2727

2828
public abstract class InfoItemCollector {
29-
private List<InfoItem> itemList = new Vector<>();
30-
private List<Throwable> errors = new Vector<>();
29+
private List<InfoItem> itemList = new ArrayList<>();
30+
private List<Throwable> errors = new ArrayList<>();
3131
private int serviceId = -1;
3232

3333
public InfoItemCollector(int serviceId) {
@@ -46,7 +46,7 @@ protected void addFromCollector(InfoItemCollector otherC) throws ExtractionExcep
4646
if (serviceId != otherC.serviceId) {
4747
throw new ExtractionException("Service Id does not equal: "
4848
+ NewPipe.getNameOfService(serviceId)
49-
+ " and " + NewPipe.getNameOfService(otherC.serviceId));
49+
+ " and " + NewPipe.getNameOfService((otherC.serviceId)));
5050
}
5151
errors.addAll(otherC.errors);
5252
itemList.addAll(otherC.itemList);

src/main/java/org/schabi/newpipe/extractor/ListExtractor.java

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,47 @@
44
import org.schabi.newpipe.extractor.stream.StreamInfoItemCollector;
55

66
import java.io.IOException;
7+
import java.util.List;
78

89
/**
910
* Base class to extractors that have a list (e.g. playlists, channels).
1011
*/
1112
public abstract class ListExtractor extends Extractor {
1213
protected String nextStreamsUrl;
1314

14-
public ListExtractor(UrlIdHandler urlIdHandler, int serviceId, String url) {
15-
super(urlIdHandler, serviceId, url);
15+
/**
16+
* Get a new ListExtractor with the given nextStreamsUrl set.
17+
* <p>
18+
* The extractor <b>WILL</b> fetch the page if {@link #fetchPageUponCreation()} return true, otherwise, it will <b>NOT</b>.
19+
* <p>
20+
* You can call {@link #fetchPage()} later, but this is mainly used just to get more items, so we don't waste bandwidth
21+
* downloading the whole page, but if the service that is being implemented need it, just do its own logic in {@link #fetchPageUponCreation()}.
22+
*/
23+
public ListExtractor(StreamingService service, String url, String nextStreamsUrl) throws IOException, ExtractionException {
24+
super(service, url);
25+
setNextStreamsUrl(nextStreamsUrl);
26+
27+
if (fetchPageUponCreation()) {
28+
fetchPage();
29+
}
1630
}
1731

18-
public boolean hasMoreStreams(){
19-
return nextStreamsUrl != null && !nextStreamsUrl.isEmpty();
32+
/**
33+
* Decide if the page will be fetched upon creation.
34+
* <p>
35+
* The default implementation checks if the nextStreamsUrl is null or empty (indication that the caller
36+
* don't need or know what is the next page, thus, fetch the page).
37+
*/
38+
protected boolean fetchPageUponCreation() {
39+
return nextStreamsUrl == null || nextStreamsUrl.isEmpty();
2040
}
2141

22-
public abstract StreamInfoItemCollector getNextStreams() throws ExtractionException, IOException;
42+
public abstract StreamInfoItemCollector getStreams() throws IOException, ExtractionException;
43+
public abstract NextItemsResult getNextStreams() throws IOException, ExtractionException;
44+
45+
public boolean hasMoreStreams() {
46+
return nextStreamsUrl != null && !nextStreamsUrl.isEmpty();
47+
}
2348

2449
public String getNextStreamsUrl() {
2550
return nextStreamsUrl;
@@ -29,4 +54,29 @@ public void setNextStreamsUrl(String nextStreamsUrl) {
2954
this.nextStreamsUrl = nextStreamsUrl;
3055
}
3156

57+
/*//////////////////////////////////////////////////////////////////////////
58+
// Inner
59+
//////////////////////////////////////////////////////////////////////////*/
60+
61+
public static class NextItemsResult {
62+
/**
63+
* The current list of items to this result
64+
*/
65+
public final List<InfoItem> nextItemsList;
66+
67+
/**
68+
* Next url to fetch more items
69+
*/
70+
public final String nextItemsUrl;
71+
72+
public NextItemsResult(List<InfoItem> nextItemsList, String nextItemsUrl) {
73+
this.nextItemsList = nextItemsList;
74+
this.nextItemsUrl = nextItemsUrl;
75+
}
76+
77+
public boolean hasMoreStreams() {
78+
return nextItemsUrl != null && !nextItemsUrl.isEmpty();
79+
}
80+
}
81+
3282
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package org.schabi.newpipe.extractor;
2+
3+
import java.util.List;
4+
5+
public abstract class ListInfo extends Info {
6+
public List<InfoItem> related_streams;
7+
public boolean has_more_streams;
8+
public String next_streams_url;
9+
}
Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package org.schabi.newpipe.extractor;
22

3-
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
4-
53
/*
64
* Created by Christian Schabesberger on 23.08.15.
75
*
@@ -22,70 +20,83 @@
2220
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
2321
*/
2422

23+
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
24+
2525
/**
26-
* Provides access to the video streaming services supported by NewPipe.
27-
* Currently only Youtube until the API becomes more stable.
26+
* Provides access to streaming services supported by NewPipe.
2827
*/
29-
30-
@SuppressWarnings("ALL")
3128
public class NewPipe {
3229
private static final String TAG = NewPipe.class.toString();
30+
private static Downloader downloader = null;
3331

3432
private NewPipe() {
3533
}
3634

37-
private static Downloader downloader = null;
35+
public static void init(Downloader d) {
36+
downloader = d;
37+
}
38+
39+
public static Downloader getDownloader() {
40+
return downloader;
41+
}
42+
43+
/*//////////////////////////////////////////////////////////////////////////
44+
// Utils
45+
//////////////////////////////////////////////////////////////////////////*/
3846

3947
public static StreamingService[] getServices() {
40-
return ServiceList.serviceList;
48+
final ServiceList[] values = ServiceList.values();
49+
final StreamingService[] streamingServices = new StreamingService[values.length];
50+
51+
for (int i = 0; i < values.length; i++) streamingServices[i] = values[i].getService();
52+
53+
return streamingServices;
4154
}
4255

4356
public static StreamingService getService(int serviceId) throws ExtractionException {
44-
for (StreamingService s : ServiceList.serviceList) {
45-
if (s.getServiceId() == serviceId) {
46-
return s;
57+
for (ServiceList item : ServiceList.values()) {
58+
if (item.getService().getServiceId() == serviceId) {
59+
return item.getService();
4760
}
4861
}
49-
return null;
62+
throw new ExtractionException("There's no service with the id = \"" + serviceId + "\"");
5063
}
5164

5265
public static StreamingService getService(String serviceName) throws ExtractionException {
53-
return ServiceList.serviceList[getIdOfService(serviceName)];
54-
}
55-
56-
public static String getNameOfService(int id) {
57-
try {
58-
return getService(id).getServiceInfo().name;
59-
} catch (Exception e) {
60-
System.err.println("Service id not known");
61-
e.printStackTrace();
62-
return "";
66+
for (ServiceList item : ServiceList.values()) {
67+
if (item.getService().getServiceInfo().name.equals(serviceName)) {
68+
return item.getService();
69+
}
6370
}
71+
throw new ExtractionException("There's no service with the name = \"" + serviceName + "\"");
6472
}
6573

66-
public static int getIdOfService(String serviceName) {
67-
for (int i = 0; i < ServiceList.serviceList.length; i++) {
68-
if (ServiceList.serviceList[i].getServiceInfo().name.equals(serviceName)) {
69-
return i;
74+
public static StreamingService getServiceByUrl(String url) throws ExtractionException {
75+
for (ServiceList item : ServiceList.values()) {
76+
if (item.getService().getLinkTypeByUrl(url) != StreamingService.LinkType.NONE) {
77+
return item.getService();
7078
}
7179
}
72-
return -1;
80+
throw new ExtractionException("No service can handle the url = \"" + url + "\"");
7381
}
7482

75-
public static void init(Downloader d) {
76-
downloader = d;
77-
}
78-
79-
public static Downloader getDownloader() {
80-
return downloader;
83+
public static int getIdOfService(String serviceName) {
84+
try {
85+
//noinspection ConstantConditions
86+
return getService(serviceName).getServiceId();
87+
} catch (ExtractionException ignored) {
88+
return -1;
89+
}
8190
}
8291

83-
public static StreamingService getServiceByUrl(String url) {
84-
for (StreamingService s : ServiceList.serviceList) {
85-
if (s.getLinkTypeByUrl(url) != StreamingService.LinkType.NONE) {
86-
return s;
87-
}
92+
public static String getNameOfService(int id) {
93+
try {
94+
//noinspection ConstantConditions
95+
return getService(id).getServiceInfo().name;
96+
} catch (Exception e) {
97+
System.err.println("Service id not known");
98+
e.printStackTrace();
99+
return "<unknown>";
88100
}
89-
return null;
90101
}
91102
}

0 commit comments

Comments
 (0)