X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~yarrgweb/git?a=blobdiff_plain;f=src%2Fcom%2Ftedpearson%2Fypp%2Fmarket%2FMarketUploader.java;h=98ef25e955239db0c402a706ded93dcd6555332d;hb=813ffd281d1dff106d6c04ef48925a45d552f223;hp=526fc25a60da242de7715973fec3a55117a56519;hpb=ddd0261a33ef991c168b73a57c76500dde031744;p=jarrg-ian.git diff --git a/src/com/tedpearson/ypp/market/MarketUploader.java b/src/com/tedpearson/ypp/market/MarketUploader.java index 526fc25..98ef25e 100644 --- a/src/com/tedpearson/ypp/market/MarketUploader.java +++ b/src/com/tedpearson/ypp/market/MarketUploader.java @@ -38,6 +38,9 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis private JFrame frame = null; private Window window = null; private JButton findMarket = null; + private JLabel resultSummary = null; + private JLabel arbitrageResult = null; + private long startTime = 0; private final static String PCTB_LIVE_HOST_URL = "http://pctb.crabdance.com/"; private final static String PCTB_TEST_HOST_URL = "http://pctb.ilk.org/"; @@ -54,6 +57,7 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis private boolean uploadToYarrg; private boolean uploadToPCTB; + private boolean showArbitrage; private String islandName = null; private String oceanName = null; @@ -61,14 +65,8 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis private AccessibleContext sidePanel; private HashMap commodMap; - private HashMap islandNumbers = new HashMap(); - { - String[] nums = new String[] - {"","Viridian","Midnight","Hunter","Cobalt","Sage","Ice","Malachite","Crimson","Opal"}; - for(int i=1;i1000")) { + return 1001; + } else { + return Integer.parseInt(str); + } + } + + private void progresslog(String s) { + if (dtxt == null) return; + long now = new Date().getTime(); + dtxt.println("progress "+(now - startTime)+"ms "+s); + } + + private void debug_write_stringdata(String what, String data) throws FileNotFoundException,IOException { + if (dtxt==null) return; + PrintStream strm = new PrintStream(new File("jarrg-debug-"+what)); + strm.print(data); + strm.close(); + } + + private void progressNote(ProgressMonitor pm, String s) { + String arb = null; + if (arbitrageResult != null) + arb = arbitrageResult.getText(); + if (arb != null && arb.length() != 0) + s = "" + arb + "
" + s; + pm.setNote(s); + } /** * An abstract market offer, entailing a commodity being bought or sold by @@ -114,11 +142,7 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis commodity = commodId.intValue(); price = Integer.parseInt(record.get(priceIndex)); String qty = record.get(priceIndex+1); - if(qty.equals(">1000")) { - quantity = 1001; - } else { - quantity = Integer.parseInt(record.get(priceIndex+1)); - } + quantity = parseQty(qty); shoppe = stallMap.get(record.get(1)).intValue(); } @@ -218,9 +242,16 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis * Entry point. Read our preferences. */ public MarketUploader() { - // check if we've been turned off in the control panel Preferences prefs = Preferences.userNodeForPackage(getClass()); + if (prefs.getBoolean("writeDebugFiles", false)) { + try { + dtxt = new PrintStream(new File("jarrg-debug-log.txt")); + } catch (java.io.FileNotFoundException e) { + System.err.println("JARRG: Error opening debug log: "+e); + } + } + if (prefs.getBoolean("useLiveServers", false)) { YARRG_URL = YARRG_LIVE_URL; PCTB_HOST_URL = PCTB_LIVE_HOST_URL; @@ -231,6 +262,7 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis uploadToYarrg=prefs.getBoolean("uploadToYarrg", true); uploadToPCTB=prefs.getBoolean("uploadToPCTB", true); + showArbitrage=prefs.getBoolean("showArbitrage", true); EventQueueMonitor.addTopLevelWindowListener(this); if (EventQueueMonitor.isGUIInitialized()) { @@ -250,9 +282,10 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis if (window.getAccessibleContext().getAccessibleName().equals("Puzzle Pirates")) frame.setVisible(true); return; } - frame = new JFrame("MarketUploader"); + frame = new JFrame("Jarrg Uploader"); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - frame.getContentPane().setLayout(new FlowLayout()); + GridLayout layout = new GridLayout(2,1); + frame.getContentPane().setLayout(layout); //frame.setPreferredSize(new Dimension(200, 60)); findMarket = new JButton("Upload Market Data"); @@ -261,24 +294,38 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis findMarket.setEnabled(false); new Thread() { public void run() { + startTime = new Date().getTime(); + resultSummary.setText(""); + arbitrageResult.setText(""); try { - runPCTB(); + runUpload(); } catch(Exception e) { error(e.toString()); e.printStackTrace(); + resultSummary.setText("failed"); } finally { if(sidePanel != null) { // remove it if it's still attached sidePanel.removePropertyChangeListener(changeListener); } } - //findMarketTable(); findMarket.setEnabled(true); } }.start(); } }); frame.add(findMarket); + + resultSummary = new JLabel("ready"); + frame.add(resultSummary); + + arbitrageResult = new JLabel(""); + + if (showArbitrage) { + layout.setRows(layout.getRows() + 1); + frame.add(arbitrageResult); + } + frame.pack(); } @@ -318,7 +365,6 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis } } } - // if we don't find the island name, hopefully the server will } /** @@ -341,8 +387,6 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis } private void error_html(String msg, String html) { - //System.err.println("===" + html + "==="); - Pattern body = Pattern.compile("(.*)", Pattern.DOTALL | Pattern.CASE_INSENSITIVE); Matcher m = body.matcher(html); if (m.find()) { @@ -354,7 +398,7 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis html = m.replaceAll(" "); } String whole_msg = "

Error

"+msg+"

PCTB Server said:

"+html+"
"; - //System.err.println("###" + whole_msg + "###"); + if (dtxt!=null) dtxt.println("###" + whole_msg + "###"); JOptionPane.showMessageDialog(frame,whole_msg,"Error",JOptionPane.ERROR_MESSAGE); } @@ -367,22 +411,39 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis * * @exception Exception if an error we didn't expect occured */ - private void runPCTB() throws Exception { - String yarrgts = ""; + private class YarrgTimestampFetcher extends Thread { + public String ts = null; + public void run() { + try { + ts = getYarrgTimestamp(); + progresslog("(async) yarrg timestamp ready."); + } catch(Exception e) { + error("Error getting YARRG timestamp: "+e); + } + } + }; + + private void runUpload() throws Exception { + progresslog("starting"); + ProgressMonitor pm = new ProgressMonitor(frame,"Processing Market Data","Getting table data",0,100); pm.setMillisToDecideToPopup(0); pm.setMillisToPopup(0); + boolean doneyarrg = false, donepctb = false; + YarrgTimestampFetcher yarrgts_thread = null; if (uploadToYarrg) { - yarrgts = getYarrgTimestamp(); + progresslog("(async) yarrg timestamp..."); + yarrgts_thread = new YarrgTimestampFetcher(); + yarrgts_thread.start(); } - AccessibleTable t = findMarketTable(); - if(t == null) { + AccessibleTable accesstable = findMarketTable(); + if(accesstable == null) { error("Market table not found! Please open the Buy/Sell Commodities interface."); return; } - if(t.getAccessibleRowCount() == 0) { + if(accesstable.getAccessibleRowCount() == 0) { error("No data found, please wait for the table to have data first!"); return; } @@ -391,17 +452,67 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis return; } + progresslog("(async) getisland..."); getIsland(); + progresslog("getocean..."); getOcean(); + progresslog("getocean done"); if (latch != null) { latch.await(2, java.util.concurrent.TimeUnit.SECONDS); } + progresslog("(async) getisland done"); - ArrayList> data = getData(t); + String yarrgts = null; + if (yarrgts_thread != null) { + progresslog("(async) yarrg timestamp join..."); + yarrgts_thread.join(); + progresslog("(async) yarrg timestamp joined."); + yarrgts = yarrgts_thread.ts; + } - if (uploadToYarrg) { - pm.setNote("Preparing data for Yarrg"); + if (islandName == null) { + error("Could not find island name in YPP user interface."); + return; + } + + progresslog("table check..."); + + String headings_expected[] = new String[] + { "Commodity", "Trading outlet", "Buy price", "Will buy", "Sell price", "Will sell" }; + ArrayList> headers = getData(accesstable.getAccessibleColumnHeader()); + if (headers.size() != 1) { + error("Table headings not one row! " + headers.toString()); + return; + } + if (headers.get(0).size() != 6) { + error("Table headings not six columns! " + headers.toString()); + return; + } + for (int col=0; col> data = getData(accesstable); + + if (showArbitrage) { + progresslog("arbitrage..."); + calculateArbitrage(data); + progresslog("arbitrage done."); + } + + if (uploadToYarrg && yarrgts != null) { + progresslog("yarrg prepare..."); + progressNote(pm, "Yarrg: Preparing data"); pm.setProgress(10); StringBuilder yarrgsb = new StringBuilder(); @@ -421,63 +532,87 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis yarrgdata = yarrgsb.toString(); - pm.setNote("Uploading to Yarrg"); + progressNote(pm, "Yarrg: Uploading"); + progresslog("yarrg upload..."); - if (islandName != null) { - runYarrg(yarrgts, oceanName, islandName, yarrgdata); - } else { - System.out.println("Couldn't upload to Yarrg - no island name found"); - } + debug_write_stringdata("yarrg-deduped.tsv", yarrgdata); + + doneyarrg = runYarrg(yarrgts, oceanName, islandName, yarrgdata); + progresslog("yarrg done."); } - pm.setNote("Getting stall names"); - pm.setProgress(20); - if(pm.isCanceled()) { + if (uploadToPCTB) { + progresslog("pctb prepare..."); + progressNote(pm, "PCTB: Getting stall names"); + pm.setProgress(20); + if(pm.isCanceled()) { return; - } - TreeSet buys = new TreeSet(); - TreeSet sells = new TreeSet(); - LinkedHashMap stallMap = getStallMap(data); - pm.setProgress(40); - pm.setNote("Sorting offers"); - if(pm.isCanceled()) { + } + TreeSet buys = new TreeSet(); + TreeSet sells = new TreeSet(); + LinkedHashMap stallMap = getStallMap(data); + pm.setProgress(40); + progressNote(pm, "PCTB: Sorting offers"); + if(pm.isCanceled()) { return; - } - // get commod map + } + // get commod map - HashMap commodMap = getCommodMap(); - if(commodMap == null) { + progresslog("pctb commodmap..."); + HashMap commodMap = getCommodMap(); + if(commodMap == null) { return; - } - int[] offerCount = getBuySellMaps(data,buys,sells,stallMap,commodMap); - //println(buys.toString()); - //System.out.println(sells); - //System.out.println("\n\n\n"+buys); + } + progresslog("pctb commodmap done."); + int[] offerCount = getBuySellMaps(data,buys,sells,stallMap,commodMap); + // if (dtxt!=null) dtxt.println(sells); + // if (dtxt!=null) dtxt.println("\n\n\n"+buys); - if (uploadToPCTB) { - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - pm.setProgress(60); - pm.setNote("Sending data"); - if(pm.isCanceled()) { - return; - } - GZIPOutputStream out = new GZIPOutputStream(outStream); - //FileOutputStream out = new FileOutputStream(new File("output.text")); - DataOutputStream dos = new DataOutputStream(out); - dos.writeBytes("005y\n"); - dos.writeBytes(stallMap.size()+"\n"); - dos.writeBytes(getAbbrevStallList(stallMap)); - writeBuySellOffers(buys,sells,offerCount,out); - out.finish(); - InputStream in = sendInitialData(new ByteArrayInputStream(outStream.toByteArray())); - pm.setProgress(80); - if(pm.isCanceled()) { - return; - } - pm.setNote("Waiting for PCTB..."); - finishUpload(in); + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + pm.setProgress(60); + progressNote(pm, "PCTB: Sending data"); + if(pm.isCanceled()) { + return; + } + GZIPOutputStream out = new GZIPOutputStream(outStream); + DataOutputStream dos = new DataOutputStream(out); + dos.writeBytes("005y\n"); + dos.writeBytes(stallMap.size()+"\n"); + dos.writeBytes(getAbbrevStallList(stallMap)); + writeBuySellOffers(buys,sells,offerCount,out); + out.finish(); + progresslog("pctb send..."); + + byte[] ba = outStream.toByteArray(); + if (dtxt!=null) { + FileOutputStream dbgdata = new FileOutputStream(new File("jarrg-debug-pctb-marketdata.gz")); + dbgdata.write(ba); + dbgdata.close(); + } + + InputStream in = sendInitialData(new ByteArrayInputStream(ba)); + progresslog("pctb sent."); + if (in == null) return; + pm.setProgress(80); + if(pm.isCanceled()) { + return; + } + progressNote(pm, "PCTB: Waiting ..."); + progresslog("pctb finish..."); + donepctb = finishUpload(in); + progresslog("pctb done."); } pm.setProgress(100); + + if ((uploadToPCTB && !donepctb) || + (uploadToYarrg && !doneyarrg)) { + resultSummary.setText("trouble"); + } else if (donepctb || doneyarrg) { + resultSummary.setText("Done " + islandName); + } else { + resultSummary.setText("uploaded nowhere!"); + } + progresslog("done."); } /** @@ -505,13 +640,13 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis Accessible node1 = window; Accessible node = descendNodes(node1,new int[] {0,1,0,0,0,0,1,0,0,1,0,0}); // commod market // commod market: {0,1,0,0,0,0,1,0,0,1,0} {0,1,0,0,0,0,1,0,1,0,0,1,0,0}) - //System.out.println(node); + // if (dtxt!=null) dtxt.println(node); if (!(node instanceof JTable)) { node = descendNodes(node1,new int[] {0,1,0,0,0,0,1,0,1,0,0,1,0,0}); // commod market } if (!(node instanceof JTable)) return null; AccessibleTable table = node.getAccessibleContext().getAccessibleTable(); - //System.out.println(table); + // if (dtxt!=null) dtxt.println(table); return table; } @@ -528,7 +663,7 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis private Accessible descendNodes(Accessible parent, int[] path) { for(int i=0;iPreferences. - *

- * Potential issues: When more commodities are added to the server, this - * program will currently break unless the user deletes the preferences - * file or we give them a new release with a slighly different storage - * location for the data. * * @return a map where the key is the commodity and the value is the commodity id. */ @@ -600,7 +728,6 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis return commodMap; } HashMap map = new HashMap(); - Preferences prefs = Preferences.userNodeForPackage(getClass()); String xml; try { URL host = new URL(PCTB_HOST_URL + "commodmap.php"); @@ -613,7 +740,6 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis int first = sb.indexOf("

") + 5;
 			int last = sb.indexOf("");
 			xml = sb.substring(first,last);
-			//System.out.println(xml);
 			Reader reader = new CharArrayReader(xml.toCharArray());
 			Document d = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(reader));
 			NodeList maps = d.getElementsByTagName("CommodMap");
@@ -683,7 +809,7 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis
 					buySellCount[1]++;
 				}
 			} catch(IllegalArgumentException e) {
-				System.err.println("Error: Unsupported Commodity \"" + offer.get(0) + "\"");
+				if (dtxt!=null) dtxt.println("Error: Unsupported Commodity \"" + offer.get(0) + "\"");
 			}
 		}
 		if (buySellCount[0]==0 && buySellCount[1]==0) {
@@ -804,6 +930,16 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis
 		writeOffers(out,sells);
 	}
 	
