From: Bill Erickson Date: Mon, 14 Nov 2016 17:58:33 +0000 (-0500) Subject: LP#1640255 Hatch native messaging extension X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=0eb8943e4be1b230b3b8d99bbdd50af2937db8bd;p=working%2FEvergreen.git LP#1640255 Hatch native messaging extension Replaces Hatch Websockets communication layer with browser extension- based communication. Hatch API remains the same with 2 notable exceptions: 1. appendItem() API call has been removed. It did not work as designed and (thus far) has served no purpose. It was originally intended for offline data storage, but that will probably require something a little smarter. 2. The printer configuration API is no more. This will be replaced with an in-app configuration page. Note, this does not prevent use of the printer dialog, it only means settings are not collected from the printer dialog. Overhaul still in design... Signed-off-by: Bill Erickson --- diff --git a/Open-ILS/src/templates/staff/admin/workstation/t_print_config.tt2 b/Open-ILS/src/templates/staff/admin/workstation/t_print_config.tt2 index ef5dafbccb..ce4d670fa0 100644 --- a/Open-ILS/src/templates/staff/admin/workstation/t_print_config.tt2 +++ b/Open-ILS/src/templates/staff/admin/workstation/t_print_config.tt2 @@ -71,24 +71,6 @@ value="{{printConfig[context].printer}}"> -
-
-
- - -
-
-
diff --git a/Open-ILS/src/templates/staff/admin/workstation/t_splash.tt2 b/Open-ILS/src/templates/staff/admin/workstation/t_splash.tt2 index 360f6d7e2a..0a2a26710e 100644 --- a/Open-ILS/src/templates/staff/admin/workstation/t_splash.tt2 +++ b/Open-ILS/src/templates/staff/admin/workstation/t_splash.tt2 @@ -23,15 +23,6 @@
-
-
- -
-
diff --git a/Open-ILS/web/js/ui/default/staff/admin/workstation/app.js b/Open-ILS/web/js/ui/default/staff/admin/workstation/app.js index d31c5fd8a8..c14612da4f 100644 --- a/Open-ILS/web/js/ui/default/staff/admin/workstation/app.js +++ b/Open-ILS/web/js/ui/default/staff/admin/workstation/app.js @@ -159,7 +159,6 @@ function($scope , $window , $location , egCore , egConfirmDialog) { // --------------------- // Hatch Configs - $scope.hatchURL = egCore.hatch.hatchURL(); $scope.hatchRequired = egCore.hatch.getLocalItem('eg.hatch.required'); @@ -168,11 +167,6 @@ function($scope , $window , $location , egCore , egConfirmDialog) { 'eg.hatch.required', $scope.hatchRequired); } - $scope.updateHatchURL = function() { - egCore.hatch.setLocalItem( - 'eg.hatch.url', $scope.hatchURL); - } - egCore.hatch.getItem('eg.audio.disable').then(function(val) { $scope.disable_sound = val; }); @@ -282,20 +276,6 @@ function($scope , egCore) { .finally(function() {$scope.actionPending = false}); } - $scope.configurePrinter = function() { - $scope.printConfigError = null; - $scope.actionPending = true; - egCore.hatch.configurePrinter( - $scope.context, - $scope.printConfig[$scope.context].printer - ) - .then( - function(config) {$scope.printConfig = config}, - function(error) {$scope.printConfigError = error} - ) - .finally(function() {$scope.actionPending = false}); - } - $scope.setPrinter = function(name) { $scope.printConfig[$scope.context].printer = name; } diff --git a/Open-ILS/web/js/ui/default/staff/services/hatch.js b/Open-ILS/web/js/ui/default/staff/services/hatch.js index ff517fc940..7115ecc11f 100644 --- a/Open-ILS/web/js/ui/default/staff/services/hatch.js +++ b/Open-ILS/web/js/ui/default/staff/services/hatch.js @@ -24,19 +24,27 @@ */ angular.module('egCoreMod') +.constant("HATCH_CONFIG", { + /* TODO: Extension name will change once the extension is + * registered and will presumably be different per browser. + * Current extension name is borrowed from: + * https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/docs/examples/api/nativeMessaging + */ + EXT_NAME_CHROME : "knldjmfmopnpolahpmmgbagdohdnhkik" +}) + .factory('egHatch', - ['$q','$window','$timeout','$interpolate','$http','$cookies', - function($q , $window , $timeout , $interpolate , $http , $cookies) { + ['$q','$window','$timeout','$interpolate','$http','$cookies','HATCH_CONFIG', + function($q , $window , $timeout , $interpolate , $http , $cookies , HATCH_CONFIG) { var service = {}; - service.msgId = 0; + service.port = null; // Hatch extension connection + service.msgId = 1; service.messages = {}; service.pending = []; - service.socket = null; service.hatchAvailable = null; - service.defaultHatchURL = 'wss://localhost:8443/hatch'; - // write a message to the Hatch websocket + // write a message to the Hatch port service.sendToHatch = function(msg) { var msg2 = {}; @@ -47,7 +55,7 @@ angular.module('egCoreMod') }); console.debug("sending to Hatch: " + JSON.stringify(msg2,null,2)); - service.socket.send(JSON.stringify(msg2)); + service.port.postMessage(msg2); } // Send the request to Hatch if it's available. @@ -90,18 +98,18 @@ angular.module('egCoreMod') msg.deferred = service.messages[msg.msgid].deferred; delete service.messages[msg.msgid]; // un-cache - // resolve / reject - if (msg.error) { - throw new Error( - "egHatch command failed : " - + JSON.stringify(msg.error, null, 2)); + if (msg.status != 200) { + msg.deferred.reject(); + throw new Error("Hatch command failed with status=" + + msg.status + " and message=" + msg.message); + } else { msg.deferred.resolve(msg.content); } } service.hatchClosed = function() { - service.socket = null; + service.port = null; service.printers = []; service.printConfig = {}; while ( (msg = service.pending.shift()) ) { @@ -112,11 +120,6 @@ angular.module('egCoreMod') service.onHatchClose(); } - service.hatchURL = function() { - return service.getLocalItem('eg.hatch.url') - || service.defaultHatchURL; - } - // Returns true if Hatch is required or if we are currently // communicating with the Hatch service. service.usingHatch = function() { @@ -131,56 +134,59 @@ angular.module('egCoreMod') service.hatchConnect = function() { - if (service.socket && - service.socket.readyState == service.socket.CONNECTING) { - // connection in progress. Nothing to do. Our queued - // message will be delivered when onopen() fires - return; - } + if (service.port) return; + + service.initting = true; try { - service.socket = new WebSocket(service.hatchURL()); + service.port = + chrome.runtime.connect(HATCH_CONFIG.EXT_NAME_CHROME); } catch(e) { service.hatchAvailable = false; service.hatchClosed(); + console.debug("Hatch connection failed: " + e); return; } - service.socket.onopen = function() { - console.debug('connected to Hatch'); - service.hatchAvailable = true; - if (service.onHatchOpen) - service.onHatchOpen(); - while ( (msg = service.pending.shift()) ) { - service.sendToHatch(msg); - }; - } + service.port.onDisconnect.addListener(function() { + if (service.hatchAvailable === false) return; // already noted + service.hatchAvailable = null; // reset + service.hatchClosed(); + }); - service.socket.onclose = function() { - if (service.hatchAvailable === false) return; // already registered + service.port.onMessage.addListener(function(msg) { + console.debug('Hatch says: ' + JSON.stringify(msg, null, 2)); - // onclose() will be called regularly as we disconnect from - // Hatch via timeouts. Return hatchAvailable to its unknow state - service.hatchAvailable = null; - service.hatchClosed(); - } + if (service.initting) { + service.initting = false; + console.debug("Hatch init completed with " + msg.message); - service.socket.onerror = function() { - if (service.hatchAvailable === false) return; // already registered - service.hatchAvailable = false; - console.debug( - "unable to connect to Hatch server at " + service.hatchURL()); - service.hatchClosed(); - } + if (msg.status == 200) { + service.hatchOpened(); + } else { + console.warn("Hatch init failed"); + } - service.socket.onmessage = function(evt) { - var msgStr = evt.data; - if (!msgStr) throw new Error("Hatch returned empty message"); + } else { + service.resolveRequest(msg); + } + }); - var msgObj = JSON.parse(msgStr); - console.debug('Hatch says ' + JSON.stringify(msgObj, null, 2)); - service.resolveRequest(msgObj); - } + console.debug('Connected to Hatch'); + service.hatchAvailable = true; + + // The first message to Hatch must be "init" + service.attemptHatchDelivery({action : 'init'}); + } + + service.hatchOpened = function() { + // let others know we're connected + if (service.onHatchOpen) service.onHatchOpen(); + + // Deliver any previously queued requests + while ( (msg = service.pending.shift()) ) { + service.sendToHatch(msg); + }; } service.getPrintConfig = function() { @@ -291,8 +297,8 @@ angular.module('egCoreMod') service.getRemoteItem = function(key) { return service.attemptHatchDelivery({ key : key, - action : 'get', - }); + action : 'get' + }) } service.getLocalItem = function(key) { @@ -318,16 +324,14 @@ angular.module('egCoreMod') * tmp values are removed during logout or browser close. */ service.setItem = function(key, value) { - var str = JSON.stringify(value); - - return service.setRemoteItem(key, str)['catch']( + return service.setRemoteItem(key, value)['catch']( function(msg) { if (service.hatchRequired()) { console.error("Unable to setItem: " + key + "; hatchRequired=true, but hatch is not connected"); return null; } - return service.setLocalItem(msg.key, null, str); + return service.setLocalItem(msg.key, value); } ); } @@ -336,7 +340,7 @@ angular.module('egCoreMod') service.setRemoteItem = function(key, value) { return service.attemptHatchDelivery({ key : key, - value : value, + content : value, action : 'set', }); } @@ -374,29 +378,6 @@ angular.module('egCoreMod') $window.sessionStorage.setItem(key, jsonified); } - // appends the value to the existing item stored at key. - // If not item is found at key, this behaves just like setItem() - service.appendItem = function(key, value) { - return service.appendRemoteItem(key, value)['catch']( - function(msg) { - if (service.hatchRequired()) { - console.error("Unable to appendItem: " + key - + "; hatchRequired=true, but hatch is not connected"); - return null; - } - service.appendLocalItem(msg.key, msg.value); - } - ); - } - - service.appendRemoteItem = function(key, value) { - return service.attemptHatchDelivery({ - key : key, - value : value, - action : 'append', - }); - } - // assumes the appender and appendee are both strings // TODO: support arrays as well service.appendLocalItem = function(key, value) {