config with options
authorThierry Parmentelat <thierry.parmentelat@sophia.inria.fr>
Fri, 10 Sep 2010 14:33:20 +0000 (16:33 +0200)
committerThierry Parmentelat <thierry.parmentelat@sophia.inria.fr>
Fri, 10 Sep 2010 14:33:20 +0000 (16:33 +0200)
sface.py
sface/screens/configscreen.py
sface/screens/mainscreen.py
sface/sficonfig.py
sface/sfiprocess.py

index f719257..ad91372 100644 (file)
--- a/sface.py
+++ b/sface.py
@@ -1,10 +1,12 @@
-
 import sys
 sys.path.append(".")
 
+from optparse import OptionParser
+
 from PyQt4.QtGui import *
-from sface.sfawindow import SfaWindow
 
+from sface.sfawindow import SfaWindow
+from sface.sficonfig import config
 
 def main(args):
     app = QApplication(args)
@@ -30,4 +32,9 @@ QLabel {
 
 
 if __name__ == "__main__":
+    parser=OptionParser()
+    config.add_options_to_OptionParser(parser)
+    (options,args)=parser.parse_args()
+    config.update_from_OptionParser(options)
+    config.display("After command-line")
     main(sys.argv)
index 3ea4cb8..6b8e86b 100644 (file)
@@ -1,6 +1,6 @@
 
 from PyQt4.QtCore import SIGNAL, Qt
-from PyQt4.QtGui import QWidget, QLabel, QLineEdit, QPushButton, QVBoxLayout, QSizePolicy
+from PyQt4.QtGui import QWidget, QLabel, QLineEdit, QPushButton, QCheckBox, QVBoxLayout, QSizePolicy
 
 from sface.sficonfig import config
 from sface.screens.sfascreen import SfaScreen
@@ -9,29 +9,43 @@ class ConfigWidget(QWidget):
     def __init__(self, parent):
         QWidget.__init__(self, parent)
 
-        label1 = QLabel("User HRN:", self)
-        self.user = QLineEdit(config.getUser(), self)
-        self.user.setAttribute(Qt.WA_MacShowFocusRect, 0)
-        label2 = QLabel("Slice HRN:", self)
-        self.slice = QLineEdit(config.getSlice(), self)
-        self.slice.setAttribute(Qt.WA_MacShowFocusRect, 0)
-        apply = QPushButton("Apply", self)
-        apply.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
-        
         layout = QVBoxLayout()
-        layout.addWidget(label1)
-        layout.addWidget(self.user)
-        layout.addWidget(label2)
-        layout.addWidget(self.slice)
-        layout.addWidget(apply, 0, Qt.AlignRight)
-        layout.addStretch()
+        for (field,msg) in config.field_labels():
+            # label
+            layout.addWidget(QLabel(msg,self))
+            # edit : text or checkbox
+            default=config.field_default(field)
+            if isinstance(default,bool):
+                edit=QCheckBox(msg)
+                edit.setCheckState(config.get(field))
+            else:
+                edit=QLineEdit(config.get(field), self)
+                edit.setAttribute(Qt.WA_MacShowFocusRect, 0)
+            setattr(self,field,edit)
+            layout.addWidget (edit)
+
+        for (action,label) in [('apply','Apply'),
+                               ('save','Apply & Save')]:
+            button=QPushButton(label, self)
+            button.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
+            layout.addWidget(button, 0, Qt.AlignRight)
+            layout.addStretch()
+            self.connect(button, SIGNAL('clicked()'), getattr(self,action))
         self.setLayout(layout)
 
-        self.connect(apply, SIGNAL('clicked()'), self.apply)
 
     def apply(self):
-        config.setUser("%s" % self.user.text())
-        config.setSlice("%s" % self.slice.text())
+        for field in config.fields():
+            widget=getattr(self,field)
+            if isinstance(widget,QCheckBox):
+                config.set(field,widget.checkState())
+            else:
+                config.set(field,str(widget.text()))
+        self.parent().setStatus("<font color='green'>Settings loaded for current session</font>",timeout=5000)
+        config.display("after apply")
+
+    def save(self):
+        self.apply()
         config.save_config()
         self.parent().setStatus("<font color='green'>Configuration saved!</font>", timeout=3000)
         
@@ -41,4 +55,4 @@ class ConfigScreen(SfaScreen):
         SfaScreen.__init__(self, parent)
         
         widget = ConfigWidget(self)
-        self.init(widget, "Configure", "Configure the PlanetLab Federation GUI")
+        self.init(widget, "Configure", "Configure the OneLab Federation GUI")
index ccbe8dd..4b636bc 100644 (file)
@@ -232,4 +232,4 @@ class MainScreen(SfaScreen):
         SfaScreen.__init__(self, parent)
 
         slice = SliceWidget(self)
-        self.init(slice, "Main Window", "PlanetLab Federation GUI")
+        self.init(slice, "Main Window", "OneLab Federation GUI")
index 2ff64e7..542734e 100644 (file)
+# config for sface 
+# uses in this order
+# command-line args
+# ~/.sfi/sfi_config
+###
 
 import os
+from optparse import OptionParser
+
 
 class SfiConfig:
-    defaults = { 'SFI_AUTH' : None,
-                 'SFI_USER' : None,
-                 'SFI_SLICE' : None,
-                 'SFI_REGISTRY' : "http://www.planet-lab.org:12345",
-                 'SFI_AM' : "http://www.planet-lab.org:12346",
-                 'SFI_SM' : "http://www.planet-lab.org:12347",
-                 'SFACE_VERBOSE' : False,
-                 'SFACE_DEBUG' : False,
-                 }
+
+    d_registry= "http://www.planet-lab.org:12345"
+    d_slicemgr= "http://www.planet-lab.org:12347"
+    d_aggmgr=   "http://www.planet-lab.org:12346"
+
+    supported = [
+        # local code name, config variable name, default
+        ('slice',      'SFI_SLICE' ,   None,           '-s','--slice',         "slice HRN"),
+        ('user',       'SFI_USER',     None,           '-u','--user',          "user HRN"),
+        ('authority',  'SFI_AUTH',     None,           '-t','--auth',          "users's authority HRN"),
+        ('registry',   'SFI_REGISTRY', d_registry,     '-r','--registry',      "registry's URL"),
+        ('slicemgr',   'SFI_SM' ,      d_slicemgr,     '-m','--slicemgr',      "slice manager's URL"),
+        ('aggmgr',     'SFI_AM',       d_aggmgr,       '-a','--aggregate',     "aggregate manager's URL"),
+        ('verbose',    'SFACE_VERBOSE',False,          '-v','--verbose',       "UI verbosity"),
+        ('debug',      'SFACE_DEBUG',  False,          '-d','--debug',         "UI debug flag"),
+        ]
+
+    def fields (self):
+        return [ tup[0] for tup in SfiConfig.supported ]
+
+    def field_labels (self):
+        return [ (tup[0],tup[5]) for tup in SfiConfig.supported ]
+
+    def sfi_field (self, sfi):
+        for tuple in SfiConfig.supported:
+            if tuple[1]==sfi: return tuple[0]
+        return None
+
+    def field_default (self, field):
+        for tuple in SfiConfig.supported:
+            if tuple[0]==field: return tuple[2]
+        return None
+
+    # xxx todo - need for validators - not even sure this is still useful
+    def define_accessors (self):
+        for (field,sfi,default,_,__,___) in SfiConfig.supported:
+            self.define_accessor (field,sfi,default)
+
+    def define_accessor (self,field,sfi,default):
+        get_name="get" + field.capitalize();
+        if not hasattr(SfiConfig,get_name):
+            def get_call (self): return getattr(self,field)
+            setattr (SfiConfig, get_name, get_call)
+        set_name="set" + field.capitalize();
+        if not hasattr(SfiConfig,set_name):
+            def set_call (self, newvalue): setattr (self, field, newvalue)
+            setattr (SfiConfig, set_name, set_call)
+
+    # the generic form of accessors
+    def get(self,field): return getattr(self,field)
+    def set(self,field,value): setattr(self,field,value)
 
     def __init__(self):
         self.read_config()
 
+    def filename (self):
+        return os.path.expanduser("~/.sfi/sfi_config")
+
     def read_config(self):
-        filename = os.path.expanduser("~/.sfi/sfi_config")
-        execfile(filename, SfiConfig.__dict__)
-        for (k,v) in SfiConfig.defaults.items():
-            if not hasattr(SfiConfig,k): setattr(SfiConfig,k,v)
-        if SfiConfig.SFACE_VERBOSE:
-            print "After reading config from %s"%filename
-            for (k,v) in SfiConfig.defaults.items():
-                print "%-20s: %r"%(k,getattr(SfiConfig,k))
+        tmp={}
+        try:
+            execfile(self.filename(), tmp)
+        except:
+            print "Warning - no config file found %s"%self.filename()
+            pass
+        for (field,sfi,default,_,__,___) in SfiConfig.supported:
+            if tmp.has_key(sfi):setattr(self,field,tmp[sfi])
+            else:               setattr(self,field,default)
+        self.display("After reading config from %s"%self.filename())
+
+    def display (self, msg):
+        if self.debug:
+            print msg
+            for k in self.fields():
+                print "%-20s: %r"%(k,getattr(self,k))
 
     def save_config(self):
-        config_keys = SfiConfig.defaults.keys()
-        configfile = os.path.expanduser("~/.sfi/sfi_config")
+        configfile = self.filename()
         tmpfile = configfile + ".tmp"
 
         out = open(tmpfile, "w")
-        for line in open(os.path.expanduser("~/.sfi/sfi_config")):
+        lineno=0
+        fields=self.fields()
+        for line in open(configfile):
+            lineno += 1
             try:
-                key, val = line.split('=')
-                key = key.strip()
+                sfi, val = line.split('=')
+                sfi = sfi.strip()
                 val = val.strip()
-                if key in config_keys:
-                    line = "%s = '%s'\n" % (key, getattr(self, key))
+                field=self.sfi_field(sfi)
+                if field:
+                    line = "%s = '%s'\n" % (sfi, getattr(self, field))
             except:
-                pass
+                if self.debug:
+                    import traceback
+                    print 'line',lineno,'ignored',line
             out.write(line)
         out.close()
 
         os.unlink(configfile)
         os.rename(tmpfile, configfile)
-                    
-
-    def getAuthority(self):
-        return SfiConfig.SFI_AUTH
-
-    def getUser(self):
-        return SfiConfig.SFI_USER
-
-    def setUser(self, user):
-        SfiConfig.SFI_USER = user
 
-        # Should probably get authority from user record instead...
-        a = user.split('.')
-        SfiConfig.SFI_AUTH = '.'.join(a[:len(a)-1])
-
-    def getSlice(self):
-        return SfiConfig.SFI_SLICE
-
-    def setSlice(self, slice):
-        SfiConfig.SFI_SLICE = slice
-
-    def registry(self):
-        return SfiConfig.SFI_REGISTRY
-
-    def slicemgr(self):
-        return SfiConfig.SFI_SM
-
-    def aggmgr(self):
-        return SfiConfig.SFI_AM
+    def add_options_to_OptionParser (self, parser):
+        for (field,_,default,short,long,msg) in SfiConfig.supported:
+            if default==True or default==False:
+                parser.add_option(short,long,dest=field,action="store_true",help=msg)
+            else:
+                parser.add_option(short,long,dest=field,action="store",default=None, help=msg)
+
+    def update_from_OptionParser (self, optparse_options):
+        for field in self.fields():
+            if not hasattr(optparse_options,field) : continue
+            value=getattr(optparse_options,field)
+            if value is not None:
+                setattr(self,field,getattr(optparse_options,field))
+        
+#    def setUser(self, user):
+#        SfiConfig.SFI_USER = user
+#
+#        # Should probably get authority from user record instead...
+#        a = user.split('.')
+#        SfiConfig.SFI_AUTH = '.'.join(a[:len(a)-1])
 
     def getSliceRSpecFile(self):
         return os.path.expanduser("~/.sfi/%s.rspec" % self.getSlice())
@@ -81,3 +138,4 @@ class SfiConfig:
 
 # configuration singleton
 config = SfiConfig()
+config.define_accessors()
index 27c5b7c..05199c9 100644 (file)
@@ -25,6 +25,9 @@ class SfiProcess(QObject):
             self.args << QString(arg)
 
         self.exe = find_executable("sfi.py")
+        if not self.exe:
+            print "FATAL.. Could not locate binary sfi.py - not much we can do without that"
+
         self.process = QProcess()
 
         self.connect(self.process, SIGNAL("finished(int, QProcess::ExitStatus)"),
@@ -43,7 +46,7 @@ class SfiProcess(QObject):
         except:
             pass
         args = ["-u", config.getUser(), "-a", config.getAuthority(), 
-                "-r", config.registry(), "-s", mgr, "resources", 
+                "-r", config.getRegistry(), "-s", mgr, "resources", 
                 "-o", filename, slice]
 
         self.__init_command(args)
@@ -51,14 +54,14 @@ class SfiProcess(QObject):
         return filename
 
     def getRSpecFromSM(self):
-        return self.__getRSpec(config.slicemgr())
+        return self.__getRSpec(config.getSlicemgr())
 
     def getRSpecFromAM(self):
-        return self.__getRSpec(config.aggmgr())
+        return self.__getRSpec(config.getAggmgr())
 
     def getRecord(self, hrn):
         args = ["-u", config.getUser(), "-a", config.getAuthority(), 
-                "-r", config.registry(), "-s", config.slicemgr(), "show", hrn]
+                "-r", config.getRegistry(), "-s", config.getSlicemgr(), "show", hrn]
         self.__init_command(args)
         self.start()
 
@@ -71,12 +74,12 @@ class SfiProcess(QObject):
             return self.process.readAll()
 
     def trace_command (self):
-        if config.SFACE_VERBOSE:
+        if config.verbose:
             self._trace=time.time()
             command = "%s %s" % (self.exe, self.args.join(" "))
             print time.strftime('%M:%S'),'Invoking',command
 
     def trace_end (self):
-        if config.SFACE_VERBOSE:
+        if config.verbose:
             command = "%s %s" % (self.exe, self.args.join(" "))
             print time.strftime('%M:%S'),"[%.3f s]"%(time.time()-self._trace),command,'Done'