Package com.echonest.api.v4.util

Source Code of com.echonest.api.v4.util.Commander

package com.echonest.api.v4.util;

import com.echonest.api.v4.EchoNestException;
import com.echonest.api.v4.Params;
import com.echonest.api.v4.util.StatsManager.Tracker;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

public class Commander {

    private String name;
    private String defaultHost = "developer.echonest.com";
    private String host;
    private String prefix = "/api/v4/";
    private boolean traceSends = false;
    private boolean traceRecvs = false;
    private boolean traceErrs = false;
    private int minCommandTime = 0;
    private int timeout = 30000;
    private int tryCount = 1;
    private long lastCommandTime;
    private Params standardParams = new Params();
    private StatsManager statsManager = new StatsManager();
    private long startTime;
    private int cmdCount = 0;
    private String expectedVersion = "4.";
    private JSONParser parser = new JSONParser();
    private boolean autoThrottle = true;
    private int autoThrottleTime = 0;

    public Commander(String name) {
        this.name = name;
        startTime = System.currentTimeMillis();
        host = System.getenv("ECHO_NEST_API_HOST");
        if (host == null) {
            host = defaultHost;
        }
        if (System.getenv("ECHO_NEST_API_TRACE_SENDS") != null) {
            traceSends = true;
        }
        if (System.getenv("ECHO_NEST_API_TRACE_RECVS") != null) {
            traceRecvs = true;
        }
    }

    @SuppressWarnings("unchecked")
    public Map sendCommand(String command, Params params)
            throws EchoNestException {
        return sendCommand(command, params, false);
    }

    @SuppressWarnings("unchecked")
    public Map sendCommand(String command, Params params, boolean usePost)
            throws EchoNestException {
        return sendCommand(command, params, usePost, null);
    }

    @SuppressWarnings("unchecked")
    public Map sendCommand(String command, Params params, boolean usePost,
            File file) throws EchoNestException {

        long curGap = System.currentTimeMillis() - lastCommandTime;
        long delayTime = minCommandTime - curGap;

        delay(delayTime);

        Tracker tracker = statsManager.start(command);

        try {
            StringBuilder url = new StringBuilder();
            url.append("http://");
            url.append(host);
            url.append(prefix);
            url.append(command);
            url.append(params.toString(true));
            url.append(standardParams.toString(params.size() == 0));

            Map results = getCheckedResults(url.toString(), usePost, file);
            statsManager.end(tracker);
            return results;
        } finally {
            statsManager.close(tracker);
        }
    }

    public String buildFeedUrl(String command) {
        StringBuilder url = new StringBuilder();
        url.append("http://");
        url.append(host);
        url.append(command);
        return url.toString();
    }

    @SuppressWarnings("unchecked")
    static public Map fetchURLAsJSON(String urls) throws IOException {
        InputStream is = null;

        try {
            JSONParser parser = new JSONParser();

            URI uri = new URI(urls);
            URL url = uri.toURL();

            URLConnection urc = url.openConnection();
            is = new BufferedInputStream(urc.getInputStream());
            BufferedReader in = new BufferedReader(new InputStreamReader(is,
                    Charset.forName("UTF-8")));

            return (JSONObject) parser.parse(in);
        } catch (ParseException e) {
            throw new IOException("Parse Exception", e);
        } catch (URISyntaxException e) {
            throw new IOException("Bad URI " + urls);
        } finally {
            if (is != null) {
                is.close();
            }
        }
    }

    public void showStats() {
        statsManager.dump();
    }

    @SuppressWarnings("unchecked")
    private Map getCheckedResults(String command, boolean usePost, File file)
            throws EchoNestException {
        boolean ok = false;
        Map results = null;
        try {
            results = getMapResults(command, usePost, file);
            checkStatus(results);
            ok = true;
            return results;
        } catch (IOException ioe) {
            throw new EchoNestException(ioe);
        } finally {
            if (!ok && traceErrs && !traceSends) {
                System.out.println("send-err-> " + command);
                if (results != null && !traceRecvs) {
                    System.out.println("recv-err-> " + results.toString());
                }
            }
        }
    }

    @SuppressWarnings("unchecked")
    private Map getMapResults(String command, boolean usePost, File file)
            throws IOException {
        String results = getStringResults(command, usePost, file);
        try {
            return (JSONObject) parser.parse(results);
        } catch (ParseException e) {
            throw new IOException("Parse Exception", e);
        }
    }

