diff options
author | ByteHamster <info@bytehamster.com> | 2021-08-28 00:12:48 +0200 |
---|---|---|
committer | ByteHamster <info@bytehamster.com> | 2021-08-28 09:57:41 +0200 |
commit | 24389d42e89037b205fff2bc681e4ad998895286 (patch) | |
tree | 1c3d979e043510431d54bd9ff0fab86ac7159737 /core | |
parent | 85c8a419acb385cdf249662866715965de219c93 (diff) | |
download | AntennaPod-24389d42e89037b205fff2bc681e4ad998895286.zip |
Moved feed parser to its own module
Diffstat (limited to 'core')
44 files changed, 57 insertions, 2219 deletions
diff --git a/core/build.gradle b/core/build.gradle index e78b70881..2190ad35f 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -24,6 +24,7 @@ dependencies { implementation project(':net:ssl') implementation project(':net:sync:gpoddernet') implementation project(':net:sync:model') + implementation project(':parser:feed') implementation project(':ui:app-start-intent') implementation project(':ui:common') implementation project(':ui:png-icons') diff --git a/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlWriter.java b/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlWriter.java index e2205471c..a44d90557 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlWriter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlWriter.java @@ -4,6 +4,7 @@ import android.content.Context; import android.util.Log; import android.util.Xml; +import de.danoeh.antennapod.core.util.DateFormatter; import org.xmlpull.v1.XmlSerializer; import java.io.IOException; @@ -13,7 +14,6 @@ import java.util.List; import de.danoeh.antennapod.core.export.ExportWriter; import de.danoeh.antennapod.model.feed.Feed; -import de.danoeh.antennapod.core.util.DateUtils; /** Writes OPML documents. */ public class OpmlWriter implements ExportWriter { @@ -44,7 +44,7 @@ public class OpmlWriter implements ExportWriter { xs.text(OPML_TITLE); xs.endTag(null, OpmlSymbols.TITLE); xs.startTag(null, OpmlSymbols.DATE_CREATED); - xs.text(DateUtils.formatRFC822Date(new Date())); + xs.text(DateFormatter.formatRfc822Date(new Date())); xs.endTag(null, OpmlSymbols.DATE_CREATED); xs.endTag(null, OpmlSymbols.HEAD); diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java b/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java index 7a8c4969b..82583b7b5 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java +++ b/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java @@ -27,7 +27,7 @@ import de.danoeh.antennapod.core.service.download.DownloadStatus; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBWriter; -import de.danoeh.antennapod.core.util.DateUtils; +import de.danoeh.antennapod.parser.feed.util.DateUtils; import de.danoeh.antennapod.core.util.DownloadError; import de.danoeh.antennapod.model.feed.Feed; import de.danoeh.antennapod.model.feed.FeedItem; diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/SimpleChapter.java b/core/src/main/java/de/danoeh/antennapod/core/feed/SimpleChapter.java deleted file mode 100644 index ca59f867b..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/SimpleChapter.java +++ /dev/null @@ -1,16 +0,0 @@ -package de.danoeh.antennapod.core.feed; - -import de.danoeh.antennapod.model.feed.Chapter; - -public class SimpleChapter extends Chapter { - public static final int CHAPTERTYPE_SIMPLECHAPTER = 0; - - public SimpleChapter(long start, String title, String link, String imageUrl) { - super(start, title, link, imageUrl); - } - - @Override - public int getChapterType() { - return CHAPTERTYPE_SIMPLECHAPTER; - } -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java index 1320b7052..781110f82 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java @@ -24,7 +24,7 @@ import java.util.regex.Pattern; import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.model.feed.FeedMedia; -import de.danoeh.antennapod.core.util.DateUtils; +import de.danoeh.antennapod.parser.feed.util.DateUtils; import de.danoeh.antennapod.core.util.DownloadError; import de.danoeh.antennapod.core.util.StorageUtils; import de.danoeh.antennapod.core.util.URIUtil; diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedParserTask.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedParserTask.java index 3e3da00e7..9a0916109 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedParserTask.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedParserTask.java @@ -8,9 +8,9 @@ import de.danoeh.antennapod.model.feed.VolumeAdaptionSetting; import de.danoeh.antennapod.core.service.download.DownloadRequest; import de.danoeh.antennapod.core.service.download.DownloadStatus; import de.danoeh.antennapod.core.storage.DownloadRequester; -import de.danoeh.antennapod.core.syndication.handler.FeedHandler; -import de.danoeh.antennapod.core.syndication.handler.FeedHandlerResult; -import de.danoeh.antennapod.core.syndication.handler.UnsupportedFeedtypeException; +import de.danoeh.antennapod.parser.feed.FeedHandler; +import de.danoeh.antennapod.parser.feed.FeedHandlerResult; +import de.danoeh.antennapod.parser.feed.UnsupportedFeedtypeException; import de.danoeh.antennapod.core.util.DownloadError; import de.danoeh.antennapod.core.util.InvalidFeedException; import org.xml.sax.SAXException; diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedSyncTask.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedSyncTask.java index 1ca4d1194..dcc1c8fdb 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedSyncTask.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedSyncTask.java @@ -9,7 +9,7 @@ import de.danoeh.antennapod.core.service.download.DownloadStatus; import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DownloadRequestException; import de.danoeh.antennapod.core.storage.DownloadRequester; -import de.danoeh.antennapod.core.syndication.handler.FeedHandlerResult; +import de.danoeh.antennapod.parser.feed.FeedHandlerResult; public class FeedSyncTask { private static final String TAG = "FeedParserTask"; diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/mapper/ChapterCursorMapper.java b/core/src/main/java/de/danoeh/antennapod/core/storage/mapper/ChapterCursorMapper.java index b171f2bcc..61613a25a 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/mapper/ChapterCursorMapper.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/mapper/ChapterCursorMapper.java @@ -4,7 +4,7 @@ import android.database.Cursor; import androidx.annotation.NonNull; import de.danoeh.antennapod.model.feed.Chapter; import de.danoeh.antennapod.core.feed.ID3Chapter; -import de.danoeh.antennapod.core.feed.SimpleChapter; +import de.danoeh.antennapod.parser.feed.element.SimpleChapter; import de.danoeh.antennapod.core.feed.VorbisCommentChapter; import de.danoeh.antennapod.core.storage.PodDBAdapter; diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/FeedHandler.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/FeedHandler.java deleted file mode 100644 index 2928ba836..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/FeedHandler.java +++ /dev/null @@ -1,90 +0,0 @@ -package de.danoeh.antennapod.core.syndication.handler; - -import android.text.TextUtils; -import android.util.Log; - -import org.apache.commons.io.input.XmlStreamReader; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; - -import java.io.File; -import java.io.IOException; -import java.io.Reader; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -import de.danoeh.antennapod.model.feed.Feed; -import de.danoeh.antennapod.model.feed.FeedItem; - -public class FeedHandler { - private static final String TAG = "FeedHandler"; - - public FeedHandlerResult parseFeed(Feed feed) throws SAXException, IOException, - ParserConfigurationException, UnsupportedFeedtypeException { - TypeGetter tg = new TypeGetter(); - TypeGetter.Type type = tg.getType(feed); - SyndHandler handler = new SyndHandler(feed, type); - - SAXParserFactory factory = SAXParserFactory.newInstance(); - factory.setNamespaceAware(true); - SAXParser saxParser = factory.newSAXParser(); - File file = new File(feed.getFile_url()); - Reader inputStreamReader = new XmlStreamReader(file); - InputSource inputSource = new InputSource(inputStreamReader); - - saxParser.parse(inputSource, handler); - inputStreamReader.close(); - feed.setItems(dedupItems(feed.getItems())); - return new FeedHandlerResult(handler.state.feed, handler.state.alternateUrls); - } - - /** - * For updating items that are stored in the database, see also: DBTasks.searchFeedItemByIdentifyingValue - */ - public static List<FeedItem> dedupItems(List<FeedItem> items) { - if (items == null) { - return null; - } - List<FeedItem> list = new ArrayList<>(items); - Set<String> seen = new HashSet<>(); - Iterator<FeedItem> it = list.iterator(); - while (it.hasNext()) { - FeedItem item = it.next(); - if (!TextUtils.isEmpty(item.getItemIdentifier()) && seen.contains(item.getItemIdentifier())) { - Log.d(TAG, "Removing duplicate episode guid " + item.getItemIdentifier()); - it.remove(); - continue; - } - - if (item.getMedia() == null || TextUtils.isEmpty(item.getMedia().getStreamUrl())) { - continue; - } - if (seen.contains(item.getMedia().getStreamUrl())) { - Log.d(TAG, "Removing duplicate episode stream url " + item.getMedia().getStreamUrl()); - it.remove(); - } else { - seen.add(item.getMedia().getStreamUrl()); - if (TextUtils.isEmpty(item.getTitle()) || item.getPubDate() == null) { - continue; - } - if (!seen.contains(item.getTitle() + item.getPubDate().toString())) { - seen.add(item.getTitle() + item.getPubDate().toString()); - } else { - Log.d(TAG, "Removing duplicate episode title and pubDate " - + item.getTitle() - + " " + item.getPubDate()); - it.remove(); - } - } - seen.add(item.getItemIdentifier()); - } - return list; - } -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/FeedHandlerResult.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/FeedHandlerResult.java deleted file mode 100644 index fb4bf4707..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/FeedHandlerResult.java +++ /dev/null @@ -1,19 +0,0 @@ -package de.danoeh.antennapod.core.syndication.handler; - -import java.util.Map; - -import de.danoeh.antennapod.model.feed.Feed; - -/** - * Container for results returned by the Feed parser - */ -public class FeedHandlerResult { - - public final Feed feed; - public final Map<String, String> alternateFeedUrls; - - public FeedHandlerResult(Feed feed, Map<String, String> alternateFeedUrls) { - this.feed = feed; - this.alternateFeedUrls = alternateFeedUrls; - } -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/HandlerState.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/HandlerState.java deleted file mode 100644 index 2fecb0536..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/HandlerState.java +++ /dev/null @@ -1,121 +0,0 @@ -package de.danoeh.antennapod.core.syndication.handler; - -import androidx.collection.ArrayMap; - -import java.util.ArrayList; -import java.util.Map; -import java.util.Stack; - -import de.danoeh.antennapod.model.feed.Feed; -import de.danoeh.antennapod.model.feed.FeedFunding; -import de.danoeh.antennapod.model.feed.FeedItem; -import de.danoeh.antennapod.core.syndication.namespace.Namespace; -import de.danoeh.antennapod.core.syndication.namespace.SyndElement; - -/** - * Contains all relevant information to describe the current state of a - * SyndHandler. - */ -public class HandlerState { - - /** - * Feed that the Handler is currently processing. - */ - Feed feed; - /** - * Contains links to related feeds, e.g. feeds with enclosures in other formats. The key of the map is the - * URL of the feed, the value is the title - */ - final Map<String, String> alternateUrls; - private final ArrayList<FeedItem> items; - private FeedItem currentItem; - private FeedFunding currentFunding; - final Stack<SyndElement> tagstack; - /** - * Namespaces that have been defined so far. - */ - final Map<String, Namespace> namespaces; - final Stack<Namespace> defaultNamespaces; - /** - * Buffer for saving characters. - */ - protected StringBuilder contentBuf; - - /** - * Temporarily saved objects. - */ - private final Map<String, Object> tempObjects; - - public HandlerState(Feed feed) { - this.feed = feed; - alternateUrls = new ArrayMap<>(); - items = new ArrayList<>(); - tagstack = new Stack<>(); - namespaces = new ArrayMap<>(); - defaultNamespaces = new Stack<>(); - tempObjects = new ArrayMap<>(); - } - - public Feed getFeed() { - return feed; - } - - public ArrayList<FeedItem> getItems() { - return items; - } - - public FeedItem getCurrentItem() { - return currentItem; - } - - public Stack<SyndElement> getTagstack() { - return tagstack; - } - - public void setFeed(Feed feed) { - this.feed = feed; - } - - public void setCurrentItem(FeedItem currentItem) { - this.currentItem = currentItem; - } - - public FeedFunding getCurrentFunding() { - return currentFunding; - } - - public void setCurrentFunding(FeedFunding currentFunding) { - this.currentFunding = currentFunding; - } - - /** - * Returns the SyndElement that comes after the top element of the tagstack. - */ - public SyndElement getSecondTag() { - SyndElement top = tagstack.pop(); - SyndElement second = tagstack.peek(); - tagstack.push(top); - return second; - } - - public SyndElement getThirdTag() { - SyndElement top = tagstack.pop(); - SyndElement second = tagstack.pop(); - SyndElement third = tagstack.peek(); - tagstack.push(second); - tagstack.push(top); - return third; - } - - public StringBuilder getContentBuf() { - return contentBuf; - } - - public void addAlternateFeedUrl(String title, String url) { - alternateUrls.put(url, title); - } - - public Map<String, Object> getTempObjects() { - return tempObjects; - } -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/SyndHandler.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/SyndHandler.java deleted file mode 100644 index 9c09be714..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/SyndHandler.java +++ /dev/null @@ -1,138 +0,0 @@ -package de.danoeh.antennapod.core.syndication.handler; - -import android.util.Log; - -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -import de.danoeh.antennapod.model.feed.Feed; -import de.danoeh.antennapod.core.syndication.namespace.NSContent; -import de.danoeh.antennapod.core.syndication.namespace.NSDublinCore; -import de.danoeh.antennapod.core.syndication.namespace.NSITunes; -import de.danoeh.antennapod.core.syndication.namespace.NSMedia; -import de.danoeh.antennapod.core.syndication.namespace.NSRSS20; -import de.danoeh.antennapod.core.syndication.namespace.NSSimpleChapters; -import de.danoeh.antennapod.core.syndication.namespace.Namespace; -import de.danoeh.antennapod.core.syndication.namespace.PodcastIndex; -import de.danoeh.antennapod.core.syndication.namespace.SyndElement; -import de.danoeh.antennapod.core.syndication.namespace.atom.NSAtom; - -/** Superclass for all SAX Handlers which process Syndication formats */ -class SyndHandler extends DefaultHandler { - private static final String TAG = "SyndHandler"; - private static final String DEFAULT_PREFIX = ""; - final HandlerState state; - - public SyndHandler(Feed feed, TypeGetter.Type type) { - state = new HandlerState(feed); - if (type == TypeGetter.Type.RSS20 || type == TypeGetter.Type.RSS091) { - state.defaultNamespaces.push(new NSRSS20()); - } - } - - @Override - public void startElement(String uri, String localName, String qName, - Attributes attributes) throws SAXException { - state.contentBuf = new StringBuilder(); - Namespace handler = getHandlingNamespace(uri, qName); - if (handler != null) { - SyndElement element = handler.handleElementStart(localName, state, - attributes); - state.tagstack.push(element); - - } - } - - @Override - public void characters(char[] ch, int start, int length) - throws SAXException { - if (!state.tagstack.empty()) { - if (state.getTagstack().size() >= 2) { - if (state.contentBuf != null) { - state.contentBuf.append(ch, start, length); - } - } - } - } - - @Override - public void endElement(String uri, String localName, String qName) - throws SAXException { - Namespace handler = getHandlingNamespace(uri, qName); - if (handler != null) { - handler.handleElementEnd(localName, state); - state.tagstack.pop(); - - } - state.contentBuf = null; - - } - - @Override - public void endPrefixMapping(String prefix) throws SAXException { - if (state.defaultNamespaces.size() > 1 && prefix.equals(DEFAULT_PREFIX)) { - state.defaultNamespaces.pop(); - } - } - - @Override - public void startPrefixMapping(String prefix, String uri) - throws SAXException { - // Find the right namespace - if (!state.namespaces.containsKey(uri)) { - if (uri.equals(NSAtom.NSURI)) { - if (prefix.equals(DEFAULT_PREFIX)) { - state.defaultNamespaces.push(new NSAtom()); - } else if (prefix.equals(NSAtom.NSTAG)) { - state.namespaces.put(uri, new NSAtom()); - Log.d(TAG, "Recognized Atom namespace"); - } - } else if (uri.equals(NSContent.NSURI) - && prefix.equals(NSContent.NSTAG)) { - state.namespaces.put(uri, new NSContent()); - Log.d(TAG, "Recognized Content namespace"); - } else if (uri.equals(NSITunes.NSURI) - && prefix.equals(NSITunes.NSTAG)) { - state.namespaces.put(uri, new NSITunes()); - Log.d(TAG, "Recognized ITunes namespace"); - } else if (uri.equals(NSSimpleChapters.NSURI) - && prefix.matches(NSSimpleChapters.NSTAG)) { - state.namespaces.put(uri, new NSSimpleChapters()); - Log.d(TAG, "Recognized SimpleChapters namespace"); - } else if (uri.equals(NSMedia.NSURI) - && prefix.equals(NSMedia.NSTAG)) { - state.namespaces.put(uri, new NSMedia()); - Log.d(TAG, "Recognized media namespace"); - } else if (uri.equals(NSDublinCore.NSURI) - && prefix.equals(NSDublinCore.NSTAG)) { - state.namespaces.put(uri, new NSDublinCore()); - Log.d(TAG, "Recognized DublinCore namespace"); - } else if (uri.equals(PodcastIndex.NSURI) || uri.equals(PodcastIndex.NSURI2) - && prefix.equals(PodcastIndex.NSTAG)) { - state.namespaces.put(uri, new PodcastIndex()); - Log.d(TAG, "Recognized PodcastIndex namespace"); - } - } - } - - private Namespace getHandlingNamespace(String uri, String qName) { - Namespace handler = state.namespaces.get(uri); - if (handler == null && !state.defaultNamespaces.empty() - && !qName.contains(":")) { - handler = state.defaultNamespaces.peek(); - } - return handler; - } - - @Override - public void endDocument() throws SAXException { - super.endDocument(); - state.getFeed().setItems(state.getItems()); - } - - public HandlerState getState() { - return state; - } - -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/TypeGetter.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/TypeGetter.java deleted file mode 100644 index e6011e3fa..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/TypeGetter.java +++ /dev/null @@ -1,120 +0,0 @@ -package de.danoeh.antennapod.core.syndication.handler; - -import android.util.Log; - -import org.apache.commons.io.input.XmlStreamReader; -import org.jsoup.Jsoup; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlPullParserFactory; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.Reader; - -import de.danoeh.antennapod.model.feed.Feed; - -/** Gets the type of a specific feed by reading the root element. */ -public class TypeGetter { - private static final String TAG = "TypeGetter"; - - public enum Type { - RSS20, RSS091, ATOM, INVALID - } - - private static final String ATOM_ROOT = "feed"; - private static final String RSS_ROOT = "rss"; - - public Type getType(Feed feed) throws UnsupportedFeedtypeException { - XmlPullParserFactory factory; - if (feed.getFile_url() != null) { - Reader reader = null; - try { - factory = XmlPullParserFactory.newInstance(); - factory.setNamespaceAware(true); - XmlPullParser xpp = factory.newPullParser(); - reader = createReader(feed); - xpp.setInput(reader); - int eventType = xpp.getEventType(); - - while (eventType != XmlPullParser.END_DOCUMENT) { - if (eventType == XmlPullParser.START_TAG) { - String tag = xpp.getName(); - switch (tag) { - case ATOM_ROOT: - feed.setType(Feed.TYPE_ATOM1); - Log.d(TAG, "Recognized type Atom"); - - String strLang = xpp.getAttributeValue("http://www.w3.org/XML/1998/namespace", "lang"); - if (strLang != null) { - feed.setLanguage(strLang); - } - - return Type.ATOM; - case RSS_ROOT: - String strVersion = xpp.getAttributeValue(null, "version"); - if (strVersion == null) { - feed.setType(Feed.TYPE_RSS2); - Log.d(TAG, "Assuming type RSS 2.0"); - return Type.RSS20; - } else if (strVersion.equals("2.0")) { - feed.setType(Feed.TYPE_RSS2); - Log.d(TAG, "Recognized type RSS 2.0"); - return Type.RSS20; - } else if (strVersion.equals("0.91") || strVersion.equals("0.92")) { - Log.d(TAG, "Recognized type RSS 0.91/0.92"); - return Type.RSS091; - } - throw new UnsupportedFeedtypeException("Unsupported rss version"); - default: - Log.d(TAG, "Type is invalid"); - throw new UnsupportedFeedtypeException(Type.INVALID, tag); - } - } else { - eventType = xpp.next(); - } - } - } catch (XmlPullParserException e) { - e.printStackTrace(); - // XML document might actually be a HTML document -> try to parse as HTML - String rootElement = null; - try { - if (Jsoup.parse(new File(feed.getFile_url()), null) != null) { - rootElement = "html"; - } - } catch (IOException e1) { - e1.printStackTrace(); - } - throw new UnsupportedFeedtypeException(Type.INVALID, rootElement); - - } catch (IOException e) { - e.printStackTrace(); - } finally { - if(reader != null) { - try { - reader.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - } - Log.d(TAG, "Type is invalid"); - throw new UnsupportedFeedtypeException(Type.INVALID); - } - - private Reader createReader(Feed feed) { - Reader reader; - try { - reader = new XmlStreamReader(new File(feed.getFile_url())); - } catch (FileNotFoundException e) { - e.printStackTrace(); - return null; - } catch (IOException e) { - e.printStackTrace(); - return null; - } - return reader; - } -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/UnsupportedFeedtypeException.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/UnsupportedFeedtypeException.java deleted file mode 100644 index c9f9f19c8..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/UnsupportedFeedtypeException.java +++ /dev/null @@ -1,44 +0,0 @@ -package de.danoeh.antennapod.core.syndication.handler; - -import de.danoeh.antennapod.core.syndication.handler.TypeGetter.Type; - -public class UnsupportedFeedtypeException extends Exception { - private static final long serialVersionUID = 9105878964928170669L; - private final TypeGetter.Type type; - private String rootElement; - private String message = null; - - public UnsupportedFeedtypeException(Type type) { - super(); - this.type = type; - } - - public UnsupportedFeedtypeException(Type type, String rootElement) { - this.type = type; - this.rootElement = rootElement; - } - - public UnsupportedFeedtypeException(String message) { - this.message = message; - type = Type.INVALID; - } - - public TypeGetter.Type getType() { - return type; - } - - public String getRootElement() { - return rootElement; - } - - @Override - public String getMessage() { - if (message != null) { - return message; - } else if (type == TypeGetter.Type.INVALID) { - return "Invalid type"; - } else { - return "Type " + type + " not supported"; - } - } -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSContent.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSContent.java deleted file mode 100644 index bedf377aa..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSContent.java +++ /dev/null @@ -1,25 +0,0 @@ -package de.danoeh.antennapod.core.syndication.namespace; - -import org.xml.sax.Attributes; - -import de.danoeh.antennapod.core.syndication.handler.HandlerState; - -public class NSContent extends Namespace { - public static final String NSTAG = "content"; - public static final String NSURI = "http://purl.org/rss/1.0/modules/content/"; - - private static final String ENCODED = "encoded"; - - @Override - public SyndElement handleElementStart(String localName, HandlerState state, Attributes attributes) { - return new SyndElement(localName, this); - } - - @Override - public void handleElementEnd(String localName, HandlerState state) { - if (ENCODED.equals(localName) && state.getCurrentItem() != null && state.getContentBuf() != null) { - state.getCurrentItem().setDescriptionIfLonger(state.getContentBuf().toString()); - } - } - -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSDublinCore.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSDublinCore.java deleted file mode 100644 index 0394b754a..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSDublinCore.java +++ /dev/null @@ -1,37 +0,0 @@ -package de.danoeh.antennapod.core.syndication.namespace; - -import org.xml.sax.Attributes; - -import de.danoeh.antennapod.model.feed.FeedItem; -import de.danoeh.antennapod.core.syndication.handler.HandlerState; -import de.danoeh.antennapod.core.util.DateUtils; - -public class NSDublinCore extends Namespace { - private static final String TAG = "NSDublinCore"; - public static final String NSTAG = "dc"; - public static final String NSURI = "http://purl.org/dc/elements/1.1/"; - - private static final String ITEM = "item"; - private static final String DATE = "date"; - - @Override - public SyndElement handleElementStart(String localName, HandlerState state, - Attributes attributes) { - return new SyndElement(localName, this); - } - - @Override - public void handleElementEnd(String localName, HandlerState state) { - if (state.getCurrentItem() != null && state.getContentBuf() != null && - state.getTagstack() != null && state.getTagstack().size() >= 2) { - FeedItem currentItem = state.getCurrentItem(); - String top = state.getTagstack().peek().getName(); - String second = state.getSecondTag().getName(); - if (DATE.equals(top) && ITEM.equals(second)) { - String content = state.getContentBuf().toString(); - currentItem.setPubDate(DateUtils.parseOrNullIfFuture(content)); - } - } - } - -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java deleted file mode 100644 index 1dc8d8af3..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java +++ /dev/null @@ -1,113 +0,0 @@ -package de.danoeh.antennapod.core.syndication.namespace; - -import android.text.TextUtils; -import android.util.Log; - -import androidx.core.text.HtmlCompat; - -import org.xml.sax.Attributes; - -import de.danoeh.antennapod.core.syndication.handler.HandlerState; -import de.danoeh.antennapod.core.syndication.parsers.DurationParser; - -public class NSITunes extends Namespace { - - public static final String NSTAG = "itunes"; - public static final String NSURI = "http://www.itunes.com/dtds/podcast-1.0.dtd"; - - private static final String IMAGE = "image"; - private static final String IMAGE_HREF = "href"; - - private static final String AUTHOR = "author"; - public static final String DURATION = "duration"; - private static final String SUBTITLE = "subtitle"; - private static final String SUMMARY = "summary"; - - @Override - public SyndElement handleElementStart(String localName, HandlerState state, - Attributes attributes) { - if (IMAGE.equals(localName)) { - String url = attributes.getValue(IMAGE_HREF); - - if (state.getCurrentItem() != null) { - state.getCurrentItem().setImageUrl(url); - } else { - // this is the feed image - // prefer to all other images - if (!TextUtils.isEmpty(url)) { - state.getFeed().setImageUrl(url); - } - } - } - return new SyndElement(localName, this); - } - - @Override - public void handleElementEnd(String localName, HandlerState state) { - if (state.getContentBuf() == null) { - return; - } - - if (AUTHOR.equals(localName)) { - parseAuthor(state); - } else if (DURATION.equals(localName)) { - parseDuration(state); - } else if (SUBTITLE.equals(localName)) { - parseSubtitle(state); - } else if (SUMMARY.equals(localName)) { - SyndElement secondElement = state.getSecondTag(); - parseSummary(state, secondElement.getName()); - } - } - - private void parseAuthor(HandlerState state) { - if (state.getFeed() != null) { - String author = state.getContentBuf().toString(); - state.getFeed().setAuthor(HtmlCompat.fromHtml(author, - HtmlCompat.FROM_HTML_MODE_LEGACY).toString()); - } - } - - private void parseDuration(HandlerState state) { - String durationStr = state.getContentBuf().toString(); - if (TextUtils.isEmpty(durationStr)) { - return; - } - - try { - long durationMs = DurationParser.inMillis(durationStr); - state.getTempObjects().put(DURATION, (int) durationMs); - } catch (NumberFormatException e) { - Log.e(NSTAG, String.format("Duration '%s' could not be parsed", durationStr)); - } - } - - private void parseSubtitle(HandlerState state) { - String subtitle = state.getContentBuf().toString(); - if (TextUtils.isEmpty(subtitle)) { - return; - } - if (state.getCurrentItem() != null) { - if (TextUtils.isEmpty(state.getCurrentItem().getDescription())) { - state.getCurrentItem().setDescriptionIfLonger(subtitle); - } - } else { - if (state.getFeed() != null && TextUtils.isEmpty(state.getFeed().getDescription())) { - state.getFeed().setDescription(subtitle); - } - } - } - - private void parseSummary(HandlerState state, String secondElementName) { - String summary = state.getContentBuf().toString(); - if (TextUtils.isEmpty(summary)) { - return; - } - - if (state.getCurrentItem() != null) { - state.getCurrentItem().setDescriptionIfLonger(summary); - } else if (NSRSS20.CHANNEL.equals(secondElementName) && state.getFeed() != null) { - state.getFeed().setDescription(summary); - } - } -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSMedia.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSMedia.java deleted file mode 100644 index 3dba0735d..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSMedia.java +++ /dev/null @@ -1,132 +0,0 @@ -package de.danoeh.antennapod.core.syndication.namespace; - -import android.text.TextUtils; -import android.util.Log; - -import org.xml.sax.Attributes; - -import java.util.concurrent.TimeUnit; - -import de.danoeh.antennapod.model.feed.FeedMedia; -import de.danoeh.antennapod.core.syndication.handler.HandlerState; -import de.danoeh.antennapod.core.syndication.namespace.atom.AtomText; -import de.danoeh.antennapod.core.syndication.util.SyndTypeUtils; - -/** Processes tags from the http://search.yahoo.com/mrss/ namespace. */ -public class NSMedia extends Namespace { - private static final String TAG = "NSMedia"; - - public static final String NSTAG = "media"; - public static final String NSURI = "http://search.yahoo.com/mrss/"; - - private static final String CONTENT = "content"; - private static final String DOWNLOAD_URL = "url"; - private static final String SIZE = "fileSize"; - private static final String MIME_TYPE = "type"; - private static final String DURATION = "duration"; - private static final String DEFAULT = "isDefault"; - private static final String MEDIUM = "medium"; - - private static final String MEDIUM_IMAGE = "image"; - private static final String MEDIUM_AUDIO = "audio"; - private static final String MEDIUM_VIDEO = "video"; - - private static final String IMAGE = "thumbnail"; - private static final String IMAGE_URL = "url"; - - private static final String DESCRIPTION = "description"; - private static final String DESCRIPTION_TYPE = "type"; - - @Override - public SyndElement handleElementStart(String localName, HandlerState state, - Attributes attributes) { - if (CONTENT.equals(localName)) { - String url = attributes.getValue(DOWNLOAD_URL); - String type = attributes.getValue(MIME_TYPE); - String defaultStr = attributes.getValue(DEFAULT); - String medium = attributes.getValue(MEDIUM); - boolean validTypeMedia = false; - boolean validTypeImage = false; - boolean isDefault = "true".equals(defaultStr); - String guessedType = SyndTypeUtils.getMimeTypeFromUrl(url); - - if (MEDIUM_AUDIO.equals(medium)) { - validTypeMedia = true; - type = "audio/*"; - } else if (MEDIUM_VIDEO.equals(medium)) { - validTypeMedia = true; - type = "video/*"; - } else if (MEDIUM_IMAGE.equals(medium) && (guessedType == null - || (!guessedType.startsWith("audio/") && !guessedType.startsWith("video/")))) { - // Apparently, some publishers explicitly specify the audio file as an image - validTypeImage = true; - type = "image/*"; - } else { - if (type == null) { - type = guessedType; - } - - if (SyndTypeUtils.enclosureTypeValid(type)) { - validTypeMedia = true; - } else if (SyndTypeUtils.imageTypeValid(type)) { - validTypeImage = true; - } - } - - if (state.getCurrentItem() != null && (state.getCurrentItem().getMedia() == null || isDefault) - && url != null && validTypeMedia) { - long size = 0; - String sizeStr = attributes.getValue(SIZE); - try { - size = Long.parseLong(sizeStr); - } catch (NumberFormatException e) { - Log.e(TAG, "Size \"" + sizeStr + "\" could not be parsed."); - } - - int durationMs = 0; - String durationStr = attributes.getValue(DURATION); - if (!TextUtils.isEmpty(durationStr)) { - try { - long duration = Long.parseLong(durationStr); - durationMs = (int) TimeUnit.MILLISECONDS.convert(duration, TimeUnit.SECONDS); - } catch (NumberFormatException e) { - Log.e(TAG, "Duration \"" + durationStr + "\" could not be parsed"); - } - } - FeedMedia media = new FeedMedia(state.getCurrentItem(), url, size, type); - if (durationMs > 0) { - media.setDuration(durationMs); - } - state.getCurrentItem().setMedia(media); - } else if (state.getCurrentItem() != null && url != null && validTypeImage) { - state.getCurrentItem().setImageUrl(url); - } - } else if (IMAGE.equals(localName)) { - String url = attributes.getValue(IMAGE_URL); - if (url != null) { - if (state.getCurrentItem() != null) { - state.getCurrentItem().setImageUrl(url); - } else { - if (state.getFeed().getImageUrl() == null) { - state.getFeed().setImageUrl(url); - } - } - } - } else if (DESCRIPTION.equals(localName)) { - String type = attributes.getValue(DESCRIPTION_TYPE); - return new AtomText(localName, this, type); - } - return new SyndElement(localName, this); - } - - @Override - public void handleElementEnd(String localName, HandlerState state) { - if (DESCRIPTION.equals(localName)) { - String content = state.getContentBuf().toString(); - if (state.getCurrentItem() != null) { - state.getCurrentItem().setDescriptionIfLonger(content); - } - } - } -} - diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSRSS20.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSRSS20.java deleted file mode 100644 index 50c2dc118..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSRSS20.java +++ /dev/null @@ -1,145 +0,0 @@ -package de.danoeh.antennapod.core.syndication.namespace; - -import android.text.TextUtils; -import android.util.Log; - -import de.danoeh.antennapod.core.syndication.util.SyndStringUtils; -import org.xml.sax.Attributes; - -import de.danoeh.antennapod.model.feed.FeedItem; -import de.danoeh.antennapod.model.feed.FeedMedia; -import de.danoeh.antennapod.core.syndication.handler.HandlerState; -import de.danoeh.antennapod.core.syndication.util.SyndTypeUtils; -import de.danoeh.antennapod.core.util.DateUtils; - -/** - * SAX-Parser for reading RSS-Feeds. - */ -public class NSRSS20 extends Namespace { - - private static final String TAG = "NSRSS20"; - - public static final String CHANNEL = "channel"; - public static final String ITEM = "item"; - private static final String GUID = "guid"; - private static final String TITLE = "title"; - private static final String LINK = "link"; - private static final String DESCR = "description"; - private static final String PUBDATE = "pubDate"; - private static final String ENCLOSURE = "enclosure"; - private static final String IMAGE = "image"; - private static final String URL = "url"; - private static final String LANGUAGE = "language"; - - private static final String ENC_URL = "url"; - private static final String ENC_LEN = "length"; - private static final String ENC_TYPE = "type"; - - @Override - public SyndElement handleElementStart(String localName, HandlerState state, - Attributes attributes) { - if (ITEM.equals(localName)) { - state.setCurrentItem(new FeedItem()); - state.getItems().add(state.getCurrentItem()); - state.getCurrentItem().setFeed(state.getFeed()); - - } else if (ENCLOSURE.equals(localName)) { - String type = attributes.getValue(ENC_TYPE); - String url = attributes.getValue(ENC_URL); - - boolean validType = SyndTypeUtils.enclosureTypeValid(type); - if (!validType) { - type = SyndTypeUtils.getMimeTypeFromUrl(url); - validType = SyndTypeUtils.enclosureTypeValid(type); - } - - boolean validUrl = !TextUtils.isEmpty(url); - if (state.getCurrentItem() != null && state.getCurrentItem().getMedia() == null - && validType && validUrl) { - long size = 0; - try { - size = Long.parseLong(attributes.getValue(ENC_LEN)); - if (size < 16384) { - // less than 16kb is suspicious, check manually - size = 0; - } - } catch (NumberFormatException e) { - Log.d(TAG, "Length attribute could not be parsed."); - } - FeedMedia media = new FeedMedia(state.getCurrentItem(), url, size, type); - state.getCurrentItem().setMedia(media); - } - - } - return new SyndElement(localName, this); - } - - @Override - public void handleElementEnd(String localName, HandlerState state) { - if (ITEM.equals(localName)) { - if (state.getCurrentItem() != null) { - FeedItem currentItem = state.getCurrentItem(); - // the title tag is optional in RSS 2.0. The description is used - // as a title if the item has no title-tag. - if (currentItem.getTitle() == null) { - currentItem.setTitle(currentItem.getDescription()); - } - - if (state.getTempObjects().containsKey(NSITunes.DURATION)) { - if (currentItem.hasMedia()) { - Integer duration = (Integer) state.getTempObjects().get(NSITunes.DURATION); - currentItem.getMedia().setDuration(duration); - } - state.getTempObjects().remove(NSITunes.DURATION); - } - } - state.setCurrentItem(null); - } else if (state.getTagstack().size() >= 2 && state.getContentBuf() != null) { - String contentRaw = state.getContentBuf().toString(); - String content = SyndStringUtils.trimAllWhitespace(contentRaw); - SyndElement topElement = state.getTagstack().peek(); - String top = topElement.getName(); - SyndElement secondElement = state.getSecondTag(); - String second = secondElement.getName(); - String third = null; - if (state.getTagstack().size() >= 3) { - third = state.getThirdTag().getName(); - } - if (GUID.equals(top) && ITEM.equals(second)) { - // some feed creators include an empty or non-standard guid-element in their feed, - // which should be ignored - if (!TextUtils.isEmpty(contentRaw) && state.getCurrentItem() != null) { - state.getCurrentItem().setItemIdentifier(contentRaw); - } - } else if (TITLE.equals(top)) { - if (ITEM.equals(second) && state.getCurrentItem() != null) { - state.getCurrentItem().setTitle(content); - } else if (CHANNEL.equals(second) && state.getFeed() != null) { - state.getFeed().setTitle(content); - } - } else if (LINK.equals(top)) { - if (CHANNEL.equals(second) && state.getFeed() != null) { - state.getFeed().setLink(content); - } else if (ITEM.equals(second) && state.getCurrentItem() != null) { - state.getCurrentItem().setLink(content); - } - } else if (PUBDATE.equals(top) && ITEM.equals(second) && state.getCurrentItem() != null) { - state.getCurrentItem().setPubDate(DateUtils.parseOrNullIfFuture(content)); - } else if (URL.equals(top) && IMAGE.equals(second) && CHANNEL.equals(third)) { - // prefer itunes:image - if (state.getFeed() != null && state.getFeed().getImageUrl() == null) { - state.getFeed().setImageUrl(content); - } - } else if (DESCR.equals(localName)) { - if (CHANNEL.equals(second) && state.getFeed() != null) { - state.getFeed().setDescription(content); - } else if (ITEM.equals(second) && state.getCurrentItem() != null) { - state.getCurrentItem().setDescriptionIfLonger(content); - } - } else if (LANGUAGE.equals(localName) && state.getFeed() != null) { - state.getFeed().setLanguage(content.toLowerCase()); - } - } - } - -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSSimpleChapters.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSSimpleChapters.java deleted file mode 100644 index 97d0ebb53..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSSimpleChapters.java +++ /dev/null @@ -1,53 +0,0 @@ -package de.danoeh.antennapod.core.syndication.namespace; - -import android.util.Log; - -import org.xml.sax.Attributes; - -import java.util.ArrayList; - -import de.danoeh.antennapod.model.feed.FeedItem; -import de.danoeh.antennapod.core.feed.SimpleChapter; -import de.danoeh.antennapod.core.syndication.handler.HandlerState; -import de.danoeh.antennapod.core.util.DateUtils; - -public class NSSimpleChapters extends Namespace { - private static final String TAG = "NSSimpleChapters"; - - public static final String NSTAG = "psc|sc"; - public static final String NSURI = "http://podlove.org/simple-chapters"; - - private static final String CHAPTERS = "chapters"; - private static final String CHAPTER = "chapter"; - private static final String START = "start"; - private static final String TITLE = "title"; - private static final String HREF = "href"; - private static final String IMAGE = "image"; - - @Override - public SyndElement handleElementStart(String localName, HandlerState state, Attributes attributes) { - FeedItem currentItem = state.getCurrentItem(); - if (currentItem != null) { - if (localName.equals(CHAPTERS)) { - currentItem.setChapters(new ArrayList<>()); - } else if (localName.equals(CHAPTER)) { - try { - long start = DateUtils.parseTimeString(attributes.getValue(START)); - String title = attributes.getValue(TITLE); - String link = attributes.getValue(HREF); - String imageUrl = attributes.getValue(IMAGE); - SimpleChapter chapter = new SimpleChapter(start, title, link, imageUrl); - currentItem.getChapters().add(chapter); - } catch (NumberFormatException e) { - Log.e(TAG, "Unable to read chapter", e); - } - } - } - return new SyndElement(localName, this); - } - - @Override - public void handleElementEnd(String localName, HandlerState state) { - } - -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/Namespace.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/Namespace.java deleted file mode 100644 index e5fbdb9bb..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/Namespace.java +++ /dev/null @@ -1,21 +0,0 @@ -package de.danoeh.antennapod.core.syndication.namespace; - -import org.xml.sax.Attributes; - -import de.danoeh.antennapod.core.syndication.handler.HandlerState; - - -public abstract class Namespace { - public static final String NSTAG = null; - public static final String NSURI = null; - - /** Called by a Feedhandler when in startElement and it detects a namespace element - * @return The SyndElement to push onto the stack - * */ - public abstract SyndElement handleElementStart(String localName, HandlerState state, Attributes attributes); - - /** Called by a Feedhandler when in endElement and it detects a namespace element - * */ - public abstract void handleElementEnd(String localName, HandlerState state); - -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/PodcastIndex.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/PodcastIndex.java deleted file mode 100644 index ee150f839..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/PodcastIndex.java +++ /dev/null @@ -1,38 +0,0 @@ -package de.danoeh.antennapod.core.syndication.namespace; - -import org.jsoup.helper.StringUtil; -import org.xml.sax.Attributes; -import de.danoeh.antennapod.model.feed.FeedFunding; -import de.danoeh.antennapod.core.syndication.handler.HandlerState; - -public class PodcastIndex extends Namespace { - - public static final String NSTAG = "podcast"; - public static final String NSURI = "https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md"; - public static final String NSURI2 = "https://podcastindex.org/namespace/1.0"; - private static final String URL = "url"; - private static final String FUNDING = "funding"; - - @Override - public SyndElement handleElementStart(String localName, HandlerState state, - Attributes attributes) { - if (FUNDING.equals(localName)) { - String href = attributes.getValue(URL); - FeedFunding funding = new FeedFunding(href, ""); - state.setCurrentFunding(funding); - state.getFeed().addPayment(state.getCurrentFunding()); - } - return new SyndElement(localName, this); - } - - @Override - public void handleElementEnd(String localName, HandlerState state) { - if (state.getContentBuf() == null) { - return; - } - String content = state.getContentBuf().toString(); - if (FUNDING.equals(localName) && state.getCurrentFunding() != null && !StringUtil.isBlank(content)) { - state.getCurrentFunding().setContent(content); - } - } -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/SyndElement.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/SyndElement.java deleted file mode 100644 index ba1b8ba5c..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/SyndElement.java +++ /dev/null @@ -1,22 +0,0 @@ -package de.danoeh.antennapod.core.syndication.namespace; - -/** Defines a XML Element that is pushed on the tagstack */ -public class SyndElement { - private final String name; - private final Namespace namespace; - - public SyndElement(String name, Namespace namespace) { - this.name = name; - this.namespace = namespace; - } - - public Namespace getNamespace() { - return namespace; - } - - public String getName() { - return name; - } - - -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/atom/AtomText.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/atom/AtomText.java deleted file mode 100644 index 0c0561279..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/atom/AtomText.java +++ /dev/null @@ -1,38 +0,0 @@ -package de.danoeh.antennapod.core.syndication.namespace.atom; - -import androidx.core.text.HtmlCompat; - -import de.danoeh.antennapod.core.syndication.namespace.Namespace; -import de.danoeh.antennapod.core.syndication.namespace.SyndElement; - -/** Represents Atom Element which contains text (content, title, summary). */ -public class AtomText extends SyndElement { - public static final String TYPE_TEXT = "text"; - public static final String TYPE_HTML = "html"; - private static final String TYPE_XHTML = "xhtml"; - - private final String type; - private String content; - - public AtomText(String name, Namespace namespace, String type) { - super(name, namespace); - this.type = type; - } - - /** Processes the content according to the type and returns it. */ - public String getProcessedContent() { - if (type == null) { - return content; - } else if (type.equals(TYPE_HTML)) { - return HtmlCompat.fromHtml(content, HtmlCompat.FROM_HTML_MODE_LEGACY).toString(); - } else if (type.equals(TYPE_XHTML)) { - return content; - } else { // Handle as text by default - return content; - } - } - - public void setContent(String content) { - this.content = content; - } -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/atom/NSAtom.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/atom/NSAtom.java deleted file mode 100644 index b93f41771..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/atom/NSAtom.java +++ /dev/null @@ -1,226 +0,0 @@ -package de.danoeh.antennapod.core.syndication.namespace.atom; - -import android.text.TextUtils; -import android.util.Log; - -import de.danoeh.antennapod.model.feed.FeedFunding; -import de.danoeh.antennapod.core.syndication.util.SyndStringUtils; -import org.xml.sax.Attributes; - -import de.danoeh.antennapod.model.feed.FeedItem; -import de.danoeh.antennapod.model.feed.FeedMedia; -import de.danoeh.antennapod.core.syndication.handler.HandlerState; -import de.danoeh.antennapod.core.syndication.namespace.NSITunes; -import de.danoeh.antennapod.core.syndication.namespace.NSRSS20; -import de.danoeh.antennapod.core.syndication.namespace.Namespace; -import de.danoeh.antennapod.core.syndication.namespace.SyndElement; -import de.danoeh.antennapod.core.syndication.util.SyndTypeUtils; -import de.danoeh.antennapod.core.util.DateUtils; - -public class NSAtom extends Namespace { - private static final String TAG = "NSAtom"; - public static final String NSTAG = "atom"; - public static final String NSURI = "http://www.w3.org/2005/Atom"; - - private static final String FEED = "feed"; - private static final String ID = "id"; - private static final String TITLE = "title"; - private static final String ENTRY = "entry"; - private static final String LINK = "link"; - private static final String UPDATED = "updated"; - private static final String AUTHOR = "author"; - private static final String AUTHOR_NAME = "name"; - private static final String CONTENT = "content"; - private static final String SUMMARY = "summary"; - private static final String IMAGE_LOGO = "logo"; - private static final String IMAGE_ICON = "icon"; - private static final String SUBTITLE = "subtitle"; - private static final String PUBLISHED = "published"; - - private static final String TEXT_TYPE = "type"; - // Link - private static final String LINK_HREF = "href"; - private static final String LINK_REL = "rel"; - private static final String LINK_TYPE = "type"; - private static final String LINK_TITLE = "title"; - private static final String LINK_LENGTH = "length"; - // rel-values - private static final String LINK_REL_ALTERNATE = "alternate"; - private static final String LINK_REL_ARCHIVES = "archives"; - private static final String LINK_REL_ENCLOSURE = "enclosure"; - private static final String LINK_REL_PAYMENT = "payment"; - private static final String LINK_REL_NEXT = "next"; - // type-values - private static final String LINK_TYPE_ATOM = "application/atom+xml"; - private static final String LINK_TYPE_HTML = "text/html"; - private static final String LINK_TYPE_XHTML = "application/xml+xhtml"; - - private static final String LINK_TYPE_RSS = "application/rss+xml"; - - /** - * Regexp to test whether an Element is a Text Element. - */ - private static final String isText = TITLE + "|" + CONTENT + "|" - + SUBTITLE + "|" + SUMMARY; - - private static final String isFeed = FEED + "|" + NSRSS20.CHANNEL; - private static final String isFeedItem = ENTRY + "|" + NSRSS20.ITEM; - - @Override - public SyndElement handleElementStart(String localName, HandlerState state, - Attributes attributes) { - if (ENTRY.equals(localName)) { - state.setCurrentItem(new FeedItem()); - state.getItems().add(state.getCurrentItem()); - state.getCurrentItem().setFeed(state.getFeed()); - } else if (localName.matches(isText)) { - String type = attributes.getValue(TEXT_TYPE); - return new AtomText(localName, this, type); - } else if (LINK.equals(localName)) { - String href = attributes.getValue(LINK_HREF); - String rel = attributes.getValue(LINK_REL); - SyndElement parent = state.getTagstack().peek(); - if (parent.getName().matches(isFeedItem)) { - if (rel == null || LINK_REL_ALTERNATE.equals(rel)) { - state.getCurrentItem().setLink(href); - } else if (LINK_REL_ENCLOSURE.equals(rel)) { - String strSize = attributes.getValue(LINK_LENGTH); - long size = 0; - try { - if (strSize != null) { - size = Long.parseLong(strSize); - } - } catch (NumberFormatException e) { - Log.d(TAG, "Length attribute could not be parsed."); - } - String type = attributes.getValue(LINK_TYPE); - - if (type == null) { - type = SyndTypeUtils.getMimeTypeFromUrl(href); - } - - FeedItem currItem = state.getCurrentItem(); - if (SyndTypeUtils.enclosureTypeValid(type) && currItem != null && !currItem.hasMedia()) { - currItem.setMedia(new FeedMedia(currItem, href, size, type)); - } - } else if (LINK_REL_PAYMENT.equals(rel)) { - state.getCurrentItem().setPaymentLink(href); - } - } else if (parent.getName().matches(isFeed)) { - if (rel == null || LINK_REL_ALTERNATE.equals(rel)) { - String type = attributes.getValue(LINK_TYPE); - /* - * Use as link if a) no type-attribute is given and - * feed-object has no link yet b) type of link is - * LINK_TYPE_HTML or LINK_TYPE_XHTML - */ - if (state.getFeed() != null && - ((type == null && state.getFeed().getLink() == null) || - (LINK_TYPE_HTML.equals(type) || LINK_TYPE_XHTML.equals(type)))) { - state.getFeed().setLink(href); - } else if (LINK_TYPE_ATOM.equals(type) || LINK_TYPE_RSS.equals(type)) { - // treat as podlove alternate feed - String title = attributes.getValue(LINK_TITLE); - if (TextUtils.isEmpty(title)) { - title = href; - } - state.addAlternateFeedUrl(title, href); - } - } else if (LINK_REL_ARCHIVES.equals(rel) && state.getFeed() != null) { - String type = attributes.getValue(LINK_TYPE); - if (LINK_TYPE_ATOM.equals(type) || LINK_TYPE_RSS.equals(type)) { - String title = attributes.getValue(LINK_TITLE); - if (TextUtils.isEmpty(title)) { - title = href; - } - state.addAlternateFeedUrl(title, href); - } else if (LINK_TYPE_HTML.equals(type) || LINK_TYPE_XHTML.equals(type)) { - //A Link such as to a directory such as iTunes - } - } else if (LINK_REL_PAYMENT.equals(rel) && state.getFeed() != null) { - state.getFeed().addPayment(new FeedFunding(href, "")); - } else if (LINK_REL_NEXT.equals(rel) && state.getFeed() != null) { - state.getFeed().setPaged(true); - state.getFeed().setNextPageLink(href); - } - } - } - return new SyndElement(localName, this); - } - - @Override - public void handleElementEnd(String localName, HandlerState state) { - if (ENTRY.equals(localName)) { - if (state.getCurrentItem() != null && - state.getTempObjects().containsKey(NSITunes.DURATION)) { - FeedItem currentItem = state.getCurrentItem(); - if (currentItem.hasMedia()) { - Integer duration = (Integer) state.getTempObjects().get(NSITunes.DURATION); - currentItem.getMedia().setDuration(duration); - } - state.getTempObjects().remove(NSITunes.DURATION); - } - state.setCurrentItem(null); - } - - if (state.getTagstack().size() >= 2) { - AtomText textElement = null; - String contentRaw; - if (state.getContentBuf() != null) { - contentRaw = state.getContentBuf().toString(); - } else { - contentRaw = ""; - } - String content = SyndStringUtils.trimAllWhitespace(contentRaw); - SyndElement topElement = state.getTagstack().peek(); - String top = topElement.getName(); - SyndElement secondElement = state.getSecondTag(); - String second = secondElement.getName(); - - if (top.matches(isText)) { - textElement = (AtomText) topElement; - textElement.setContent(content); - } - - if (ID.equals(top)) { - if (FEED.equals(second) && state.getFeed() != null) { - state.getFeed().setFeedIdentifier(contentRaw); - } else if (ENTRY.equals(second) && state.getCurrentItem() != null) { - state.getCurrentItem().setItemIdentifier(contentRaw); - } - } else if (TITLE.equals(top) && textElement != null) { - if (FEED.equals(second) && state.getFeed() != null) { - state.getFeed().setTitle(textElement.getProcessedContent()); - } else if (ENTRY.equals(second) && state.getCurrentItem() != null) { - state.getCurrentItem().setTitle(textElement.getProcessedContent()); - } - } else if (SUBTITLE.equals(top) && FEED.equals(second) && textElement != null && - state.getFeed() != null) { - state.getFeed().setDescription(textElement.getProcessedContent()); - } else if (CONTENT.equals(top) && ENTRY.equals(second) && textElement != null && - state.getCurrentItem() != null) { - state.getCurrentItem().setDescriptionIfLonger(textElement.getProcessedContent()); - } else if (SUMMARY.equals(top) && ENTRY.equals(second) && textElement != null - && state.getCurrentItem() != null) { - state.getCurrentItem().setDescriptionIfLonger(textElement.getProcessedContent()); - } else if (UPDATED.equals(top) && ENTRY.equals(second) && state.getCurrentItem() != null && - state.getCurrentItem().getPubDate() == null) { - state.getCurrentItem().setPubDate(DateUtils.parseOrNullIfFuture(content)); - } else if (PUBLISHED.equals(top) && ENTRY.equals(second) && state.getCurrentItem() != null) { - state.getCurrentItem().setPubDate(DateUtils.parseOrNullIfFuture(content)); - } else if (IMAGE_LOGO.equals(top) && state.getFeed() != null && state.getFeed().getImageUrl() == null) { - state.getFeed().setImageUrl(content); - } else if (IMAGE_ICON.equals(top) && state.getFeed() != null) { - state.getFeed().setImageUrl(content); - } else if (AUTHOR_NAME.equals(top) && AUTHOR.equals(second) && - state.getFeed() != null && state.getCurrentItem() == null) { - String currentName = state.getFeed().getAuthor(); - if (currentName == null) { - state.getFeed().setAuthor(content); - } else { - state.getFeed().setAuthor(currentName + ", " + content); - } - } - } - } -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/parsers/DurationParser.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/parsers/DurationParser.java deleted file mode 100644 index 8b036c6a9..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/parsers/DurationParser.java +++ /dev/null @@ -1,37 +0,0 @@ -package de.danoeh.antennapod.core.syndication.parsers; - -import static java.util.concurrent.TimeUnit.HOURS; -import static java.util.concurrent.TimeUnit.MINUTES; -import static java.util.concurrent.TimeUnit.SECONDS; - -public class DurationParser { - public static long inMillis(String durationStr) throws NumberFormatException { - String[] parts = durationStr.trim().split(":"); - - if (parts.length == 1) { - return toMillis(parts[0]); - } else if (parts.length == 2) { - return toMillis("0", parts[0], parts[1]); - } else if (parts.length == 3) { - return toMillis(parts[0], parts[1], parts[2]); - } else { - throw new NumberFormatException(); - } - } - - private static long toMillis(String hours, String minutes, String seconds) { - return HOURS.toMillis(Long.parseLong(hours)) - + MINUTES.toMillis(Long.parseLong(minutes)) - + toMillis(seconds); - } - - private static long toMillis(String seconds) { - if (seconds.contains(".")) { - float value = Float.parseFloat(seconds); - float millis = value % 1; - return SECONDS.toMillis((long) value) + (long) (millis * 1000); - } else { - return SECONDS.toMillis(Long.parseLong(seconds)); - } - } -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndStringUtils.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndStringUtils.java deleted file mode 100644 index addcdd4b7..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndStringUtils.java +++ /dev/null @@ -1,14 +0,0 @@ -package de.danoeh.antennapod.core.syndication.util; - -public class SyndStringUtils { - private SyndStringUtils() { - - } - - /** - * Trims all whitespace from beginning and ending of a String. {{@link String#trim()}} only trims spaces. - */ - public static String trimAllWhitespace(String string) { - return string.replaceAll("(^\\s*)|(\\s*$)", ""); - } -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndTypeUtils.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndTypeUtils.java deleted file mode 100644 index 155673296..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndTypeUtils.java +++ /dev/null @@ -1,44 +0,0 @@ -package de.danoeh.antennapod.core.syndication.util; - -import android.webkit.MimeTypeMap; -import org.apache.commons.io.FilenameUtils; - -/** - * Utility class for handling MIME-Types of enclosures. - * */ -public class SyndTypeUtils { - private SyndTypeUtils() { - - } - - public static boolean enclosureTypeValid(String type) { - if (type == null) { - return false; - } else { - return type.startsWith("audio/") - || type.startsWith("video/") - || type.equals("application/ogg") - || type.equals("application/octet-stream"); - } - } - - public static boolean imageTypeValid(String type) { - if (type == null) { - return false; - } else { - return type.startsWith("image/"); - } - } - - /** - * Should be used if mime-type of enclosure tag is not supported. This - * method will return the mime-type of the file extension. - */ - public static String getMimeTypeFromUrl(String url) { - if (url == null) { - return null; - } - String extension = FilenameUtils.getExtension(url); - return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); - } -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/DateFormatter.java b/core/src/main/java/de/danoeh/antennapod/core/util/DateFormatter.java new file mode 100644 index 000000000..99628dfcc --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/util/DateFormatter.java @@ -0,0 +1,46 @@ +package de.danoeh.antennapod.core.util; + +import android.content.Context; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Locale; + +/** + * Formats dates. + */ +public class DateFormatter { + private DateFormatter() { + + } + + public static String formatRfc822Date(Date date) { + SimpleDateFormat format = new SimpleDateFormat("dd MMM yy HH:mm:ss Z", Locale.US); + return format.format(date); + } + + public static String formatAbbrev(final Context context, final Date date) { + if (date == null) { + return ""; + } + GregorianCalendar now = new GregorianCalendar(); + GregorianCalendar cal = new GregorianCalendar(); + cal.setTime(date); + boolean withinLastYear = now.get(Calendar.YEAR) == cal.get(Calendar.YEAR); + int format = android.text.format.DateUtils.FORMAT_ABBREV_ALL; + if (withinLastYear) { + format |= android.text.format.DateUtils.FORMAT_NO_YEAR; + } + return android.text.format.DateUtils.formatDateTime(context, date.getTime(), format); + } + + public static String formatForAccessibility(final Context context, final Date date) { + if (date == null) { + return ""; + } + return DateFormat.getDateInstance(DateFormat.LONG).format(date); + } +} diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java deleted file mode 100644 index a0b9fbef9..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java +++ /dev/null @@ -1,202 +0,0 @@ -package de.danoeh.antennapod.core.util; - -import android.content.Context; -import android.util.Log; - -import androidx.annotation.Nullable; -import org.apache.commons.lang3.StringUtils; - -import java.text.DateFormat; -import java.text.ParsePosition; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.Locale; -import java.util.TimeZone; - -/** - * Parses several date formats. - */ -public class DateUtils { - - private DateUtils(){} - - private static final String TAG = "DateUtils"; - private static final TimeZone defaultTimezone = TimeZone.getTimeZone("GMT"); - - public static Date parse(final String input) { - if (input == null) { - throw new IllegalArgumentException("Date must not be null"); - } - String date = input.trim().replace('/', '-').replaceAll("( ){2,}+", " "); - - // remove colon from timezone to avoid differences between Android and Java SimpleDateFormat - date = date.replaceAll("([+-]\\d\\d):(\\d\\d)$", "$1$2"); - - // CEST is widely used but not in the "ISO 8601 Time zone" list. Let's hack around. - date = date.replaceAll("CEST$", "+0200"); - date = date.replaceAll("CET$", "+0100"); - - // some generators use "Sept" for September - date = date.replaceAll("\\bSept\\b", "Sep"); - - // if datetime is more precise than seconds, make sure the value is in ms - if (date.contains(".")) { - int start = date.indexOf('.'); - int current = start + 1; - while (current < date.length() && Character.isDigit(date.charAt(current))) { - current++; - } - // even more precise than microseconds: discard further decimal places - if (current - start > 4) { - if (current < date.length() - 1) { - date = date.substring(0, start + 4) + date.substring(current); - } else { - date = date.substring(0, start + 4); - } - // less than 4 decimal places: pad to have a consistent format for the parser - } else if (current - start < 4) { - if (current < date.length() - 1) { - date = date.substring(0, current) + StringUtils.repeat("0", 4 - (current - start)) + date.substring(current); - } else { - date = date.substring(0, current) + StringUtils.repeat("0", 4 - (current - start)); - } - } - } - final String[] patterns = { - "dd MMM yy HH:mm:ss Z", - "dd MMM yy HH:mm Z", - "EEE, dd MMM yyyy HH:mm:ss Z", - "EEE, dd MMM yyyy HH:mm:ss", - "EEE, dd MMMM yyyy HH:mm:ss Z", - "EEE, dd MMMM yyyy HH:mm:ss", - "EEEE, dd MMM yyyy HH:mm:ss Z", - "EEEE, dd MMM yy HH:mm:ss Z", - "EEEE, dd MMM yyyy HH:mm:ss", - "EEEE, dd MMM yy HH:mm:ss", - "EEE MMM d HH:mm:ss yyyy", - "EEE, dd MMM yyyy HH:mm Z", - "EEE, dd MMM yyyy HH:mm", - "EEE, dd MMMM yyyy HH:mm Z", - "EEE, dd MMMM yyyy HH:mm", - "EEEE, dd MMM yyyy HH:mm Z", - "EEEE, dd MMM yy HH:mm Z", - "EEEE, dd MMM yyyy HH:mm", - "EEEE, dd MMM yy HH:mm", - "EEE MMM d HH:mm yyyy", - "yyyy-MM-dd'T'HH:mm:ss", - "yyyy-MM-dd'T'HH:mm:ss.SSS Z", - "yyyy-MM-dd'T'HH:mm:ss.SSS", - "yyyy-MM-dd'T'HH:mm:ssZ", - "yyyy-MM-dd'T'HH:mm:ss'Z'", - "yyyy-MM-dd'T'HH:mm:ss.SSSZ", - "yyyy-MM-ddZ", - "yyyy-MM-dd", - "EEE d MMM yyyy HH:mm:ss 'GMT'Z (z)" - }; - - SimpleDateFormat parser = new SimpleDateFormat("", Locale.US); - parser.setLenient(false); - parser.setTimeZone(defaultTimezone); - - ParsePosition pos = new ParsePosition(0); - for (String pattern : patterns) { - parser.applyPattern(pattern); - pos.setIndex(0); - try { - Date result = parser.parse(date, pos); - if (result != null && pos.getIndex() == date.length()) { - return result; - } - } catch (Exception e) { - Log.e(TAG, Log.getStackTraceString(e)); - } - } - - // if date string starts with a weekday, try parsing date string without it - if (date.matches("^\\w+, .*$")) { - return parse(date.substring(date.indexOf(',') + 1)); - } - - Log.d(TAG, "Could not parse date string \"" + input + "\" [" + date + "]"); - return null; - } - - /** - * Parses the date but if the date is in the future, returns null. - */ - @Nullable - public static Date parseOrNullIfFuture(final String input) { - Date date = parse(input); - if (date == null) { - return null; - } - Date now = new Date(); - if (date.after(now)) { - return null; - } - return date; - } - - /** - * Takes a string of the form [HH:]MM:SS[.mmm] and converts it to - * milliseconds. - * - * @throws java.lang.NumberFormatException if the number segments contain invalid numbers. - */ - public static long parseTimeString(final String time) { - String[] parts = time.split(":"); - long result = 0; - int idx = 0; - if (parts.length == 3) { - // string has hours - result += Integer.parseInt(parts[idx]) * 3600000L; - idx++; - } - if (parts.length >= 2) { - result += Integer.parseInt(parts[idx]) * 60000L; - idx++; - result += (long) (Float.parseFloat(parts[idx]) * 1000L); - } - return result; - } - - public static String formatRFC822Date(Date date) { - SimpleDateFormat format = new SimpleDateFormat("dd MMM yy HH:mm:ss Z", Locale.US); - return format.format(date); - } - - public static String formatRFC3339Local(Date date) { - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US); - return format.format(date); - } - - public static String formatRFC3339UTC(Date date) { - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); - format.setTimeZone(defaultTimezone); - return format.format(date); - } - - public static String formatAbbrev(final Context context, final Date date) { - if (date == null) { - return ""; - } - GregorianCalendar now = new GregorianCalendar(); - GregorianCalendar cal = new GregorianCalendar(); - cal.setTime(date); - boolean withinLastYear = now.get(Calendar.YEAR) == cal.get(Calendar.YEAR); - int format = android.text.format.DateUtils.FORMAT_ABBREV_ALL; - if (withinLastYear) { - format |= android.text.format.DateUtils.FORMAT_NO_YEAR; - } - return android.text.format.DateUtils.formatDateTime(context, date.getTime(), format); - } - - public static String formatForAccessibility(final Context context, final Date date) { - if (date == null) { - return ""; - } - return DateFormat.getDateInstance(DateFormat.LONG).format(date); - } -} diff --git a/core/src/test/java/de/danoeh/antennapod/core/storage/DbTestUtils.java b/core/src/test/java/de/danoeh/antennapod/core/storage/DbTestUtils.java index 6c1e8d4f9..413243d1d 100644 --- a/core/src/test/java/de/danoeh/antennapod/core/storage/DbTestUtils.java +++ b/core/src/test/java/de/danoeh/antennapod/core/storage/DbTestUtils.java @@ -9,7 +9,7 @@ import de.danoeh.antennapod.model.feed.Chapter; import de.danoeh.antennapod.model.feed.Feed; import de.danoeh.antennapod.model.feed.FeedItem; import de.danoeh.antennapod.model.feed.FeedMedia; -import de.danoeh.antennapod.core.feed.SimpleChapter; +import de.danoeh.antennapod.parser.feed.element.SimpleChapter; import de.danoeh.antennapod.core.util.comparator.FeedItemPubdateComparator; import static org.junit.Assert.assertTrue; diff --git a/core/src/test/java/de/danoeh/antennapod/core/syndication/handler/AtomParserTest.java b/core/src/test/java/de/danoeh/antennapod/core/syndication/handler/AtomParserTest.java deleted file mode 100644 index 36ca7f0d8..000000000 --- a/core/src/test/java/de/danoeh/antennapod/core/syndication/handler/AtomParserTest.java +++ /dev/null @@ -1,98 +0,0 @@ -package de.danoeh.antennapod.core.syndication.handler; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; - -import java.io.File; -import java.util.Date; - -import de.danoeh.antennapod.model.feed.Feed; -import de.danoeh.antennapod.model.feed.FeedItem; -import de.danoeh.antennapod.model.feed.FeedMedia; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertFalse; - -/** - * Tests for Atom feeds in FeedHandler. - */ -@RunWith(RobolectricTestRunner.class) -public class AtomParserTest { - - @Test - public void testAtomBasic() throws Exception { - File feedFile = FeedParserTestHelper.getFeedFile("feed-atom-testAtomBasic.xml"); - Feed feed = FeedParserTestHelper.runFeedParser(feedFile); - assertEquals(Feed.TYPE_ATOM1, feed.getType()); - assertEquals("title", feed.getTitle()); - assertEquals("http://example.com/feed", feed.getFeedIdentifier()); - assertEquals("http://example.com", feed.getLink()); - assertEquals("This is the description", feed.getDescription()); - assertEquals("http://example.com/payment", feed.getPaymentLinks().get(0).url); - assertEquals("http://example.com/picture", feed.getImageUrl()); - assertEquals(10, feed.getItems().size()); - for (int i = 0; i < feed.getItems().size(); i++) { - FeedItem item = feed.getItems().get(i); - assertEquals("http://example.com/item-" + i, item.getItemIdentifier()); - assertEquals("item-" + i, item.getTitle()); - assertNull(item.getDescription()); - assertEquals("http://example.com/items/" + i, item.getLink()); - assertEquals(new Date(i * 60000), item.getPubDate()); - assertNull(item.getPaymentLink()); - assertEquals("http://example.com/picture", item.getImageLocation()); - // media - assertTrue(item.hasMedia()); - FeedMedia media = item.getMedia(); - //noinspection ConstantConditions - assertEquals("http://example.com/media-" + i, media.getDownload_url()); - assertEquals(1024 * 1024, media.getSize()); - assertEquals("audio/mp3", media.getMime_type()); - // chapters - assertNull(item.getChapters()); - } - } - - @Test - public void testEmptyRelLinks() throws Exception { - File feedFile = FeedParserTestHelper.getFeedFile("feed-atom-testEmptyRelLinks.xml"); - Feed feed = FeedParserTestHelper.runFeedParser(feedFile); - assertEquals(Feed.TYPE_ATOM1, feed.getType()); - assertEquals("title", feed.getTitle()); - assertEquals("http://example.com/feed", feed.getFeedIdentifier()); - assertEquals("http://example.com", feed.getLink()); - assertEquals("This is the description", feed.getDescription()); - assertNull(feed.getPaymentLinks()); - assertEquals("http://example.com/picture", feed.getImageUrl()); - assertEquals(1, feed.getItems().size()); - - // feed entry - FeedItem item = feed.getItems().get(0); - assertEquals("http://example.com/item-0", item.getItemIdentifier()); - assertEquals("item-0", item.getTitle()); - assertNull(item.getDescription()); - assertEquals("http://example.com/items/0", item.getLink()); - assertEquals(new Date(0), item.getPubDate()); - assertNull(item.getPaymentLink()); - assertEquals("http://example.com/picture", item.getImageLocation()); - // media - assertFalse(item.hasMedia()); - // chapters - assertNull(item.getChapters()); - } - - @Test - public void testLogoWithWhitespace() throws Exception { - File feedFile = FeedParserTestHelper.getFeedFile("feed-atom-testLogoWithWhitespace.xml"); - Feed feed = FeedParserTestHelper.runFeedParser(feedFile); - assertEquals("title", feed.getTitle()); - assertEquals("http://example.com/feed", feed.getFeedIdentifier()); - assertEquals("http://example.com", feed.getLink()); - assertEquals("This is the description", feed.getDescription()); - assertEquals("http://example.com/payment", feed.getPaymentLinks().get(0).url); - assertEquals("https://example.com/image.png", feed.getImageUrl()); - assertEquals(0, feed.getItems().size()); - } -} diff --git a/core/src/test/java/de/danoeh/antennapod/core/syndication/handler/FeedParserTestHelper.java b/core/src/test/java/de/danoeh/antennapod/core/syndication/handler/FeedParserTestHelper.java deleted file mode 100644 index b9318b377..000000000 --- a/core/src/test/java/de/danoeh/antennapod/core/syndication/handler/FeedParserTestHelper.java +++ /dev/null @@ -1,35 +0,0 @@ -package de.danoeh.antennapod.core.syndication.handler; - -import androidx.annotation.NonNull; - -import java.io.File; - -import de.danoeh.antennapod.model.feed.Feed; - -/** - * Tests for FeedHandler. - */ -public abstract class FeedParserTestHelper { - - /** - * Returns the File object for a file in the resources folder. - */ - @NonNull - static File getFeedFile(@NonNull String fileName) { - //noinspection ConstantConditions - return new File(FeedParserTestHelper.class.getClassLoader().getResource(fileName).getFile()); - } - - /** - * Runs the feed parser on the given file. - */ - @NonNull - static Feed runFeedParser(@NonNull File feedFile) throws Exception { - FeedHandler handler = new FeedHandler(); - Feed parsedFeed = new Feed("http://example.com/feed", null); - parsedFeed.setFile_url(feedFile.getAbsolutePath()); - parsedFeed.setDownloaded(true); - handler.parseFeed(parsedFeed); - return parsedFeed; - } -} diff --git a/core/src/test/java/de/danoeh/antennapod/core/syndication/handler/RssParserTest.java b/core/src/test/java/de/danoeh/antennapod/core/syndication/handler/RssParserTest.java deleted file mode 100644 index d95c8b3ab..000000000 --- a/core/src/test/java/de/danoeh/antennapod/core/syndication/handler/RssParserTest.java +++ /dev/null @@ -1,99 +0,0 @@ -package de.danoeh.antennapod.core.syndication.handler; - -import android.text.TextUtils; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; - -import java.io.File; -import java.util.Date; - -import de.danoeh.antennapod.model.feed.Feed; -import de.danoeh.antennapod.model.feed.FeedItem; -import de.danoeh.antennapod.model.feed.FeedMedia; -import de.danoeh.antennapod.model.playback.MediaType; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -/** - * Tests for RSS feeds in FeedHandler. - */ -@RunWith(RobolectricTestRunner.class) -public class RssParserTest { - - @Test - public void testRss2Basic() throws Exception { - File feedFile = FeedParserTestHelper.getFeedFile("feed-rss-testRss2Basic.xml"); - Feed feed = FeedParserTestHelper.runFeedParser(feedFile); - assertEquals(Feed.TYPE_RSS2, feed.getType()); - assertEquals("title", feed.getTitle()); - assertEquals("en", feed.getLanguage()); - assertEquals("http://example.com", feed.getLink()); - assertEquals("This is the description", feed.getDescription()); - assertEquals("http://example.com/payment", feed.getPaymentLinks().get(0).url); - assertEquals("http://example.com/picture", feed.getImageUrl()); - assertEquals(10, feed.getItems().size()); - for (int i = 0; i < feed.getItems().size(); i++) { - FeedItem item = feed.getItems().get(i); - assertEquals("http://example.com/item-" + i, item.getItemIdentifier()); - assertEquals("item-" + i, item.getTitle()); - assertNull(item.getDescription()); - assertEquals("http://example.com/items/" + i, item.getLink()); - assertEquals(new Date(i * 60000), item.getPubDate()); - assertNull(item.getPaymentLink()); - assertEquals("http://example.com/picture", item.getImageLocation()); - // media - assertTrue(item.hasMedia()); - FeedMedia media = item.getMedia(); - //noinspection ConstantConditions - assertEquals("http://example.com/media-" + i, media.getDownload_url()); - assertEquals(1024 * 1024, media.getSize()); - assertEquals("audio/mp3", media.getMime_type()); - // chapters - assertNull(item.getChapters()); - } - } - - @Test - public void testImageWithWhitespace() throws Exception { - File feedFile = FeedParserTestHelper.getFeedFile("feed-rss-testImageWithWhitespace.xml"); - Feed feed = FeedParserTestHelper.runFeedParser(feedFile); - assertEquals("title", feed.getTitle()); - assertEquals("http://example.com", feed.getLink()); - assertEquals("This is the description", feed.getDescription()); - assertEquals("http://example.com/payment", feed.getPaymentLinks().get(0).url); - assertEquals("https://example.com/image.png", feed.getImageUrl()); - assertEquals(0, feed.getItems().size()); - } - - @Test - public void testMediaContentMime() throws Exception { - File feedFile = FeedParserTestHelper.getFeedFile("feed-rss-testMediaContentMime.xml"); - Feed feed = FeedParserTestHelper.runFeedParser(feedFile); - assertEquals("title", feed.getTitle()); - assertEquals("http://example.com", feed.getLink()); - assertEquals("This is the description", feed.getDescription()); - assertEquals("http://example.com/payment", feed.getPaymentLinks().get(0).url); - assertNull(feed.getImageUrl()); - assertEquals(1, feed.getItems().size()); - FeedItem feedItem = feed.getItems().get(0); - //noinspection ConstantConditions - assertEquals(MediaType.VIDEO, feedItem.getMedia().getMediaType()); - assertEquals("https://www.example.com/file.mp4", feedItem.getMedia().getDownload_url()); - } - - @Test - public void testMultipleFundingTags() throws Exception { - File feedFile = FeedParserTestHelper.getFeedFile("feed-rss-testMultipleFundingTags.xml"); - Feed feed = FeedParserTestHelper.runFeedParser(feedFile); - assertEquals(3, feed.getPaymentLinks().size()); - assertEquals("Text 1", feed.getPaymentLinks().get(0).content); - assertEquals("https://example.com/funding1", feed.getPaymentLinks().get(0).url); - assertEquals("Text 2", feed.getPaymentLinks().get(1).content); - assertEquals("https://example.com/funding2", feed.getPaymentLinks().get(1).url); - assertTrue(TextUtils.isEmpty(feed.getPaymentLinks().get(2).content)); - assertEquals("https://example.com/funding3", feed.getPaymentLinks().get(2).url); - } -} diff --git a/core/src/test/java/de/danoeh/antennapod/core/syndication/namespace/atom/AtomTextTest.java b/core/src/test/java/de/danoeh/antennapod/core/syndication/namespace/atom/AtomTextTest.java deleted file mode 100644 index 6bc614364..000000000 --- a/core/src/test/java/de/danoeh/antennapod/core/syndication/namespace/atom/AtomTextTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package de.danoeh.antennapod.core.syndication.namespace.atom; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; - -import static org.junit.Assert.assertEquals; - -/** - * Unit test for {@link AtomText}. - */ -@RunWith(RobolectricTestRunner.class) -public class AtomTextTest { - - private static final String[][] TEST_DATA = { - {">", ">"}, - {">", ">"}, - {"<Français>", "<Français>"}, - {"ßÄÖÜ", "ßÄÖÜ"}, - {""", "\""}, - {"ß", "ß"}, - {"’", "’"}, - {"‰", "‰"}, - {"€", "€"} - }; - - @Test - public void testProcessingHtml() { - for (String[] pair : TEST_DATA) { - final AtomText atomText = new AtomText("", new NSAtom(), AtomText.TYPE_HTML); - atomText.setContent(pair[0]); - assertEquals(pair[1], atomText.getProcessedContent()); - } - } -} diff --git a/core/src/test/java/de/danoeh/antennapod/core/syndication/parsers/DurationParserTest.java b/core/src/test/java/de/danoeh/antennapod/core/syndication/parsers/DurationParserTest.java deleted file mode 100644 index e7c861969..000000000 --- a/core/src/test/java/de/danoeh/antennapod/core/syndication/parsers/DurationParserTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package de.danoeh.antennapod.core.syndication.parsers; - -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -public class DurationParserTest { - private int milliseconds = 1; - private int seconds = 1000 * milliseconds; - private int minutes = 60 * seconds; - private int hours = 60 * minutes; - - @Test - public void testSecondDurationInMillis() { - long duration = DurationParser.inMillis("00:45"); - assertEquals(45 * seconds, duration); - } - - @Test - public void testSingleNumberDurationInMillis() { - int twoHoursInSeconds = 2 * 60 * 60; - long duration = DurationParser.inMillis(String.valueOf(twoHoursInSeconds)); - assertEquals(2 * hours, duration); - } - - @Test - public void testMinuteSecondDurationInMillis() { - long duration = DurationParser.inMillis("05:10"); - assertEquals(5 * minutes + 10 * seconds, duration); - } - - @Test - public void testHourMinuteSecondDurationInMillis() { - long duration = DurationParser.inMillis("02:15:45"); - assertEquals(2 * hours + 15 * minutes + 45 * seconds, duration); - } - - @Test - public void testSecondsWithMillisecondsInMillis() { - long duration = DurationParser.inMillis("00:00:00.123"); - assertEquals(123, duration); - } -} diff --git a/core/src/test/java/de/danoeh/antennapod/core/util/DateUtilsTest.java b/core/src/test/java/de/danoeh/antennapod/core/util/DateUtilsTest.java deleted file mode 100644 index 92888ae8b..000000000 --- a/core/src/test/java/de/danoeh/antennapod/core/util/DateUtilsTest.java +++ /dev/null @@ -1,174 +0,0 @@ -package de.danoeh.antennapod.core.util; - -import org.junit.Test; - -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.TimeZone; - -import static org.junit.Assert.assertEquals; - -/** - * Unit test for {@link DateUtils}. - */ -public class DateUtilsTest { - - @Test - public void testParseDateWithMicroseconds() { - GregorianCalendar exp = new GregorianCalendar(2015, 2, 28, 13, 31, 4); - exp.setTimeZone(TimeZone.getTimeZone("UTC")); - Date expected = new Date(exp.getTimeInMillis() + 963); - Date actual = DateUtils.parse("2015-03-28T13:31:04.963870"); - assertEquals(expected, actual); - } - - @Test - public void testParseDateWithCentiseconds() { - GregorianCalendar exp = new GregorianCalendar(2015, 2, 28, 13, 31, 4); - exp.setTimeZone(TimeZone.getTimeZone("UTC")); - Date expected = new Date(exp.getTimeInMillis() + 960); - Date actual = DateUtils.parse("2015-03-28T13:31:04.96"); - assertEquals(expected, actual); - } - - @Test - public void testParseDateWithDeciseconds() { - GregorianCalendar exp = new GregorianCalendar(2015, 2, 28, 13, 31, 4); - exp.setTimeZone(TimeZone.getTimeZone("UTC")); - Date expected = new Date(exp.getTimeInMillis() + 900); - Date actual = DateUtils.parse("2015-03-28T13:31:04.9"); - assertEquals(expected.getTime() / 1000, actual.getTime() / 1000); - assertEquals(900, actual.getTime() % 1000); - } - - @Test - public void testParseDateWithMicrosecondsAndTimezone() { - GregorianCalendar exp = new GregorianCalendar(2015, 2, 28, 6, 31, 4); - exp.setTimeZone(TimeZone.getTimeZone("UTC")); - Date expected = new Date(exp.getTimeInMillis() + 963); - Date actual = DateUtils.parse("2015-03-28T13:31:04.963870 +0700"); - assertEquals(expected, actual); - } - - @Test - public void testParseDateWithCentisecondsAndTimezone() { - GregorianCalendar exp = new GregorianCalendar(2015, 2, 28, 6, 31, 4); - exp.setTimeZone(TimeZone.getTimeZone("UTC")); - Date expected = new Date(exp.getTimeInMillis() + 960); - Date actual = DateUtils.parse("2015-03-28T13:31:04.96 +0700"); - assertEquals(expected, actual); - } - - @Test - public void testParseDateWithDecisecondsAndTimezone() { - GregorianCalendar exp = new GregorianCalendar(2015, 2, 28, 6, 31, 4); - exp.setTimeZone(TimeZone.getTimeZone("UTC")); - Date expected = new Date(exp.getTimeInMillis() + 900); - Date actual = DateUtils.parse("2015-03-28T13:31:04.9 +0700"); - assertEquals(expected.getTime() / 1000, actual.getTime() / 1000); - assertEquals(900, actual.getTime() % 1000); - } - - @Test - public void testParseDateWithTimezoneName() { - GregorianCalendar exp = new GregorianCalendar(2015, 2, 28, 6, 31, 4); - exp.setTimeZone(TimeZone.getTimeZone("UTC")); - Date expected = new Date(exp.getTimeInMillis()); - Date actual = DateUtils.parse("Sat, 28 Mar 2015 01:31:04 EST"); - assertEquals(expected, actual); - } - - @Test - public void testParseDateWithTimezoneName2() { - GregorianCalendar exp = new GregorianCalendar(2015, 2, 28, 6, 31, 0); - exp.setTimeZone(TimeZone.getTimeZone("UTC")); - Date expected = new Date(exp.getTimeInMillis()); - Date actual = DateUtils.parse("Sat, 28 Mar 2015 01:31 EST"); - assertEquals(expected, actual); - } - - @Test - public void testParseDateWithTimeZoneOffset() { - GregorianCalendar exp = new GregorianCalendar(2015, 2, 28, 12, 16, 12); - exp.setTimeZone(TimeZone.getTimeZone("UTC")); - Date expected = new Date(exp.getTimeInMillis()); - Date actual = DateUtils.parse("Sat, 28 March 2015 08:16:12 -0400"); - assertEquals(expected, actual); - } - - @Test - public void testAsctime() { - GregorianCalendar exp = new GregorianCalendar(2011, 4, 25, 12, 33, 0); - exp.setTimeZone(TimeZone.getTimeZone("UTC")); - Date expected = new Date(exp.getTimeInMillis()); - Date actual = DateUtils.parse("Wed, 25 May 2011 12:33:00"); - assertEquals(expected, actual); - } - - @Test - public void testMultipleConsecutiveSpaces() { - GregorianCalendar exp = new GregorianCalendar(2010, 2, 23, 6, 6, 26); - exp.setTimeZone(TimeZone.getTimeZone("UTC")); - Date expected = new Date(exp.getTimeInMillis()); - Date actual = DateUtils.parse("Tue, 23 Mar 2010 01:06:26 -0500"); - assertEquals(expected, actual); - } - - @Test - public void testParseDateWithNoTimezonePadding() { - GregorianCalendar exp = new GregorianCalendar(2017, 1, 22, 22, 28, 0); - exp.setTimeZone(TimeZone.getTimeZone("UTC")); - Date expected = new Date(exp.getTimeInMillis() + 2); - Date actual = DateUtils.parse("2017-02-22T14:28:00.002-08:00"); - assertEquals(expected, actual); - } - - /** - * Requires Android platform. Root cause: {@link DateUtils} implementation makes - * use of ISO 8601 time zone, which does not work on standard JDK. - * - * @see #testParseDateWithNoTimezonePadding() - */ - @Test - public void testParseDateWithForCest() { - GregorianCalendar exp1 = new GregorianCalendar(2017, 0, 28, 22, 0, 0); - exp1.setTimeZone(TimeZone.getTimeZone("UTC")); - Date expected1 = new Date(exp1.getTimeInMillis()); - Date actual1 = DateUtils.parse("Sun, 29 Jan 2017 00:00:00 CEST"); - assertEquals(expected1, actual1); - - GregorianCalendar exp2 = new GregorianCalendar(2017, 0, 28, 23, 0, 0); - exp2.setTimeZone(TimeZone.getTimeZone("UTC")); - Date expected2 = new Date(exp2.getTimeInMillis()); - Date actual2 = DateUtils.parse("Sun, 29 Jan 2017 00:00:00 CET"); - assertEquals(expected2, actual2); - } - - @Test - public void testParseDateWithIncorrectWeekday() { - GregorianCalendar exp1 = new GregorianCalendar(2014, 9, 8, 9, 0, 0); - exp1.setTimeZone(TimeZone.getTimeZone("GMT")); - Date expected = new Date(exp1.getTimeInMillis()); - Date actual = DateUtils.parse("Thu, 8 Oct 2014 09:00:00 GMT"); // actually a Wednesday - assertEquals(expected, actual); - } - - @Test - public void testParseDateWithBadAbbreviation() { - GregorianCalendar exp1 = new GregorianCalendar(2014, 8, 8, 0, 0, 0); - exp1.setTimeZone(TimeZone.getTimeZone("GMT")); - Date expected = new Date(exp1.getTimeInMillis()); - Date actual = DateUtils.parse("Mon, 8 Sept 2014 00:00:00 GMT"); // should be Sep - assertEquals(expected, actual); - } - - @Test - public void testParseDateWithTwoTimezones() { - final GregorianCalendar exp1 = new GregorianCalendar(2015, Calendar.MARCH, 1, 1, 0, 0); - exp1.setTimeZone(TimeZone.getTimeZone("GMT-4")); - final Date expected = new Date(exp1.getTimeInMillis()); - final Date actual = DateUtils.parse("Sun 01 Mar 2015 01:00:00 GMT-0400 (EDT)"); - assertEquals(expected, actual); - } -} diff --git a/core/src/test/resources/feed-atom-testAtomBasic.xml b/core/src/test/resources/feed-atom-testAtomBasic.xml deleted file mode 100644 index cefc4f979..000000000 --- a/core/src/test/resources/feed-atom-testAtomBasic.xml +++ /dev/null @@ -1 +0,0 @@ -<?xml version='1.0' encoding='UTF-8' ?><feed xmlns="http://www.w3.org/2005/Atom"><id>http://example.com/feed</id><title>title</title><link rel="alternate" href="http://example.com" /><subtitle>This is the description</subtitle><logo>http://example.com/picture</logo><link rel="payment" href="http://example.com/payment" type="text/html" /><entry><id>http://example.com/item-0</id><title>item-0</title><link rel="alternate" href="http://example.com/items/0" /><published>1970-01-01T00:00:00Z</published><link rel="enclosure" href="http://example.com/media-0" type="audio/mp3" length="1048576" /></entry><entry><id>http://example.com/item-1</id><title>item-1</title><link rel="alternate" href="http://example.com/items/1" /><published>1970-01-01T00:01:00Z</published><link rel="enclosure" href="http://example.com/media-1" type="audio/mp3" length="1048576" /></entry><entry><id>http://example.com/item-2</id><title>item-2</title><link rel="alternate" href="http://example.com/items/2" /><published>1970-01-01T00:02:00Z</published><link rel="enclosure" href="http://example.com/media-2" type="audio/mp3" length="1048576" /></entry><entry><id>http://example.com/item-3</id><title>item-3</title><link rel="alternate" href="http://example.com/items/3" /><published>1970-01-01T00:03:00Z</published><link rel="enclosure" href="http://example.com/media-3" type="audio/mp3" length="1048576" /></entry><entry><id>http://example.com/item-4</id><title>item-4</title><link rel="alternate" href="http://example.com/items/4" /><published>1970-01-01T00:04:00Z</published><link rel="enclosure" href="http://example.com/media-4" type="audio/mp3" length="1048576" /></entry><entry><id>http://example.com/item-5</id><title>item-5</title><link rel="alternate" href="http://example.com/items/5" /><published>1970-01-01T00:05:00Z</published><link rel="enclosure" href="http://example.com/media-5" type="audio/mp3" length="1048576" /></entry><entry><id>http://example.com/item-6</id><title>item-6</title><link rel="alternate" href="http://example.com/items/6" /><published>1970-01-01T00:06:00Z</published><link rel="enclosure" href="http://example.com/media-6" type="audio/mp3" length="1048576" /></entry><entry><id>http://example.com/item-7</id><title>item-7</title><link rel="alternate" href="http://example.com/items/7" /><published>1970-01-01T00:07:00Z</published><link rel="enclosure" href="http://example.com/media-7" type="audio/mp3" length="1048576" /></entry><entry><id>http://example.com/item-8</id><title>item-8</title><link rel="alternate" href="http://example.com/items/8" /><published>1970-01-01T00:08:00Z</published><link rel="enclosure" href="http://example.com/media-8" type="audio/mp3" length="1048576" /></entry><entry><id>http://example.com/item-9</id><title>item-9</title><link rel="alternate" href="http://example.com/items/9" /><published>1970-01-01T00:09:00Z</published><link rel="enclosure" href="http://example.com/media-9" type="audio/mp3" length="1048576" /></entry></feed>
\ No newline at end of file diff --git a/core/src/test/resources/feed-atom-testEmptyRelLinks.xml b/core/src/test/resources/feed-atom-testEmptyRelLinks.xml deleted file mode 100644 index 04c28ef67..000000000 --- a/core/src/test/resources/feed-atom-testEmptyRelLinks.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<feed xmlns="http://www.w3.org/2005/Atom"> - <id>http://example.com/feed</id> - <title>title</title> - <link href="http://example.com" /> - <subtitle>This is the description</subtitle> - <logo>http://example.com/picture</logo> - <entry> - <id>http://example.com/item-0</id> - <title>item-0</title> - <link href="http://example.com/items/0" /> - <published>1970-01-01T00:00:00Z</published> - </entry> -</feed> diff --git a/core/src/test/resources/feed-atom-testLogoWithWhitespace.xml b/core/src/test/resources/feed-atom-testLogoWithWhitespace.xml deleted file mode 100644 index f4886d56a..000000000 --- a/core/src/test/resources/feed-atom-testLogoWithWhitespace.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version='1.0' encoding='UTF-8' ?><feed xmlns="http://www.w3.org/2005/Atom"><id>http://example.com/feed</id><title>title</title><link rel="alternate" href="http://example.com" /><subtitle>This is the description</subtitle><link rel="payment" href="http://example.com/payment" type="text/html" /><logo> https://example.com/image.png -</logo></feed>
\ No newline at end of file diff --git a/core/src/test/resources/feed-rss-testImageWithWhitespace.xml b/core/src/test/resources/feed-rss-testImageWithWhitespace.xml deleted file mode 100644 index 2be9401d2..000000000 --- a/core/src/test/resources/feed-rss-testImageWithWhitespace.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version='1.0' encoding='UTF-8' ?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>title</title><description>This is the description</description><link>http://example.com</link><language>en</language><atom:link rel="payment" href="http://example.com/payment" type="text/html" /><image><url> https://example.com/image.png -</url></image></channel></rss>
\ No newline at end of file diff --git a/core/src/test/resources/feed-rss-testMediaContentMime.xml b/core/src/test/resources/feed-rss-testMediaContentMime.xml deleted file mode 100644 index a715abb37..000000000 --- a/core/src/test/resources/feed-rss-testMediaContentMime.xml +++ /dev/null @@ -1 +0,0 @@ -<?xml version='1.0' encoding='UTF-8' ?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>title</title><description>This is the description</description><link>http://example.com</link><language>en</language><atom:link rel="payment" href="http://example.com/payment" type="text/html" /><item xmlns:media="http://search.yahoo.com/mrss/"><media:content url="https://www.example.com/file.mp4" medium="video" /></item></channel></rss>
\ No newline at end of file diff --git a/core/src/test/resources/feed-rss-testMultipleFundingTags.xml b/core/src/test/resources/feed-rss-testMultipleFundingTags.xml deleted file mode 100644 index 2535bda32..000000000 --- a/core/src/test/resources/feed-rss-testMultipleFundingTags.xml +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version='1.0' encoding='UTF-8' ?> -<rss version="2.0" xmlns:podcast="https://podcastindex.org/namespace/1.0"> - <channel> - <title>title</title> - </channel> - <podcast:funding url="https://example.com/funding1">Text 1</podcast:funding> - <podcast:funding url="https://example.com/funding2">Text 2</podcast:funding> - <podcast:funding url="https://example.com/funding3" /> -</rss> diff --git a/core/src/test/resources/feed-rss-testRss2Basic.xml b/core/src/test/resources/feed-rss-testRss2Basic.xml deleted file mode 100644 index dd771b61a..000000000 --- a/core/src/test/resources/feed-rss-testRss2Basic.xml +++ /dev/null @@ -1 +0,0 @@ -<?xml version='1.0' encoding='UTF-8' ?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>title</title><description>This is the description</description><link>http://example.com</link><language>en</language><image><url>http://example.com/picture</url></image><atom:link rel="payment" href="http://example.com/payment" type="text/html" /><item><title>item-0</title><link>http://example.com/items/0</link><pubDate>01 Jan 70 01:00:00 +0100</pubDate><guid>http://example.com/item-0</guid><enclosure url="http://example.com/media-0" length="1048576" type="audio/mp3" /></item><item><title>item-1</title><link>http://example.com/items/1</link><pubDate>01 Jan 70 01:01:00 +0100</pubDate><guid>http://example.com/item-1</guid><enclosure url="http://example.com/media-1" length="1048576" type="audio/mp3" /></item><item><title>item-2</title><link>http://example.com/items/2</link><pubDate>01 Jan 70 01:02:00 +0100</pubDate><guid>http://example.com/item-2</guid><enclosure url="http://example.com/media-2" length="1048576" type="audio/mp3" /></item><item><title>item-3</title><link>http://example.com/items/3</link><pubDate>01 Jan 70 01:03:00 +0100</pubDate><guid>http://example.com/item-3</guid><enclosure url="http://example.com/media-3" length="1048576" type="audio/mp3" /></item><item><title>item-4</title><link>http://example.com/items/4</link><pubDate>01 Jan 70 01:04:00 +0100</pubDate><guid>http://example.com/item-4</guid><enclosure url="http://example.com/media-4" length="1048576" type="audio/mp3" /></item><item><title>item-5</title><link>http://example.com/items/5</link><pubDate>01 Jan 70 01:05:00 +0100</pubDate><guid>http://example.com/item-5</guid><enclosure url="http://example.com/media-5" length="1048576" type="audio/mp3" /></item><item><title>item-6</title><link>http://example.com/items/6</link><pubDate>01 Jan 70 01:06:00 +0100</pubDate><guid>http://example.com/item-6</guid><enclosure url="http://example.com/media-6" length="1048576" type="audio/mp3" /></item><item><title>item-7</title><link>http://example.com/items/7</link><pubDate>01 Jan 70 01:07:00 +0100</pubDate><guid>http://example.com/item-7</guid><enclosure url="http://example.com/media-7" length="1048576" type="audio/mp3" /></item><item><title>item-8</title><link>http://example.com/items/8</link><pubDate>01 Jan 70 01:08:00 +0100</pubDate><guid>http://example.com/item-8</guid><enclosure url="http://example.com/media-8" length="1048576" type="audio/mp3" /></item><item><title>item-9</title><link>http://example.com/items/9</link><pubDate>01 Jan 70 01:09:00 +0100</pubDate><guid>http://example.com/item-9</guid><enclosure url="http://example.com/media-9" length="1048576" type="audio/mp3" /></item></channel></rss>
\ No newline at end of file |