diff --git a/extractor/.attach_pid31246 b/extractor/.attach_pid31246 new file mode 100644 index 000000000..e69de29bb diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/ServiceList.java b/extractor/src/main/java/org/schabi/newpipe/extractor/ServiceList.java index 36690438f..a171db71d 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/ServiceList.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/ServiceList.java @@ -1,5 +1,6 @@ package org.schabi.newpipe.extractor; +import org.schabi.newpipe.extractor.services.media_ccc.MediaCCCService; import org.schabi.newpipe.extractor.services.soundcloud.SoundcloudService; import org.schabi.newpipe.extractor.services.youtube.YoutubeService; @@ -36,6 +37,7 @@ public final class ServiceList { public static final YoutubeService YouTube; public static final SoundcloudService SoundCloud; + public static final MediaCCCService MediaCCC; /** * When creating a new service, put this service in the end of this list, @@ -44,7 +46,8 @@ public final class ServiceList { private static final List SERVICES = unmodifiableList( asList( YouTube = new YoutubeService(0), - SoundCloud = new SoundcloudService(1) + SoundCloud = new SoundcloudService(1), + MediaCCC = new MediaCCCService(2) )); /** diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCService.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCService.java new file mode 100644 index 000000000..1a78110b5 --- /dev/null +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCService.java @@ -0,0 +1,88 @@ +package org.schabi.newpipe.extractor.services.media_ccc; + +import org.schabi.newpipe.extractor.StreamingService; +import org.schabi.newpipe.extractor.SuggestionExtractor; +import org.schabi.newpipe.extractor.channel.ChannelExtractor; +import org.schabi.newpipe.extractor.exceptions.ExtractionException; +import org.schabi.newpipe.extractor.kiosk.KioskList; +import org.schabi.newpipe.extractor.linkhandler.*; +import org.schabi.newpipe.extractor.playlist.PlaylistExtractor; +import org.schabi.newpipe.extractor.search.SearchExtractor; +import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCSearchExtractor; +import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.MediaCCCSearchQueryHandlerFactory; +import org.schabi.newpipe.extractor.stream.StreamExtractor; +import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor; +import org.schabi.newpipe.extractor.utils.Localization; + +import static java.util.Arrays.asList; +import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.*; + +public class MediaCCCService extends StreamingService { + public MediaCCCService(int id) { + super(id, "Media.CCC", asList(AUDIO, VIDEO)); + } + + @Override + public SearchExtractor getSearchExtractor(SearchQueryHandler query, Localization localization) { + return new MediaCCCSearchExtractor(this, query, localization); + } + + @Override + public LinkHandlerFactory getStreamLHFactory() { + return null; + } + + @Override + public ListLinkHandlerFactory getChannelLHFactory() { + return null; + } + + @Override + public ListLinkHandlerFactory getPlaylistLHFactory() { + return null; + } + + @Override + public SearchQueryHandlerFactory getSearchQHFactory() { + return new MediaCCCSearchQueryHandlerFactory(); + } + + @Override + public StreamExtractor getStreamExtractor(LinkHandler linkHandler, Localization localization) { + return null; + } + + @Override + public ChannelExtractor getChannelExtractor(ListLinkHandler linkHandler, Localization localization) { + return null; + } + + @Override + public PlaylistExtractor getPlaylistExtractor(ListLinkHandler linkHandler, Localization localization) { + return null; + } + + @Override + public SuggestionExtractor getSuggestionExtractor(Localization localization) { + return null; + } + + @Override + public KioskList getKioskList() throws ExtractionException { + KioskList list = new KioskList(getServiceId()); + + // add kiosks here e.g.: + try { + // Add kiosk here + } catch (Exception e) { + throw new ExtractionException(e); + } + + return list; + } + + @Override + public SubscriptionExtractor getSubscriptionExtractor() { + return null; + } +} diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCSearchExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCSearchExtractor.java new file mode 100644 index 000000000..2eb0dee7f --- /dev/null +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCSearchExtractor.java @@ -0,0 +1,67 @@ +package org.schabi.newpipe.extractor.services.media_ccc.extractors; + +import com.grack.nanojson.JsonArray; +import com.grack.nanojson.JsonObject; +import com.grack.nanojson.JsonParser; +import com.grack.nanojson.JsonParserException; +import org.schabi.newpipe.extractor.Downloader; +import org.schabi.newpipe.extractor.InfoItem; +import org.schabi.newpipe.extractor.InfoItemsCollector; +import org.schabi.newpipe.extractor.StreamingService; +import org.schabi.newpipe.extractor.exceptions.ExtractionException; +import org.schabi.newpipe.extractor.exceptions.ParsingException; +import org.schabi.newpipe.extractor.linkhandler.SearchQueryHandler; +import org.schabi.newpipe.extractor.search.SearchExtractor; +import org.schabi.newpipe.extractor.services.media_ccc.extractors.infoItems.MediaCCCStreamInfoItemExtractor; +import org.schabi.newpipe.extractor.utils.Localization; + +import javax.annotation.Nonnull; +import java.io.IOException; + +public class MediaCCCSearchExtractor extends SearchExtractor { + + JsonObject doc; + + public MediaCCCSearchExtractor(StreamingService service, SearchQueryHandler linkHandler, Localization localization) { + super(service, linkHandler, localization); + } + + @Override + public String getSearchSuggestion() throws ParsingException { + return null; + } + + @Nonnull + @Override + public InfoItemsPage getInitialPage() throws IOException, ExtractionException { + InfoItemsCollector searchItems = getInfoItemSearchCollector(); + JsonArray events = doc.getArray("events"); + for(int i = 0; i < events.size(); i++) { + searchItems.commit(new MediaCCCStreamInfoItemExtractor( + events.getObject(i))); + } + return new InfoItemsPage<>(searchItems, null); + } + + @Override + public String getNextPageUrl() throws IOException, ExtractionException { + return null; + } + + @Override + public InfoItemsPage getPage(String pageUrl) throws IOException, ExtractionException { + return null; + } + + @Override + public void onFetchPage(@Nonnull Downloader downloader) throws IOException, ExtractionException { + final String site; + final String url = getUrl(); + site = downloader.download(url, getLocalization()); + try { + doc = JsonParser.object().from(site); + } catch (JsonParserException jpe) { + throw new ExtractionException("Could not parse json.", jpe); + } + } +} diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/infoItems/MediaCCCStreamInfoItemExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/infoItems/MediaCCCStreamInfoItemExtractor.java new file mode 100644 index 000000000..adb57e886 --- /dev/null +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/infoItems/MediaCCCStreamInfoItemExtractor.java @@ -0,0 +1,67 @@ +package org.schabi.newpipe.extractor.services.media_ccc.extractors.infoItems; + +import com.grack.nanojson.JsonObject; +import org.schabi.newpipe.extractor.exceptions.ParsingException; +import org.schabi.newpipe.extractor.stream.StreamInfoItemExtractor; +import org.schabi.newpipe.extractor.stream.StreamType; + +public class MediaCCCStreamInfoItemExtractor implements StreamInfoItemExtractor { + + JsonObject event; + + public MediaCCCStreamInfoItemExtractor(JsonObject event) { + this.event = event; + } + + @Override + public StreamType getStreamType() throws ParsingException { + return StreamType.VIDEO_STREAM; + } + + @Override + public boolean isAd() throws ParsingException { + return false; + } + + @Override + public long getDuration() throws ParsingException { + return event.getInt("length"); + } + + @Override + public long getViewCount() throws ParsingException { + return event.getInt("view_count"); + } + + @Override + public String getUploaderName() throws ParsingException { + return event.getString("conference_url") + .replace("https://api.media.ccc.de/public/conferences/", ""); + } + + @Override + public String getUploaderUrl() throws ParsingException { + return event.getString("conference_url"); + } + + @Override + public String getUploadDate() throws ParsingException { + return event.getString("release_date"); + } + + @Override + public String getName() throws ParsingException { + return event.getString("title"); + } + + @Override + public String getUrl() throws ParsingException { + return "https://api.media.ccc.de/public/events/" + + event.getString("guid"); + } + + @Override + public String getThumbnailUrl() throws ParsingException { + return event.getString("thumbnails_url"); + } +} diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/linkHandler/MediaCCCSearchQueryHandlerFactory.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/linkHandler/MediaCCCSearchQueryHandlerFactory.java new file mode 100644 index 000000000..f94c253e3 --- /dev/null +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/linkHandler/MediaCCCSearchQueryHandlerFactory.java @@ -0,0 +1,30 @@ +package org.schabi.newpipe.extractor.services.media_ccc.linkHandler; + +import org.schabi.newpipe.extractor.exceptions.ParsingException; +import org.schabi.newpipe.extractor.linkhandler.SearchQueryHandlerFactory; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.List; + +public class MediaCCCSearchQueryHandlerFactory extends SearchQueryHandlerFactory { + + @Override + public String[] getAvailableContentFilter() { + return null; + } + + @Override + public String[] getAvailableSortFilter() { + return null; + } + + @Override + public String getUrl(String querry, List contentFilter, String sortFilter) throws ParsingException { + try { + return "https://api.media.ccc.de/public/events/search?q=" + URLEncoder.encode(querry, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new ParsingException("Could not create search string with querry: " + querry, e); + } + } +} diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCSearchExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCSearchExtractorTest.java new file mode 100644 index 000000000..c88c0bca5 --- /dev/null +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCSearchExtractorTest.java @@ -0,0 +1,36 @@ +package org.schabi.newpipe.extractor.services.media_ccc; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.schabi.newpipe.Downloader; +import org.schabi.newpipe.extractor.InfoItem; +import org.schabi.newpipe.extractor.ListExtractor; +import org.schabi.newpipe.extractor.NewPipe; +import org.schabi.newpipe.extractor.search.SearchExtractor; +import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCSearchExtractor; +import org.schabi.newpipe.extractor.utils.Localization; + +import static junit.framework.TestCase.assertTrue; +import static org.schabi.newpipe.extractor.ServiceList.MediaCCC; + +/** + * Test for {@link MediaCCCSearchExtractor} + */ +public class MediaCCCSearchExtractorTest { + private static SearchExtractor extractor; + private static ListExtractor.InfoItemsPage itemsPage; + + @BeforeClass + public static void setUpClass() throws Exception { + NewPipe.init(Downloader.getInstance(), new Localization("GB", "en")); + extractor = MediaCCC.getSearchExtractor("source"); + extractor.fetchPage(); + itemsPage = extractor.getInitialPage(); + } + + @Test + public void testCount() throws Exception { + assertTrue(Integer.toString(itemsPage.getItems().size()), + itemsPage.getItems().size() >= 25); + } +}