From bccf7a477c3a7f7b4463041f6e34f0e1389c118f Mon Sep 17 00:00:00 2001
From: Stavros Sachtouris <saxtouri@admin.grnet.gr>
Date: Tue, 24 Mar 2015 13:34:09 +0200
Subject: [PATCH] Implement pause and start GUI operation

---
 agkyra/gui.json        |   4 --
 agkyra/gui/protocol.js | 116 +++++++++++++++++++++++++++++++++++------
 agkyra/protocol.py     |  49 ++++++++++++-----
 3 files changed, 136 insertions(+), 33 deletions(-)
 delete mode 100644 agkyra/gui.json

diff --git a/agkyra/gui.json b/agkyra/gui.json
deleted file mode 100644
index 75b4e4b..0000000
--- a/agkyra/gui.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-    "port": 1234,
-    "token": "s0m3-70k3n"
-}
\ No newline at end of file
diff --git a/agkyra/gui/protocol.js b/agkyra/gui/protocol.js
index 16ece23..0751f19 100644
--- a/agkyra/gui/protocol.js
+++ b/agkyra/gui/protocol.js
@@ -1,4 +1,5 @@
 var gui = require('nw.gui');
+var path = require('path');
 
 // Read config file
 var fs = require('fs');
@@ -16,6 +17,7 @@ var globals = {
     'url': null,
     'container': null,
     'directory': null,
+    'pithos_url': null,
     'exclude': null
   },
   'status': {"progress": null, "paused": null}
