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