Merge pull request #37 from mishako/itunes-more-fields
"Support more iTunes tags" Looks good to me. Thanks Misha!
This commit is contained in:
commit
a432e8d4d5
9 changed files with 114 additions and 60 deletions
|
@ -40,6 +40,8 @@
|
||||||
*/
|
*/
|
||||||
package com.rometools.modules.itunes;
|
package com.rometools.modules.itunes;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is an abstract object that implements the attributes common across Feeds or Items in an
|
* This is an abstract object that implements the attributes common across Feeds or Items in an
|
||||||
* iTunes compatible RSS feed.
|
* iTunes compatible RSS feed.
|
||||||
|
@ -74,6 +76,7 @@ public abstract class AbstractITunesObject implements ITunes, java.lang.Cloneabl
|
||||||
private String author;
|
private String author;
|
||||||
private boolean block;
|
private boolean block;
|
||||||
private boolean explicit;
|
private boolean explicit;
|
||||||
|
private URL image;
|
||||||
private String[] keywords;
|
private String[] keywords;
|
||||||
private String subtitle;
|
private String subtitle;
|
||||||
private String summary;
|
private String summary;
|
||||||
|
@ -166,6 +169,16 @@ public abstract class AbstractITunesObject implements ITunes, java.lang.Cloneabl
|
||||||
this.explicit = explicit;
|
this.explicit = explicit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URL getImage() {
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setImage(final URL image) {
|
||||||
|
this.image = image;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of keywords for this feed or entry
|
* A list of keywords for this feed or entry
|
||||||
*
|
*
|
||||||
|
@ -239,6 +252,8 @@ public abstract class AbstractITunesObject implements ITunes, java.lang.Cloneabl
|
||||||
sb.append(getBlock());
|
sb.append(getBlock());
|
||||||
sb.append(" Explicit: ");
|
sb.append(" Explicit: ");
|
||||||
sb.append(getExplicit());
|
sb.append(getExplicit());
|
||||||
|
sb.append(" Image: ");
|
||||||
|
sb.append(getImage());
|
||||||
sb.append(" Keywords: ");
|
sb.append(" Keywords: ");
|
||||||
|
|
||||||
if (getKeywords() != null) {
|
if (getKeywords() != null) {
|
||||||
|
|
|
@ -43,6 +43,12 @@ package com.rometools.modules.itunes;
|
||||||
import com.rometools.modules.itunes.types.Duration;
|
import com.rometools.modules.itunes.types.Duration;
|
||||||
import com.rometools.rome.feed.CopyFrom;
|
import com.rometools.rome.feed.CopyFrom;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class contains information for iTunes podcast feeds that exist at the Item level.
|
* This class contains information for iTunes podcast feeds that exist at the Item level.
|
||||||
*
|
*
|
||||||
|
@ -54,6 +60,9 @@ public class EntryInformationImpl extends AbstractITunesObject implements EntryI
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(EntryInformationImpl.class);
|
||||||
|
|
||||||
private Duration duration;
|
private Duration duration;
|
||||||
private boolean closedCaptioned;
|
private boolean closedCaptioned;
|
||||||
private Integer order;
|
private Integer order;
|
||||||
|
@ -121,6 +130,14 @@ public class EntryInformationImpl extends AbstractITunesObject implements EntryI
|
||||||
|
|
||||||
setExplicit(info.getExplicit());
|
setExplicit(info.getExplicit());
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (info.getImage() != null) {
|
||||||
|
setImage(new URL(info.getImage().toExternalForm()));
|
||||||
|
}
|
||||||
|
} catch (final MalformedURLException e) {
|
||||||
|
LOG.debug("Error copying URL:" + info.getImage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
if (info.getKeywords() != null) {
|
if (info.getKeywords() != null) {
|
||||||
setKeywords(info.getKeywords().clone());
|
setKeywords(info.getKeywords().clone());
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,23 +67,13 @@ public interface FeedInformation extends ITunes {
|
||||||
*/
|
*/
|
||||||
public void setCategories(List<Category> categories);
|
public void setCategories(List<Category> categories);
|
||||||
|
|
||||||
/**
|
public boolean getComplete();
|
||||||
* Sets the URL for the image.
|
|
||||||
*
|
|
||||||
* NOTE: To specification images should be in PNG or JPEG format.
|
|
||||||
*
|
|
||||||
* @param image Sets the URL for the image.
|
|
||||||
*/
|
|
||||||
public void setImage(URL image);
|
|
||||||
|
|
||||||
/**
|
public void setComplete(boolean complete);
|
||||||
* Returns the URL for the image.
|
|
||||||
*
|
public String getNewFeedUrl();
|
||||||
* NOTE: To specification images should be in PNG or JPEG format.
|
|
||||||
*
|
public void setNewFeedUrl(String newFeedUrl);
|
||||||
* @return Returns the URL for the image.
|
|
||||||
*/
|
|
||||||
public URL getImage();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the owner email address for the feed.
|
* Sets the owner email address for the feed.
|
||||||
|
|
|
@ -66,8 +66,9 @@ public class FeedInformationImpl extends AbstractITunesObject implements FeedInf
|
||||||
|
|
||||||
private String ownerName;
|
private String ownerName;
|
||||||
private String ownerEmailAddress;
|
private String ownerEmailAddress;
|
||||||
private URL image;
|
|
||||||
private List<Category> categories;
|
private List<Category> categories;
|
||||||
|
private boolean complete;
|
||||||
|
private String newFeedUrl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance of FeedInformationImpl
|
* Creates a new instance of FeedInformationImpl
|
||||||
|
@ -95,6 +96,26 @@ public class FeedInformationImpl extends AbstractITunesObject implements FeedInf
|
||||||
this.categories = categories;
|
this.categories = categories;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getComplete() {
|
||||||
|
return complete;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setComplete(boolean complete) {
|
||||||
|
this.complete = complete;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNewFeedUrl() {
|
||||||
|
return newFeedUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNewFeedUrl(String newFeedUrl) {
|
||||||
|
this.newFeedUrl = newFeedUrl;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the owner name for the feed
|
* Returns the owner name for the feed
|
||||||
*
|
*
|
||||||
|
@ -135,30 +156,6 @@ public class FeedInformationImpl extends AbstractITunesObject implements FeedInf
|
||||||
this.ownerEmailAddress = ownerEmailAddress;
|
this.ownerEmailAddress = ownerEmailAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the URL for the image.
|
|
||||||
*
|
|
||||||
* NOTE: To specification images should be in PNG or JPEG format.
|
|
||||||
*
|
|
||||||
* @return Returns the URL for the image.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public URL getImage() {
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the URL for the image.
|
|
||||||
*
|
|
||||||
* NOTE: To specification images should be in PNG or JPEG format.
|
|
||||||
*
|
|
||||||
* @param image Sets the URL for the image.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setImage(final URL image) {
|
|
||||||
this.image = image;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Required by the ROME API
|
* Required by the ROME API
|
||||||
*
|
*
|
||||||
|
@ -175,6 +172,8 @@ public class FeedInformationImpl extends AbstractITunesObject implements FeedInf
|
||||||
getCategories().addAll(info.getCategories());
|
getCategories().addAll(info.getCategories());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setComplete(info.getComplete());
|
||||||
|
setNewFeedUrl(info.getNewFeedUrl());
|
||||||
setExplicit(info.getExplicit());
|
setExplicit(info.getExplicit());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -215,10 +214,12 @@ public class FeedInformationImpl extends AbstractITunesObject implements FeedInf
|
||||||
sb.append(getOwnerEmailAddress());
|
sb.append(getOwnerEmailAddress());
|
||||||
sb.append(" name: ");
|
sb.append(" name: ");
|
||||||
sb.append(getOwnerName());
|
sb.append(getOwnerName());
|
||||||
sb.append(" image: ");
|
|
||||||
sb.append(getImage());
|
|
||||||
sb.append(" categories: ");
|
sb.append(" categories: ");
|
||||||
sb.append(getCategories());
|
sb.append(getCategories());
|
||||||
|
sb.append(" complete: ");
|
||||||
|
sb.append(getComplete());
|
||||||
|
sb.append(" newFeedUrl: ");
|
||||||
|
sb.append(getNewFeedUrl());
|
||||||
sb.append("]");
|
sb.append("]");
|
||||||
sb.append(super.toString());
|
sb.append(super.toString());
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,8 @@ package com.rometools.modules.itunes;
|
||||||
|
|
||||||
import com.rometools.rome.feed.module.Module;
|
import com.rometools.rome.feed.module.Module;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface contains the methods common to all iTunes module points.
|
* This interface contains the methods common to all iTunes module points.
|
||||||
*
|
*
|
||||||
|
@ -94,6 +96,10 @@ public interface ITunes extends Module {
|
||||||
*/
|
*/
|
||||||
public void setExplicit(boolean explicit);
|
public void setExplicit(boolean explicit);
|
||||||
|
|
||||||
|
public URL getImage();
|
||||||
|
|
||||||
|
public void setImage(URL image);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of keywords for this feed or entry
|
* A list of keywords for this feed or entry
|
||||||
*
|
*
|
||||||
|
|
|
@ -98,12 +98,6 @@ public class ITunesGenerator implements ModuleGenerator {
|
||||||
owner.addContent(name);
|
owner.addContent(name);
|
||||||
element.addContent(owner);
|
element.addContent(owner);
|
||||||
|
|
||||||
if (info.getImage() != null) {
|
|
||||||
final Element image = generateSimpleElement("image", "");
|
|
||||||
image.setAttribute("href", info.getImage().toExternalForm());
|
|
||||||
element.addContent(image);
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<Category> categories = info.getCategories();
|
final List<Category> categories = info.getCategories();
|
||||||
for (final Category cat : categories) {
|
for (final Category cat : categories) {
|
||||||
|
|
||||||
|
@ -118,6 +112,15 @@ public class ITunesGenerator implements ModuleGenerator {
|
||||||
|
|
||||||
element.addContent(category);
|
element.addContent(category);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (info.getComplete()) {
|
||||||
|
element.addContent(generateSimpleElement("complete", "yes"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.getNewFeedUrl() != null) {
|
||||||
|
element.addContent(generateSimpleElement("new-feed-url", info.getNewFeedUrl()));
|
||||||
|
}
|
||||||
|
|
||||||
} else if (itunes instanceof EntryInformationImpl) {
|
} else if (itunes instanceof EntryInformationImpl) {
|
||||||
final EntryInformationImpl info = (EntryInformationImpl) itunes;
|
final EntryInformationImpl info = (EntryInformationImpl) itunes;
|
||||||
|
|
||||||
|
@ -146,6 +149,12 @@ public class ITunesGenerator implements ModuleGenerator {
|
||||||
element.addContent(generateSimpleElement("explicit", "no"));
|
element.addContent(generateSimpleElement("explicit", "no"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (itunes.getImage() != null) {
|
||||||
|
final Element image = generateSimpleElement("image", "");
|
||||||
|
image.setAttribute("href", itunes.getImage().toExternalForm());
|
||||||
|
element.addContent(image);
|
||||||
|
}
|
||||||
|
|
||||||
if (itunes.getKeywords() != null) {
|
if (itunes.getKeywords() != null) {
|
||||||
final StringBuffer sb = new StringBuffer();
|
final StringBuffer sb = new StringBuffer();
|
||||||
|
|
||||||
|
|
|
@ -109,17 +109,6 @@ public class ITunesParser implements ModuleParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final Element image = element.getChild("image", ns);
|
|
||||||
|
|
||||||
if (image != null && image.getAttributeValue("href") != null) {
|
|
||||||
try {
|
|
||||||
final URL imageURL = new URL(image.getAttributeValue("href").trim());
|
|
||||||
feedInfo.setImage(imageURL);
|
|
||||||
} catch (final MalformedURLException e) {
|
|
||||||
LOG.debug("Malformed URL Exception reading itunes:image tag: {}", image.getAttributeValue("href"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<Element> categories = element.getChildren("category", ns);
|
final List<Element> categories = element.getChildren("category", ns);
|
||||||
for (final Element element2 : categories) {
|
for (final Element element2 : categories) {
|
||||||
final Element category = element2;
|
final Element category = element2;
|
||||||
|
@ -139,6 +128,16 @@ public class ITunesParser implements ModuleParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final Element complete = element.getChild("complete", ns);
|
||||||
|
if (complete != null) {
|
||||||
|
feedInfo.setComplete("yes".equals(complete.getTextTrim().toLowerCase()));
|
||||||
|
}
|
||||||
|
|
||||||
|
final Element newFeedUrl = element.getChild("new-feed-url", ns);
|
||||||
|
if (newFeedUrl != null) {
|
||||||
|
feedInfo.setNewFeedUrl(newFeedUrl.getTextTrim());
|
||||||
|
}
|
||||||
|
|
||||||
} else if (element.getName().equals("item")) {
|
} else if (element.getName().equals("item")) {
|
||||||
final EntryInformationImpl entryInfo = new EntryInformationImpl();
|
final EntryInformationImpl entryInfo = new EntryInformationImpl();
|
||||||
module = entryInfo;
|
module = entryInfo;
|
||||||
|
@ -209,6 +208,17 @@ public class ITunesParser implements ModuleParser {
|
||||||
if (summary != null) {
|
if (summary != null) {
|
||||||
module.setSummary(summary.getTextTrim());
|
module.setSummary(summary.getTextTrim());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final Element image = element.getChild("image", ns);
|
||||||
|
|
||||||
|
if (image != null && image.getAttributeValue("href") != null) {
|
||||||
|
try {
|
||||||
|
final URL imageURL = new URL(image.getAttributeValue("href").trim());
|
||||||
|
module.setImage(imageURL);
|
||||||
|
} catch (final MalformedURLException e) {
|
||||||
|
LOG.debug("Malformed URL Exception reading itunes:image tag: {}", image.getAttributeValue("href"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return module;
|
return module;
|
||||||
|
|
|
@ -81,6 +81,8 @@ public class ITunesParserTest extends AbstractTestCase {
|
||||||
"summary",
|
"summary",
|
||||||
"A weekly, hour-long romp through the worlds of media, politics, sports and show business, leavened with an eclectic mix of mysterious music, hosted by Harry Shearer.",
|
"A weekly, hour-long romp through the worlds of media, politics, sports and show business, leavened with an eclectic mix of mysterious music, hosted by Harry Shearer.",
|
||||||
feedInfo.getSummary());
|
feedInfo.getSummary());
|
||||||
|
assertEquals(true, feedInfo.getComplete());
|
||||||
|
assertEquals("http://example.org", feedInfo.getNewFeedUrl());
|
||||||
|
|
||||||
List<SyndEntry> entries = syndfeed.getEntries();
|
List<SyndEntry> entries = syndfeed.getEntries();
|
||||||
Iterator<SyndEntry> it = entries.iterator();
|
Iterator<SyndEntry> it = entries.iterator();
|
||||||
|
@ -116,5 +118,6 @@ public class ITunesParserTest extends AbstractTestCase {
|
||||||
EntryInformationImpl entryInfo = (EntryInformationImpl) entry.getModule(AbstractITunesObject.URI);
|
EntryInformationImpl entryInfo = (EntryInformationImpl) entry.getModule(AbstractITunesObject.URI);
|
||||||
assertEquals(true, entryInfo.getClosedCaptioned());
|
assertEquals(true, entryInfo.getClosedCaptioned());
|
||||||
assertEquals(Integer.valueOf(2), entryInfo.getOrder());
|
assertEquals(Integer.valueOf(2), entryInfo.getOrder());
|
||||||
|
assertEquals("http://example.org/image.png", entryInfo.getImage().toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
<description>A weekly, hour-long romp through the worlds of media, politics, sports and show business, leavened with an eclectic mix of mysterious music, hosted by Harry Shearer.</description>
|
<description>A weekly, hour-long romp through the worlds of media, politics, sports and show business, leavened with an eclectic mix of mysterious music, hosted by Harry Shearer.</description>
|
||||||
<itunes:subtitle>An hour's worth of Harry Shearer</itunes:subtitle>
|
<itunes:subtitle>An hour's worth of Harry Shearer</itunes:subtitle>
|
||||||
<itunes:summary>A weekly, hour-long romp through the worlds of media, politics, sports and show business, leavened with an eclectic mix of mysterious music, hosted by Harry Shearer.</itunes:summary>
|
<itunes:summary>A weekly, hour-long romp through the worlds of media, politics, sports and show business, leavened with an eclectic mix of mysterious music, hosted by Harry Shearer.</itunes:summary>
|
||||||
|
<itunes:complete>yes</itunes:complete>
|
||||||
|
<itunes:new-feed-url>http://example.org</itunes:new-feed-url>
|
||||||
<language>en</language>
|
<language>en</language>
|
||||||
|
|
||||||
<copyright>KCRW 2005</copyright>
|
<copyright>KCRW 2005</copyright>
|
||||||
|
@ -68,6 +70,7 @@
|
||||||
<itunes:keywords></itunes:keywords>
|
<itunes:keywords></itunes:keywords>
|
||||||
<itunes:isClosedCaptioned>yes</itunes:isClosedCaptioned>
|
<itunes:isClosedCaptioned>yes</itunes:isClosedCaptioned>
|
||||||
<itunes:order>2</itunes:order>
|
<itunes:order>2</itunes:order>
|
||||||
|
<itunes:image href="http://example.org/image.png"></itunes:image>
|
||||||
</item>
|
</item>
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue