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 index 24dd20ba3..d3ed918a8 100644 --- 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 @@ -14,18 +14,14 @@ import org.schabi.newpipe.extractor.linkhandler.SearchQueryHandler; import org.schabi.newpipe.extractor.linkhandler.SearchQueryHandlerFactory; import org.schabi.newpipe.extractor.playlist.PlaylistExtractor; import org.schabi.newpipe.extractor.search.SearchExtractor; -import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCConferenceExtractor; -import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCConferenceKiosk; -import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCSearchExtractor; -import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCStreamExtractor; -import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.MediaCCCConferenceLinkHandlerFactory; -import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.MediaCCCConferencesListLinkHandlerFactory; -import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.MediaCCCSearchQueryHandlerFactory; -import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.MediaCCCStreamLinkHandlerFactory; +import org.schabi.newpipe.extractor.services.media_ccc.extractors.*; +import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.*; import org.schabi.newpipe.extractor.stream.StreamExtractor; import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor; import org.schabi.newpipe.extractor.suggestion.SuggestionExtractor; +import java.io.IOException; + import static java.util.Arrays.asList; import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.AUDIO; import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.VIDEO; @@ -95,7 +91,18 @@ public class MediaCCCService extends StreamingService { new MediaCCCConferencesListLinkHandlerFactory().fromUrl(url), kioskId); } }, new MediaCCCConferencesListLinkHandlerFactory(), "conferences"); - list.setDefaultKiosk("conferences"); + + list.addKioskEntry(new KioskList.KioskExtractorFactory() { + @Override + public KioskExtractor createNewKiosk(final StreamingService streamingService, + final String url, final String kioskId) + throws ExtractionException { + return new MediaCCCRecentKiosk(MediaCCCService.this, + new MediaCCCRecentListLinkHandlerFactory().fromUrl(url), kioskId); + } + }, new MediaCCCRecentListLinkHandlerFactory(), "recent"); + + list.setDefaultKiosk("recent"); } catch (Exception e) { throw new ExtractionException(e); } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCRecentKiosk.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCRecentKiosk.java new file mode 100644 index 000000000..2656f7d64 --- /dev/null +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCRecentKiosk.java @@ -0,0 +1,60 @@ +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.Page; +import org.schabi.newpipe.extractor.StreamingService; +import org.schabi.newpipe.extractor.downloader.Downloader; +import org.schabi.newpipe.extractor.exceptions.ExtractionException; +import org.schabi.newpipe.extractor.exceptions.ParsingException; +import org.schabi.newpipe.extractor.kiosk.KioskExtractor; +import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; +import org.schabi.newpipe.extractor.stream.StreamInfoItem; +import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; + +import javax.annotation.Nonnull; +import java.io.IOException; + +public class MediaCCCRecentKiosk extends KioskExtractor { + + private JsonObject doc; + + public MediaCCCRecentKiosk(StreamingService streamingService, ListLinkHandler linkHandler, String kioskId) { + super(streamingService, linkHandler, kioskId); + } + + @Override + public void onFetchPage(@Nonnull Downloader downloader) throws IOException, ExtractionException { + final String site = downloader.get("https://api.media.ccc.de/public/events/recent", + getExtractorLocalization()).responseBody(); + try { + doc = JsonParser.object().from(site); + } catch (JsonParserException jpe) { + throw new ExtractionException("Could not parse json.", jpe); + } + } + + @Nonnull + @Override + public InfoItemsPage getInitialPage() throws IOException, ExtractionException { + final JsonArray events = doc.getArray("events"); + StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId()); + for (int i = 0; i < events.size(); i++) { + collector.commit(new MediaCCCRecentKioskExtractor(events.getObject(i))); + } + return new InfoItemsPage<>(collector, null); + } + + @Override + public InfoItemsPage getPage(Page page) throws IOException, ExtractionException { + return InfoItemsPage.emptyPage(); + } + + @Nonnull + @Override + public String getName() throws ParsingException { + return "recent"; + } +} diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCRecentKioskExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCRecentKioskExtractor.java new file mode 100644 index 000000000..77c7b1df7 --- /dev/null +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCRecentKioskExtractor.java @@ -0,0 +1,79 @@ +package org.schabi.newpipe.extractor.services.media_ccc.extractors; + +import com.grack.nanojson.JsonObject; +import org.schabi.newpipe.extractor.exceptions.ParsingException; +import org.schabi.newpipe.extractor.localization.DateWrapper; +import org.schabi.newpipe.extractor.stream.StreamInfoItemExtractor; +import org.schabi.newpipe.extractor.stream.StreamType; + +import javax.annotation.Nullable; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; + +public class MediaCCCRecentKioskExtractor implements StreamInfoItemExtractor { + + private final JsonObject event; + + public MediaCCCRecentKioskExtractor(final JsonObject event) { + this.event = event; + } + + @Override + public String getName() throws ParsingException { + return event.getString("title"); + } + + @Override + public String getUrl() throws ParsingException { + return event.getString("frontend_link"); + } + + @Override + public String getThumbnailUrl() throws ParsingException { + return event.getString("thumb_url"); + } + + @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("duration"); + } + + @Override + public long getViewCount() throws ParsingException { + return event.getInt("view_count"); + } + + @Override + public String getUploaderName() throws ParsingException { + return ""; + } + + @Override + public String getUploaderUrl() throws ParsingException { + return event.getString("conference_url"); + } + + @Nullable + @Override + public String getTextualUploadDate() throws ParsingException { + return event.getString("date"); + } + + @Nullable + @Override + public DateWrapper getUploadDate() throws ParsingException { + final ZonedDateTime zonedDateTime = ZonedDateTime.parse(event.getString("date"), + DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSzzzz")); + return new DateWrapper(zonedDateTime.toOffsetDateTime(), false); + } +} diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/infoItems/MediaCCCConferenceInfoItemExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/infoItems/MediaCCCConferenceInfoItemExtractor.java index cea663edb..3ced44d9a 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/infoItems/MediaCCCConferenceInfoItemExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/infoItems/MediaCCCConferenceInfoItemExtractor.java @@ -7,7 +7,7 @@ import org.schabi.newpipe.extractor.channel.ChannelInfoItemExtractor; import org.schabi.newpipe.extractor.exceptions.ParsingException; public class MediaCCCConferenceInfoItemExtractor implements ChannelInfoItemExtractor { - private JsonObject conference; + private final JsonObject conference; public MediaCCCConferenceInfoItemExtractor(final JsonObject conference) { this.conference = conference; diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/linkHandler/MediaCCCRecentListLinkHandlerFactory.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/linkHandler/MediaCCCRecentListLinkHandlerFactory.java new file mode 100644 index 000000000..8f9408ad9 --- /dev/null +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/linkHandler/MediaCCCRecentListLinkHandlerFactory.java @@ -0,0 +1,24 @@ +package org.schabi.newpipe.extractor.services.media_ccc.linkHandler; + +import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory; + +import java.util.List; +import java.util.regex.Pattern; + +public class MediaCCCRecentListLinkHandlerFactory extends ListLinkHandlerFactory { + @Override + public String getId(String url) { + return "recent"; + } + + @Override + public boolean onAcceptUrl(String url) { + final String pattern = "^(https?://)?media.ccc.de/recent/?$"; + return Pattern.matches(pattern, url); + } + + @Override + public String getUrl(String id, List contentFilter, String sortFilter) { + return "https://media.ccc.de/recent"; + } +}