    public String getStringResults(String command, boolean usePost, File file)
            throws IOException {

        InputStream is = null;
        if (usePost && file != null) {
            is = post(command, file);
        } else {
            is = sendCommandRaw(command, usePost, file);
        }
        BufferedReader in = new BufferedReader(new InputStreamReader(is,
                Charset.forName("UTF-8")));

        String line = null;
        StringBuilder results = new StringBuilder();

        while ((line = in.readLine()) != null) {
            results.append(line);
        }

        if (traceRecvs) {
            System.out.println("received-->     " + results.toString());
        }
        in.close();
        return results.toString();
    }
    long last_time = 0;

    private InputStream post(String command, File file) throws IOException {
        HttpURLConnection conn = null;
        DataOutputStream dos = null;

        URL url = null;
        try {
            URI uri = new URI(command);
            url = uri.toURL();
        } catch (URISyntaxException e) {
            throw new IOException("Bad URL " + e);
        } catch (MalformedURLException e) {
            throw new IOException("Bad URL " + e);
        }

        if (traceSends) {
            System.out.println("Sending-->     " + url);
        }

        conn = (HttpURLConnection) url.openConnection();
        conn.setDoInput(true);
        conn.setDoOutput(true);
        conn.setFixedLengthStreamingMode((int) file.length());
        conn.setAllowUserInteraction(false);
        conn.setUseCaches(false);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/octet-stream");

        if (getTimeout() != -1) {
            conn.setReadTimeout(getTimeout());
            conn.setConnectTimeout(getTimeout());
        }


        dos = new DataOutputStream(conn.getOutputStream());

        InputStream fis = new FileInputStream(file);
        int r = 0;
        byte[] data = new byte[1024];
        while ((r = fis.read(data, 0, data.length)) != -1) {
            dos.write(data, 0, r);
        }
        fis.close();

        dos.flush();
        dos.close();

        int code = conn.getResponseCode();

        InputStream is = null;
        if (code >= 300) {
            is = conn.getErrorStream();
        } else {
            is = conn.getInputStream();
        }
        return is;
    }

    public InputStream sendCommandRaw(String command, boolean usePost, File file)
            throws IOException {
        try {
            String fullCommand = command;

            URI uri = new URI(fullCommand);
            URL url = uri.toURL();

            cmdCount++;
            if (traceSends) {
                long now = System.currentTimeMillis();
                long delta = now - last_time;
                last_time = now;
                System.out.printf("Sending %d %d %d-->     %s\n", cmdCount, now
                        - startTime, delta, url);
            }

            InputStream is = null;
            for (int i = 0; i < tryCount; i++) {
                try {
                    HttpURLConnection urc = (HttpURLConnection) url.openConnection();


                    if (usePost) {
                        if (urc instanceof HttpURLConnection) {
                            ((HttpURLConnection) urc).setRequestMethod("POST");
                            ((HttpURLConnection) urc).setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                            ((HttpURLConnection) urc).setRequestProperty("Content-Length", "0");
                        }
                    }

                    if (getTimeout() != -1) {
                        urc.setReadTimeout(getTimeout());
                        urc.setConnectTimeout(getTimeout());
                    }

                    if (false) {
                        System.out.println();
                        for (String key : urc.getHeaderFields().keySet()) {
                            String val = urc.getHeaderField(key);
                            System.out.println("response '" + key + "' " + val);
                        }
                        System.out.println();
                    }

                    autoThrottleTime = throttle(urc);
                    int code = urc.getResponseCode();

                    is = null;
                    if (code >= 300) {
                        is = urc.getErrorStream();
                    } else {
                        is = urc.getInputStream();
                    }
                    is = new BufferedInputStream(is);
                    break;
                } catch (FileNotFoundException e) {
                    throw e;
                } catch (IOException e) {
                    System.out.println(name + " Error: " + e + " cmd: "
                            + command);
                }
            }

            lastCommandTime = System.currentTimeMillis();
            if (is == null) {
                System.out.println(name + " retry failure  cmd: " + url);
                throw new IOException("Can't send command");
            }
            return is;
        } catch (URISyntaxException ex) {
            throw new IOException("bad uri " + ex);
        }
    }

    private int getMillisecondsRemaining(String date) {
        // Date Tue, 08 Jan 2013 18:47:38 GMT
        String time = date.split(" ")[4];
        int secs = Integer.parseInt(time.split(":")[2]);
        return 60000 - (secs * 1000);
    }

    private int throttle(HttpURLConnection urc) {
        int throttle = 0;

        if (autoThrottle) {
            try {

                int remainingCalls = Integer.parseInt(urc.getHeaderField("X-RateLimit-Remaining"));
                int remainingTime = getMillisecondsRemaining(urc.getHeaderField("Date"));
                if (remainingCalls > 0) {
                    throttle = remainingTime / remainingCalls;
                } else {
                    throttle = remainingTime;
                }
            } catch (NumberFormatException e) {
                throttle = minCommandTime;
            }
            // System.out.printf("Autothrottle rt:%d rc:%d throttle:%d\n", remainingTime, remainingCalls, throttle);
        }
        return throttle;
    }