+	private String readstreamstring(InputStream in) throws IOException {
+		StringBuilder sb = new StringBuilder();
+		BufferedReader br = new BufferedReader(new InputStreamReader(in));
+		String str;
+		while((str = br.readLine()) != null) {
+			sb.append(str+"\n");
+		}
+		return sb.toString();
+	}
+
 	/**
 	*	Sends the data to the server via multipart-formdata POST,
 	*	with the gzipped data as a file upload.
@@ -813,7 +949,12 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis
 	private InputStream sendInitialData(InputStream file) throws IOException {
 		ClientHttpRequest http = new ClientHttpRequest(PCTB_HOST_URL + "upload.php");
 		http.setParameter("marketdata","marketdata.gz",file,"application/gzip");
-		return http.post();
+		if (!http.post()) {
+			String err = readstreamstring(http.resultstream());
+			error("Error sending initial data:\n"+err);
+			return null;
+		}
+		return http.resultstream();
 	}
 	
 	/**
@@ -836,122 +977,74 @@ public class MarketUploader implements TopLevelWindowListener, GUIInitializedLis
 	*
 	*	@param in stream of data from the server to read
 	*/
-	private void finishUpload(InputStream in) throws IOException {
-		StringBuilder sb = new StringBuilder();
-		BufferedReader br = new BufferedReader(new InputStreamReader(in));
-		String str;
-		while((str = br.readLine()) != null) {
-			sb.append(str+"\n");
-		}
-		String html = sb.toString();
-		//System.out.println(html);
-		String topIsland = "0", ocean, islandNum, action, forceReload, filename;
+	private boolean finishUpload(InputStream in) throws IOException {
+		String html = readstreamstring(in);
+		debug_write_stringdata("pctb-initial.html", html);
 		Matcher m;
-		Pattern whoIsland = Pattern.compile("