]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/chrome/content/util/network.js
fix for nasty little copy/paste regression, trying to support null ilsevent's. This...
[working/Evergreen.git] / Open-ILS / xul / staff_client / chrome / content / util / network.js
1 dump('entering util/network.js\n');
2 // vim:noet:sw=4:ts=4:
3
4 var offlineStrings;
5
6 if (typeof util == 'undefined') util = {};
7 util.network = function () {
8
9         JSAN.use('util.error'); this.error = new util.error();
10         JSAN.use('util.sound'); this.sound = new util.sound();
11
12     offlineStrings = document.getElementById('offlineStrings');
13
14         return this;
15 };
16
17 util.network.prototype = {
18
19         'link_id' : 0,
20
21     'network_timeout' : 55, /* seconds */
22
23         'NETWORK_FAILURE' : null,
24
25         'simple_request' : function(method_id,params,f,override_params) {
26                 //var obj = this;
27                 //var sparams = js2JSON(params);
28                 //obj.error.sdump('D_SES','simple_request '+ method_id +' '+obj.error.pretty_print(sparams.slice(1,sparams.length-1))+
29                 //      '\noverride_params = ' + override_params + '\n');
30                 if (typeof api[method_id] == 'undefined') {
31                         throw( offlineStrings.getFormattedString('network.method_not_found.error', [method_id]) );
32                 }
33                 var secure = true; if (typeof api[method_id].secure != 'undefined') secure = api[method_id].secure;
34                 return this.request(api[method_id].app,api[method_id].method,params,f,override_params,{ 'secure' : secure, 'method_id' : method_id });
35         },
36
37         'get_result' : function (req) {
38                 var obj = this;
39                 var result;
40         var fake_ilsevent_for_network_errors = { 'ilsevent' : -1, 'textcode' : offlineStrings.getString('network.server_or_method.error') }; 
41                 try {
42             if (req.cancelled) {
43                 result = fake_ilsevent_for_network_errors;
44             } else {
45                         result = req.getResultObject(); 
46             }
47                 } catch(E) {
48                         try {
49                                 if (instanceOf(E, NetworkFailure)) {
50                                         obj.NETWORK_FAILURE = E;
51                                 } else {
52                                         try { obj.NETWORK_FAILURE = js2JSON(E); } catch(F) { dump(F + '\n'); obj.NETWORK_FAILURE = E; };
53                                 }
54                         } catch(I) { 
55                                 obj.NETWORK_FAILURE = offlineStrings.getString('network.unknown_status');
56                         }
57             result = fake_ilsevent_for_network_errors;
58         }
59                 return result;
60         },
61
62         'request' : function (app,name,params,f,override_params,_params) {
63
64                 var obj = this;
65                 
66                 //var sparams = js2JSON(params);
67                 //obj.error.sdump('D_SES','request '+ app + ' ' + name +' '+obj.error.pretty_print(sparams.slice(1,sparams.length-1))+
68                 //      '\noverride_params = ' + override_params + '\n_params = ' + _params + '\n');
69
70                 try { 
71
72                         var request =  this._request(app,name,params,f,override_params,_params);
73                         if (request) {
74                                 return this.get_result(request);
75                         } else {
76                                 return null;
77                         }
78         
79                 } catch(E) {
80                         alert('1: ' + E); 
81                 }
82         },
83
84         '_request' : function (app,name,params,f,override_params,_params) {
85                 var obj = this;
86                 try {
87                         var sparams = js2JSON(params);
88                         obj.error.sdump('D_SES','_request '+app+' '+name+' '+obj.error.pretty_print(sparams.slice(1,sparams.length-1))+
89                                 '\noverride_params = ' + override_params + '\n_params = ' + _params +
90                                 '\nResult #' + (++obj.link_id) + ( f ? ' asynced' : ' synced' ) );
91
92             if (document.getElementById('network_progress')) {
93                 if (g && g.menu && g.menu.network_meter && typeof g.menu.network_meter.inc == 'function') g.menu.network_meter.inc(app,name);
94             } else if (typeof xulG != 'undefined') {
95                 if (xulG && xulG.network_meter && typeof xulG.network_meter.inc == 'function') xulG.network_meter.inc(app,name);
96             }
97
98                         var request = new RemoteRequest( app, name );
99                         if (_params && _params.secure) {
100                                 request.setSecure(true);
101                         } else {
102                                 request.setSecure(false);
103                         }
104                         for(var index in params) {
105                                 request.addParam(params[index]);
106                         }
107
108             var start_timer = (new Date).getTime();     
109                         if (f)  {
110                                 request.setCompleteCallback(
111                                         function(req) {
112                                                 try {
113                             var duration = ( (new Date).getTime() - start_timer )/1000;
114                             if ( obj.get_result(req) == null && duration > obj.network_timeout ) req.cancelled = true;
115
116                             if (document.getElementById('network_progress')) {
117                                 if (g && g.menu && g.menu.network_meter && typeof g.menu.network_meter.dec == 'function') g.menu.network_meter.dec(app,name);
118                             } else if (typeof xulG != 'undefined') {
119                                 if (xulG && xulG.network_meter && typeof xulG.network_meter.dec == 'function') xulG.network_meter.dec(app,name);
120                             }
121
122                                                         var json_string = js2JSON(obj.get_result(req));
123                                                         obj.error.sdump('D_SES_RESULT','asynced result #' 
124                                                                 + obj.link_id + '\n\n' 
125                                                                 + (json_string.length > 80 ? obj.error.pretty_print(json_string) : json_string) 
126                                                                 + '\n\nOriginal Request:\n\n' 
127                                                                 + 'request '+app+' '+name+' '+ sparams.slice(1,sparams.length-1));
128                                                         req = obj.rerequest_on_session_timeout(app,name,params,req,override_params,_params);
129                                                         req = obj.rerequest_on_perm_failure(app,name,params,req,override_params,_params);
130                                                         if (override_params) {
131                                                                 req = obj.rerequest_on_override(app,name,params,req,override_params,_params);
132                                                         }
133                                                         req = obj.check_for_offline(app,name,params,req,override_params,_params);
134                                                         f(req);
135                                                         obj.NETWORK_FAILURE = null;
136                                                 } catch(E) {
137                                                         try {
138                                                                 E.ilsevent = -2;
139                                                                 E.textcode = offlineStrings.getString('network.server_or_method.error');
140                                                         } catch(F) {}
141                                                         f( { 'getResultObject' : function() { return E; } } );
142                                                 }
143                                         }
144                                 );
145                                 try {
146                                         request.send(false);
147                                 } catch(E) {
148                                         throw(E);
149                                 }
150                                 return null;
151                         } else {
152                                 try {
153                                         request.send(true);
154                     var duration = ( (new Date).getTime() - start_timer )/1000;
155                     if ( obj.get_result(request) == null && duration > obj.network_timeout ) request.cancelled = true;
156
157                     if (document.getElementById('network_progress')) {
158                         if (g && g.menu && g.menu.network_meter && typeof g.menu.network_meter.dec == 'function') g.menu.network_meter.dec(app,name);
159                     } else if (typeof xulG != 'undefined') {
160                         if (xulG && xulG.network_meter && typeof xulG.network_meter.dec == 'function') xulG.network_meter.dec(app,name);
161                     }
162
163                                 } catch(E) {
164                                         throw(E);
165                                 }
166                                 var result = obj.get_result(request);
167                                 var json_string = js2JSON(result);
168                                 this.error.sdump('D_SES_RESULT','synced result #' 
169                                         + obj.link_id + '\n\n' + ( json_string.length > 80 ? obj.error.pretty_print(json_string) : json_string ) 
170                                         + '\n\nOriginal Request:\n\n' 
171                                         + 'request '+app+' '+name+' '+ sparams.slice(1,sparams.length-1));
172                                 request = obj.rerequest_on_session_timeout(app,name,params,request,override_params,_params);
173                                 request = obj.rerequest_on_perm_failure(app,name,params,request,override_params,_params);
174                                 if (override_params) {
175                                         request = obj.rerequest_on_override(app,name,params,request,override_params,_params);
176                                 }
177                                 request = obj.check_for_offline(app,name,params,request,override_params,_params);
178                                 obj.NETWORK_FAILURE = null;
179                                 return request;
180                         }
181
182                 } catch(E) {
183                         alert('2: ' + E);
184                         if (instanceOf(E,perm_ex)) {
185                                 alert('in util.network, _request : permission exception: ' + js2JSON(E));
186                         }
187                         throw(E);
188                 }
189         },
190
191         'check_for_offline' : function (app,name,params,req,override_params,_params) {
192         try {
193             var obj = this;
194             var result = obj.get_result(req);
195             if (result == null) return req;
196             if (typeof result.ilsevent == 'undefined') return req;
197             if (result.ilsevent != -1) return req;
198
199             JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
200             var proceed = true;
201
202             while(proceed) {
203
204                 proceed = false;
205
206                 var r;
207
208                 if (data.proceed_offline) {
209
210                     r = 1;
211
212                 } else {
213
214                     var network_failure_string;
215                     var network_failure_status_string;
216                     var msg;
217
218                     try { network_failure_string = String( obj.NETWORK_FAILURE ); } catch(E) { network_failure_string = E; }
219                     try { network_failure_status_string = typeof obj.NETWORK_FAILURE == 'object' && typeof obj.NETWORK_FAILURE != 'null' && typeof obj.NETWORK_FAILURE.status == 'function' ? obj.NETWORK_FAILURE.status() : ''; } catch(E) { network_failure_status_string = ''; obj.error.sdump('D_ERROR', 'setting network_failure_status_string: ' + E); }
220                     
221                     try { msg = offlineStrings.getFormattedString('network.server.failure.exception', [data.server_unadorned]) + '\n' +
222                                 offlineStrings.getFormattedString('network.server.method', [name]) + '\n' + 
223                                 offlineStrings.getFormattedString('network.server.params', [js2JSON(params)]) + '\n' + 
224                                 offlineStrings.getString('network.server.thrown_label') + '\n' + network_failure_string + '\n' + 
225                                 offlineStrings.getString('network.server.status_label') + '\n' + network_failure_status_string;
226                     } catch(E) { msg = E; }
227
228                     try { obj.error.sdump('D_SES_ERROR',msg); } catch(E) { alert('3: ' + E); }
229
230                     r = obj.error.yns_alert(
231                         msg,
232                         offlineStrings.getString('network.network_failure'),
233                         offlineStrings.getString('network.retry_network'),
234                         offlineStrings.getString('network.ignore_errors'),
235                         null,
236                         offlineStrings.getString('common.confirm')
237                     );
238                     if (r == 1) {
239                         data.proceed_offline = true; data.stash('proceed_offline');
240                         dump('Remembering proceed_offline for 200000 ms.\n');
241                         setTimeout(
242                             function() {
243                                 data.proceed_offline = false; data.stash('proceed_offline');
244                                 dump('Setting proceed_offline back to false.\n');
245                             }, 200000
246                         );
247                     }
248                 }
249
250                 dump( r == 0 ? 'Retry Network\n' : 'Ignore Errors\n' );
251
252                 switch(r) {
253                     case 0: 
254                         req = obj._request(app,name,params,null,override_params,_params);
255                         if (obj.get_result(req)) proceed = true; /* daily WTF, why am I even doing this? :) */
256                         return req;
257                     break;
258
259                     case 1: 
260                         return req;
261                     break;
262                 }
263             }
264         } catch(E) {
265                         alert('4: ' + E);
266             throw(E);
267         }
268         },
269
270         'reset_titlebars' : function(data) {
271                 var obj = this;
272                 data.stash_retrieve();
273                 try {
274                         JSAN.use('util.window'); var win =  new util.window();
275                         var windowManager = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService();
276                         var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
277                         var enumerator = windowManagerInterface.getEnumerator(null);
278
279                         var w; // set title on all appshell windows
280                         while ( w = enumerator.getNext() ) {
281                                 if (w.document.title.match(/^\d/)) {
282                                         w.document.title = 
283                                                 win.appshell_name_increment() 
284                                                 + ': ' + data.list.au[0].usrname() 
285                                                 + '@' + data.ws_name;
286                                                 + '.' + data.server_unadorned 
287                                 }
288                         }
289                 } catch(E) {
290                         obj.error.standard_unexpected_error_alert(offlineStrings.getString('network.window_title.error'),E);
291                 }
292         },
293
294         'get_new_session' : function(name,xulG,text) {
295                 var obj = this;
296                 try {
297
298                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
299                 var url = urls.XUL_AUTH_SIMPLE;
300                 if (typeof xulG != 'undefined' && typeof xulG.url_prefix == 'function') url = xulG.url_prefix( url );
301                 JSAN.use('util.window'); var win = new util.window();
302                 var my_xulG = win.open(
303                         url,
304                         //+ '?login_type=staff'
305                         //+ '&desc_brief=' + window.escape( text ? 'Session Expired' : 'Operator Change' )
306                         //+ '&desc_full=' + window.escape( text ? 'Please enter the credentials for a new login session.' : 'Please enter the credentials for the new login session.  Note that the previous session is still active.'),
307                         //'simple_auth' + (new Date()).toString(),
308                         offlineStrings.getString('network.new_session.authorize'),
309                         'chrome,resizable,modal,width=700,height=500',
310                         {
311                                 'login_type' : 'staff',
312                                 'desc_brief' : text ? offlineStrings.getString('network.new_session.expired') : offlineStrings.getString('network.new_session.operator_change'),
313                                 'desc_full' : text ? offlineStrings.getString('network.new_session.expired.prompt') : offlineStrings.getString('network.new_session.operator_change.prompt')
314                                 //'simple_auth' : (new Date()).toString(),
315                         }
316                 );
317                 JSAN.use('OpenILS.data');
318                 var data = new OpenILS.data(); data.init({'via':'stash'});
319                 if (typeof data.temporary_session != 'undefined' && data.temporary_session != '') {
320                         data.session.key = data.temporary_session.key; 
321                         data.session.authtime = data.temporary_session.authtime; 
322                         data.stash('session');
323             try {
324                 var ios = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
325                 var cookieUri = ios.newURI("http://" + data.server_unadorned, null, null);
326                 var cookieUriSSL = ios.newURI("https://" + data.server_unadorned, null, null);
327                 var cookieSvc = Components.classes["@mozilla.org/cookieService;1"].getService(Components.interfaces.nsICookieService);
328
329                 cookieSvc.setCookieString(cookieUri, null, "ses="+data.session.key, null);
330                 cookieSvc.setCookieString(cookieUriSSL, null, "ses="+data.session.key, null);
331
332             } catch(E) {
333                 alert(offineStrings.getFormattedString('main.session_cookie.error', [E]));
334             }
335                         if (! data.list.au ) data.list.au = [];
336                         data.list.au[0] = JSON2js( data.temporary_session.usr );
337                         data.stash('list');
338                         obj.reset_titlebars(data);
339                         return true;
340         } else {
341             obj.error.sdump('D_TRACE','No new session key after simple_auth in util/network\n');
342         }
343                 return false;
344
345                 } catch(E) {
346                         obj.error.standard_unexpected_error_alert('util.network.get_new_session',E);
347                 }
348         },
349
350         'rerequest_on_session_timeout' : function(app,name,params,req,override_params,_params) {
351                 try {
352                         var obj = this;
353                         var robj = obj.get_result(req);
354                         if (robj != null && robj.ilsevent && robj.ilsevent == 1001) {
355
356                                 if (obj.get_new_session(name,undefined,true)) {
357                                         JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
358                                         params[0] = data.session.key;
359                                         req = obj._request(app,name,params,null,override_params,_params);
360                                 }
361                         }
362                 } catch(E) {
363                         this.error.standard_unexpected_error_alert('rerequest_on_session_timeout',E);
364                 }
365                 return req;
366         },
367         
368         'rerequest_on_perm_failure' : function(app,name,params,req,override_params,_params) {
369                 try {
370                         var obj = this;
371                         var robj = obj.get_result(req);
372                         if (robj != null && robj.ilsevent && robj.ilsevent == 5000) {
373                                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
374                                 if (location.href.match(/^chrome/)) {
375                                         //alert('Permission denied.');
376                                 } else {
377                                         JSAN.use('util.window'); var win = new util.window();
378                                         var my_xulG = win.open(
379                                                 urls.XUL_AUTH_SIMPLE,
380                                                 //+ '?login_type=temp'
381                                                 //+ '&desc_brief=' + window.escape('Permission Denied: ' + robj.ilsperm)
382                                                 //+ '&desc_full=' + window.escape('Another staff member with the above permission may authorize this specific action.  Please notify your library administrator if you need this permission.  If you feel you have received this exception in error, inform your friendly Evergreen developers of the above permission and this debug information: ' + name),
383                                                 //'simple_auth' + (new Date()).toString(),
384                                                 offlineStrings.getFormattedString('network.permission.authorize'),
385                                                 'chrome,resizable,modal,width=700,height=500',
386                                                 {
387                                                         'login_type' : 'temp',
388                                                         'desc_brief' : offlineStrings.getFormattedString('network.permission.description.brief', [robj.ilsperm]),
389                                                         'desc_full' : offlineStrings.getFormattedString('network.permission.description.full', [name])
390                                                         //'simple_auth' : (new Date()).toString(),
391                                                 }
392                                         );
393                                         JSAN.use('OpenILS.data');
394                                         //var data = new OpenILS.data(); data.init({'via':'stash'});
395                                         if (typeof my_xulG.temporary_session != 'undefined' && my_xulG.temporary_session != '') {
396                                                 params[0] = my_xulG.temporary_session.key;
397                                                 req = obj._request(app,name,params,null,override_params,_params);
398                                         }
399                                 }
400                         }
401                 } catch(E) {
402                         this.error.sdump('D_ERROR',E);
403                 }
404                 return req;
405         },
406
407         'rerequest_on_override' : function (app,name,params,req,override_params,_params) {
408                 var obj = this;
409                 try {
410                         if (!override_params.text) override_params.text = {};
411                         function override(r) {
412                                 try {
413                                         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
414                                         obj.sound.bad();
415                                         var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">' + 
416                                                 '<groupbox><caption label="' + offlineStrings.getString('network.override.exceptions') + '"/>' + 
417                                                 '<grid><columns><column/><column/></columns><rows>';
418                                         for (var i = 0; i < r.length; i++) {
419                                                 var t1 = String(r[i].ilsevent).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
420                                                 var t2 = String(r[i].textcode).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
421                                                 var t3 = String((override_params.text[r[i].ilsevent] ? override_params.text[r[i].ilsevent](r[i]) : '')).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
422                                                 var t4 = String(r[i].desc).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
423                                                 xml += '<row>' + 
424                                                         '<description style="color: red" tooltiptext="' + t1 + '">' + t2 + '</description>' + 
425                                                         '<description>' + t3 + '</description>' + 
426                                                         '</row><row>' + '<description>' + t4 + '</description>' + '</row>';
427                                         }
428                                         xml += '</rows></grid></groupbox><groupbox><caption label="' + offlineStrings.getString('network.override.override') +'"/><hbox>' + 
429                                                 '<description>' + offlineStrings.getString('network.override.force.prompt') + '</description>' + 
430                                                 '<button accesskey="' + offlineStrings.getString('common.no.accesskey') + '" label="' + offlineStrings.getString('common.no') + '" name="fancy_cancel"/>' + 
431                                                 '<button id="override" accesskey="' + offlineStrings.getString('common.yes.accesskey') + '" label="' + offlineStrings.getString('common.yes') + '" name="fancy_submit" value="override"/></hbox></groupbox></vbox>';
432                                         //JSAN.use('OpenILS.data');
433                                         //var data = new OpenILS.data(); data.init({'via':'stash'});
434                                         //data.temp_override_xml = xml; data.stash('temp_override_xml');
435                                         JSAN.use('util.window'); var win = new util.window();
436                                         var fancy_prompt_data = win.open(
437                                                 urls.XUL_FANCY_PROMPT,
438                                                 //+ '?xml_in_stash=temp_override_xml'
439                                                 //+ '&title=' + window.escape(override_params.title),
440                                                 'fancy_prompt', 'chrome,resizable,modal,width=700,height=500',
441                                                 { 'xml' : xml, 'title' : override_params.title }
442                                         );
443                                         if (fancy_prompt_data.fancy_status == 'complete') {
444                                                 req = obj._request(app,name + '.override',params);
445                                         }
446                                         return req;
447                                 } catch(E) {
448                                         alert('in util.network, rerequest_on_override, override:' + E);
449                                 }
450                         }
451
452                         var result = obj.get_result(req);
453                         if (!result) return req;
454
455                         if ( (typeof result.ilsevent != 'undefined') && (override_params.overridable_events.indexOf( result.ilsevent == null ? null : Number(result.ilsevent) ) != -1) ) {
456                                 req = override([result]);
457                         } else {
458                                 var found_good = false; var found_bad = false;
459                                 for (var i = 0; i < result.length; i++) {
460                                         if ( (result[i].ilsevent != 'undefined') && (override_params.overridable_events.indexOf( result[i].ilsevent == null ? null : Number(result[i].ilsevent) ) != -1) ) {
461                                                 found_good = true;
462                                         } else {
463                                                 found_bad = true;
464                                         }
465                                 }
466                                 if (found_good && (!found_bad)) req = override(result);
467                         }
468
469                         return req;
470                 } catch(E) {
471                         throw(E);
472                 }
473         },
474
475     'ping' : function() {
476         try {
477             JSAN.use('util.file'); JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
478                         var file = new util.file('ping.bat');
479             var path = file._file.path;
480                         file.write_content('truncate+exec',
481                 '#!/bin/sh\n' +
482                 'ping -n 15 ' + data.server_unadorned + ' > "' + path + '.txt"\n' + /* windows */
483                 'ping -c 15 ' + data.server_unadorned + ' >> "' + path + '.txt"\n'  /* unix */
484             );
485             file.close();
486                         file = new util.file('ping.bat');
487
488                         var process = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
489                         process.init(file._file);
490
491                         var args = [];
492
493                         dump('process.run = ' + process.run(true, args, args.length) + '\n');
494
495             file.close();
496
497             var file = new util.file('ping.bat.txt');
498             var output = file.get_content();
499             file.close();
500
501             return output;
502         } catch(E) {
503             alert(E);
504         }
505     }
506 }
507
508 /*
509 function sample_callback(request) {
510         var result = request.getResultObject();
511 }
512 */
513
514 dump('exiting util/network.js\n');