From 19297a1c255f331d5beaa1ccaa73948fc195597d Mon Sep 17 00:00:00 2001 From: daniel oeh Date: Mon, 31 Dec 2012 18:55:43 +0100 Subject: [PATCH] Added support for media:content tag, fixes #82 --- .../syndication/handler/SyndHandler.java | 9 ++- .../syndication/namespace/NSMedia.java | 70 +++++++++++++++++++ .../syndication/namespace/NSRSS20.java | 2 +- .../syndication/namespace/atom/NSAtom.java | 2 +- .../syndication/util/SyndTypeUtils.java | 4 +- .../de/danoeh/antennapod/test/TestFeeds.java | 3 +- 6 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 src/de/danoeh/antennapod/syndication/namespace/NSMedia.java diff --git a/src/de/danoeh/antennapod/syndication/handler/SyndHandler.java b/src/de/danoeh/antennapod/syndication/handler/SyndHandler.java index 4c73e72e8..f830f0933 100644 --- a/src/de/danoeh/antennapod/syndication/handler/SyndHandler.java +++ b/src/de/danoeh/antennapod/syndication/handler/SyndHandler.java @@ -9,6 +9,7 @@ import de.danoeh.antennapod.AppConfig; import de.danoeh.antennapod.feed.Feed; import de.danoeh.antennapod.syndication.namespace.NSContent; import de.danoeh.antennapod.syndication.namespace.NSITunes; +import de.danoeh.antennapod.syndication.namespace.NSMedia; import de.danoeh.antennapod.syndication.namespace.NSRSS20; import de.danoeh.antennapod.syndication.namespace.NSSimpleChapters; import de.danoeh.antennapod.syndication.namespace.Namespace; @@ -101,13 +102,19 @@ public class SyndHandler extends DefaultHandler { state.namespaces.put(uri, new NSSimpleChapters()); if (AppConfig.DEBUG) Log.d(TAG, "Recognized SimpleChapters namespace"); + } else if (uri.equals(NSMedia.NSURI) + && prefix.equals(NSMedia.NSTAG)) { + state.namespaces.put(uri, new NSMedia()); + if (AppConfig.DEBUG) + Log.d(TAG, "Recognized media namespace"); } } } private Namespace getHandlingNamespace(String uri, String qName) { Namespace handler = state.namespaces.get(uri); - if (handler == null && !state.defaultNamespaces.empty() && !qName.contains(":")) { + if (handler == null && !state.defaultNamespaces.empty() + && !qName.contains(":")) { handler = state.defaultNamespaces.peek(); } return handler; diff --git a/src/de/danoeh/antennapod/syndication/namespace/NSMedia.java b/src/de/danoeh/antennapod/syndication/namespace/NSMedia.java new file mode 100644 index 000000000..e480a0266 --- /dev/null +++ b/src/de/danoeh/antennapod/syndication/namespace/NSMedia.java @@ -0,0 +1,70 @@ +package de.danoeh.antennapod.syndication.namespace; + +import java.util.concurrent.TimeUnit; + +import org.xml.sax.Attributes; + +import android.util.Log; + +import de.danoeh.antennapod.AppConfig; +import de.danoeh.antennapod.feed.FeedMedia; +import de.danoeh.antennapod.syndication.handler.HandlerState; +import de.danoeh.antennapod.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"; + + @Override + public SyndElement handleElementStart(String localName, HandlerState state, + Attributes attributes) { + if (localName.equals(CONTENT)) { + String url = attributes.getValue(DOWNLOAD_URL); + String type = attributes.getValue(MIME_TYPE); + if (state.getCurrentItem().getMedia() == null + && url != null + && (SyndTypeUtils.enclosureTypeValid(type) || ((type = SyndTypeUtils + .getValidMimeTypeFromUrl(url)) != null))) { + + long size = 0; + try { + size = Long.parseLong(attributes.getValue(SIZE)); + } catch (NumberFormatException e) { + if (AppConfig.DEBUG) + Log.d(TAG, "Length attribute could not be parsed."); + } + + int duration = 0; + try { + String durationStr = attributes.getValue(DURATION); + if (durationStr != null) { + duration = (int) TimeUnit.MILLISECONDS.convert( + Long.parseLong(durationStr), TimeUnit.SECONDS); + } + } catch (NumberFormatException e) { + if (AppConfig.DEBUG) + Log.d(TAG, "Duration attribute could not be parsed"); + } + + state.getCurrentItem().setMedia( + new FeedMedia(state.getCurrentItem(), url, size, type)); + } + } + return new SyndElement(localName, this); + } + + @Override + public void handleElementEnd(String localName, HandlerState state) { + + } + +} diff --git a/src/de/danoeh/antennapod/syndication/namespace/NSRSS20.java b/src/de/danoeh/antennapod/syndication/namespace/NSRSS20.java index dfdf188db..a8c43800c 100644 --- a/src/de/danoeh/antennapod/syndication/namespace/NSRSS20.java +++ b/src/de/danoeh/antennapod/syndication/namespace/NSRSS20.java @@ -50,7 +50,7 @@ public class NSRSS20 extends Namespace { String type = attributes.getValue(ENC_TYPE); String url = attributes.getValue(ENC_URL); if (state.getCurrentItem().getMedia() == null - && (SyndTypeUtils.typeValid(type) || ((type = SyndTypeUtils + && (SyndTypeUtils.enclosureTypeValid(type) || ((type = SyndTypeUtils .getValidMimeTypeFromUrl(url)) != null))) { long size = 0; diff --git a/src/de/danoeh/antennapod/syndication/namespace/atom/NSAtom.java b/src/de/danoeh/antennapod/syndication/namespace/atom/NSAtom.java index 51c30e579..e3cdce534 100644 --- a/src/de/danoeh/antennapod/syndication/namespace/atom/NSAtom.java +++ b/src/de/danoeh/antennapod/syndication/namespace/atom/NSAtom.java @@ -73,7 +73,7 @@ public class NSAtom extends Namespace { if (strSize != null) size = Long.parseLong(strSize); String type = attributes.getValue(LINK_TYPE); - if (SyndTypeUtils.typeValid(type) + if (SyndTypeUtils.enclosureTypeValid(type) || (type = SyndTypeUtils .getValidMimeTypeFromUrl(href)) != null) { state.getCurrentItem().setMedia( diff --git a/src/de/danoeh/antennapod/syndication/util/SyndTypeUtils.java b/src/de/danoeh/antennapod/syndication/util/SyndTypeUtils.java index d989b7be1..fe7836d37 100644 --- a/src/de/danoeh/antennapod/syndication/util/SyndTypeUtils.java +++ b/src/de/danoeh/antennapod/syndication/util/SyndTypeUtils.java @@ -14,7 +14,7 @@ public class SyndTypeUtils { } - public static boolean typeValid(String type) { + public static boolean enclosureTypeValid(String type) { if (type == null) { return false; } else { @@ -33,7 +33,7 @@ public class SyndTypeUtils { if (extension != null) { String type = MimeTypeMap.getSingleton() .getMimeTypeFromExtension(extension); - if (type != null && typeValid(type)) { + if (type != null && enclosureTypeValid(type)) { return type; } } diff --git a/tests/src/de/danoeh/antennapod/test/TestFeeds.java b/tests/src/de/danoeh/antennapod/test/TestFeeds.java index 58de4ab19..38aff463a 100644 --- a/tests/src/de/danoeh/antennapod/test/TestFeeds.java +++ b/tests/src/de/danoeh/antennapod/test/TestFeeds.java @@ -3,6 +3,7 @@ package de.danoeh.antennapod.test; public class TestFeeds { public static final String[] urls = { + "http://www.guardian.co.uk/global-development/series/global-development-podcast/rss", "http://rss.sciam.com/sciam/60secsciencepodcast", "http://rss.sciam.com/sciam/60-second-mind", "http://rss.sciam.com/sciam/60-second-space", @@ -37,7 +38,6 @@ public class TestFeeds { "http://www.casasola.de/137b/1337motiv/1337motiv.xml", "http://alternativlos.org/ogg.rss", "http://www.bitsundso.de/feed", "http://www.gamesundso.de/feed/", - "http://chaosradio.ccc.de/chaosradio-latest.rss", "http://feeds.feedburner.com/cre-podcast", "http://feeds.feedburner.com/NotSafeForWorkPodcast", "http://feeds.feedburner.com/mobile-macs-podcast", @@ -228,7 +228,6 @@ public class TestFeeds { "http://bitlove.org/mfromm/explorism/feed", "http://bitlove.org/mfromm/transientesichten/feed", "http://bitlove.org/mhpod/pofacs/feed", - "http://bitlove.org/michaela_w/michaelaswelt/feed", "http://bitlove.org/michaelgreth/sharepointpdcast/feed", "http://bitlove.org/mintcast/podcast/feed", "http://bitlove.org/mitgezwitschert/brandung/feed",