    @SuppressWarnings("unchecked")
    public Map post(String command, Map<String, Object> params)
            throws EchoNestException {
        try {
            String NEWLINE = "\r\n";
            String PREFIX = "--";
            String BOUNDARY = "-----------"
                    + Long.toString(System.currentTimeMillis(), 16);

            HttpURLConnection conn = null;

            StringBuilder urlSB = new StringBuilder();
            urlSB.append("http://");
            urlSB.append(host);
            urlSB.append(prefix);
            urlSB.append(command);

            String fullCommand = urlSB.toString();
            URL url = null;

            try {
                URI uri = new URI(fullCommand);
                url = uri.toURL();
            } catch (URISyntaxException e) {
                throw new EchoNestException(
                        EchoNestException.CLIENT_SERVER_INCONSISTENCY,
                        "Bad URL " + e);
            } catch (MalformedURLException e) {
                throw new EchoNestException(
                        EchoNestException.CLIENT_SERVER_INCONSISTENCY,
                        "Bad URL " + e);
            }

            if (traceSends) {
                System.out.println("Sending-->     " + url);
            }

            conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setAllowUserInteraction(false);
            conn.setUseCaches(false);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Accept", "*/*");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Cache-Control", "no-cache");
            conn.setRequestProperty("Content-Type",
                    "multipart/form-data;boundary=" + BOUNDARY);
            DataOutputStream dostream = new DataOutputStream(conn.getOutputStream());
            //DataOutputStream dostream = new DataOutputStream(System.out);
            OutputStreamWriter out = new OutputStreamWriter(dostream, "utf-8");

            Map<String, Object> p = new HashMap<String, Object>(params);

            for (Entry<String, Object> kv : standardParams.getMap().entrySet()) {
                p.put(kv.getKey(), kv.getValue());
            }


            if (false) {
                for (String s : p.keySet()) {
                    System.out.printf("   %s=%s\n", s, p.get(s));
                }
            }
            for (String key : p.keySet()) {
                out.write(PREFIX);
                out.write(BOUNDARY);
                out.write(NEWLINE);
                Object val = p.get(key);

                if (val instanceof File) {

                    File file = (File) val;

                    out
                            .write("Content-Disposition: form-data; name=\"file\";"
                            + " filename=\"" + file.getName() + "\"");
                    out.write(NEWLINE);
                    out.write("Content-Type: application/octet-stream");
                    out.write(NEWLINE);
                    out.write(NEWLINE);
                    out.flush();

                    InputStream is = new FileInputStream(file);
                    int r = 0;
                    byte[] data = new byte[1024];
                    while ((r = is.read(data, 0, data.length)) != -1) {
                        dostream.write(data, 0, r);
                    }
                    is.close();
                    out.write(NEWLINE);
                } else {
                    out.write("Content-Disposition: form-data; name=\""
                            + key + "\"");
                    out.write(NEWLINE);
                    out.write(NEWLINE);
                    out.write(val.toString());
                    //dos.writeUTF(val.toString());
                    out.write(NEWLINE);
                }
            }
            out.write(PREFIX);
            out.write(BOUNDARY);
            out.write(PREFIX);
            out.write(NEWLINE);
            // close streams
            out.flush();
            out.close();

            int code = conn.getResponseCode();

            InputStream is = null;
            if (code >= 300) {
                is = conn.getErrorStream();
            } else {
                is = conn.getInputStream();
            }
            BufferedReader in = new BufferedReader(new InputStreamReader(is,
                    Charset.forName("UTF-8")));

            String line = null;
            StringBuilder results = new StringBuilder();

            while ((line = in.readLine()) != null) {
                results.append(line);
            }

            if (traceRecvs) {
                System.out.println("received-->     " + results.toString());
            }
            in.close();
            String resultString = results.toString();

            try {
                JSONObject jobj = (JSONObject) parser.parse(resultString);
                checkStatus(jobj);
                return (Map) jobj;
            } catch (ParseException e) {
                throw new IOException("Parse Exception", e);
            }
        } catch (IOException ioe) {
            throw new EchoNestException(ioe);
        }
    }

    private void cmdDelay() {
        long curGap = System.currentTimeMillis() - lastCommandTime;
        long delayTime;

        if (autoThrottle) {
            delayTime = autoThrottleTime - curGap;
        } else {
            delayTime = minCommandTime - curGap;
        }
        delay(delayTime);

    }

    private void delay(long time) {

        if (time > 0) {
            try {
                Thread.sleep(time);
            } catch (InterruptedException ie) {
            }
        }
    }

    /**
     * @return the host
     */
    public String getHost() {
        return host;
    }

    /**
     * @param host the host to set
     */
    public void setHost(String host) {
        this.host = host;
    }

    /**
     * @return the prefix
     */
    public String getPrefix() {
        return prefix;
    }

    /**
     * @param prefix the prefix to set
     */
    public void setPrefix(String prefix) {
        this.prefix = prefix;
    }

    /**
     * @return the traceSends
     */
    public boolean isTraceSends() {
        return traceSends;
    }

    /**
     * @param traceSends the traceSends to set
     */
    public void setTraceSends(boolean traceSends) {
        this.traceSends = traceSends;
    }

    /**
     * @return the trackRecvs
     */
    public boolean isTraceRecvs() {
        return traceRecvs;
    }

    /**
     * @param trackRecvs the trackRecvs to set
     */
    public void setTraceRecvs(boolean trackRecvs) {
        this.traceRecvs = trackRecvs;
    }

    /**
     * @return the minCommandTime
     */
    public int getMinCommandTime() {
        return minCommandTime;
    }

    /**
     * @param minCommandTime the minCommandTime to set
     */
    public void setMinCommandTime(int minCommandTime) {
        if (minCommandTime < 0) {
            autoThrottle = true;
        } else {
            this.minCommandTime = minCommandTime;
            autoThrottle = false;
        }
    }

    /**
     * @return the timeout
     */
    public int getTimeout() {
        return timeout;
    }

    /**
     * @param timeout the timeout to set
     */
    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    /**
     * @return the tryCount
     */
    public int getTryCount() {
        return tryCount;
    }

    /**
     * @param tryCount the tryCount to set
     */
    public void setTryCount(int tryCount) {
        this.tryCount = tryCount;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @return the standardParams
     */
    public Params getStandardParams() {
        return standardParams;
    }

    /**
     * @param standardParams the standardParams to set
     */
    public void setStandardParams(Params standardParams) {
        this.standardParams = standardParams;
    }

    @SuppressWarnings("unchecked")
    private void checkStatus(Map results) throws EchoNestException {
        Map response = (Map) results.get("response");
        Map status = (Map) response.get("status");
        String version = (String) status.get("version");
        String message = (String) status.get("message");
        Long scode = (Long) status.get("code");

        int code = scode.intValue();

        if (!version.startsWith(expectedVersion)) {
            throw new EchoNestException(
                    EchoNestException.CLIENT_SERVER_INCONSISTENCY,
                    "Unexpected API version number");
        }

        if (code != 0) {
            throw new EchoNestException(code, message);
        }
    }

    @SuppressWarnings("unchecked")
    void test() throws IOException, EchoNestException {
        String command = "http://developer3.sandpit.us/api/v4/artist/get_similar?&api_key=XZTXVRO3VC3FBXS8C&id=ARH6W4X1187B99274F&format=json&rows=10&start=0&bucket=hotttnesss";
        String results = getStringResults(command, false, null);
        System.out.println(results);

        Map jo = getCheckedResults(command, false, null);
        System.out.println(jo);

        String errcmd = "http://developer3.sandpit.us/api/v4/artist/get_similar?&api_key=AZTXVRO3VC3FBXS8C&id=ARH6W4X1187B99274F&format=json&rows=10&start=0&bucket=hotttnesss";
        Map jo2 = getCheckedResults(errcmd, false, null);
        System.out.println(jo2);
    }

    @SuppressWarnings("unchecked")
    void test2() throws EchoNestException {
        Params params = new Params();
        params.add("rows", 10);
        params.add("bucket", "hotttnesss");
        params.add("bucket", "familiarity");
        params.add("id", "ARH6W4X1187B99274F");

        Map results = sendCommand("artist/get_similar", params, false);
        System.out.println(results);
    }

    @SuppressWarnings("unchecked")
    void test3() throws EchoNestException {
        Params params = new Params();
        params.add("rows", 10);
        params.add("bucket", "hotttnesss");
        params.add("bucket", "familiarity");
        params.add("bucket", "crap");

        params.add("id", "ARH6W4X1187B99274F");
        params.add("id", "ARH1N081187B9AC562");

        Map results = sendCommand("artist/get_similar", params, false);
        System.out.println(results);
    }

    public static void main(String[] args) throws Exception {
        Commander cmd = new Commander("test");
        Params stdParams = new Params();
        stdParams.add("api_key", "FILDTEOIK2HBORODV");
        cmd.setStandardParams(stdParams);
        cmd.test2();
        cmd.test3();
    }
}
TOP

Related Classes of com.echonest.api.v4.util.Commander

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.