summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Fietz <Martin.Fietz@gmail.com>2019-05-19 13:40:20 +0200
committerGitHub <noreply@github.com>2019-05-19 13:40:20 +0200
commit135df61692ee1d6d3cee59039ae633a0ac9549f3 (patch)
tree31061c685d75c2aca667626dac7d52364623e530
parent5db139958aaf674de06fa0b6e47084e81e375e63 (diff)
parentfb3bfa9f8018bd89b97fd0e0c53ea4fab1687aa2 (diff)
downloadAntennaPod-135df61692ee1d6d3cee59039ae633a0ac9549f3.zip
Merge pull request #3159 from andersonvom/3024-itunes-duration-format
Handle iTunes single-number duration format
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java115
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/syndication/parsers/DurationParser.java37
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/syndication/parsers/DurationParserTest.java43
3 files changed, 142 insertions, 53 deletions
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
index b3b8a40ce..1e069a1f0 100644
--- 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
@@ -5,9 +5,9 @@ import android.util.Log;
import org.xml.sax.Attributes;
-import java.util.concurrent.TimeUnit;
-
+import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.syndication.handler.HandlerState;
+import de.danoeh.antennapod.core.syndication.parsers.DurationParser;
public class NSITunes extends Namespace {
@@ -22,7 +22,6 @@ public class NSITunes extends Namespace {
private static final String SUBTITLE = "subtitle";
private static final String SUMMARY = "summary";
-
@Override
public SyndElement handleElementStart(String localName, HandlerState state,
Attributes attributes) {
@@ -44,65 +43,75 @@ public class NSITunes extends Namespace {
@Override
public void handleElementEnd(String localName, HandlerState state) {
- if(state.getContentBuf() == null) {
+ if (state.getContentBuf() == null) {
return;
}
- SyndElement secondElement = state.getSecondTag();
- String second = secondElement.getName();
if (AUTHOR.equals(localName)) {
- if (state.getFeed() != null) {
- String author = state.getContentBuf().toString();
- state.getFeed().setAuthor(author);
- }
+ parseAuthor(state);
} else if (DURATION.equals(localName)) {
- String durationStr = state.getContentBuf().toString();
- if(TextUtils.isEmpty(durationStr)) {
- return;
- }
- String[] parts = durationStr.trim().split(":");
- try {
- int durationMs = 0;
- if (parts.length == 2) {
- durationMs += TimeUnit.MINUTES.toMillis(Long.parseLong(parts[0])) +
- TimeUnit.SECONDS.toMillis((long)Float.parseFloat(parts[1]));
- } else if (parts.length >= 3) {
- durationMs += TimeUnit.HOURS.toMillis(Long.parseLong(parts[0])) +
- TimeUnit.MINUTES.toMillis(Long.parseLong(parts[1])) +
- TimeUnit.SECONDS.toMillis((long)Float.parseFloat(parts[2]));
- } else {
- return;
- }
- state.getTempObjects().put(DURATION, durationMs);
- } catch (NumberFormatException e) {
- Log.e(NSTAG, "Duration \"" + durationStr + "\" could not be parsed");
- }
+ parseDuration(state);
} else if (SUBTITLE.equals(localName)) {
- String subtitle = state.getContentBuf().toString();
- if (TextUtils.isEmpty(subtitle)) {
- return;
- }
- if (state.getCurrentItem() != null) {
- if (TextUtils.isEmpty(state.getCurrentItem().getDescription())) {
- state.getCurrentItem().setDescription(subtitle);
- }
- } else {
- if (state.getFeed() != null && TextUtils.isEmpty(state.getFeed().getDescription())) {
- state.getFeed().setDescription(subtitle);
- }
- }
+ parseSubtitle(state);
} else if (SUMMARY.equals(localName)) {
- String summary = state.getContentBuf().toString();
- if (TextUtils.isEmpty(summary)) {
- return;
+ 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(author);
+ }
+ }
+
+ 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().setDescription(subtitle);
}
- if (state.getCurrentItem() != null &&
- (TextUtils.isEmpty(state.getCurrentItem().getDescription()) ||
- state.getCurrentItem().getDescription().length() * 1.25 < summary.length())) {
- state.getCurrentItem().setDescription(summary);
- } else if (NSRSS20.CHANNEL.equals(second) && state.getFeed() != null) {
- state.getFeed().setDescription(summary);
+ } 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;
+ }
+
+ FeedItem currentItem = state.getCurrentItem();
+ String description = getDescription(currentItem);
+ if (currentItem != null && description.length() * 1.25 < summary.length()) {
+ currentItem.setDescription(summary);
+ } else if (NSRSS20.CHANNEL.equals(secondElementName) && state.getFeed() != null) {
+ state.getFeed().setDescription(summary);
+ }
+ }
+
+ private String getDescription(FeedItem item) {
+ return (item != null && item.getDescription() != null) ? item.getDescription() : "";
+ }
}
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
new file mode 100644
index 000000000..8b036c6a9
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/parsers/DurationParser.java
@@ -0,0 +1,37 @@
+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/test/java/de/danoeh/antennapod/core/syndication/parsers/DurationParserTest.java b/core/src/test/java/de/danoeh/antennapod/core/syndication/parsers/DurationParserTest.java
new file mode 100644
index 000000000..e7c861969
--- /dev/null
+++ b/core/src/test/java/de/danoeh/antennapod/core/syndication/parsers/DurationParserTest.java
@@ -0,0 +1,43 @@
+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);
+ }
+}