diff options
author | Martin Fietz <Martin.Fietz@gmail.com> | 2019-05-19 13:40:20 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-19 13:40:20 +0200 |
commit | 135df61692ee1d6d3cee59039ae633a0ac9549f3 (patch) | |
tree | 31061c685d75c2aca667626dac7d52364623e530 | |
parent | 5db139958aaf674de06fa0b6e47084e81e375e63 (diff) | |
parent | fb3bfa9f8018bd89b97fd0e0c53ea4fab1687aa2 (diff) | |
download | AntennaPod-135df61692ee1d6d3cee59039ae633a0ac9549f3.zip |
Merge pull request #3159 from andersonvom/3024-itunes-duration-format
Handle iTunes single-number duration format
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); + } +} |