package org.discogs.ws; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.net.URLEncoder; import java.nio.charset.Charset; import java.util.List; import java.util.Map; import org.benow.java.rest.DocumentLoader; import org.benow.java.rest.XML; import org.discogs.model.Artist; import org.discogs.model.Label; import org.discogs.model.Release; import org.discogs.model.Track; import org.discogs.ws.search.Search; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * Various tools for discogs lookup via rest interface. * <p/> * Usage: * <pre> * // create new client with your api key * // see https://www.discogs.com/users/api_key * Discogs discogs=new Discogs("1234"); * Artist artist=discogs.getArtist("Richard H. Kirk"); * System.out.println(artist); * </pre> * @author andy * */ public class Discogs { /**d * API key to use in discogs communication. May be set directly, specfified in Discogs(String) constructor * or as the system property 'apiKey' on startup (ie -DapiKey=12345). An API key must be provided in some * form. */ public static final String API_KEY = System.getProperty("apiKey"); public static final String SEARCH_TYPE_RELEASE = "release"; public static final String SEARCH_TYPE_LABEL = "label"; public static final String SEARCH_TYPE_ARTIST = "artists"; public final DocumentLoader loader; private final String apiKey; /** * Create client with API_KEY key statically set or via apiKey system property (-DapiKey=12345 ). * <p/> * See <a href="https://www.discogs.com/users/api_key">discogs</a> to get an api key. */ public Discogs() { this(API_KEY); } /** * Create client with a given api key. * <p/> * See <a href="https://www.discogs.com/users/api_key">discogs</a> to get an api key. */ public Discogs(String apiKey) { this(apiKey, true, System.getProperty("java.io.tmpdir", "")); } /** * Create client with a given api key. * <p/> * See <a href="https://www.discogs.com/users/api_key">discogs</a> to get an api key. */ public Discogs(String apiKey, boolean cacheEnabled, String cacheDir) { super(); if (apiKey == null) throw new NullPointerException("Error, an apiKey must be given. Specify directly in constructor, set the API_KEY field or provide an apiKey system property (-DapiKey=1234)"); try { loader = new DocumentLoader(new URL("http://discogs.com")); loader.setCharset(Charset.forName("UTF-8")); loader.setLoadInterval(1000); loader.setUserAgent("discogs-java/0.01 +http://benow.ca/projects/discogs-java"); setCacheEnabled(cacheEnabled); setCacheDir(cacheDir); } catch (MalformedURLException e) { throw new RuntimeException("Impossible", e); } this.apiKey = apiKey; } public Release getRelease( String id) { Element resultE = loadResult("/release/" + id); if (resultE != null) return new Release(resultE, this); return null; } public Artist getArtist( String name, String anv) { try { String convName = URLEncoder.encode(name, "ISO-8859-1"); String convAnv = null; if (anv != null) convAnv = URLEncoder.encode(name, "ISO-8859-1"); Element resultE = loadResult("/artist/" + convName + (anv != null ? "?anv=" + convAnv : "")); if (resultE != null) return new Artist(resultE, this); return null; } catch (UnsupportedEncodingException e) { e.printStackTrace(); return null; } } public Artist getArtist( String name) { return getArtist(name, null); } public Label getLabel( String name) { try { String convName = URLEncoder.encode(name, "ISO-8859-1"); Element resultE = loadResult("/label/" + convName); if (resultE != null) return new Label(resultE, this); return null; } catch (UnsupportedEncodingException e) { e.printStackTrace(); return null; } } public Search search( String term) { return search(null, term); } public Search search( String type, String term) { try { String convTerm = URLEncoder.encode(term, "UTF-8"); Element resultE = loadResult("/search?" + (type == null ? "" : "type=" + type + "&") + "q=" + convTerm); if (resultE != null) return new Search((Element) resultE.getParentNode(), this); return null; } catch (UnsupportedEncodingException e) { e.printStackTrace(); return null; } } private Element loadResult( String relURL) { try { Document doc = loader.loadDocument(relURL + (relURL.contains("?") ? "&" : "?") + "f=xml&api_key=" + apiKey); Element resp = doc.getDocumentElement(); if (!resp.hasAttribute("stat") || !resp.getAttribute("stat").equals("ok")) throw new IOException("Error fetching from: " + relURL + ". Expected stat='ok' in:\n" + XML.elementToString(resp)); NodeList cn = resp.getChildNodes(); for (int i = 0; i < cn.getLength(); i++) { Node curr = cn.item(0); if (curr instanceof Element) return (Element) curr; } throw new IOException("Error fetching from: " + relURL + ". Expected contained element in:\n" + XML.elementToString(resp)); } catch (IOException e) { throw new RuntimeException("Error during fetch", e); } } public static String readFromURL( URL fromURL, Map<String, String> headers) throws IOException { URLConnection conn = fromURL.openConnection(); conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0"); if (headers != null) { for (String key : headers.keySet()) { String val = headers.get(key); conn.setRequestProperty(key, val); } } BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inStr = ""; String currStr = in.readLine(); while (currStr != null) { inStr += currStr + "\n"; currStr = in.readLine(); } in.close(); return inStr; } public void setCacheEnabled(boolean b) { loader.setCacheEnabled(b); } public void setCacheDir(String s) { loader.setCacheDir(new File(s)); } public static void main( String[] args) { try { Discogs discogs = new Discogs(); String id = "3614"; Release release = discogs.getRelease(id); if (release == null) System.out.println("Release not found for id: " + id); else { System.out.println(release); System.out.println("Title: " + release.getTitle()); System.out.println("Artist: " + release.getArtists().get(0).getName()); System.out.println("Tracks"); List<Track> tracks = release.getTracks(); for (int i = 0; i < tracks.size(); i++) { Track curr = tracks.get(i); System.out.println("\t" + (i + 1) + ": " + curr.getTitle()); } } Artist artist = discogs.getArtist("Richard H. Kirk", "Richard H Kirk"); System.out.println(artist); Label label = discogs.getLabel("Warp Records"); System.out.println(label.getProfile()); // this fails on extended characters. artist = discogs.getArtist("Stéphane Pompougnac"); System.out.println(artist.getProfile()); Search s = discogs.search(SEARCH_TYPE_ARTIST, "Stéphane Pompougnac"); System.out.println(s); Release r = discogs.getRelease("507569"); System.out.println("Track name with UTF-8 char: " + r.getTracks().get(1).getTitle()); // System.out.println(r); System.exit(0); } catch (Exception e) { e.printStackTrace(); System.exit(-1); } } }