From 555763dd8fba59a6fa5332d1faabef3076e925de Mon Sep 17 00:00:00 2001 From: Sinisa Veseli <sveseli@aps.anl.gov> Date: Mon, 6 Mar 2017 22:02:49 +0000 Subject: [PATCH] adding skeleton for station gui --- bin/dm-station-gui | 18 ++++++ .../dm/aps_beamline_tools/gui/__init__.py | 1 + .../dm/aps_beamline_tools/gui/daqsTab.py | 37 ++++++++++++ .../dm/aps_beamline_tools/gui/dmApiFactory.py | 44 ++++++++++++++ .../dm/aps_beamline_tools/gui/dmStationUi.py | 58 +++++++++++++++++++ .../aps_beamline_tools/gui/experimentsTab.py | 36 ++++++++++++ .../dm/aps_beamline_tools/gui/uploadsTab.py | 35 +++++++++++ .../dm/common/utility/configurationManager.py | 18 ++++++ .../daq_web_service/api/experimentDaqApi.py | 4 +- .../dm/ds_web_service/api/dsRestApiFactory.py | 7 +-- 10 files changed, 251 insertions(+), 7 deletions(-) create mode 100755 bin/dm-station-gui create mode 100644 src/python/dm/aps_beamline_tools/gui/__init__.py create mode 100644 src/python/dm/aps_beamline_tools/gui/daqsTab.py create mode 100755 src/python/dm/aps_beamline_tools/gui/dmApiFactory.py create mode 100755 src/python/dm/aps_beamline_tools/gui/dmStationUi.py create mode 100644 src/python/dm/aps_beamline_tools/gui/experimentsTab.py create mode 100644 src/python/dm/aps_beamline_tools/gui/uploadsTab.py diff --git a/bin/dm-station-gui b/bin/dm-station-gui new file mode 100755 index 00000000..55325469 --- /dev/null +++ b/bin/dm-station-gui @@ -0,0 +1,18 @@ +#!/bin/sh + +# Run command + +if [ -z $DM_ROOT_DIR ]; then + cd `dirname $0` && myDir=`pwd` + setupFile=$myDir/../setup.sh + if [ ! -f $setupFile ]; then + echo "Cannot find setup file: $setupFile" + exit 1 + fi + source $setupFile > /dev/null +fi +source $DM_ROOT_DIR/bin/dm_command_setup.sh + +eval "$DM_ROOT_DIR/src/python/dm/aps_beamline_tools/gui/dmStationUi.py $DM_COMMAND_ARGS" + + diff --git a/src/python/dm/aps_beamline_tools/gui/__init__.py b/src/python/dm/aps_beamline_tools/gui/__init__.py new file mode 100644 index 00000000..63426004 --- /dev/null +++ b/src/python/dm/aps_beamline_tools/gui/__init__.py @@ -0,0 +1 @@ +__version__ = "1.1 (2017.03.01)" diff --git a/src/python/dm/aps_beamline_tools/gui/daqsTab.py b/src/python/dm/aps_beamline_tools/gui/daqsTab.py new file mode 100644 index 00000000..1da1ab47 --- /dev/null +++ b/src/python/dm/aps_beamline_tools/gui/daqsTab.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +import wx +from dmApiFactory import DmApiFactory + +# Define the DAQs tab content: +class DaqsTab(wx.ListCtrl): + def __init__(self, stationName, parent, id=-1): + wx.ListCtrl.__init__(self, parent, id, style=wx.LC_REPORT) + self.stationName = stationName + self.experimentDaqApi = DmApiFactory.getInstance().getExperimentDaqApi() + + self.InsertColumn(0, 'Id') + self.InsertColumn(2, 'Data Directory') + self.InsertColumn(3, '# Files') + + self.SetColumnWidth(0, 150) + self.SetColumnWidth(1, 350) + self.SetColumnWidth(2, 250) + + self.updateList() + + def updateList(self): + self.daqList = self.experimentDaqApi.listDaqs() + + i = 0 + for daq in self.daqList: + print daq + self.InsertStringItem(i, daq.get('id')) + self.SetStringItem(i, 1, daq.get('dataDirectory', '')) + self.SetStringItem(i, 2, str(daq.get('nFiles', '0'))) + if (i % 2) == 0: + self.SetItemBackgroundColour(i, '#e6f1f5') + i += 1 + + + diff --git a/src/python/dm/aps_beamline_tools/gui/dmApiFactory.py b/src/python/dm/aps_beamline_tools/gui/dmApiFactory.py new file mode 100755 index 00000000..de3b6571 --- /dev/null +++ b/src/python/dm/aps_beamline_tools/gui/dmApiFactory.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python + +from dm.common.utility.singleton import Singleton +from dm.common.utility.loggingManager import LoggingManager +from dm.common.utility.configurationManager import ConfigurationManager + +class DmApiFactory(Singleton): + + + def __init__(self): + self.__configure() + + def __configure(self): + self.logger = LoggingManager.getInstance().getLogger(self.__class__.__name__) + configManager = ConfigurationManager.getInstance() + (self.username,self.password) = configManager.parseLoginFile() + self.protocol = configManager.getWebServiceProtocol() + self.dsHost = configManager.getDsWebServiceHost() + self.dsPort = configManager.getDsWebServicePort() + self.daqHost = configManager.getDaqWebServiceHost() + self.daqPort = configManager.getDaqWebServicePort() + + def getUserDsApi(self): + from dm.ds_web_service.api.userDsApi import UserDsApi + api = UserDsApi(self.username, self.password, self.dsHost, self.dsPort, self.protocol) + return api + + def getExperimentDsApi(self): + from dm.ds_web_service.api.experimentDsApi import ExperimentDsApi + api = ExperimentDsApi(self.username, self.password, self.dsHost, self.dsPort, self.protocol) + return api + + def getExperimentDaqApi(self): + from dm.daq_web_service.api.experimentDaqApi import ExperimentDaqApi + api = ExperimentDaqApi(self.username, self.password, self.daqHost, self.daqPort, self.protocol) + return api + + +#################################################################### +# Testing + +if __name__ == '__main__': + pass + diff --git a/src/python/dm/aps_beamline_tools/gui/dmStationUi.py b/src/python/dm/aps_beamline_tools/gui/dmStationUi.py new file mode 100755 index 00000000..bd2926cc --- /dev/null +++ b/src/python/dm/aps_beamline_tools/gui/dmStationUi.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python + +import sys +import wx + +from dm.common.constants import dmStatus +from dm.common.exceptions.dmException import DmException +from dm.common.exceptions.configurationError import ConfigurationError +from dm.common.utility.loggingManager import LoggingManager +from dm.common.utility.configurationManager import ConfigurationManager + +from experimentsTab import ExperimentsTab +from daqsTab import DaqsTab +from uploadsTab import UploadsTab + +class DmStationUi(wx.Frame): + def __init__(self): + self.__configure() + self.logger.debug('Starting UI for DM Station: %s' % self.stationName) + wx.Frame.__init__(self, None, title='DM Station: %s' % self.stationName, size=(900,500)) + + # Create a panel and notebook (tabs holder) + p = wx.Panel(self) + nb = wx.Notebook(p) + + # Create the tab windows + experimentsTab = ExperimentsTab(self.stationName, nb) + daqsTab = DaqsTab(self.stationName, nb) + uploadsTab = UploadsTab(self.stationName, nb) + + # Add the windows to tabs and name them. + nb.AddPage(experimentsTab, "Experiments") + nb.AddPage(daqsTab, "Real Time DAQs") + nb.AddPage(uploadsTab, "Data Uploads") + + # Set noteboook in a sizer to create the layout + sizer = wx.BoxSizer() + sizer.Add(nb, 1, wx.EXPAND) + p.SetSizer(sizer) + + def __configure(self): + self.logger = LoggingManager.getInstance().getLogger(self.__class__.__name__) + configManager = ConfigurationManager.getInstance() + self.stationName = configManager.getInstance().getStationName() + if not self.stationName: + raise ConfigurationError('DM_STATION_NAME environment variable is not defined.') + +if __name__ == "__main__": + try: + app = wx.App() + DmStationUi().Show() + app.MainLoop() + except DmException, ex: + print >>sys.stderr, 'ERROR: %s' % ex + raise SystemExit(ex.getErrorCode()) + except Exception, ex: + print >>sys.stderr, '%s' % ex + raise SystemExit(dmStatus.DM_ERROR) diff --git a/src/python/dm/aps_beamline_tools/gui/experimentsTab.py b/src/python/dm/aps_beamline_tools/gui/experimentsTab.py new file mode 100644 index 00000000..a4b28474 --- /dev/null +++ b/src/python/dm/aps_beamline_tools/gui/experimentsTab.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python + +import wx +from dmApiFactory import DmApiFactory + +# Define the experiments tab content: +class ExperimentsTab(wx.ListCtrl): + def __init__(self, stationName, parent, id=-1): + wx.ListCtrl.__init__(self, parent, id, style=wx.LC_REPORT) + self.stationName = stationName + self.experimentDsApi = DmApiFactory.getInstance().getExperimentDsApi() + + self.InsertColumn(0, 'Name') + self.InsertColumn(1, 'Description') + self.InsertColumn(2, 'Start Date') + + self.SetColumnWidth(0, 150) + self.SetColumnWidth(1, 500) + self.SetColumnWidth(2, 250) + + self.updateList() + + def updateList(self): + self.experimentList = self.experimentDsApi.getExperimentsByStation(self.stationName) + + i = 0 + for experiment in self.experimentList: + self.InsertStringItem(i, experiment.get('name')) + self.SetStringItem(i, 1, experiment.get('description', '')) + self.SetStringItem(i, 2, str(experiment.get('startDate', ''))) + if (i % 2) == 0: + self.SetItemBackgroundColour(i, '#e6f1f5') + i += 1 + + + diff --git a/src/python/dm/aps_beamline_tools/gui/uploadsTab.py b/src/python/dm/aps_beamline_tools/gui/uploadsTab.py new file mode 100644 index 00000000..1ed425d1 --- /dev/null +++ b/src/python/dm/aps_beamline_tools/gui/uploadsTab.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python + +import wx +from dmApiFactory import DmApiFactory + +# Define the experiments tab content: +class UploadsTab(wx.ListCtrl): + def __init__(self, stationName, parent, id=-1): + wx.ListCtrl.__init__(self, parent, id, style=wx.LC_REPORT) + self.stationName = stationName + self.experimentDaqApi = DmApiFactory.getInstance().getExperimentDaqApi() + + self.InsertColumn(0, 'Id') + self.InsertColumn(2, 'Data Directory') + self.InsertColumn(3, '# Files') + + self.SetColumnWidth(0, 150) + self.SetColumnWidth(1, 350) + self.SetColumnWidth(2, 250) + + self.updateList() + + def updateList(self): + self.uploadList = self.experimentDaqApi.listUploads() + + i = 0 + for upload in self.uploadList: + self.InsertStringItem(i, upload.get('id')) + self.SetStringItem(i, 1, upload.get('dataDirectory', '')) + self.SetStringItem(i, 2, str(upload.get('nFiles', '0'))) + if (i % 2) == 0: + self.SetItemBackgroundColour(i, '#e6f1f5') + i += 1 + + diff --git a/src/python/dm/common/utility/configurationManager.py b/src/python/dm/common/utility/configurationManager.py index 09c20cd2..af29ba51 100755 --- a/src/python/dm/common/utility/configurationManager.py +++ b/src/python/dm/common/utility/configurationManager.py @@ -924,6 +924,24 @@ class ConfigurationManager(UserDict.UserDict): def hasBeamlineManagers(self): return self.has_key('beamlineManagers') + # Parse given login file for username/password + # Assume form <username><delimiter><password> + def parseLoginFile(self, loginFile=None, delimiter='|'): + username = None + password = None + if not loginFile: + loginFile = self.getLoginFile() + if not loginFile: + raise ConfigurationError('DM login file is not defined.') + try: + tokenList = open(loginFile).readline().split(delimiter) + if len(tokenList) == 2: + username = tokenList[0].strip() + password = tokenList[1].strip() + except Exception, ex: + raise ConfigurationError('Cannot parse login file %s: ex.' % (loginFile, ex)) + return (username,password) + ####################################################################### # Testing. diff --git a/src/python/dm/daq_web_service/api/experimentDaqApi.py b/src/python/dm/daq_web_service/api/experimentDaqApi.py index cb68f542..4dc9f83f 100755 --- a/src/python/dm/daq_web_service/api/experimentDaqApi.py +++ b/src/python/dm/daq_web_service/api/experimentDaqApi.py @@ -239,7 +239,7 @@ class ExperimentDaqApi(DaqRestApi): :raises DmException: in case of any other errors - >>> uplaodInfo = api.getUploadInfo('84311a75-c88b-4605-8948-08257eae6f5c') + >>> uploadInfo = api.getUploadInfo('84311a75-c88b-4605-8948-08257eae6f5c') >>> uploadStatus = uploadInfo.get('status') ''' @@ -292,7 +292,7 @@ class ExperimentDaqApi(DaqRestApi): :raises DmException: in case of any other errors - >>> uplaodInfo = api.stopUpload('84311a75-c88b-4605-8948-08257eae6f5c') + >>> uploadInfo = api.stopUpload('84311a75-c88b-4605-8948-08257eae6f5c') >>> print uploadInfo.get('nCompletedFiles') ''' url = '%s/experimentUploads/stopUpload/%s' % (self.getContextRoot(),id) diff --git a/src/python/dm/ds_web_service/api/dsRestApiFactory.py b/src/python/dm/ds_web_service/api/dsRestApiFactory.py index 2b39f81b..e74c1700 100755 --- a/src/python/dm/ds_web_service/api/dsRestApiFactory.py +++ b/src/python/dm/ds_web_service/api/dsRestApiFactory.py @@ -52,11 +52,7 @@ class DsRestApiFactory: @classmethod def getExperimentDsApi(cls): from experimentDsApi import ExperimentDsApi - try: - (username, password, host, port, protocol) = cls.__getConfiguration() - except Exception, ex: - print ex - raise + (username, password, host, port, protocol) = cls.__getConfiguration() api = ExperimentDsApi(username, password, host, port, protocol) return api @@ -66,6 +62,7 @@ class DsRestApiFactory: (username, password, host, port, protocol) = cls.__getConfiguration() api = FileDsApi(username, password, host, port, protocol) return api + #################################################################### # Testing -- GitLab