2

I want to write a simple program in Processing, that would take data from here:

https://btc-e.com/api/2/btc_usd/trades

and display them in a chart. Let's consider the simplest example of accessing the data:

void setup() {
  size(400,400);
}

void draw() {
  background(0);
  fill(244);
  String[] t = loadStrings("https://btc-e.com/api/2/btc_usd/trades");
  text(t[0],100,100);
}

This works perfectly, when I run this as Java Application directly from Processing IDE (from both Processing 1.5 and 2.0). But then I export this as Java Applet (from Processing 1.5) I can not run this on either localhost or OpenProcessing. Java Machine runs, asks, whether I want to run the applet, I accept that, and then applet stays grey or white and nothing happens. What's the reason?

Is there any security problem, that Java Machine does not allow the code to get external data from other server? Is there any way to walk around the problem?

I stress, that I am working in Java/Java Applet mode, not in JavaScript, which I am sure does not allow such cross-source of data.

morten.c
  • 3,414
  • 5
  • 40
  • 45
Paweł Tokarz
  • 326
  • 2
  • 15
  • Can you put a try catch around your loading of strings and get an error message? Also can you post your `loadStrings` method – ug_ Jan 07 '14 at 17:40
  • 2
    You should see some sort of error in the Java [console](http://docs.oracle.com/javase/7/docs/technotes/guides/deployment/deployment-guide/console.html) and that will most likely be about some security [restriction of Applets](http://docs.oracle.com/javase/tutorial/deployment/applet/security.html). – zapl Jan 07 '14 at 17:41
  • @ns47731 - loadStrings is the method provided by Processing, it's not mine. – Paweł Tokarz Jan 07 '14 at 17:51
  • @zapl - It seems, that this is the reason. The source you gave me states: "Sandbox applets cannot (...) retrieve resources from any third party server (any server other than the server it originated from)." That's sad... – Paweł Tokarz Jan 07 '14 at 17:51
  • Have you signed the applet ? – George Profenza Jan 08 '14 at 01:51

2 Answers2

2

The data you're loading is a JSON formatted array so loadStrings won't be very useful in this case.

You should be using loadJSONArray() and JSONObject to parse the data from each entry in the array you're loading.

Here's a basic sample using just the amount values:

void setup(){
  JSONArray data = loadJSONArray("https://btc-e.com/api/2/btc_usd/trades");//load the data

  for (int i = 0; i < data.size(); i++) {//traverse the data

    JSONObject entry = data.getJSONObject(i); //get each entry in the list/array
    //parse the values
    float amount = entry.getFloat("amount");
    int price    = entry.getInt("price");
    String item  = entry.getString("item");
    String pc    = entry.getString("price_currency");
    int tid      = entry.getInt("tid");
    int date     = entry.getInt("date");
    String tt    = entry.getString("trade_type");

    //do something with the data
    float x = (float)i/data.size() * width;
    float y = 100 - (amount * 20);
    line(x,height,x,y);
  }
}

And here's the output:

chart

Another note: in your code, you use loadStrings in the draw() loop which means you're loading the same data over and over again multiple times(about 60 by default) per second which is not a good idea. You should load the data once, have it available in a top level variable and reuse the loaded data in a draw() loop when you need it.

Also, if you're loading external data you might need to sign the applet. Check out this guide. I've used the same guide to post this applet.

George Profenza
  • 50,687
  • 19
  • 144
  • 218
1

You're going to run into security problems as pointed out in the comments.

Options 1 Create a job that retrieves the data from the external URL and loads it into your own server side database. You would then need a server side servlet (perhaps a REST service) on the same host that loaded your applet to retrieve the data from your database.

Options 2 Server side servlet that retrieves the data from the remote URL and pipes it to the HTTP response, this way no load job or database is needed.

The only other option is setting up a reverse proxy to bypass the same origin policy which is a terrible hacky idea.

Kabron
  • 151
  • 1
  • 11