/*
* PS3 Media Server, for streaming any medias to your PS3.
* Copyright (C) 2008 A.Brochard
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package net.pms.dlna;
import com.sun.syndication.feed.synd.SyndCategory;
import com.sun.syndication.feed.synd.SyndEnclosure;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;
import org.apache.commons.lang3.StringUtils;
import org.jdom.Content;
import org.jdom.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* TODO: Change all instance variables to private. For backwards compatibility
* with external plugin code the variables have all been marked as deprecated
* instead of changed to private, but this will surely change in the future.
* When everything has been changed to private, the deprecated note can be
* removed.
*/
public class Feed extends DLNAResource {
private static final Logger logger = LoggerFactory.getLogger(Feed.class);
private static final int REFRESH_INTERVAL = 60 * 60 * 1000; // 1 hour
/**
* @deprecated Use standard getter and setter to access this variable.
*/
@Deprecated
protected String name;
/**
* @deprecated Use standard getter and setter to access this variable.
*/
@Deprecated
protected String url;
/**
* @deprecated Use standard getter and setter to access this variable.
*/
@Deprecated
protected String tempItemTitle;
/**
* @deprecated Use standard getter and setter to access this variable.
*/
@Deprecated
protected String tempItemLink;
/**
* @deprecated Use standard getter and setter to access this variable.
*/
@Deprecated
protected String tempFeedLink;
/**
* @deprecated Use standard getter and setter to access this variable.
*/
@Deprecated
protected String tempCategory;
/**
* @deprecated Use standard getter and setter to access this variable.
*/
@Deprecated
protected String tempItemThumbURL;
@Override
protected void resolveOnce() {
try {
parse();
} catch (Exception e) {
logger.error("Error in parsing stream: " + url, e);
}
}
public Feed(String name, String url, int type) {
super(type);
setUrl(url);
setName(name);
}
@SuppressWarnings("unchecked")
public void parse() throws Exception {
SyndFeedInput input = new SyndFeedInput();
byte b[] = downloadAndSendBinary(url);
if (b != null) {
SyndFeed feed = input.build(new XmlReader(new ByteArrayInputStream(b)));
setName(feed.getTitle());
if (feed.getCategories() != null && feed.getCategories().size() > 0) {
SyndCategory category = (SyndCategory) feed.getCategories().get(0);
setTempCategory(category.getName());
}
List<SyndEntry> entries = feed.getEntries();
for (SyndEntry entry : entries) {
setTempItemTitle(entry.getTitle());
setTempItemLink(entry.getLink());
setTempFeedLink(entry.getUri());
setTempItemThumbURL(null);
ArrayList<Element> elements = (ArrayList<Element>) entry.getForeignMarkup();
for (Element elt : elements) {
if ("group".equals(elt.getName()) && "media".equals(elt.getNamespacePrefix())) {
List<Content> subElts = elt.getContent();
for (Content subelt : subElts) {
if (subelt instanceof Element) {
parseElement((Element) subelt, false);
}
}
}
parseElement(elt, true);
}
List<SyndEnclosure> enclosures = entry.getEnclosures();
for (SyndEnclosure enc : enclosures) {
if (StringUtils.isNotBlank(enc.getUrl())) {
setTempItemLink(enc.getUrl());
}
}
manageItem();
}
}
setLastModified(System.currentTimeMillis());
}
@SuppressWarnings("unchecked")
private void parseElement(Element elt, boolean parseLink) {
if ("content".equals(elt.getName()) && "media".equals(elt.getNamespacePrefix())) {
if (parseLink) {
setTempItemLink(elt.getAttribute("url").getValue());
}
List<Content> subElts = elt.getContent();
for (Content subelt : subElts) {
if (subelt instanceof Element) {
parseElement((Element) subelt, false);
}
}
}
if ("thumbnail".equals(elt.getName()) && "media".equals(elt.getNamespacePrefix())
&& getTempItemThumbURL() == null) {
setTempItemThumbURL(elt.getAttribute("url").getValue());
}
if ("image".equals(elt.getName()) && "exInfo".equals(elt.getNamespacePrefix())
&& getTempItemThumbURL() == null) {
setTempItemThumbURL(elt.getValue());
}
}
public InputStream getInputStream() throws IOException {
return null;
}
public String getName() {
return name;
}
public boolean isFolder() {
return true;
}
public long length() {
return 0;
}
// XXX unused
@Deprecated
public long lastModified() {
return 0;
}
@Override
public String getSystemName() {
return url;
}
@Override
public boolean isValid() {
return true;
}
protected void manageItem() {
FeedItem fi = new FeedItem(getTempItemTitle(), getTempItemLink(), getTempItemThumbURL(), null, getSpecificType());
addChild(fi);
}
@Override
public boolean isRefreshNeeded() {
return (System.currentTimeMillis() - getLastModified() > REFRESH_INTERVAL);
}
@Override
public void doRefreshChildren() {
try {
getChildren().clear();
parse();
} catch (Exception e) {
logger.error("Error in parsing stream: " + url, e);
}
}
/**
* @return the url
* @since 1.50.0
*/
protected String getUrl() {
return url;
}
/**
* @param url the url to set
* @since 1.50.0
*/
protected void setUrl(String url) {
this.url = url;
}
/**
* @return the tempItemTitle
* @since 1.50.0
*/
protected String getTempItemTitle() {
return tempItemTitle;
}
/**
* @param tempItemTitle the tempItemTitle to set
* @since 1.50.0
*/
protected void setTempItemTitle(String tempItemTitle) {
this.tempItemTitle = tempItemTitle;
}
/**
* @return the tempItemLink
* @since 1.50.0
*/
protected String getTempItemLink() {
return tempItemLink;
}
/**
* @param tempItemLink the tempItemLink to set
* @since 1.50.0
*/
protected void setTempItemLink(String tempItemLink) {
this.tempItemLink = tempItemLink;
}
/**
* @return the tempFeedLink
* @since 1.50.0
*/
protected String getTempFeedLink() {
return tempFeedLink;
}
/**
* @param tempFeedLink the tempFeedLink to set
* @since 1.50.0
*/
protected void setTempFeedLink(String tempFeedLink) {
this.tempFeedLink = tempFeedLink;
}
/**
* @return the tempCategory
* @since 1.50.0
*/
protected String getTempCategory() {
return tempCategory;
}
/**
* @param tempCategory the tempCategory to set
* @since 1.50.0
*/
protected void setTempCategory(String tempCategory) {
this.tempCategory = tempCategory;
}
/**
* @return the tempItemThumbURL
* @since 1.50.0
*/
protected String getTempItemThumbURL() {
return tempItemThumbURL;
}
/**
* @param tempItemThumbURL the tempItemThumbURL to set
* @since 1.50.0
*/
protected void setTempItemThumbURL(String tempItemThumbURL) {
this.tempItemThumbURL = tempItemThumbURL;
}
/**
* @param name the name to set
* @since 1.50.0
*/
protected void setName(String name) {
this.name = name;
}
}