/*
* 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.util;
import net.pms.network.HTTPResource;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
public class CoverUtil extends HTTPResource {
private static final Logger logger = LoggerFactory.getLogger(CoverUtil.class);
/**
* Use www.discogs.com as backend for cover lookups.
*/
public static final int AUDIO_DISCOGS = 0;
/**
* Use www.amazon.com as backend for cover lookups.
*/
public static final int AUDIO_AMAZON = 1;
/**
* Class instance.
*/
private static CoverUtil instance;
/**
* Storage for cover information (artist + album and thumbnail data).
* FIXME: Storing the thumbnail image data in memory is very costly.
* It would be wiser to store the image as a file instead.
*/
private HashMap<String, byte[]> covers;
/**
* Returns the instance of the CoverUtil class.
*
* @return The class instance.
*/
public static synchronized CoverUtil get() {
if (instance == null) {
instance = new CoverUtil();
}
return instance;
}
/**
* This class is not meant to be instantiated. Use {@link #get()} instead.
*/
private CoverUtil() {
covers = new HashMap<String, byte[]>();
}
/**
* Tries to look up a thumbnail based on artist and album information from a
* given backend and returns the image data on success or <code>null</code>
* if no thumbnail could be determined.
*
* @param backend
* The backend to use for thumbnail lookup. Can be
* {@link #AUDIO_AMAZON} or {@link #AUDIO_DISCOGS}.
* @param info The name of the artist and the album.
*
* @return The thumbnail image data or <code>null</code>.
* @throws IOException Thrown when downloading the thumbnail fails.
*/
public synchronized byte[] getThumbnailFromArtistAlbum(int backend, String... info) throws IOException {
if (info.length >= 2 && StringUtils.isNotBlank(info[0]) && StringUtils.isNotBlank(info[1])) {
String artist = URLEncoder.encode(info[0], "UTF-8");
String album = URLEncoder.encode(info[1], "UTF-8");
if (covers.get(artist + album) != null) {
byte[] data = covers.get(artist + album);
if (data.length == 0) {
return null;
} else {
return data;
}
}
if (backend == AUDIO_DISCOGS) {
String url = "http://www.discogs.com/advanced_search?artist=" + artist
+ "&release_title=" + album + "&btn=Search+Releases";
byte[] data = downloadAndSendBinary(url);
if (data != null) {
try {
String html = new String(data, "UTF-8");
int firstItem = html.indexOf("<li style=\"background:");
if (firstItem > -1) {
String detailUrl = html.substring(html.indexOf("<a href=\"/", firstItem) + 10,
html.indexOf("\"><em>", firstItem));
data = downloadAndSendBinary("http://www.discogs.com/" + detailUrl);
html = new String(data, "UTF-8");
firstItem = html.indexOf("<a href=\"/viewimages?");
if (firstItem > -1) {
String imageUrl = html.substring(html.indexOf("<img src=\"", firstItem) + 10,
html.indexOf("\" border", firstItem));
data = downloadAndSendBinary(imageUrl);
if (data != null) {
covers.put(artist + album, data);
} else {
covers.put(artist + album, new byte[0]);
}
return data;
}
}
} catch (IOException e) {
logger.error("Error while retrieving cover for " + artist + album, e);
}
}
} else if (backend == AUDIO_AMAZON) {
String url = "http://www.amazon.com/gp/search/ref=sr_adv_m_pop/?search-alias=popular&unfiltered=1&field-keywords=&field-artist="
+ artist + "&field-title=" + album
+ "&field-label=&field-binding=&sort=relevancerank&Adv-Srch-Music-Album-Submit.x=35&Adv-Srch-Music-Album-Submit.y=13";
byte[] data = downloadAndSendBinary(url);
if (data != null) {
try {
String html = new String(data, "UTF-8");
int firstItem = html.indexOf("class=\"imageColumn\"");
if (firstItem > -1) {
int imageUrlPos = html.indexOf("src=\"", firstItem) + 5;
String imageUrl = html.substring(imageUrlPos, html.indexOf("\" class", imageUrlPos));
data = downloadAndSendBinary(imageUrl);
if (data != null) {
covers.put(artist + album, data);
} else {
covers.put(artist + album, new byte[0]);
}
return data;
}
} catch (IOException e) {
logger.error("Error while retrieving cover for " + artist + album, e);
}
}
}
covers.put(artist + album, new byte[0]);
}
return null;
}
}