]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/chrome/content/util/network.js
Timing: Set offlineStrings variable after network.init, and not inline.
[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                         var request = new RemoteRequest( app, name );
93                         if (_params && _params.secure) {
94                                 request.setSecure(true);
95                         } else {
96                                 request.setSecure(false);
97                         }
98                         for(var index in params) {
99                                 request.addParam(params[index]);
100                         }
101
102             var start_timer = (new Date).getTime();     
103                         if (f)  {
104                                 request.setCompleteCallback(
105                                         function(req) {
106                                                 try {
107                             var duration = ( (new Date).getTime() - start_timer )/1000;
108                             if ( obj.get_result(req) == null && duration > obj.network_timeout ) req.cancelled = true;
109                                                         var json_string = js2JSON(obj.get_result(req));
110                                                         obj.error.sdump('D_SES_RESULT','asynced result #' 
111                                                                 + obj.link_id + '\n\n' 
112                                                                 + (json_string.length > 80 ? obj.error.pretty_print(json_string) : json_string) 
113                                                                 + '\n\nOriginal Request:\n\n' 
114                                                                 + 'request '+app+' '+name+' '+ sparams.slice(1,sparams.length-1));
115                                                         req = obj.rerequest_on_session_timeout(app,name,params,req,override_params,_params);
116                                                         req = obj.rerequest_on_perm_failure(app,name,params,req,override_params,_params);
117                                                         if (override_params) {
118                                                                 req = obj.rerequest_on_override(app,name,params,req,override_params,_params);
119                                                         }
120                                                         req = obj.check_for_offline(app,name,params,req,override_params,_params);
121                                                         f(req);
122                                                         obj.NETWORK_FAILURE = null;
123                                                 } catch(E) {
124                                                         try {
125                                                                 E.ilsevent = -2;
126                                                                 E.textcode = offlineStrings.getString('network.server_or_method.error');
127                                                         } catch(F) {}
128                                                         f( { 'getResultObject' : function() { return E; } } );
129                                                 }
130                                         }
131                                 );
132                                 try {
133                                         request.send(false);
134                                 } catch(E) {
135                                         throw(E);
136                                 }
137                                 return null;
138                         } else {
139                                 try {
140                                         request.send(true);
141                     var duration = ( (new Date).getTime() - start_timer )/1000;
142                     if ( obj.get_result(request) == null && duration > obj.network_timeout ) request.cancelled = true;
143                                 } catch(E) {
144                                         throw(E);
145                                 }
146                                 var result = obj.get_result(request);
147                                 var json_string = js2JSON(result);
148                                 this.error.sdump('D_SES_RESULT','synced result #' 
149                                         + obj.link_id + '\n\n' + ( json_string.length > 80 ? obj.error.pretty_print(json_string) : json_string ) 
150                                         + '\n\nOriginal Request:\n\n' 
151                                         + 'request '+app+' '+name+' '+ sparams.slice(1,sparams.length-1));
152                                 request = obj.rerequest_on_session_timeout(app,name,params,request,override_params,_params);
153                                 request = obj.rerequest_on_perm_failure(app,name,params,request,override_params,_params);
154                                 if (override_params) {
155                                         request = obj.rerequest_on_override(app,name,params,request,override_params,_params);
156                                 }
157                                 request = obj.check_for_offline(app,name,params,request,override_params,_params);
158                                 obj.NETWORK_FAILURE = null;
159                                 return request;
160                         }
161
162                 } catch(E) {
163                         alert('2: ' + E);
164                         if (instanceOf(E,perm_ex)) {
165                                 alert('in util.network, _request : permission exception: ' + js2JSON(E));
166                         }
167                         throw(E);
168                 }
169         },
170
171         'check_for_offline' : function (app,name,params,req,override_params,_params) {
172         try {
173             var obj = this;
174             var result = obj.get_result(req);
175             if (result == null) return req;
176             if (typeof result.ilsevent == 'undefined') return req;
177             if (result.ilsevent != -1) return req;
178
179             JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
180             var proceed = true;
181
182             while(proceed) {
183
184                 proceed = false;
185
186                 var r;
187
188                 if (data.proceed_offline) {
189
190                     r = 1;
191
192                 } else {
193
194                     var network_failure_string;
195                     var network_failure_status_string;
196                     var msg;
197
198                     try { network_failure_string = String( obj.NETWORK_FAILURE ); } catch(E) { network_failure_string = E; }
199                     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); }
200                     
201                     try { msg = offlineStrings.getFormattedString('network.server.failure.exception', [data.server_unadorned]) + '\n' +
202                                 offlineStrings.getFormattedString('network.server.method', [name]) + '\n' + 
203                                 offlineStrings.getFormattedString('network.server.params', [js2JSON(params)]) + '\n' + 
204                                 offlineStrings.getString('network.server.thrown_label') + '\n' + network_failure_string + '\n' + 
205                                 offlineStrings.getString('network.server.status_label') + '\n' + network_failure_status_string;
206                     } catch(E) { msg = E; }
207
208                     try { obj.error.sdump('D_SES_ERROR',msg); } catch(E) { alert('3: ' + E); }
209
210                     r = obj.error.yns_alert(
211                         msg,
212                         offlineStrings.getString('network.network_failure'),
213                         offlineStrings.getString('network.retry_network'),
214                         offlineStrings.getString('network.ignore_errors'),
215                         null,
216                         offlineStrings.getString('common.confirm')
217                     );
218                     if (r == 1) {
219                         data.proceed_offline = true; data.stash('proceed_offline');
220                         dump('Remembering proceed_offline for 200000 ms.\n');
221                         setTimeout(
222                             function() {
223                                 data.proceed_offline = false; data.stash('proceed_offline');
224                                 dump('Setting proceed_offline back to false.\n');
225                             }, 200000
226                         );
227                     }
228                 }
229
230                 dump( r == 0 ? 'Retry Network\n' : 'Ignore Errors\n' );
231
232                 switch(r) {
233                     case 0: 
234                         req = obj._request(app,name,params,null,override_params,_params);
235                         if (obj.get_result(req)) proceed = true; /* daily WTF, why am I even doing this? :) */
236                         return req;
237                     break;
238
239                     case 1: 
240                         return req;
241                     break;
242                 }
243             }
244         } catch(E) {
245                         alert('4: ' + E);
246             throw(E);
247         }
248         },
249
250         'reset_titlebars' : function(data) {
251                 var obj = this;
252                 data.stash_retrieve();
253                 try {
254                         JSAN.use('util.window'); var win =  new util.window();
255                         var windowManager = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService();
256                         var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
257                         var enumerator = windowManagerInterface.getEnumerator(null);
258
259                         var w; // set title on all appshell windows
260                         while ( w = enumerator.getNext() ) {
261                                 if (w.document.title.match(/^\d/)) {
262                                         w.document.title = 
263                                                 win.appshell_name_increment() 
264                                                 + ': ' + data.list.au[0].usrname() 
265                                                 + '@' + data.ws_name;
266                                                 + '.' + data.server_unadorned 
267                                 }
268                         }
269                 } catch(E) {
270                         obj.error.standard_unexpected_error_alert(offlineStrings.getString('network.window_title.error'),E);
271                 }
272         },
273
274         'get_new_session' : function(name,xulG,text) {
275                 var obj = this;
276                 try {
277
278                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
279                 var url = urls.XUL_AUTH_SIMPLE;
280                 if (typeof xulG != 'undefined' && typeof xulG.url_prefix == 'function') url = xulG.url_prefix( url );
281                 JSAN.use('util.window'); var win = new util.window();
282                 var my_xulG = win.open(
283                         url,
284                         //+ '?login_type=staff'
285                         //+ '&desc_brief=' + window.escape( text ? 'Session Expired' : 'Operator Change' )
286                         //+ '&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.'),
287                         //'simple_auth' + (new Date()).toString(),
288                         offlineStrings.getString('network.new_session.authorize'),
289                         'chrome,resizable,modal,width=700,height=500',
290                         {
291                                 'login_type' : 'staff',
292                                 'desc_brief' : text ? offlineStrings.getString('network.new_session.expired') : offlineStrings.getString('network.new_session.operator_change'),
293                                 'desc_full' : text ? offlineStrings.getString('network.new_session.expired.prompt') : offlineStrings.getString('network.new_session.operator_change.prompt')
294                                 //'simple_auth' : (new Date()).toString(),
295                         }
296                 );
297                 JSAN.use('OpenILS.data');
298                 var data = new OpenILS.data(); data.init({'via':'stash'});
299                 if (typeof data.temporary_session != 'undefined' && data.temporary_session != '') {
300                         data.session.key = data.temporary_session.key; 
301                         data.session.authtime = data.temporary_session.authtime; 
302                         data.stash('session');
303             try {
304                 var ios = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
305                 var cookieUri = ios.newURI("http://" + data.server_unadorned, null, null);
306                 var cookieUriSSL = ios.newURI("https://" + data.server_unadorned, null, null);
307                 var cookieSvc = Components.classes["@mozilla.org/cookieService;1"].getService(Components.interfaces.nsICookieService);
308
309                 cookieSvc.setCookieString(cookieUri, null, "ses="+data.session.key, null);
310                 cookieSvc.setCookieString(cookieUriSSL, null, "ses="+data.session.key, null);
311
312             } catch(E) {
313                 alert(offineStrings.getFormattedString('main.session_cookie.error', [E]));
314             }
315                         if (! data.list.au ) data.list.au = [];
316                         data.list.au[0] = JSON2js( data.temporary_session.usr );
317                         data.stash('list');
318                         obj.reset_titlebars(data);
319                         return true;
320         } else {
321             obj.error.sdump('D_TRACE','No new session key after simple_auth in util/network\n');
322         }
323                 return false;
324
325                 } catch(E) {
326                         obj.error.standard_unexpected_error_alert('util.network.get_new_session',E);
327                 }
328         },
329
330         'rerequest_on_session_timeout' : function(app,name,params,req,override_params,_params) {
331                 try {
332                         var obj = this;
333                         var robj = obj.get_result(req);
334                         if (robj != null && robj.ilsevent && robj.ilsevent == 1001) {
335
336                                 if (obj.get_new_session(name,undefined,true)) {
337                                         JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
338                                         params[0] = data.session.key;
339                                         req = obj._request(app,name,params,null,override_params,_params);
340                                 }
341                         }
342                 } catch(E) {
343                         this.error.standard_unexpected_error_alert('rerequest_on_session_timeout',E);
344                 }
345                 return req;
346         },
347         
348         'rerequest_on_perm_failure' : function(app,name,params,req,override_params,_params) {
349                 try {
350                         var obj = this;
351                         var robj = obj.get_result(req);
352                         if (robj != null && robj.ilsevent && robj.ilsevent == 5000) {
353                                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
354                                 if (location.href.match(/^chrome/)) {
355                                         //alert('Permission denied.');
356                                 } else {
357                                         JSAN.use('util.window'); var win = new util.window();
358                                         var my_xulG = win.open(
359                                                 urls.XUL_AUTH_SIMPLE,
360                                                 //+ '?login_type=temp'
361                                                 //+ '&desc_brief=' + window.escape('Permission Denied: ' + robj.ilsperm)
362                                                 //+ '&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),
363                                                 //'simple_auth' + (new Date()).toString(),
364                                                 offlineStrings.getFormattedString('network.permission.authorize'),
365                                                 'chrome,resizable,modal,width=700,height=500',
366                                                 {
367                                                         'login_type' : 'temp',
368                                                         'desc_brief' : offlineStrings.getFormattedString('network.permission.description.brief', [robj.ilsperm]),
369                                                         'desc_full' : offlineStrings.getFormattedString('network.permission.description.full', [name])
370                                                         //'simple_auth' : (new Date()).toString(),
371                                                 }
372                                         );
373                                         JSAN.use('OpenILS.data');
374                                         //var data = new OpenILS.data(); data.init({'via':'stash'});
375                                         if (typeof my_xulG.temporary_session != 'undefined' && my_xulG.temporary_session != '') {
376                                                 params[0] = my_xulG.temporary_session.key;
377                                                 req = obj._request(app,name,params,null,override_params,_params);
378                                         }
379                                 }
380                         }
381                 } catch(E) {
382                         this.error.sdump('D_ERROR',E);
383                 }
384                 return req;
385         },
386
387         'rerequest_on_override' : function (app,name,params,req,override_params,_params) {
388                 var obj = this;
389                 try {
390                         if (!override_params.text) override_params.text = {};
391                         function override(r) {
392                                 try {
393                                         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
394                                         obj.sound.bad();
395                                         var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">' + 
396                                                 '<groupbox><caption label="' + offlineStrings.getString('network.override.exceptions') + '"/>' + 
397                                                 '<grid><columns><column/><column/></columns><rows>';
398                                         for (var i = 0; i < r.length; i++) {
399                                                 var t1 = String(r[i].ilsevent).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
400                                                 var t2 = String(r[i].textcode).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
401                                                 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;');
402                                                 var t4 = String(r[i].desc).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
403                                                 xml += '<row>' + 
404                                                         '<description style="color: red" tooltiptext="' + t1 + '">' + t2 + '</description>' + 
405                                                         '<description>' + t3 + '</description>' + 
406                                                         '</row><row>' + '<description>' + t4 + '</description>' + '</row>';
407                                         }
408                                         xml += '</rows></grid></groupbox><groupbox><caption label="' + offlineStrings.getString('network.override.override') +'"/><hbox>' + 
409                                                 '<description>' + offlineStrings.getString('network.override.force.prompt') + '</description>' + 
410                                                 '<button accesskey="' + offlineStrings.getString('common.no.accesskey') + '" label="' + offlineStrings.getString('common.no') + '" name="fancy_cancel"/>' + 
411                                                 '<button id="override" accesskey="' + offlineStrings.getString('common.yes.accesskey') + '" label="' + offlineStrings.getString('common.yes') + '" name="fancy_submit" value="override"/></hbox></groupbox></vbox>';
412                                         //JSAN.use('OpenILS.data');
413                                         //var data = new OpenILS.data(); data.init({'via':'stash'});
414                                         //data.temp_override_xml = xml; data.stash('temp_override_xml');
415                                         JSAN.use('util.window'); var win = new util.window();
416                                         var fancy_prompt_data = win.open(
417                                                 urls.XUL_FANCY_PROMPT,
418                                                 //+ '?xml_in_stash=temp_override_xml'
419                                                 //+ '&title=' + window.escape(override_params.title),
420                                                 'fancy_prompt', 'chrome,resizable,modal,width=700,height=500',
421                                                 { 'xml' : xml, 'title' : override_params.title }
422                                         );
423                                         if (fancy_prompt_data.fancy_status == 'complete') {
424                                                 req = obj._request(app,name + '.override',params);
425                                         }
426                                         return req;
427                                 } catch(E) {
428                                         alert('in util.network, rerequest_on_override, override:' + E);
429                                 }
430                         }
431
432                         var result = obj.get_result(req);
433                         if (!result) return req;
434
435                         if ( (typeof result.ilsevent != 'undefined') && (override_params.overridable_events.indexOf( result.ilsevent == null ? null : Number(result.ilsevent) ) != -1) ) {
436                                 req = override([result]);
437                         } else {
438                                 var found_good = false; var found_bad = false;
439                                 for (var i = 0; i < result.length; i++) {
440                                         if ( (result[i].ilsevent != 'undefined') && (override_params.overridable_events.indexOf( result.ilsevent == null ? null : Number(result[i].ilsevent) ) != -1) ) {
441                                                 found_good = true;
442                                         } else {
443                                                 found_bad = true;
444                                         }
445                                 }
446                                 if (found_good && (!found_bad)) req = override(result);
447                         }
448
449                         return req;
450                 } catch(E) {
451                         throw(E);
452                 }
453         }
454 }
455
456 /*
457 function sample_callback(request) {
458         var result = request.getResultObject();
459 }
460 */
461
462 dump('exiting util/network.js\n');