Merge pull request #3159 from andersonvom/3024-itunes-duration-format
Handle iTunes single-number duration format
This commit is contained in:
commit
135df61692
@ -5,9 +5,9 @@ import android.util.Log;
|
|||||||
|
|
||||||
import org.xml.sax.Attributes;
|
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.handler.HandlerState;
|
||||||
|
import de.danoeh.antennapod.core.syndication.parsers.DurationParser;
|
||||||
|
|
||||||
public class NSITunes extends Namespace {
|
public class NSITunes extends Namespace {
|
||||||
|
|
||||||
@ -22,7 +22,6 @@ public class NSITunes extends Namespace {
|
|||||||
private static final String SUBTITLE = "subtitle";
|
private static final String SUBTITLE = "subtitle";
|
||||||
private static final String SUMMARY = "summary";
|
private static final String SUMMARY = "summary";
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SyndElement handleElementStart(String localName, HandlerState state,
|
public SyndElement handleElementStart(String localName, HandlerState state,
|
||||||
Attributes attributes) {
|
Attributes attributes) {
|
||||||
@ -44,40 +43,44 @@ public class NSITunes extends Namespace {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleElementEnd(String localName, HandlerState state) {
|
public void handleElementEnd(String localName, HandlerState state) {
|
||||||
if(state.getContentBuf() == null) {
|
if (state.getContentBuf() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SyndElement secondElement = state.getSecondTag();
|
|
||||||
String second = secondElement.getName();
|
|
||||||
|
|
||||||
if (AUTHOR.equals(localName)) {
|
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) {
|
if (state.getFeed() != null) {
|
||||||
String author = state.getContentBuf().toString();
|
String author = state.getContentBuf().toString();
|
||||||
state.getFeed().setAuthor(author);
|
state.getFeed().setAuthor(author);
|
||||||
}
|
}
|
||||||
} else if (DURATION.equals(localName)) {
|
}
|
||||||
|
|
||||||
|
private void parseDuration(HandlerState state) {
|
||||||
String durationStr = state.getContentBuf().toString();
|
String durationStr = state.getContentBuf().toString();
|
||||||
if(TextUtils.isEmpty(durationStr)) {
|
if (TextUtils.isEmpty(durationStr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String[] parts = durationStr.trim().split(":");
|
|
||||||
try {
|
try {
|
||||||
int durationMs = 0;
|
long durationMs = DurationParser.inMillis(durationStr);
|
||||||
if (parts.length == 2) {
|
state.getTempObjects().put(DURATION, (int) durationMs);
|
||||||
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) {
|
} catch (NumberFormatException e) {
|
||||||
Log.e(NSTAG, "Duration \"" + durationStr + "\" could not be parsed");
|
Log.e(NSTAG, String.format("Duration '%s' could not be parsed", durationStr));
|
||||||
}
|
}
|
||||||
} else if (SUBTITLE.equals(localName)) {
|
}
|
||||||
|
|
||||||
|
private void parseSubtitle(HandlerState state) {
|
||||||
String subtitle = state.getContentBuf().toString();
|
String subtitle = state.getContentBuf().toString();
|
||||||
if (TextUtils.isEmpty(subtitle)) {
|
if (TextUtils.isEmpty(subtitle)) {
|
||||||
return;
|
return;
|
||||||
@ -91,18 +94,24 @@ public class NSITunes extends Namespace {
|
|||||||
state.getFeed().setDescription(subtitle);
|
state.getFeed().setDescription(subtitle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (SUMMARY.equals(localName)) {
|
}
|
||||||
|
|
||||||
|
private void parseSummary(HandlerState state, String secondElementName) {
|
||||||
String summary = state.getContentBuf().toString();
|
String summary = state.getContentBuf().toString();
|
||||||
if (TextUtils.isEmpty(summary)) {
|
if (TextUtils.isEmpty(summary)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (state.getCurrentItem() != null &&
|
|
||||||
(TextUtils.isEmpty(state.getCurrentItem().getDescription()) ||
|
FeedItem currentItem = state.getCurrentItem();
|
||||||
state.getCurrentItem().getDescription().length() * 1.25 < summary.length())) {
|
String description = getDescription(currentItem);
|
||||||
state.getCurrentItem().setDescription(summary);
|
if (currentItem != null && description.length() * 1.25 < summary.length()) {
|
||||||
} else if (NSRSS20.CHANNEL.equals(second) && state.getFeed() != null) {
|
currentItem.setDescription(summary);
|
||||||
|
} else if (NSRSS20.CHANNEL.equals(secondElementName) && state.getFeed() != null) {
|
||||||
state.getFeed().setDescription(summary);
|
state.getFeed().setDescription(summary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getDescription(FeedItem item) {
|
||||||
|
return (item != null && item.getDescription() != null) ? item.getDescription() : "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user