00001 package myShell; 00002 00003 // java tools 00004 import java.io.BufferedWriter; 00005 import java.io.FileWriter; 00006 import java.util.*; 00007 // CPS specific classes 00008 import sorter.SplitSort; 00009 import sorter.Comparator; 00010 import myDataBases.MySQLbase; 00011 import myDataBases.MediaBase; 00012 import crowdUser.CrowdManager; 00013 00014 00029 public class MainClass { 00030 00031 00032 // Attributes 00033 00034 00035 00039 public static LogWriter log; 00043 public static Map<String,String> config; 00047 public static MySQLbase hitBdd; 00051 public static MediaBase mediaBdd; 00055 public static List<Integer[]> allMedia; 00060 public static CrowdManager theBoss; 00064 public static Interpreter inter; 00068 public static Comparator comp; 00072 public static Boolean keepGoing; 00073 00074 00075 // Methods 00076 00086 public static void main(String args[]) 00087 { 00088 // creating a new log file 00089 log = new LogWriter(); 00090 00091 // if no argument was given, displays help 00092 if (args.length == 0) 00093 displayHelp(); 00094 00095 // if at least one argument is given, it depend on its value: 00096 else if (args.length > 0) 00097 { 00098 // displaying help 00099 if ( args[0].equals("--help") ) 00100 displayHelp(); 00101 00102 // creating the .sql file 00103 else if ( args[0].equals("--sql-file") ) 00104 sqlFile(); 00105 00106 // creating a new splitsort, but checking the config file and the connection with the database first. 00107 else if ( args[0].equals("--new") ) 00108 { 00109 if (args.length <= 1) 00110 displayHelp(); // if no password was given, displays help 00111 else if (Interpreter.checkFile(log)) 00112 if ( MySQLbase.testConnection(log, args[1]) ) 00113 generateJob(args[1]); // if all the tests were correct, a job is generated 00114 else 00115 System.out.println("\nERROR : a problem was encountered. Check logs for more details."); 00116 } 00117 00118 // launching one iteration, but checking the config file and the connection with the database first. 00119 else if ( args[0].equals("--iteration") ) 00120 { 00121 if (args.length <= 1) 00122 displayHelp(); // if the password was not given, displays help 00123 else if (Interpreter.checkFile(log)) 00124 if ( MySQLbase.testConnection(log, args[1]) ) // if the tests were correct: 00125 { 00126 useResults(args[1]); // results are used to finish a quicksort iteration 00127 comp.display(); 00128 if (keepGoing) 00129 generateJob(args[1]); // a new one is launched and a new job is created if it is not finished 00130 } 00131 else 00132 System.out.println("\nERROR : a problem was encountered. Check logs for more details."); 00133 else 00134 System.out.println("\nERROR : a problem was encountered. Check logs for more details."); 00135 } 00136 00137 00138 // checking... 00139 else if (args[0].equals("--check")) 00140 { 00141 // ... nothing (not enough arguments) 00142 if (args.length == 1) 00143 displayHelp(); 00144 00145 // ... the content of the configuration file 00146 if (args[1].equals("config")) 00147 { 00148 if (Interpreter.checkFile(log)) 00149 System.out.println("\nThe config.xml file contains all the information necessary.\n\n"); 00150 else 00151 System.out.println("\nA problem was encountered (information missing)." + 00152 "Check log for more information\n"); 00153 } 00154 00155 // ... the connection with the database 00156 else if (args[1].equals("sql-db")) 00157 { 00158 if (args.length <= 2) 00159 displayHelp(); // if the password was not given, displays help 00160 else if ( MySQLbase.testConnection(log, args[2]) ) 00161 System.out.println("connection with the database successfully created"); 00162 else 00163 System.out.println("A problem was encountered while connecting with the database." + 00164 "Check log for more information\n"); 00165 } 00166 00167 // ... the creation of a HIT 00168 else if (args[1].equals("newjob")) 00169 { 00170 config = Interpreter.getConfig() ; 00171 CrowdManager test = new CrowdManager(Integer.parseInt( config.get("cfJobNumber") ), config.get("cfKey"), 00172 config.get("antechamberUrl"), null, null, Interpreter.getFields("CSVfield") ); 00173 System.out.println(" new job identifier : " + test.createNewJob()); 00174 } 00175 00176 // ... the sending of a final e-mail when everything is finished 00177 else if (args[1].equals("final-email")) 00178 { 00179 config = Interpreter.getConfig(); 00180 CrowdManager.thisIsTheEnd(config.get("antechamberUrl") + "main.php", 00181 "<?xml version='1.0' encoding='UTF-8'?>\n" + 00182 "<results>\n <media id='99'>\n <timecode>99</timecode>\n <name>truc99.ogg</name>\n" + 00183 " <axe1>-0.8181818181818181</axe1>\n </media>\n</results>"); 00184 System.out.println("Signal sent at " + config.get("antechamberUrl") + "main.php\n"); 00185 } 00186 00187 // ... nothing because the argument given was invalid: displays help 00188 else 00189 displayHelp(); 00190 } 00191 00192 // displaying help otherwise 00193 else 00194 displayHelp(); 00195 } 00196 00197 // writing the date and time of end in the log file. 00198 log.finish(); 00199 System.out.println(); 00200 } 00201 00202 00221 public static void save(Boolean finished) 00222 { 00223 if (finished) 00224 { 00225 Map<String,Integer[]> xmlParameters = new Hashtable<String,Integer[]>(); 00226 // writing results in the shell, formatted like a python dictionnary to make it easier to check it. 00227 System.out.println("This is for '../data/CM-stub/stub.py check' if you where testing CPS:"); 00228 System.out.print("{ "); 00229 for ( Iterator<String> str = comp.getSplitSorts().keySet().iterator(); str.hasNext(); ) 00230 { 00231 String axis = str.next(); 00232 Integer[] res = comp.getSplitSorts().get(axis).getFinalResult(); 00233 System.out.print(" '" + axis + "' : ["); 00234 for (int i=0; i<res.length; i++) 00235 System.out.print(res[i]+", "); 00236 System.out.print("] , "); 00237 xmlParameters.put(axis, res); 00238 } 00239 System.out.print("}\n\n"); 00240 // saving results in the ../data/results.xml file 00241 String results = inter.generateFinalXML("../results.xml",xmlParameters); 00242 log.append("[DONE] writing results in results.xml"); 00243 // sending final email 00244 CrowdManager.thisIsTheEnd(config.get("antechamberUrl") + "main.php",results); 00245 log.append("[DONE] sending end notification e-mail."); 00246 System.out.println("\n\nThis splitsort is finished! You can now get the results in the data/results.xml file."); 00247 } 00248 else 00249 for (String axis : comp.getSplitSorts().keySet()) 00250 { 00251 log.append("[DONE] writing temporary state in " + axis + ".xml"); 00252 inter.generateIntermediaryXMLs("../data/previously/" + axis + ".xml",comp.getCurrentState().get(axis)); 00253 } 00254 } 00255 00256 00257 00269 public static void initialize(String dbPasswd) 00270 { 00271 config = Interpreter.getConfig() ; 00272 log.append("[DONE] reading configuration file"); 00273 00274 mediaBdd = new MediaBase(config.get("mediaPath")); 00275 log.append("[DONE] reading media to be sorted"); 00276 00277 inter = new Interpreter(mediaBdd); 00278 log.append("[DONE] initialisation of the Interpreter"); 00279 00280 Integer drop = Integer.parseInt(config.get("drop")); // the size of the arrays under which they are not sorted 00281 log.append("[DONE] array to be sorted created\n Note : the sort will stop for arrays having" + 00282 " a smaller than " + drop + " size"); 00283 00284 Map<String,SplitSort> splitsortMap = new HashMap<String,SplitSort>(); 00285 List<String> axes = Interpreter.getAxes(); 00286 00287 keepGoing = false; // "default" value 00288 for (String axis : axes) 00289 { 00290 allMedia = inter.getCurrentState(log,axis); 00291 SplitSort sorter = new SplitSort(allMedia,drop); 00292 splitsortMap.put(axis,sorter); 00293 if (sorter.notFinished()) 00294 keepGoing = true; 00295 } 00296 00297 // If the sort must go on : 00298 if (keepGoing) 00299 { 00300 hitBdd = new MySQLbase("jdbc:mysql://localhost:3306/" + config.get("sqlBase") , config.get("sqlUser"), 00301 dbPasswd, Interpreter.getFields("SQLfield"), Interpreter.getFields("SQLtype")); 00302 log.append("[DONE] connexion to mySQL database"); 00303 00304 comp = new Comparator(splitsortMap,hitBdd); 00305 log.append("[DONE] initialisation of the comparator"); 00306 00307 theBoss = new CrowdManager(Integer.parseInt( config.get("cfJobNumber") ), config.get("cfKey"), 00308 config.get("antechamberUrl"), hitBdd, mediaBdd, Interpreter.getFields("CSVfield") ); 00309 log.append("[DONE] initialisation of the CrowdManager"); 00310 } 00311 // Otherwise, final results are written without going further. 00312 else 00313 { 00314 comp = new Comparator(splitsortMap); 00315 log.append("[DONE] initialisation of the comparator.\n Note: No connexion to the My SQL database created."); 00316 save(true); 00317 } 00318 } 00319 00320 00336 public static void generateJob(String dbPasswd) 00337 { 00338 log.append("\n___________ generating Jobs ___________"); 00339 00340 // step 1: initialization 00341 initialize(dbPasswd); 00342 if (keepGoing) 00343 { 00344 00345 // step 2: first step of the quicksort 00346 comp.sortIteration(); 00347 log.append("[DONE] first step of the quicksort"); 00348 00349 // step 3: sending unknown comparisons to a CrowdManager instance 00350 comp.demandNewComparisons(theBoss.getGreater(),theBoss.getSmaller(),theBoss.getAxes()); 00351 log.append("[DONE] asking for new comparisons\n Note : " + 00352 theBoss.getGreater().size() + " new comparisons required") ; 00353 00354 // step 4: uploading a new job if necessary 00355 if (theBoss.getGreater().size() >= 1) 00356 { 00357 Integer jobId = theBoss.createNewJob(); 00358 Interpreter.setLastJob(jobId); 00359 log.append("[DONE] creating a new job at CrowdFlower (id=" + jobId + ")"); 00360 theBoss.uploadHIT(jobId); 00361 log.append("[DONE] uploading HIT\n ... Now waiting for HIT results."); 00362 } 00363 else 00364 { 00365 log.append(" Note : all comparisons are already known : no HIT"); 00366 useResults(dbPasswd); 00367 } 00368 } 00369 } 00370 00371 00388 public static void useResults(String dbPasswd) 00389 { 00390 log.append("\n___________ Using Results ___________"); 00391 00392 // step 1: initialization 00393 initialize(dbPasswd); 00394 if (keepGoing) 00395 { 00396 comp.sortIteration(); // Each splitsort recreates its comparisons in order to be able to understand the results 00397 String path2results = theBoss.getHITresults( Interpreter.getLastJob() ); 00398 00399 // step 2 : after the Job is done, the results are read and ameliorated. 00400 theBoss.readHITresults( path2results ); 00401 log.append("[DONE] reading HIT results"); 00402 00403 // step 3 : last step of the quicksort 00404 comp.endIteration(); 00405 log.append("[DONE] last step of the quicksort"); 00406 00407 // step 4 : generating a dump of the database 00408 hitBdd.generateDump(); 00409 log.append("[DONE] dump of the MySQL database"); 00410 00411 // step 5 : saving current results 00412 save(false); 00413 } 00414 } 00415 00416 00417 00431 public static void sqlFile() 00432 { 00433 String user = Interpreter.getConfig().get("sqlUser"); 00434 String fileContent = "CREATE DATABASE DBcps ;\n" + 00435 "GRANT DELETE,DROP,SELECT,INSERT,LOCK TABLES,UPDATE,CREATE ON DBcps.* TO '" + 00436 user + "'@'localhost' ;\n" + 00437 "USE DBcps ;\n" + 00438 "CREATE TABLE results (axis VARCHAR(40), idMedia1 INT, idMedia2 INT, greater TINYINT," + 00439 " nameMedia1 VARCHAR(300), nameMedia2 VARCHAR(300) ) ;\n" + 00440 "CREATE TABLE hit ("; 00441 List<String> fields = Interpreter.getFields("SQLfield"); 00442 List<String> types = Interpreter.getFields("SQLtype"); 00443 for (int i=0; i<fields.size()-1; i++) 00444 fileContent += fields.get(i) +" "+ types.get(i) +", "; 00445 fileContent += fields.get(fields.size()-1) +" "+ types.get(fields.size()-1) +" ) ;"; 00446 try 00447 { 00448 BufferedWriter sqlFile = new BufferedWriter 00449 (new FileWriter("../data/mysql/createCPStables.sql",false)); 00450 sqlFile.write(fileContent); 00451 sqlFile.newLine(); 00452 sqlFile.close(); 00453 } 00454 catch (Exception e) { e.printStackTrace(); } 00455 System.out.println("File created : data/mysql/createCPStables.sql"); 00456 } 00457 00458 00464 public static void displayHelp() 00465 { 00466 System.out.println("\n\n\n =========================== CROWD-POWERED-SORT =========================== "); 00467 System.out.println(); 00468 System.out.println("Sorts media along specified axis and returns the results in a file (xml format)."); 00469 System.out.println("A CrowdFlower (<http://crowdflower.com>) account is necessary."); 00470 System.out.println(); 00471 System.out.println(" OPTIONS"); 00472 System.out.println(); 00473 System.out.println(" --new 'DBpasswd' Launches the splitsort of the media contained in the "); 00474 System.out.println(" data/media.txt file or in the data/media folder (this must be "); 00475 System.out.println(" precised in the config.xml file). 'DBpasswd' is the password of"); 00476 System.out.println(" the database. In order for the sort to continue, you must use"); 00477 System.out.println(" this program again, but with the '--iteration' option when you"); 00478 System.out.println(" receive an e-mail."); 00479 System.out.println(); 00480 System.out.println(" --iteration 'DBpasswd' Works just like '--sort' but launches a unique "); 00481 System.out.println(" splitsort iteration. Results are stored as xml files"); 00482 System.out.println(" corresponding to each axis in the '../data/tmp' folder."); 00483 System.out.println(); 00484 System.out.println(" --sql-file creates a .sql file which, uploaded with the mysql root account,"); 00485 System.out.println(" will create the database DBcps and the tables necessary for CPS"); 00486 System.out.println(" to work, i.e 'hit' and 'results'."); 00487 System.out.println(); 00488 System.out.println(" --check=[OPTION] this option can have several value :"); 00489 System.out.println(" config checks the content of the config.xml file."); 00490 System.out.println(" sql-db 'DBpasswd' checks the connection with the MySQL database."); 00491 System.out.println(" newjob attempts to create a new job by copying the one whose id"); 00492 System.out.println(" is specified in the config.xml file"); 00493 System.out.println(" final-email Asks the antechamber to send a final notification email"); 00494 System.out.println(" spotting the end of an imaginary splitsort. Fake results are"); 00495 System.out.println(" attached in order to check this as well."); 00496 System.out.println(); 00497 System.out.println(" --help displays this help and exit"); 00498 System.out.println("\n\n\n"); 00499 } 00500 }