@@ -29,8 +31,21 @@ function post_gui_id(socket) {
 
 function post_shutdown(socket) {
   send_json(socket, {'method': 'post', 'path': 'shutdown'});
+  closeWindows();
 } // expected response: nothing
 
+function post_pause(socket) {
+  console.log('SEND post pause');
+  requests.push('post pause');
+  send_json(socket, {'method': 'post', 'path': 'pause'});
+} // expected response: {"OK": 200}
+
+function post_start(socket) {
+  console.log('SEND post start');
+  requests.push('post start');
+  send_json(socket, {'method': 'post', 'path': 'start'});
+} // expected response: {"OK": 200}
+
 function get_settings(socket) {
   requests.push('get settings');
   send_json(socket, {'method': 'get', 'path': 'settings'});
@@ -59,7 +74,7 @@ socket.onmessage = function(e) {
   var r = JSON.parse(e.data)
   switch(requests.shift()) {
     case 'post gui_id':
-      if (r['ACCEPTED'] == 202) {
+      if (r['ACCEPTED'] === 202) {
         get_settings(this);
         get_status(this);
       } else {
@@ -67,13 +82,21 @@ socket.onmessage = function(e) {
         closeWindows();
       }
     break;
+    case 'post start':
+    case 'post pause': console.log('RECV ' + r['OK']);
+      if (r['OK'] === 200) {
+        get_status(this);
+      } else {
+        console.log('Helper: ' + JSON.stringify(r));
+      }
+    break;
     case 'get settings':
       console.log(r);
       globals['settings'] = r;
     break;
     case 'put settings':
-      if (r['CREATED'] == 201) {
-        get_settings(socket);
+      if (r['CREATED'] === 201) {
+        get_settings(this);
       } else {
         console.log('Helper: ' + JSON.stringify(r));
       }
@@ -113,29 +136,86 @@ var tray = new gui.Tray({
 
 var menu = new gui.Menu();
 
+// Progress and Pause
+var start_syncing = 'Start syncing';
+var pause_syncing = 'Pause syncing';
+var paused = true;
 
-progress_menu = new gui.MenuItem({
-  label: 'Calculating status',
+progress_item = new gui.MenuItem({
+  // progress menu item
+  label: 'Initializing',
+  type: 'normal'
+});
+menu.append(progress_item);
+pause_item = new gui.MenuItem({
+  // pause menu item
+  label: '',
   type: 'normal',
+  click: function() {
+    if(paused) {post_start(socket);}
+    else {post_pause(socket);}
+  }
 });
-menu.append(progress_menu);
-window.setInterval(function() {
-  var status = globals['status']
-  var msg = 'Syncing'
-  if (status['paused']) msg = 'Paused'
-  progress_menu.label = msg + ' (' + status['progress'] + '%)';
-  tray.menu = menu;
-  get_status(socket);
-}, 5000);
+pause_item.enabled = false;
+menu.append(pause_item);
 
+// Update progress
+
+function reset_status() {
+  var status = globals['status'];
+  var new_progress = progress_item.label;
+  var new_pause = pause_item.label;
+  var menu_modified = false;
+  if (status['paused'] !== null) {
+    switch(pause_item.label) {
+      case pause_syncing: if (status['paused']) {
+          // Update to "Paused - start syncing"
+          paused = true;
+          new_pause = start_syncing;
+          progress_item.enabled = false;
+          menu_modified = true;
+        } // else continue syncing
+        new_progress = 'Progress: ' + status['progress'] + '%';
+      break;
+      case start_syncing: if (status['paused']) return;
+        // else update to "Syncing - pause syncing"
+        paused = false;
+        new_pause = pause_syncing;
+        progress_item.enabled = true;
+        new_progress = 'Progress: ' + status['progress'] + '%';
+        menu_modified = true;
+      break;
+      default:
+        if (status['paused']) {new_pause = start_syncing; paused=true;}
+        else {new_pause = pause_syncing; paused=false;}
+        new_progress = 'Progress: ' + status['progress'] + '%';
+        pause_item.enabled = true;
+        progress_item.enabled = true;
+        menu_modified = true;
+    }
+  }
+  if (new_pause != pause_item.label) {
+    pause_item.label = new_pause;
+    menu_modified = true;
+  }
+  if (new_progress != progress_item.label) {
+    progress_item.label = new_progress;
+    menu_modified = true;
+  }
+  if (menu_modified) tray.menu = menu;
+  get_status(socket);
+}
+window.setInterval(reset_status, 1000);
 
-// See contents
+// Menu actions contents
 menu.append(new gui.MenuItem({type: 'separator'}));
 menu.append(new gui.MenuItem({
   label: 'Open local folder',
   icon: 'icons/folder.png',
   click: function () {
-    gui.Shell.showItemInFolder('.');
+    var dir = globals['settings']['directory'];
+    console.log('Open ' + dir);
+    gui.Shell.showItemInFolder(dir);
   }
 }));
 
@@ -143,7 +223,9 @@ menu.append(new gui.MenuItem({
   label: 'Launch Pithos+ page',
   icon: 'icons/pithos.png',
   click: function () {
-    gui.Shell.openExternal('https://pithos.okeanos.grnet.gr');
+    var pithos_url = globals['settings']['pithos_url'];
+    console.log('Visit ' + pithos_url);
+    gui.Shell.openExternal(pithos_url);
   }
 }));
 
diff --git a/agkyra/protocol.py b/agkyra/protocol.py
index c9829fd..df115fd 100644
--- a/agkyra/protocol.py
+++ b/agkyra/protocol.py
@@ -16,6 +16,14 @@ class WebSocketProtocol(WebSocket):
     -- SHUT DOWN --
     GUI: {"method": "post", "path": "shutdown"}
 
+    -- PAUSE --
+    GUI: {"method": "post", "path": "pause"}
+    HELPER: {"OK": 200} or error
+
+    -- start --
+    GUI: {"method": "post", "path": "start"}
+    HELPER: {"OK": 200} or error
+
     -- GET SETTINGS --
     GUI: {"method": "get", "path": "settings"}
     HELPER:
@@ -34,6 +42,7 @@ class WebSocketProtocol(WebSocket):
             "url": <auth url>,
             "container": <container>,
             "directory": <local directory>,
+            "pithos_url": <pithos URL>,
             "exclude": <file path>
         }
     HELPER: {"CREATED": 201} or {<ERROR>: <ERROR CODE>}
@@ -45,20 +54,28 @@ class WebSocketProtocol(WebSocket):
 
     gui_id = None
     accepted = False
+    settings = dict(
+        token='token',
+        url=' https://accounts.okeanos.grnet.gr/identity/v2.0',
+        container='pithos',
+        directory='/tmp/.',
+        exclude='agkyra.log',
+        pithos_url='https://pithos.okeanos.grnet.gr/ui/')
+    status = dict(progress=-1, paused=False)
 
     # Syncer-related methods
     def get_status(self):
-        self.progress = getattr(self, 'progress', -1)
-        self.progress += 1
-        return dict(progress=self.progress, paused=False)
+        self.status['progress'] += 1
+        return self.status
 
     def get_settings(self):
-        return dict(
-            token='token',
-            url='http://www.google.com',
-            container='pithos',
-            directory='~/tmp',
-            exclude='agkyra.log')
+        return self.settings
+
+    def pause_sync(self):
+        self.status['paused'] = True
+
+    def start_sync(self):
+        self.status['paused'] = False
 
     # WebSocket connection methods
     def opened(self):
@@ -74,10 +91,17 @@ class WebSocketProtocol(WebSocket):
     # Protocol handling methods
     def _post(self, r):
         """Handle POST requests"""
+        LOG.debug('CALLED with %s' % r)
         if self.accepted:
-            if r['path'] == 'shutdown':
+            action = r['path']
+            if action == 'shutdown':
                 self.close()
-            raise KeyError()
+                return
+            {
+                'start': self.start_sync,
+                'pause': self.pause_sync
+            }[action]()
+            self.send_json({'OK': 200})
         elif r['gui_id'] == self.gui_id:
             self.accepted = True
             self.send_json({'ACCEPTED': 202})
@@ -115,11 +139,12 @@ class WebSocketProtocol(WebSocket):
             LOG.error('JSON ERROR: %s' % ve)
             return
         try:
+            method = r.pop('method')
             {
                 'post': self._post,
                 'put': self._put,
                 'get': self._get
-            }[r.pop('method')](r)
+            }[method](r)
         except KeyError as ke:
             self.send_json({'BAD REQUEST': 400})
             LOG.error('KEY ERROR: %s' % ke)
-- 
GitLab