summaryrefslogtreecommitdiff
path: root/core/src/main/java
diff options
context:
space:
mode:
authorTony Tam <149837+tonytamsf@users.noreply.github.com>2021-04-06 09:15:14 -0700
committerGitHub <noreply@github.com>2021-04-06 18:15:14 +0200
commit79c79efce588b446cf9816a01e0056e7e3dfd9db (patch)
treefaa91fbd058c9fb93a827f68dac4062de3c0b04d /core/src/main/java
parentef41704166cc17b95159a891e7be36c8b334b8b4 (diff)
downloadAntennaPod-79c79efce588b446cf9816a01e0056e7e3dfd9db.zip
Parsing podcast:funding tag, showing payment, funding links on the show info screen (#4933)
Diffstat (limited to 'core/src/main/java')
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java28
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/FeedFunding.java91
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java3
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/syndication/handler/HandlerState.java10
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/syndication/handler/SyndHandler.java9
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/PodcastIndex.java38
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/atom/NSAtom.java3
7 files changed, 166 insertions, 16 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java b/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java
index dd8a466eb..617997465 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java
@@ -54,7 +54,7 @@ public class Feed extends FeedFile {
*/
private String lastUpdate;
- private String paymentLink;
+ private ArrayList<FeedFunding> fundingList;
/**
* Feed type, for example RSS 2 or Atom.
*/
@@ -103,8 +103,9 @@ public class Feed extends FeedFile {
/**
* This constructor is used for restoring a feed from the database.
*/
- public Feed(long id, String lastUpdate, String title, String customTitle, String link, String description, String paymentLink,
- String author, String language, String type, String feedIdentifier, String imageUrl, String fileUrl,
+ public Feed(long id, String lastUpdate, String title, String customTitle, String link,
+ String description, String paymentLinks, String author, String language,
+ String type, String feedIdentifier, String imageUrl, String fileUrl,
String downloadUrl, boolean downloaded, boolean paged, String nextPageLink,
String filter, @Nullable SortOrder sortOrder, boolean lastUpdateFailed) {
super(fileUrl, downloadUrl, downloaded);
@@ -114,7 +115,7 @@ public class Feed extends FeedFile {
this.lastUpdate = lastUpdate;
this.link = link;
this.description = description;
- this.paymentLink = paymentLink;
+ this.fundingList = FeedFunding.extractPaymentLinks(paymentLinks);
this.author = author;
this.language = language;
this.type = type;
@@ -237,8 +238,8 @@ public class Feed extends FeedFile {
if (other.author != null) {
author = other.author;
}
- if (other.paymentLink != null) {
- paymentLink = other.paymentLink;
+ if (other.fundingList != null) {
+ fundingList = other.fundingList;
}
// this feed's nextPage might already point to a higher page, so we only update the nextPage value
// if this feed is not paged and the other feed is.
@@ -285,8 +286,8 @@ public class Feed extends FeedFile {
return true;
}
}
- if (other.paymentLink != null) {
- if (paymentLink == null || !paymentLink.equals(other.paymentLink)) {
+ if (other.fundingList != null) {
+ if (fundingList == null || !fundingList.equals(other.fundingList)) {
return true;
}
}
@@ -390,12 +391,15 @@ public class Feed extends FeedFile {
this.feedIdentifier = feedIdentifier;
}
- public String getPaymentLink() {
- return paymentLink;
+ public void addPayment(FeedFunding funding) {
+ if (fundingList == null) {
+ fundingList = new ArrayList<FeedFunding>();
+ }
+ fundingList.add(funding);
}
- public void setPaymentLink(String paymentLink) {
- this.paymentLink = paymentLink;
+ public ArrayList<FeedFunding> getPaymentLinks() {
+ return fundingList;
}
public String getLanguage() {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedFunding.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedFunding.java
new file mode 100644
index 000000000..151e68a4f
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedFunding.java
@@ -0,0 +1,91 @@
+package de.danoeh.antennapod.core.feed;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.ArrayList;
+
+public class FeedFunding {
+ public static final String FUNDING_ENTRIES_SEPARATOR = "\u001e";
+ public static final String FUNDING_TITLE_SEPARATOR = "\u001f";
+
+ public String url;
+ public String content;
+
+ public FeedFunding(String url, String content) {
+ this.url = url;
+ this.content = content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || !obj.getClass().equals(this.getClass())) {
+ return false;
+ }
+
+ FeedFunding funding = (FeedFunding) obj;
+ if (url == null && funding.url == null && content == null && funding.content == null) {
+ return true;
+ }
+ if (url != null && url.equals(funding.url) && content != null && content.equals(funding.content)) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return (url + FUNDING_TITLE_SEPARATOR + content).hashCode();
+ }
+
+ public static ArrayList<FeedFunding> extractPaymentLinks(String payLinks) {
+ if (StringUtils.isBlank(payLinks)) {
+ return null;
+ }
+ // old format before we started with PodcastIndex funding tag
+ ArrayList<FeedFunding> funding = new ArrayList<FeedFunding>();
+ if (!payLinks.contains(FeedFunding.FUNDING_ENTRIES_SEPARATOR)
+ && !payLinks.contains(FeedFunding.FUNDING_TITLE_SEPARATOR)) {
+ funding.add(new FeedFunding(payLinks, ""));
+ return funding;
+ }
+ String [] list = payLinks.split(FeedFunding.FUNDING_ENTRIES_SEPARATOR);
+ if (list.length == 0) {
+ return null;
+ }
+
+ for (String str : list) {
+ String [] linkContent = str.split(FeedFunding.FUNDING_TITLE_SEPARATOR);
+ if (StringUtils.isBlank(linkContent[0])) {
+ continue;
+ }
+ String url = linkContent[0];
+ String title = "";
+ if (linkContent.length > 1 && ! StringUtils.isBlank(linkContent[1])) {
+ title = linkContent[1];
+ }
+ funding.add(new FeedFunding(url, title));
+ }
+ return funding;
+ }
+
+ public static String getPaymentLinksAsString(ArrayList<FeedFunding> fundingList) {
+ StringBuilder result = new StringBuilder();
+ if (fundingList == null) {
+ return null;
+ }
+ for (FeedFunding fund : fundingList) {
+ result.append(fund.url).append(FeedFunding.FUNDING_TITLE_SEPARATOR).append(fund.content);
+ result.append(FeedFunding.FUNDING_ENTRIES_SEPARATOR);
+ }
+ return StringUtils.removeEnd(result.toString(), FeedFunding.FUNDING_ENTRIES_SEPARATOR);
+ }
+
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
index 7ab776856..bad7775f2 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
@@ -17,6 +17,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import de.danoeh.antennapod.core.feed.FeedFunding;
import de.danoeh.antennapod.core.storage.mapper.FeedItemFilterQuery;
import org.apache.commons.io.FileUtils;
@@ -403,7 +404,7 @@ public class PodDBAdapter {
values.put(KEY_TITLE, feed.getFeedTitle());
values.put(KEY_LINK, feed.getLink());
values.put(KEY_DESCRIPTION, feed.getDescription());
- values.put(KEY_PAYMENT_LINK, feed.getPaymentLink());
+ values.put(KEY_PAYMENT_LINK, FeedFunding.getPaymentLinksAsString(feed.getPaymentLinks()));
values.put(KEY_AUTHOR, feed.getAuthor());
values.put(KEY_LANGUAGE, feed.getLanguage());
values.put(KEY_IMAGE_URL, feed.getImageUrl());
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
index 608cade88..7aaf66668 100644
--- 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
@@ -7,6 +7,7 @@ import java.util.Map;
import java.util.Stack;
import de.danoeh.antennapod.core.feed.Feed;
+import de.danoeh.antennapod.core.feed.FeedFunding;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.syndication.namespace.Namespace;
import de.danoeh.antennapod.core.syndication.namespace.SyndElement;
@@ -28,6 +29,7 @@ public class HandlerState {
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.
@@ -78,6 +80,14 @@ public class HandlerState {
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.
*/
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
index ab66b912b..5beb36d6d 100644
--- 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
@@ -14,6 +14,7 @@ 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;
@@ -107,9 +108,13 @@ class SyndHandler extends DefaultHandler {
&& 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);
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
new file mode 100644
index 000000000..eb68c0915
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/PodcastIndex.java
@@ -0,0 +1,38 @@
+package de.danoeh.antennapod.core.syndication.namespace;
+
+import org.jsoup.helper.StringUtil;
+import org.xml.sax.Attributes;
+import de.danoeh.antennapod.core.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/atom/NSAtom.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/atom/NSAtom.java
index 42f787d98..eeca82aee 100644
--- 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
@@ -3,6 +3,7 @@ package de.danoeh.antennapod.core.syndication.namespace.atom;
import android.text.TextUtils;
import android.util.Log;
+import de.danoeh.antennapod.core.feed.FeedFunding;
import de.danoeh.antennapod.core.syndication.util.SyndStringUtils;
import org.xml.sax.Attributes;
@@ -137,7 +138,7 @@ public class NSAtom extends Namespace {
//A Link such as to a directory such as iTunes
}
} else if (LINK_REL_PAYMENT.equals(rel) && state.getFeed() != null) {
- state.getFeed().setPaymentLink(href);
+ state.getFeed().addPayment(new FeedFunding(href, ""));
} else if (LINK_REL_NEXT.equals(rel) && state.getFeed() != null) {
state.getFeed().setPaged(true);
state.getFeed().setNextPageLink(href);