1 /** 2 * A set of data calls which use the new MONK proxy 3 * @name Monk Project Library 0.1 Alpha 1 4 * @copyright Copyright(c) 2007, Monk Project, All rights reserved. 5 * @license Code licensed under the <a href="http://www.gnu.org/licenses/lgpl.html">LGPL License</a>. 6 * 7 * @url <a href="http://monkproject.org">monkproject.org</a> 8 */ 9 10 /** 11 * @name Ext.ux 12 * @namespace 13 */ 14 Ext.namespace('Ext.ux'); 15 16 Ext.ux.Ajax = Ext.lib.Ajax; // tried to use Ext.extend here but it doesn't work 17 Ext.ux.Ajax.handleReadyState = function(o, callback) { 18 var oConn = this; 19 20 if (callback && callback.timeout) { 21 var confirmAbort = function() { 22 Ext.Msg.confirm('MONK Workbench', 'The response from the server is taking longer than expected, would you like to continue waiting? (Choosing No might affect further usage of the workbench.)', function(btn, text){ 23 if (btn == 'yes') { 24 oConn.timeout[o.tId] = window.setTimeout(function(){ 25 confirmAbort(); 26 }, callback.timeout); 27 } else { 28 oConn.abort(o, callback, true); 29 } 30 }, this); 31 } 32 33 this.timeout[o.tId] = window.setTimeout(function(){ 34 confirmAbort(); 35 }, callback.timeout); 36 } 37 38 this.poll[o.tId] = window.setInterval( 39 function() { 40 if (o.conn && o.conn.readyState == 4) { 41 window.clearInterval(oConn.poll[o.tId]); 42 delete oConn.poll[o.tId]; 43 44 if (callback && callback.timeout) { 45 window.clearTimeout(oConn.timeout[o.tId]); 46 delete oConn.timeout[o.tId]; 47 } 48 49 oConn.handleTransactionResponse(o, callback); 50 } 51 } 52 , this.pollInterval); 53 } 54 55 Ext.ux.ErrorHandlingConnection = Ext.extend(Ext.data.Connection, { 56 timeout: 60000, 57 request : function(o){ 58 if(this.fireEvent("beforerequest", this, o) !== false){ 59 var p = o.params; 60 61 if(typeof p == "function"){ 62 p = p.call(o.scope||window, o); 63 } 64 if(typeof p == "object"){ 65 p = Ext.urlEncode(p); 66 } 67 if(this.extraParams){ 68 var extras = Ext.urlEncode(this.extraParams); 69 p = p ? (p + '&' + extras) : extras; 70 } 71 72 var url = o.url || this.url; 73 if(typeof url == 'function'){ 74 url = url.call(o.scope||window, o); 75 } 76 77 if(o.form){ 78 var form = Ext.getDom(o.form); 79 url = url || form.action; 80 81 var enctype = form.getAttribute("enctype"); 82 if(o.isUpload || (enctype && enctype.toLowerCase() == 'multipart/form-data')){ 83 return this.doFormUpload(o, p, url); 84 } 85 var f = Ext.ux.Ajax.serializeForm(form); 86 p = p ? (p + '&' + f) : f; 87 } 88 89 var hs = o.headers; 90 if(this.defaultHeaders){ 91 hs = Ext.apply(hs || {}, this.defaultHeaders); 92 if(!o.headers){ 93 o.headers = hs; 94 } 95 } 96 97 var cb = { 98 success: this.handleResponse, 99 failure: this.handleFailure, 100 scope: this, 101 argument: {options: o}, 102 timeout : this.timeout 103 }; 104 105 var method = o.method||this.method||(p ? "POST" : "GET"); 106 107 if(method == 'GET' && (this.disableCaching && o.disableCaching !== false) || o.disableCaching === true){ 108 url += (url.indexOf('?') != -1 ? '&' : '?') + '_dc=' + (new Date().getTime()); 109 } 110 111 if(typeof o.autoAbort == 'boolean'){ // options gets top priority 112 if(o.autoAbort){ 113 this.abort(); 114 } 115 }else if(this.autoAbort !== false){ 116 this.abort(); 117 } 118 if((method == 'GET' && p) || o.xmlData || o.jsonData){ 119 url += (url.indexOf('?') != -1 ? '&' : '?') + p; 120 p = ''; 121 } 122 this.transId = Ext.ux.Ajax.request(method, url, cb, p, o); 123 return this.transId; 124 }else{ 125 Ext.callback(o.callback, o.scope, [o, null, null]); 126 return null; 127 } 128 }, 129 handleResponse : function(response){ 130 this.transId = false; 131 var options = response.argument.options; 132 response.argument = options ? options.argument : null; 133 134 var error = null; 135 if (response.getResponseHeader['Content-Type'].match(/text\/javascript/) != null) { 136 error = Ext.decode(response.responseText).error; 137 } else if (response.getResponseHeader['Content-Type'].match(/text\/html/) != null) { 138 var errorMatch = response.responseText.match(/<div id="error">(.*)<\/div>/); 139 if (errorMatch != null) error = errorMatch[1]; 140 }else if(response.getResponseHeader['Content-Type'].match(/text\/plain/) != null){ 141 // this assumes there are no text/plain content type 142 error=null; 143 }else { 144 var errorTest = response.responseXML.getElementsByTagName('error'); 145 if(errorTest==null){ 146 error="could not retrieve error message"; 147 }else{ 148 if (errorTest.length > 0) error = errorTest[0].firstChild.data; 149 } 150 } 151 152 if (error != null) { 153 Workbench.console.info('An error has occurred: '+error); 154 Monk.component.messenger.alert('MONK Workbench', 'An server error has occurred:<br/>'+error); 155 Workbench.component.manager.notify( 156 new Monk.event.ServerError({ 157 label: 'A server error has occurred: '+error 158 }), { 159 error: error, 160 url: this.url // the url we stored in beforerequest 161 } 162 ); 163 } else { 164 Ext.callback(options.success, options.scope, [response, options]); 165 } 166 167 this.fireEvent("requestcomplete", this, response, options); 168 Ext.callback(options.callback, options.scope, [options, true, response]); 169 } 170 }); 171 172 /** 173 * @name Monk.data.collection 174 * @namespace 175 */ 176 Workbench.namespace("Monk.data.collection"); 177 // listeners used by all connection objects 178 var listeners = { 179 'beforerequest': function(conn, options){ 180 // store the url in the connection object if we need access to it later 181 this.url = options.url; 182 var li = Ext.getCmp('loading-indicator'); 183 if (li) li.show(); 184 }, 185 'requestcomplete': function(conn, response, options){ 186 var li = Ext.getCmp('loading-indicator'); 187 if (li) li.hide(); 188 }, 189 'requestexception': function(conn, response, options){ 190 var li = Ext.getCmp('loading-indicator'); 191 if (li) li.hide(); 192 } 193 }; 194 195 196 Monk.data.collection._cachedMetaDataHierarchy = null; 197 198 Monk.data.collection.works = new Ext.util.MixedCollection(); 199 200 /** 201 * Used locally to convert XML nodes from collection metadata into a JSON array. 202 * @param {String} collectionId The collection ID to prepend 203 * @param {Object} node The root of the tree 204 * @param {Array} children An array to store the converted nodes 205 */ 206 function processChildNodes(collectionId, node, children) { 207 var childNodes = node.childNodes; 208 for (var i = 0; i < childNodes.length; i++) { 209 var node = childNodes[i]; 210 if (node.nodeType == 1) { 211 if(node.nodeName=="groups"){ 212 continue; 213 } 214 var id = node.getAttribute('id'); 215 216 var label = node.getElementsByTagName('label')[0].firstChild.data; 217 var chunkType = "work"; // hard coded for now 218 var numWorkPart = parseInt(node.getAttribute('numWorkPart')); 219 var pubNode = node.getElementsByTagName('publication')[0] 220 var startDate = pubNode.getAttribute('start'); 221 var endDate = pubNode.getAttribute('end'); 222 var authors = new Array(); 223 var authorsLabel = ""; 224 var authorNodes = node.getElementsByTagName('author'); 225 for (var j=0;j<authorNodes.length;j++) { 226 var authorNode = authorNodes[j]; 227 var authorName = authorNode.firstChild.data; 228 var authorBirthdate = authorNode.getAttribute("birthdate"); 229 if (authorBirthdate == 'null') authorBirthdate = '?'; 230 var authorEnddate = authorNode.getAttribute("enddate") 231 if (authorEnddate == 'null') authorEnddate = '?'; 232 authorsLabel += (j>0 ? "; " : "") + authorName + " (" + authorBirthdate + "-" + authorEnddate + ")"; 233 authors.push({name : authorName, birthdate : authorBirthdate, enddate: authorEnddate}) 234 } 235 var jsonNode = { 236 id: id, 237 collectionId: collectionId, 238 text: label, 239 chunkType: chunkType, 240 numWorkPart: numWorkPart, 241 authorsLabel : authorsLabel, 242 authors : authors, 243 fullLabel : authorsLabel + ": " + label, 244 publicationDates : startDate + (startDate==endDate ? "" : "-"+endDate), 245 checked: false, 246 leaf: false 247 }; 248 Monk.data.collection.works.add(id, jsonNode); 249 if (node.hasChildNodes() && node.getElementsByTagName('node').length > 0) { 250 var subchildren = [] 251 processChildNodes(collectionId, node, subchildren); 252 jsonNode.children = subchildren; 253 jsonNode.leaf = false; 254 } 255 256 children.push(jsonNode); 257 } 258 } 259 } 260 261 /** 262 * Loads the collections metadata hierarchy from the server 263 */ 264 Monk.data.collection.loadMetaDataHierarchy = function(progressWin) { 265 if (Monk.data.collection._cachedMetaDataHierarchy == null) { 266 Monk.data.collection._cachedMetaDataHierarchy = []; 267 268 var conn = new Ext.ux.ErrorHandlingConnection(); 269 conn.request({ 270 url: Monk.data.PROXY_URL + 'get/CorpusManager.getCorpora', 271 method: 'GET', 272 success: function(responseObject) { 273 274 // first get the list of collections 275 var collections = responseObject.responseXML.getElementsByTagName('collection'); 276 var collectionCounter = 0; 277 278 function getCollectionHierarchy(collection) { 279 var collectionId = collection.getAttribute('id'); 280 var label = collection.getElementsByTagName('label')[0].firstChild.data; 281 var firstChunkType = collection.getElementsByTagName('chunkType')[0].getAttribute('value'); 282 283 var progressBar = (collectionCounter + 1) / collections.length; 284 if (progressWin) { 285 progressWin.updateProgress(progressBar, 'Loading ' + label); 286 } 287 288 conn.request({ 289 url: Monk.data.PROXY_URL + 'get/CorpusManager.getWorkList', 290 method: 'GET', 291 params: { 292 corpus: collectionId 293 }, 294 success: function(responseObject) { 295 var children = [] 296 var root = responseObject.responseXML.getElementsByTagName('works')[0]; 297 try { 298 processChildNodes(collectionId, root, children); 299 300 var collectionNode = { 301 id: collectionId, 302 collectionId: collectionId, 303 text: label, 304 chunkType: 'collection', 305 leaf: false, 306 children: children 307 }; 308 Monk.data.collection._cachedMetaDataHierarchy.push(collectionNode); 309 310 // get metadata for each collection sequentially 311 collectionCounter++; 312 if (collectionCounter == collections.length) { 313 Workbench.component.manager.notify( 314 new Monk.event.CollectionsMetadataHierarchyLoaded({ 315 label: 'Collections Metadata has been loaded.' 316 }), Monk.data.collection._cachedMetaDataHierarchy 317 ); 318 } else { 319 getCollectionHierarchy(collections[collectionCounter]); 320 } 321 } catch (e) { 322 var childrenString = ''; 323 for (var i = 0, length = children.length; i < length; i++) { 324 childrenString += children[i].id + ', '; 325 } 326 childrenString = childrenString.substr(0, childrenString.length-2); 327 Ext.Msg.alert('Monk Workbench', "There was an error processing collections metadata."+ 328 "Things may not work as expected so it's recommended to refresh your browser.<br/><br/>"+ 329 "<b>Error</b>:<br/>"+e+'<br/><br/>'+ 330 '<b>P.S.</b> The error occurred while processing this collection: '+collectionId+'<br/><br/>') 331 //'<b>P.P.S.</b> The following child nodes were already processed: '+childrenString+ 332 //'<b>P.P.P.S.</b> The responseObject is: '+responseObject.responseText); 333 334 //alert('Error: '+e); 335 } 336 }, 337 failure: function(response, options) { 338 Ext.Msg.alert('Monk Workbench', "There was an error processing collections metadata. Things may not work as expected so it's recommended to refresh your browser.<br/><b>Error "+response.status+"</b>: "+response.statusText); 339 } 340 }); 341 } 342 343 // get chunk hierarchy for each collection 344 getCollectionHierarchy(collections[collectionCounter]); 345 346 }, 347 failure: function(response, options) { 348 Ext.Msg.alert('Monk Workbench', 'Error trying to get collections metadata.<br/><b>Error '+response.status+'</b>: '+response.statusText); 349 } 350 }); 351 } else { 352 // if metadata has already been loaded, then return the cached copy 353 Workbench.component.manager.notify( 354 new Monk.event.CollectionsMetadataHierarchyLoaded({ 355 label: 'Collections Metadata has been loaded.' 356 }), Monk.data.collection._cachedMetaDataHierarchy 357 ); 358 } 359 } 360 361 /** 362 * Gets the collections metadata hierarchy as a literal 363 * @return {Object} The collections metadata hierarhcy as a literal 364 */ 365 Monk.data.collection.getMetaDataHierarchy = function() { 366 if (Monk.data.collection._cachedMetaDataHierarchy == null) { 367 Monk.data.collection.loadMetaDataHierarchy(); 368 } else { 369 // return a copy so the orginal doesn't get altered 370 return Workbench.clone(Monk.data.collection._cachedMetaDataHierarchy); 371 } 372 } 373 374 // this should be access through Monk.data.collection.getWork() 375 Monk.data.collection.getWork = function(workId) { 376 var parts = workId.split('-'); 377 return Monk.data.collection.works.get(parts[0]+"-"+parts[1]); 378 } 379 380 Workbench.namespace("Monk.data.seasr"); 381 382 /** 383 * Run a SEASR analysis on the workset. 384 * @param {Object} params 385 * @config {String} projectId 386 * @config {String} worksetId 387 * @config {String} flowId 388 * @config {String} resultName 389 * @config {String} resultDescription 390 * @config {String} toolsetId 391 * @config {String} emailAddress 392 * @config {String} feature 393 * @config {String} numfeature 394 * @config {String} share 395 * @config {Boolean} async Set to true when user wants email notification 396 */ 397 Monk.data.seasr.runAnalysis = function(params) { 398 var token = ''; 399 var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz"; 400 for (var i = 0; i < 32; i++) { 401 var rnum = Math.floor(Math.random() * chars.length); 402 token += chars.substring(rnum, rnum + 1); 403 } 404 Monk.component.dataManager.token = token; // set token now, so we don't have to wait for the server response 405 params.token = token; 406 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 407 conn.request({ 408 url: Monk.data.PROXY_URL + 'get/SchedulerManager.runAnalysis', 409 method: 'GET', 410 params: params, 411 success: function(responseObject) { 412 Workbench.component.manager.notify(new Monk.event.analysis.SeasrAnalysisRun({ 413 label: 'SEASR analysis running on workset: ' + params.worksetId 414 }), {token: token}); 415 }, 416 failure: function(response, options) { 417 Ext.Msg.alert('Data', 'Error trying to run analysis on workset.<br/><b>Error</b>: '+response.statusText); 418 } 419 }); 420 } 421 422 /** 423 * Returns the status of a particular SEASR analysis. 424 * @param {String} token The token for this analysis 425 */ 426 Monk.data.seasr.getStatus = function(token) { 427 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 428 conn.request({ 429 url: Monk.data.PROXY_URL + 'get/SchedulerManager.status', 430 method: 'GET', 431 params: {token: token}, 432 success: function(responseObject) { 433 var status = responseObject.responseXML.getElementsByTagName('FlowStatusMessage')[0].getAttribute('type'); 434 var instanceId = responseObject.responseXML.getElementsByTagName('flowInstanceId')[0].firstChild.data; 435 var queuePos = responseObject.responseXML.getElementsByTagName('queueSize')[0].firstChild.data; 436 Workbench.component.manager.notify(new Monk.event.analysis.GotJobStatus({ 437 label: 'Status for token ' + token + ' received: '+status 438 }), {status: status, instanceId: instanceId, queuePos: queuePos}); 439 }, 440 failure: function(response, options) { 441 Ext.Msg.alert('Data', 'Error trying to get flow info.<br/><b>Error</b>: '+response.statusText); 442 } 443 }); 444 } 445 446 /** 447 * Returns the status of a particular SEASR analysis. 448 * @param {String} projectId The ID of the project 449 * @param {String} [status] Provide a status and only jobs with this status will be returned (possible values: FINISHED, ABORTED, SUBMITTED, RUNNING) 450 */ 451 Monk.data.seasr.getJobList = function(projectId, status) { 452 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 453 var params = {projectId: projectId}; 454 if (status != null) params.status = status; 455 conn.request({ 456 url: Monk.data.PROXY_URL + 'get/SchedulerManager.getJobListAndStatus', 457 method: 'GET', 458 params: params, 459 success: function(responseObject) { 460 var jobs = responseObject.responseXML.getElementsByTagName('job'); 461 Workbench.component.manager.notify(new Monk.event.analysis.GotJobList({ 462 label: 'Job list for project' + projectId + ' received.' 463 }), {projectId: projectId, status: status, jobs: jobs}); 464 }, 465 failure: function(response, options) { 466 Ext.Msg.alert('Data', 'Error trying to get job list.<br/><b>Error</b>: '+response.statusText); 467 } 468 }); 469 } 470 471 /** 472 * Abort an analysis 473 * @param {String} token The token for this analysis 474 */ 475 Monk.data.seasr.abort = function(token) { 476 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 477 conn.request({ 478 url: Monk.data.PROXY_URL + 'get/SchedulerManager.abort', 479 method: 'GET', 480 params: {token: token}, 481 success: function(responseObject) { 482 var status = responseObject.responseXML.getElementsByTagName('status')[0].firstChild.data; 483 Workbench.component.manager.notify(new Monk.event.analysis.Aborted({ 484 label: 'Analysis aborted for token ' + token + ' Click on Show Log to display the log message' 485 }), {status: status}); 486 }, 487 failure: function(response, options) { 488 Ext.Msg.alert('Data', 'Error trying to abort analysis.<br/><b>Error</b>: '+response.statusText); 489 } 490 }); 491 } 492 493 /** 494 * Get the results/status of a SEASR analysis. 495 * @param {String} instanceId The ID for the analysis (returned by Monk.data.seasr.doSetup) 496 * @param {Boolean} runningAnalysis Set to true if an analysis is being run (as opposed to loading previous results) 497 */ 498 Monk.data.seasr.getAnalysisResults = function(instanceId, runningAnalysis) { 499 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 500 conn.request({ 501 url: Monk.data.PROXY_URL + 'get/SeasrManager.getPrediction', 502 method: 'GET', 503 params: { 504 instanceId : instanceId 505 }, 506 success: function(responseObject) { 507 var results = responseObject.responseXML.getElementsByTagName('results')[0]; 508 if (results.getAttribute('num') != null) { 509 Workbench.component.manager.notify( 510 new Monk.event.analysis.GotSeasrAnalysisResults({ 511 label: 'Got the prediction for instance: '+instanceId 512 }), 513 {instanceId: instanceId, results: results, runningAnalysis: runningAnalysis}); 514 } 515 }, 516 failure: function(response, options) { 517 Ext.Msg.alert('Data', 'Error trying to get prediction for workset.<br/><b>Error</b>: '+response.statusText); 518 } 519 }); 520 } 521 522 /** 523 * Get the results/status of a SEASR analysis. 524 * @param {String} instanceId The ID for the analysis (returned by Monk.data.seasr.doSetup) 525 */ 526 Monk.data.seasr.getConfigParameters = function(instanceId) { 527 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 528 conn.request({ 529 url: Monk.data.PROXY_URL + 'get/SeasrManager.getConfigParameters', 530 method: 'GET', 531 params: { 532 instanceId : instanceId 533 }, 534 success: function(responseObject) { 535 var data = responseObject.responseXML.getElementsByTagName('result')[0]; 536 Workbench.component.manager.notify(new Monk.event.analysis.GotConfigParameters({ 537 label: 'Got config parameters for: ' + instanceId 538 }), {xml: data, instanceId: instanceId}); 539 }, 540 failure: function(response, options) { 541 Ext.Msg.alert('Data', 'Error trying to get config parameters for the analysis call.<br/><b>Error</b>: '+response.statusText); 542 } 543 }); 544 } 545 546 /** 547 * Retrieve the previously saved results of a SEASR analysis. 548 * @param {Integer} projectId The ID for the project 549 * @param {Boolean} [getValues] True to get the actual result values, defaults to false 550 */ 551 Monk.data.seasr.getSavedResultsForProject = function(projectId, getValues) { 552 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 553 var getValues = getValues == null ? false : getValues; 554 conn.request({ 555 url: Monk.data.PROXY_URL + 'get/SeasrManager.getSavedResultsForProject', 556 method: 'GET', 557 params: { 558 projectId: projectId, 559 value: getValues 560 }, 561 success: function(responseObject) { 562 var results = responseObject.responseXML.getElementsByTagName('results')[0]; 563 Workbench.component.manager.notify(new Monk.event.analysis.GotSavedResultsForProject({ 564 label: 'SEASR analysis results retrieved for: ' + projectId 565 }), {projectId: projectId, results: results}); 566 }, 567 failure: function(response, options) { 568 Ext.Msg.alert('Data', 'Error trying to get saved results.<br/><b>Error</b>: '+response.statusText); 569 } 570 }); 571 } 572 573 /** 574 * Retrieve all previous results of a SEASR analysis. 575 * @param {Integer} projectId The ID for the project 576 * @param {String} [status] Filter the list by a particular status. 577 * Possible values: null (all results), 'SUBMITTED', 'RUNNING', 'FINISHED', 'ABORTED' 578 */ 579 Monk.data.seasr.getAllResultsForProject = function(projectId, status) { 580 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 581 conn.request({ 582 url: Monk.data.PROXY_URL + 'get/SchedulerManager.getJobListAndStatus', 583 method: 'GET', 584 params: { 585 projectId: projectId, 586 status: status 587 }, 588 success: function(responseObject) { 589 var results = responseObject.responseXML.getElementsByTagName('jobs')[0]; 590 Workbench.component.manager.notify(new Monk.event.analysis.GotAllResultsForProject({ 591 label: 'All SEASR analysis results retrieved for: ' + projectId 592 }), {projectId: projectId, results: results}); 593 }, 594 failure: function(response, options) { 595 Ext.Msg.alert('Data', 'Error trying to get all results.<br/><b>Error</b>: '+response.statusText); 596 } 597 }); 598 } 599 600 /** 601 * Delete the result of a SEASR analysis. 602 * @param {String} instanceId The ID for the analysis (returned by Monk.data.seasr.doSetup) 603 */ 604 Monk.data.seasr.deleteResult = function(instanceId) { 605 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 606 conn.request({ 607 url: Monk.data.PROXY_URL + 'get/SeasrManager.removeResult', 608 method: 'GET', 609 params: { 610 instanceId : instanceId 611 }, 612 success: function(responseObject) { 613 var success = responseObject.responseXML.getElementsByTagName('success')[0]; 614 if (success != null) { 615 Workbench.component.manager.notify( 616 new Monk.event.analysis.AnalysisResultDeleted({ 617 label: 'Delete the analysis result for: '+instanceId 618 }), 619 {instanceId: instanceId}); 620 } else { 621 // error 622 } 623 }, 624 failure: function(response, options) { 625 Ext.Msg.alert('Data', 'Error trying to delete the analysis result.<br/><b>Error</b>: '+response.statusText); 626 } 627 }); 628 } 629 630 Workbench.namespace("Monk.data.workset"); 631 632 /** 633 * Create a workset 634 * @param {Object} workset The workset object to create 635 * @config {String} projectId 636 * @config {String} collectionId 637 * @config {String} chunkType 638 * @config {String} [workList] 639 * @config {String} [workListRating] 640 * @config {String} [trainingSet] 641 * @config {String} [trainingSetRating] 642 * @config {String} worksetName 643 * @config {String} itinerary 644 * @config {String} feature 645 */ 646 Monk.data.workset.createWorkset = function(workset) { 647 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 648 conn.request({ 649 url: Monk.data.PROXY_URL + 'get/ProjectManager.createNewWorkset', 650 method: 'POST', 651 params: { 652 projectId : workset.projectId, 653 collectionId : 'cha', 654 worksetName : workset.worksetName, 655 //chunkType : workset.chunkType, 656 workList : workset.workList, 657 workListRating : workset.workListRating, 658 trainingList : workset.trainingList, 659 trainingListRatings : workset.trainingListRating, 660 itinerary : workset.itinerary, 661 feature : workset.feature 662 }, 663 success: function(responseObject) { 664 var worksetId = responseObject.responseXML.getElementsByTagName('workset')[0].getAttribute('id'); 665 666 Workbench.component.manager.notify( 667 new Monk.event.workset.WorksetCreated({ 668 label: 'Workset created: '+workset.worksetName 669 }), 670 {worksetId: worksetId, projectId: workset.projectId, response:responseObject}); 671 }, 672 failure: function(response, options) { 673 Ext.Msg.alert('Data', 'Workset '+workset.worksetName+' could not be created.<br/><b>Error</b>: '+response.statusText); 674 } 675 }); 676 } 677 678 /** 679 * Save the workset 680 * @param {Object} workset The workset object to save 681 * @config {String} worksetId 682 * @config {String} projectId 683 * @config {String} collectionId 684 * @config {String} worksetName 685 * @config {String} chunkType 686 * @config {String} [workList] 687 * @config {String} [workListRating] 688 * @config {String} [trainingSet] 689 * @config {String} [trainingSetRating] 690 * @config {String} itinerary 691 * @config {String} feature 692 */ 693 Monk.data.workset.saveWorkset = function(workset) { 694 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 695 conn.request({ 696 url: Monk.data.PROXY_URL + 'get/ProjectManager.saveWorkset', 697 method: 'POST', 698 timeout: 600000, 699 params: { 700 worksetId : workset.worksetId, 701 projectId : workset.projectId, 702 collectionId : 'cha', 703 worksetName : workset.worksetName, 704 //chunkType : workset.chunkType, 705 workList : workset.workList, 706 workListRating : workset.workListRating, 707 trainingList : workset.trainingList, 708 trainingListRatings : workset.trainingListRating, 709 itinerary : workset.itinerary, 710 feature : workset.feature 711 }, 712 success: function(responseObject) { 713 Workbench.component.manager.notify( 714 new Monk.event.workset.WorksetSaved({ 715 label: 'Workset saved: '+workset.worksetId 716 }), 717 {worksetId: workset.worksetId, response:responseObject}); 718 }, 719 failure: function(response, options) { 720 Ext.Msg.alert('Data', 'Workset '+workset.worksetId+' could not be saved.<br/><b>Error</b>: '+response.statusText); 721 } 722 }); 723 } 724 725 /** 726 * Delete a workset 727 * @params {Integer} projectId The ID of the project that contains the workset 728 * @params {Integer} worksetId The ID of the workset to delete 729 */ 730 Monk.data.workset.deleteWorkset = function(projectId, worksetId) { 731 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 732 conn.request({ 733 url: Monk.data.PROXY_URL + 'get/ProjectManager.deleteWorkset', 734 method: 'GET', 735 params: {worksetId : worksetId, projectId: projectId}, 736 success: function(responseObject) { 737 Workbench.component.manager.notify( 738 new Monk.event.workset.WorksetDeleted({ 739 label: 'Workset deleted: '+worksetId 740 }), 741 {worksetId: worksetId, response: responseObject}); 742 }, 743 failure: function(response, options) { 744 Ext.Msg.alert('Data', 'Workset '+worksetId+' could not be deleted.<br/><b>Error</b>: '+response.statusText); 745 } 746 }); 747 } 748 749 /** 750 * Gets the labels for the workparts in a workset 751 * @param {Integer} worksetId The ID of the workset 752 * @param {String} type Either 'worklist' or 'traininglist' to get the labels for those workparts 753 */ 754 Monk.data.workset.getWorkpartLabels = function(worksetId, type) { 755 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 756 conn.on('requestexception', function(con, resp, opt, error) { 757 }); 758 conn.request({ 759 url: Monk.data.PROXY_URL + 'get/WorkSetsManager.getWorkPartLabels', 760 method: 'GET', 761 params: {worksetId : worksetId, type: type}, 762 success: function(responseObject) { 763 Workbench.component.manager.notify( 764 new Monk.event.workset.GotWorkpartLabels({ 765 label: 'Got '+type+' labels for : '+worksetId 766 }), 767 {worksetId: worksetId, type: type, response: responseObject}); 768 }, 769 failure: function(response, options) { 770 Ext.Msg.alert('Data', 'Could not get '+type+' labels for: '+worksetId+'.<br/><b>Error</b>: '+response.statusText); 771 } 772 }); 773 } 774 775 Monk.data.workset.retrieveDunningsLogLikelyHood = function(data) { 776 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 777 conn.request({ 778 url: Monk.data.PROXY_URL + 'get/AnalyticsManager.getDunningsLogLikelyHood', 779 method: 'GET', 780 params: {referenceList : data.worksets[0].workList, documentList: data.worksets[1].workList, feature : 'lemma', cutoff : 20}, 781 success: function(responseObject) { 782 Workbench.component.manager.notify( 783 new Monk.event.workset.DunningsLogLikelyHoodRetrieved({ 784 label: 'Dunnings Log Likelihood loaded.' 785 }), 786 {response: responseObject}); 787 }, 788 failure: function(response, options) { 789 Ext.Msg.alert('Data', 'Unable to retrieve Dunnings log likelihood values..<br/><b>Error</b>: '+response.statusText); 790 } 791 }); 792 } 793 794 Workbench.namespace('Monk.data.project'); 795 796 /** 797 * Create a project 798 * @param {String} name The project's name 799 * @param {String} comment A comment about the project 800 */ 801 Monk.data.project.createProject = function(name, comment) { 802 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 803 conn.request({ 804 url: Monk.data.PROXY_URL + 'get/ProjectManager.createProject', 805 method: 'GET', 806 params: { 807 name : name, 808 comment : comment 809 }, 810 success: function(responseObject) { 811 Workbench.component.manager.notify( 812 new Monk.event.project.ProjectCreated({ 813 label: 'Project created: '+name 814 }), 815 responseObject); 816 }, 817 failure: function(response, options) { 818 Ext.Msg.alert('Data', 'Project '+name+' could not be created.<br/><b>Error</b>: '+response.statusText); 819 } 820 }); 821 } 822 823 /** 824 * Delete a project 825 * @param {Integer} projectId The project's ID 826 */ 827 Monk.data.project.deleteProject = function(projectId) { 828 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 829 conn.request({ 830 url: Monk.data.PROXY_URL + 'get/ProjectManager.deleteProject', 831 method: 'GET', 832 params: {projectId : projectId}, 833 success: function(responseObject) { 834 Workbench.component.manager.notify( 835 new Monk.event.project.ProjectDeleted({ 836 label: 'Project deleted: '+projectId 837 }), 838 responseObject); 839 }, 840 failure: function(response, options) { 841 Ext.Msg.alert('Data', 'Error deleting project: '+projectId+'.<br/><b>Error</b>: '+response.statusText); 842 } 843 }); 844 } 845 846 /** 847 * Gets the projects for a user. User ID is set in a cookie after login. 848 */ 849 Monk.data.project.getProjects = function() { 850 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 851 conn.request({ 852 url: Monk.data.PROXY_URL + 'get/UserManager.getProjects', 853 method: 'GET', 854 success: function(responseObject) { 855 Workbench.component.manager.notify( 856 new Monk.event.project.ProjectsReceived({ 857 label: 'Projects received' 858 }), 859 responseObject); 860 }, 861 failure: function(response, options) { 862 Ext.Msg.alert('Data', 'Error trying to get projects.<br/><b>Error</b>: '+response.statusText); 863 } 864 }); 865 } 866 867 /** 868 * Get info about a specfic project. 869 * @param {Integer} projectId The ID of the project 870 */ 871 Monk.data.project.getProjectInfo = function(projectId) { 872 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 873 conn.request({ 874 url: Monk.data.PROXY_URL + 'get/ProjectManager.getProjectInfo', 875 method: 'GET', 876 params: {projectId : projectId}, 877 success: function(responseObject) { 878 Workbench.component.manager.notify( 879 new Monk.event.project.ProjectInfoReceived({ 880 label: 'Project info received: '+projectId 881 }), 882 responseObject); 883 }, 884 failure: function(response, options) { 885 Ext.Msg.alert('Data','Error trying to get project info.<br/><b>Error</b>: '+response.statusText); 886 } 887 }); 888 } 889 890 /** 891 * Get the workset for the current project. Needs to be used in the context of 892 * the component that calls it (using call()). 893 * @param {Integer} projectId The ID of the project 894 */ 895 Monk.data.project.getWorksets = function(projectId) { 896 var component = this; 897 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 898 conn.request({ 899 url: Monk.data.PROXY_URL + 'get/ProjectManager.getWorksets', 900 method: 'GET', 901 params: {projectId : projectId}, 902 success: function(responseObject) { 903 Workbench.component.manager.notify( 904 new Monk.event.project.WorksetsReceived({ 905 label: 'Worksets received for project: '+projectId 906 }), 907 {projectId: projectId, worksets: responseObject}); 908 }, 909 failure: function(response, options) { 910 Ext.Msg.alert('Data', 'Error trying to get worksets.<br/><b>Error</b>: '+response.statusText); 911 }, 912 scope: component 913 }); 914 } 915 916 Workbench.namespace('Monk.data.chunk'); 917 918 /** 919 * Retrieve the info (child workparts) for a particular work. 920 * @param {String} corpus The ID of a collection 921 * @param {String} id The ID of a work or workpart 922 */ 923 Monk.data.chunk.getWorkInfo = function(corpus, id) { 924 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 925 conn.request({ 926 url: Monk.data.PROXY_URL + 'get/CorpusManager.getWorkInfo', 927 method: 'GET', 928 params: { 929 corpus: corpus, 930 id: id 931 }, 932 success: function(responseObject) { 933 Workbench.component.manager.notify( 934 new Monk.event.chunk.WorkPartsRetrieved({ 935 label: 'Retrieved work parts for: '+id, 936 uri: responseObject.responseXML.documentURI 937 }), 938 responseObject); 939 }, 940 failure: function(response, options) { 941 Ext.Msg.alert('Data', 'Unable to retrieve work parts at this time.<br/><b>Error</b>: '+response.statusText); 942 } 943 }); 944 } 945 946 /** 947 * Retrieve the rendered table of content of a chunk into the specified chunk object. 948 * The chunk is expected to have the following members: id, text, chunkType. 949 * @param {Object} chunk The chunk object (with members) 950 * @config {String} id The chunk id 951 * @config {String} corpus The collection id 952 * @config {String} text The chunk label 953 * @config {String} chunkType The type of the chunk 954 * @throws {Ext.Msg} MessageBox error 955 */ 956 Monk.data.chunk.retrieveChunkTOC = function(chunk){ 957 if (chunk.id=="collections-root") { 958 var chunkHierarchy = Monk.data.collection.getMetaDataHierarchy(); 959 chunk.html = "<h2>"+chunk.text+"</h2>"+"<ul><li>number of collections: "+chunkHierarchy.length+"</li></ul>" 960 Workbench.component.manager.notify(new Monk.event.chunk.ChunkContentsRetrieved({ 961 label: 'Text toc retrieved: "' + chunk.text + '"' 962 //uri: responseObject.responseXML.documentURI 963 }), chunk); 964 } 965 else if (chunk.chunkType == "collection") { 966 var chunkHierarchy = Monk.data.collection.getMetaDataHierarchy(); 967 for (var i=0;i<chunkHierarchy.length;i++) { 968 if (chunkHierarchy[i].id==chunk.id) { 969 chunk.html = "<h2>"+chunkHierarchy[i].text+"</h2>"+"<ul><li>number of works: "+chunkHierarchy[i].children.length+"</li></ul>" 970 Workbench.component.manager.notify(new Monk.event.chunk.ChunkContentsRetrieved({ 971 label: 'Text toc retrieved: "' + chunk.text + '"' 972 //uri: responseObject.responseXML.documentURI 973 }), chunk); 974 break; 975 } 976 } 977 } 978 else { 979 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 980 conn.request({ 981 url: Monk.data.PROXY_URL + 'get/CorpusManager.getDocumentTOC', 982 method: 'GET', 983 params: { 984 id: chunk.id 985 }, 986 success: function(responseObject){ 987 chunk.html = responseObject.responseText; 988 Workbench.component.manager.notify(new Monk.event.chunk.ChunkTOCRetrieved({ 989 label: 'Text toc retrieved: "' + chunk.text + '"' 990 }), chunk); 991 }, 992 failure: function(response, options){ 993 Ext.Msg.alert('Data', 'Unable to get work TOC.<br/><b>Error</b>: '+chunk.id+" response: " + response.statusText); 994 } 995 }); 996 } 997 998 } 999 1000 1001 Monk.data.chunk.retrieveChunkHeader = function(chunk){ 1002 if (chunk.id=="collections-root") { 1003 var chunkHierarchy = Monk.data.collection.getMetaDataHierarchy(); 1004 chunk.html = "<h2>"+chunk.text+"</h2>"+"<ul><li>number of collections: "+chunkHierarchy.length+"</li></ul>" 1005 Workbench.component.manager.notify(new Monk.event.chunk.ChunkContentsRetrieved({ 1006 label: 'Text header retrieved: "' + chunk.text + '"' 1007 }), chunk); 1008 }else if (chunk.chunkType == "collection") { 1009 var chunkHierarchy = Monk.data.collection.getMetaDataHierarchy(); 1010 for (var i=0;i<chunkHierarchy.length;i++) { 1011 if (chunkHierarchy[i].id==chunk.id) { 1012 chunk.html = "<h2>"+chunkHierarchy[i].text+"</h2>"+"<ul><li>number of works: "+chunkHierarchy[i].children.length+"</li></ul>" 1013 Workbench.component.manager.notify(new Monk.event.chunk.ChunkContentsRetrieved({ 1014 label: 'Text header retrieved: "' + chunk.text + '"' 1015 //uri: responseObject.responseXML.documentURI 1016 }), chunk); 1017 break; 1018 } 1019 } 1020 } 1021 else { 1022 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 1023 conn.request({ 1024 url: Monk.data.PROXY_URL + 'get/CorpusManager.getDocumentHeader', 1025 method: 'GET', 1026 params: { 1027 id: chunk.id 1028 }, 1029 success: function(responseObject){ 1030 chunk.html = responseObject.responseText; 1031 Workbench.component.manager.notify(new Monk.event.chunk.ChunkHeaderRetrieved({ 1032 label: 'Text header retrieved: "' + chunk.text + '"' 1033 }), chunk); 1034 }, 1035 failure: function(response, options){ 1036 Ext.Msg.alert('Data', 'Unable to get work Header.<br/><b>Error</b>: ' +chunk.text+ " response: "+ response.statusText); 1037 } 1038 }); 1039 } 1040 1041 } 1042 1043 1044 1045 1046 1047 /** 1048 * Retrieve the rendered bibliographic information of a chunk into the specified chunk object. 1049 * The chunk is expected to have the following members: id, text, chunkType. 1050 * @param {Object} chunk The chunk object (with members) 1051 * @config {String} id The chunk id 1052 * @config {String} corpus The collection id 1053 * @config {String} text The chunk label 1054 * @config {String} chunkType The type of the chunk 1055 * @throws {Ext.Msg} MessageBox error 1056 */ 1057 Monk.data.chunk.retrieveChunkBib = function(chunk){ 1058 if (chunk.id=="collections-root") { 1059 var chunkHierarchy = Monk.data.collection.getMetaDataHierarchy(); 1060 chunk.html = "<h2>"+chunk.text+"</h2>"+"<ul><li>number of collections: "+chunkHierarchy.length+"</li></ul>" 1061 Workbench.component.manager.notify(new Monk.event.chunk.ChunkContentsRetrieved({ 1062 label: 'Text chunk retrieved: "' + chunk.text + '"' 1063 //uri: responseObject.responseXML.documentURI 1064 }), chunk); 1065 } 1066 else if (chunk.chunkType == "collection") { 1067 var chunkHierarchy = Monk.data.collection.getMetaDataHierarchy(); 1068 for (var i=0;i<chunkHierarchy.length;i++) { 1069 if (chunkHierarchy[i].id==chunk.id) { 1070 chunk.html = "<h2>"+chunkHierarchy[i].text+"</h2>"+"<ul><li>number of works: "+chunkHierarchy[i].children.length+"</li></ul>" 1071 Workbench.component.manager.notify(new Monk.event.chunk.ChunkContentsRetrieved({ 1072 label: 'Text chunk retrieved: "' + chunk.text + '"' 1073 //uri: responseObject.responseXML.documentURI 1074 }), chunk); 1075 break; 1076 } 1077 } 1078 } 1079 else { 1080 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 1081 conn.request({ 1082 url: Monk.data.PROXY_URL + 'get/CorpusManager.getDocumentMetadata', 1083 method: 'GET', 1084 params: { 1085 id: chunk.id 1086 }, 1087 success: function(responseObject){ 1088 chunk.html = responseObject.responseText; 1089 Workbench.component.manager.notify(new Monk.event.chunk.ChunkBibRetrieved({ 1090 label: 'chunk bib retrieved: "' + chunk.text + '"' 1091 }), chunk); 1092 }, 1093 failure: function(response, options){ 1094 Ext.Msg.alert('Data', 'Unable to get work BIB.<br/><b>Error</b>: '+chunk.text+' response: ' + response.statusText); 1095 } 1096 }); 1097 } 1098 1099 } 1100 1101 1102 /** 1103 * Retrieve the rendered contents of a chunk into the specified chunk object. 1104 * The chunk is expected to have the following members: id, text, chunkType. 1105 * @param {Object} chunk The chunk object (with members) 1106 * @config {String} id The chunk id 1107 * @config {String} corpus The collection id 1108 * @config {String} text The chunk label 1109 * @config {String} chunkType The type of the chunk 1110 * @throws {Ext.Msg} MessageBox error 1111 */ 1112 Monk.data.chunk.retrieveChunkContents = function(chunk){ 1113 if (chunk.id=="collections-root") { 1114 var chunkHierarchy = Monk.data.collection.getMetaDataHierarchy(); 1115 chunk.html = "<h2>"+chunk.text+"</h2>"+"<ul><li>number of collections: "+chunkHierarchy.length+"</li></ul>" 1116 Workbench.component.manager.notify(new Monk.event.chunk.ChunkContentsRetrieved({ 1117 label: 'Text chunk retrieved: "' + chunk.text + '"' 1118 //uri: responseObject.responseXML.documentURI 1119 }), chunk); 1120 } 1121 else if (chunk.chunkType == "collection") { 1122 var chunkHierarchy = Monk.data.collection.getMetaDataHierarchy(); 1123 for (var i=0;i<chunkHierarchy.length;i++) { 1124 if (chunkHierarchy[i].id==chunk.id) { 1125 chunk.html = "<h2>"+chunkHierarchy[i].text+"</h2>"+"<ul><li>number of works: "+chunkHierarchy[i].children.length+"</li></ul>" 1126 Workbench.component.manager.notify(new Monk.event.chunk.ChunkContentsRetrieved({ 1127 label: 'Text chunk retrieved: "' + chunk.text + '"' 1128 //uri: responseObject.responseXML.documentURI 1129 }), chunk); 1130 break; 1131 } 1132 } 1133 } 1134 else { 1135 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 1136 conn.request({ 1137 url: Monk.data.PROXY_URL + 'get/CorpusManager.getWork', 1138 method: 'GET', 1139 params: { 1140 corpus: chunk.corpus, 1141 id: chunk.id 1142 }, 1143 success: function(responseObject){ 1144 chunk.html = responseObject.responseText; 1145 Workbench.component.manager.notify(new Monk.event.chunk.ChunkContentsRetrieved({ 1146 label: 'Text chunk retrieved: "' + chunk.text + '"' 1147 //uri: responseObject.responseXML.documentURI 1148 }), chunk); 1149 }, 1150 failure: function(response, options){ 1151 Ext.Msg.alert('Data', 'Unable to get work contents.<br/><b>Error</b>: '+chunk.text+' response: ' + response.statusText); 1152 } 1153 }); 1154 } 1155 1156 } 1157 1158 /** 1159 * Retrieve a list of chunks from a collection which contain specific features. 1160 * Possible features: 1161 * corpusCriterion - the ID of the collection to search 1162 * pubDateStart / pubDateEnd - publication dates 1163 * posCriterion - a part of speech criterion 1164 * lemmaPatternCriterion - a pattern to search for 1165 * See: http://scribe.at.northwestern.edu:8090/monk/search-core.html 1166 * @param {Object} features An object with feature specifications 1167 */ 1168 Monk.data.chunk.getChunksContainingFeature = function(features) { 1169 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 1170 conn.request({ 1171 url: Monk.data.PROXY_URL + 'get/CorpusManager.getWorksWithFeature', 1172 method: 'GET', 1173 params: features, 1174 success: function(responseObject) { 1175 Workbench.component.manager.notify( 1176 new Monk.event.chunk.ChunksContainingFeatureRetrieved({ 1177 label: 'Retrieved chunks containing feature(s)' 1178 }), 1179 responseObject); 1180 }, 1181 failure: function(response, options) { 1182 Ext.Msg.alert('Data', 'Error getting works containing feature(s).<br/><b>Error</b>: '+response.statusText); 1183 } 1184 }); 1185 } 1186 1187 /** 1188 * Retrieve a list of chunks from a workset which contain specific features. 1189 * Possible features: 1190 * String lemmaPatternCriterion; * 1191 * String spellingPatternCriterion; * 1192 * int pubDateStart=-1; * 1193 * int pubDateEnd=-1; * 1194 * String posCriterion; * 1195 * String sort; 1196 * int start=-1; * 1197 * int end=-1; * 1198 * String worksetId; 1199 * String searchType; // search in "TEST" "TRAINING" "BOTH" 1200 * See: http://scribe.at.northwestern.edu:8090/monk/search-core.html 1201 * @param {Object} params An object with parameter specifications 1202 */ 1203 Monk.data.chunk.getChunksContainingFeatureWithinWorkset = function(params) { 1204 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 1205 conn.request({ 1206 url: Monk.data.PROXY_URL + 'get/WorkSetsManager.getWorksWithFeature', 1207 method: 'GET', 1208 params: params, 1209 success: function(responseObject, params) { 1210 var feature = params.params.lemmaPatternCriterion || params.params.spellingPatternCriterion; 1211 Workbench.component.manager.notify( 1212 new Monk.event.chunk.ChunksContainingFeatureWithinWorksetRetrieved({ 1213 label: 'Retrieved chunks containing feature(s) within workset: '+params.worksetId 1214 }), 1215 {feature: feature, response: responseObject}); 1216 }, 1217 failure: function(response, options) { 1218 Ext.Msg.alert('Data', 'Error getting works containing feature(s) within workset.<br/><b>Error</b>: '+response.statusText); 1219 } 1220 }); 1221 } 1222 1223 /** 1224 * Retrieve a frequencies list for a chunk into the specified chunk object. 1225 * The chunk is expected to have the following members: id, text, chunkType. 1226 * @param {Object} chunk The chunk object (with members) 1227 * @config {String} id The chunk id 1228 * @config {String} corpus The collection id 1229 * @config {String} text The chunk label 1230 * @config {String} chunkType The type of the chunk 1231 * @throws {Ext.Msg} MessageBox error 1232 */ 1233 Monk.data.chunk.retrieveChunkFrequencies = function(chunks){ 1234 var documentList = []; 1235 for (var i=0;i<chunks.length;i++) { 1236 if (chunks[i].id == 'collections-root' || chunks[i].chunkType == 'collection') {return} 1237 documentList.push(chunks[i].id); 1238 } 1239 1240 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 1241 conn.request({ 1242 url: Monk.data.PROXY_URL + 'get/CorpusManager.getLemma', 1243 method: 'GET', 1244 params: { 1245 documentList: documentList.join(',') 1246 }, 1247 success: function(responseObject){ 1248 var entries = responseObject.responseXML.getElementsByTagName('entry'); 1249 var freqs = []; 1250 var re = /\(.*?\)/g; 1251 for (var i=0;i<entries.length;i++) { 1252 var string = entries[i].getElementsByTagName('string')[0].textContent; 1253 var pos = new Array(); 1254 while ((match = re.exec(string)) != null) { 1255 pos.push(match[0]); 1256 } 1257 freqs.push({ 1258 string : string.replace(/\s+\(.*?\)/g,'').replace(/\s+/g,' '), 1259 pos : pos.join(' '), 1260 count : parseInt(entries[i].getElementsByTagName('long')[0].textContent) 1261 }) 1262 } 1263 Workbench.component.manager.notify(new Monk.event.chunk.ChunkFrequenciesRetrieved({ 1264 label: 'Text frequencies retrieved.' 1265 }), { 1266 ids : documentList, 1267 freqs : freqs 1268 }); 1269 }, 1270 failure: function(response, options){ 1271 Ext.Msg.alert('Data', 'Unable to get chunk frequencies.<br/><b>Error</b>: ' + response.statusText); 1272 } 1273 }); 1274 1275 } 1276 1277 1278 Monk.data.chunk.cloneChunkNodeWithoutChildren = function(chunkNode) { 1279 var newNode = {} 1280 for (p in chunkNode) { 1281 if (p!="children") newNode[p] = chunkNode[p] 1282 } 1283 return newNode; 1284 } 1285 1286 /** 1287 * Retrieves the concordance information for a feature (lemma/spelling) 1288 * for a particular work 1289 */ 1290 Monk.data.chunk.getChunkConcordance = function(chunkId,params){ 1291 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 1292 conn.request({ 1293 url: Monk.data.PROXY_URL + 'get/FeatureSearchManager.getFeature', 1294 method: 'GET', 1295 params: { 1296 feature: params.type, 1297 workTag: chunkId, 1298 value: params.term, 1299 format: "html" 1300 }, 1301 success: function(responseObject){ 1302 params.html = responseObject.responseText; 1303 params.id = chunkId; 1304 Workbench.component.manager.notify(new Monk.event.chunk.ChunkConcordanceRetrieved({ 1305 label: 'chunk concordance retrieved: "' + chunkId + '"' 1306 }), params); 1307 }, 1308 failure: function(response, options){ 1309 Ext.Msg.alert('Concordance', 'Unable to get work concordance.<br/><b>Error</b>: ' + response.statusText); 1310 } 1311 }); 1312 } 1313 1314 /** 1315 * Retrieve the rendered contents of a chunk (with a specific terms highlighted) 1316 * into the specified chunk object. 1317 * @param {Object} chunk The chunk object (with members) 1318 * @config {String} id The chunk id 1319 * @config {String} text The chunk label 1320 * @config {String} chunkType The type of the chunk 1321 * @param {String} feature The feature type 1322 * @param {Array} terms A list of terms to search for 1323 * @throws {Ext.Msg} MessageBox error 1324 */ 1325 /*Monk.data.chunk.retrieveChunkContentsWithFeatures = function(chunk, feature, terms){ 1326 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 1327 var delim = '|'; 1328 for (var i = 0; i < terms.length; i++) { 1329 if (terms[i].search('|') != -1) delim = ':'; 1330 } 1331 terms = terms.join(delim); 1332 var matches = chunk.id.match(/^(\w+)\.(.+)$/); 1333 if (matches) { 1334 conn.request({ 1335 url: Monk.data.PROXY_URL + 'get/CollectionManager.renderChunkWithFeatures', 1336 method: 'GET', 1337 params: { 1338 collection: matches[1], 1339 chunkId: matches[2], 1340 chunk: chunk.chunkType, 1341 feature: feature, 1342 terms: terms, 1343 delim: delim 1344 }, 1345 success: function(responseObject) { 1346 chunk.html = responseObject.responseText.replace(/<\/?canvas>/g,''); 1347 chunk.html = chunk.html.replace(/<text.*?>/g,'<div id="chunkText">'); 1348 chunk.html = chunk.html.replace(/<\/text>/g,'</div>'); 1349 Workbench.component.manager.notify( 1350 new Monk.event.chunk.ChunkContentsRetrievedWithFeatures({ 1351 label: 'Text chunk with features retrieved: "'+chunk.text+'"' 1352 // temporarily removed since response is text/html 1353 //uri: responseObject.responseXML.documentURI 1354 }), 1355 chunk); 1356 }, 1357 failure: function(response, options) { 1358 Ext.Msg.alert('Status', 'Unable to retrieve works with feature(s).<br/><b>Error</b>: '+response.statusText); 1359 } 1360 }); 1361 } 1362 else { 1363 Ext.Msg.alert('Status', 'Invalid text chunk requested (unable to find proper id).'); 1364 } 1365 }*/ 1366 1367 Workbench.namespace('Monk.data.toolset'); 1368 1369 function processToolsetConfig(toolsetConfig) { 1370 var newToolsetConfig = toolsetConfig; 1371 newToolsetConfig.toolSetConfig = Monk.utils.json2string.encode(toolsetConfig); 1372 delete newToolsetConfig.tools; 1373 return newToolsetConfig; 1374 } 1375 1376 /** 1377 * Create a new toolset. 1378 * @param {Object} toolsetConfig Contains the toolset configuration 1379 * @config {String} toolSetLabel A label for the toolset 1380 * @config {Integer} worksetId The workset to associate the toolset with 1381 * @config {String} pathToIcon A relative path to an icon for the toolset 1382 * @config {Boolean} shareable True to make the toolset public 1383 * @config {String} description A description of the toolset 1384 * @config {Object} tools An object containing the tools 1385 */ 1386 Monk.data.toolset.createToolset = function(toolsetConfig) { 1387 var toolsetParams = processToolsetConfig(toolsetConfig); 1388 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 1389 conn.request({ 1390 url: Monk.data.PROXY_URL + 'get/ProjectManager.createToolSet', 1391 method: 'GET', 1392 params: toolsetParams, 1393 success: function(responseObject) { 1394 var toolsetId = Ext.decode(responseObject.responseText).toolSetId; 1395 1396 var toolsetJson = Ext.decode(toolsetConfig.toolSetConfig); 1397 1398 Workbench.component.manager.notify( 1399 new Monk.event.toolset.ToolsetCreated({ 1400 label: 'Toolset created.' 1401 }), 1402 {toolsetId: toolsetId, toolsetJson: toolsetJson}); 1403 }, 1404 failure: function(response, options) { 1405 Ext.Msg.alert('Data', 'Error creating toolset.<br/><b>Error</b>: '+response.statusText); 1406 } 1407 }); 1408 } 1409 1410 /** 1411 * Save a toolset. 1412 * @param {Integer} toolsetId The toolset ID to update 1413 * @param {Object} toolsetConfig Contains the toolset configuration 1414 * @config {String} toolSetLabel A label for the toolset 1415 * @config {Integer} worksetId The workset ID to associate the toolset with 1416 * @config {String} pathToIcon A relative path to an icon for the toolset 1417 * @config {Boolean} shareable True to make the toolset public 1418 * @config {String} description A description of the toolset 1419 * @config {Object} tools An object containing the tools 1420 */ 1421 Monk.data.toolset.saveToolset = function(toolsetId, toolsetConfig) { 1422 var toolsetParams = processToolsetConfig(toolsetConfig); 1423 toolsetParams.toolSetId = toolsetId; 1424 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 1425 conn.request({ 1426 url: Monk.data.PROXY_URL + 'get/ProjectManager.updateToolSet', 1427 method: 'GET', 1428 params: toolsetParams, 1429 success: function(responseObject) { 1430 var toolsetJson = Ext.decode(toolsetConfig.toolSetConfig); 1431 1432 Workbench.component.manager.notify( 1433 new Monk.event.toolset.ToolsetSaved({ 1434 label: 'Toolset saved.' 1435 }), 1436 {toolsetId: toolsetId, toolsetJson: toolsetJson}); 1437 }, 1438 failure: function(response, options) { 1439 Ext.Msg.alert('Data', 'Error saving toolset.<br/><b>Error</b>: '+response.statusText); 1440 } 1441 }); 1442 } 1443 1444 /** 1445 * Delete a toolset. 1446 * @param {Integer} toolsetId The toolset to delete 1447 */ 1448 Monk.data.toolset.deleteToolset = function(toolsetId) { 1449 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 1450 conn.request({ 1451 url: Monk.data.PROXY_URL + 'get/ProjectManager.removeToolSet', 1452 method: 'GET', 1453 params: {toolSetId: toolsetId}, 1454 success: function(responseObject) { 1455 Workbench.component.manager.notify( 1456 new Monk.event.toolset.ToolsetDeleted({ 1457 label: 'Toolset deleted.' 1458 }), 1459 {toolsetId: toolsetId, response: responseObject}); 1460 }, 1461 failure: function(response, options) { 1462 Ext.Msg.alert('Data', 'Error deleting toolset.<br/><b>Error</b>: '+response.statusText); 1463 } 1464 }); 1465 } 1466 1467 /** 1468 * Get a toolset. 1469 * @param {Integer} toolsetId The toolset to get 1470 */ 1471 Monk.data.toolset.getToolset = function(toolsetId) { 1472 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 1473 conn.request({ 1474 url: Monk.data.PROXY_URL + 'get/ProjectManager.getToolSet', 1475 method: 'GET', 1476 params: {toolSetId: toolsetId}, 1477 success: function(responseObject) { 1478 Workbench.component.manager.notify( 1479 new Monk.event.toolset.ToolsetRetrieved({ 1480 label: 'Toolset retrieved.' 1481 }), 1482 {toolsetId: toolsetId, json: responseObject.responseText}); 1483 }, 1484 failure: function(response, options) { 1485 Ext.Msg.alert('Data', 'Error retrieving toolset.<br/><b>Error</b>: '+response.statusText); 1486 } 1487 }); 1488 } 1489 1490 /** 1491 * Get toolsets associated with a workset. 1492 * @param {Integer} worksetId The workset to get toolsets for 1493 */ 1494 Monk.data.toolset.getToolsetsForWorkset = function(worksetId) { 1495 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 1496 conn.request({ 1497 url: Monk.data.PROXY_URL + 'get/ProjectManager.getToolSets', 1498 method: 'GET', 1499 params: {worksetId: worksetId}, 1500 success: function(responseObject) { 1501 Workbench.component.manager.notify( 1502 new Monk.event.toolset.ToolsetsForWorksetRetrieved({ 1503 label: 'Toolsets retrieved.' 1504 }), 1505 {worksetId: worksetId, json: responseObject.responseText}); 1506 }, 1507 failure: function(response, options) { 1508 Ext.Msg.alert('Data', 'Error retrieving toolsets.<br/><b>Error</b>: '+response.statusText); 1509 } 1510 }); 1511 } 1512 1513 1514 Workbench.namespace('Monk.data.corpus'); 1515 /* 1516 * Get list of authors associated with a corpus 1517 * @param {String} corpusId 1518 * @returns a hashmap of th corpusId and the authors 1519 */ 1520 Monk.data.corpus.getAuthors = function(corpusId){ 1521 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 1522 if(corpusId==null){ 1523 corpusId="all"; 1524 } 1525 conn.request({ 1526 url: Monk.data.PROXY_URL + 'get/CorpusManager.getAuthors', 1527 method: 'GET', 1528 params: {corpusId: corpusId}, 1529 success: function(responseObject) { 1530 Workbench.component.manager.notify( 1531 new Monk.event.corpus.AuthorsRetrieved({ 1532 label: 'AuthorList retrieved.' 1533 }),{corpusId: corpusId, authors: responseObject}); 1534 1535 }, 1536 failure: function(response, options) { 1537 Ext.Msg.alert('Corpus ', 'Error retrieving author list<br/><b>Error</b>: '+response.statusText); 1538 } 1539 }); 1540 1541 } 1542 1543 /* 1544 * Get list of collections 1545 * @returns collection list 1546 */ 1547 Monk.data.corpus.getCollections = function(){ 1548 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 1549 conn.request({ 1550 url: Monk.data.PROXY_URL + 'get/CorpusManager.getCorpora', 1551 method: 'GET', 1552 success: function(responseObject) { 1553 Workbench.component.manager.notify( 1554 new Monk.event.corpus.CollectionsRetrieved({ 1555 label: 'Collection list retrieved.' 1556 }),{collections: responseObject}); 1557 1558 }, 1559 failure: function(response, options) { 1560 Ext.Msg.alert('Corpus ', 'Error retrieving collection list<br/><b>Error</b>: '+response.statusText); 1561 } 1562 }); 1563 1564 } 1565 1566 Workbench.namespace("Monk.chart"); 1567 1568 Monk.chart.getFeatureComparison = function(type,featureType,queryParam){ 1569 var conn = new Ext.ux.ErrorHandlingConnection({listeners: listeners}); 1570 conn.request({ 1571 url: Monk.data.PROXY_URL + 'get/AnalyticsManager.getFeatureGenderComparisonChart', 1572 method: 'GET', 1573 params: queryParam, 1574 success: function(responseObject) { 1575 Workbench.component.manager.notify(new Monk.event.chart.FeatureComparisonChartRetrieved({ 1576 label: 'compare features: ' 1577 }), {"featureType":featureType,"imgUrl":responseObject.responseText}); 1578 1579 }, 1580 failure: function(response, options) { 1581 Ext.Msg.alert('Chart ', 'Error retrieving chart <br/><b>Error</b>: '+response.statusText); 1582 } 1583 }); 1584 1585 } 1586 1587