diff --git a/ExperimentDetails-srv.py b/ExperimentDetails-srv.py index 3aac624d036973706ec453df4306c53d4dae06f3..0456016de10e55471851deb8f138792537561aa0 100755 --- a/ExperimentDetails-srv.py +++ b/ExperimentDetails-srv.py @@ -5,7 +5,7 @@ # # file : Experiment_Details.py # -# description : Python source for the Experiment_Details and its commands. +# description : Python source for the Experiment_Details and its commands. # The class is derived from Device. It represents the # CORBA servant object which will be accessed from the # network. All commands which can be executed on the @@ -64,7 +64,7 @@ class Experiment_Details(PyTango.Device_4Impl): # Device destructor #------------------------------------------------------------------ def delete_device(self): - print "[Device delete_device method] for device",self.get_name() + print ("[Device delete_device method] for device",self.get_name()) #------------------------------------------------------------------ @@ -82,6 +82,7 @@ class Experiment_Details(PyTango.Device_4Impl): self.StorageMngrDev = None self.ProposalList = [] self.InvestigationList = [] + self.ActionLog = [] self.free_space_readout_time = 0 self.attr_FreeSpaceScratch_read = 0 self.attr_FreeSpaceOnline_read = 0 @@ -109,9 +110,10 @@ class Experiment_Details(PyTango.Device_4Impl): self.UserId = attr_prop['__value'][0] # if self.Logged_in: - self.retrieve_proposal_investigations() if len(self.ActiveInvestigation.strip()): self.set_active_investigation() + else: + self.retrieve_proposal_investigations() #------------------------------------------------------------------ @@ -125,7 +127,7 @@ class Experiment_Details(PyTango.Device_4Impl): if (time.time() - self.last_time_activity) > (2 * 86400): self.Logout() self.last_time_activity = time.time() - + #================================================================== @@ -147,9 +149,9 @@ class Experiment_Details(PyTango.Device_4Impl): #------------------------------------------------------------------ def read_UserLogin(self, attr): #print "In ", self.get_name(), "::read_UserLogin()" - + # Add your own code here - + attr_User_read = self.UserLogin attr.set_value(attr_User_read) @@ -160,12 +162,13 @@ class Experiment_Details(PyTango.Device_4Impl): def write_UserLogin(self, attr): #print "In ", self.get_name(), "::write_UserLogin()" self.UserLogin = attr.get_write_value() - #------------------------------------------------------------------ + +#------------------------------------------------------------------ # Read ActiveInvestigation attribute #------------------------------------------------------------------ def read_ActiveInvestigation(self, attr): #print "In ", self.get_name(), "::read_ActiveInvestigation()" - + # Add your own code here attr_ActiveInvestigation_read = self.ActiveInvestigation attr.set_value(attr_ActiveInvestigation_read) @@ -176,7 +179,7 @@ class Experiment_Details(PyTango.Device_4Impl): #------------------------------------------------------------------ def write_ActiveInvestigation(self, attr): #print "In ", self.get_name(), "::write_ActiveInvestigation()" - + # Add your own code here #if not self.Logged_in: # raise Exception("User not logged in!") @@ -191,7 +194,7 @@ class Experiment_Details(PyTango.Device_4Impl): #------------------------------------------------------------------ def read_Logged_in(self, attr): #print "In ", self.get_name(), "::read_Logged_in()" - + # Add your own code here attr_Logged_in_read = self.Logged_in attr.set_value(attr_Logged_in_read) @@ -201,9 +204,9 @@ class Experiment_Details(PyTango.Device_4Impl): #------------------------------------------------------------------ def read_UserId(self, attr): #print "In ", self.get_name(), "::read_UserId()" - + # Add your own code here - + attr_UserId_read = self.UserId attr.set_value(attr_UserId_read) @@ -213,7 +216,7 @@ class Experiment_Details(PyTango.Device_4Impl): #------------------------------------------------------------------ def read_StaffMember(self, attr): #print "In ", self.get_name(), "::read_StaffMember()" - + # Add your own code here attr_StaffMember_read = self.StaffMember attr.set_value(attr_StaffMember_read) @@ -224,7 +227,7 @@ class Experiment_Details(PyTango.Device_4Impl): #------------------------------------------------------------------ def read_DataPath(self, attr): #print "In ", self.get_name(), "::read_DataPath()" - + # Add your own code here attr_DataPath_read = self.DataPath attr.set_value(attr_DataPath_read) @@ -242,9 +245,9 @@ class Experiment_Details(PyTango.Device_4Impl): #------------------------------------------------------------------ def read_ProposalList(self, attr): #print "In ", self.get_name(), "::read_ProposalList()" - + # Add your own code here - + attr_ProposalList_read = self.ProposalList attr.set_value(attr_ProposalList_read) @@ -253,9 +256,9 @@ class Experiment_Details(PyTango.Device_4Impl): #------------------------------------------------------------------ def read_InvestigationList(self, attr): #print "In ", self.get_name(), "::read_InvestigationList()" - + # Add your own code here - + attr_InvestigationList_read = self.InvestigationList attr.set_value(attr_InvestigationList_read) @@ -264,7 +267,7 @@ class Experiment_Details(PyTango.Device_4Impl): #------------------------------------------------------------------ def read_FreeSpaceScratch(self, attr): #print "In ", self.get_name(), "::read_FreeSpaceScratch()" - + # Add your own code here self.update_disk_usage_info() attr.set_value(self.attr_FreeSpaceScratch_read) @@ -275,7 +278,7 @@ class Experiment_Details(PyTango.Device_4Impl): #------------------------------------------------------------------ def read_FreeSpaceOnline(self, attr): #print "In ", self.get_name(), "::read_FreeSpaceOnline()" - + # Add your own code here self.update_disk_usage_info() attr.set_value(self.attr_FreeSpaceOnline_read) @@ -285,7 +288,7 @@ class Experiment_Details(PyTango.Device_4Impl): #------------------------------------------------------------------ def read_FreeSpaceScratch_TB(self, attr): #print "In ", self.get_name(), "::read_FreeSpaceScratch_TB()" - + # Add your own code here self.update_disk_usage_info() attr.set_value(self.attr_FreeSpaceScratch_TB_read) @@ -296,11 +299,21 @@ class Experiment_Details(PyTango.Device_4Impl): #------------------------------------------------------------------ def read_FreeSpaceOnline_TB(self, attr): #print "In ", self.get_name(), "::read_FreeSpaceOnline_TB()" - + # Add your own code here self.update_disk_usage_info() attr.set_value(self.attr_FreeSpaceOnline_TB_read) +#------------------------------------------------------------------ +# Read ActionLog attribute +#------------------------------------------------------------------ + def read_ActionLog(self, attr): + #print "In ", self.get_name(), "::read_ActionLog()" + + # Add your own code here + + attr_ActionLog_read = self.ActionLog + attr.set_value(attr_ActionLog_read) #================================================================== # @@ -311,24 +324,16 @@ class Experiment_Details(PyTango.Device_4Impl): # Login() #------------------------------------------------------------------ def Login(self, password): - if self.StorageMngrDev == None: - self.connect_to_storage_manager() - # self.StaffMember = False - # - arg_in = [self.UserLogin,password,self.TAG] - resp = self.StorageMngrDev.Authenticate(arg_in) - if resp.find("OK:") < 0: - self.Logged_in = False - raise Exception("User authentication failed!") - else: - only_resp = (resp.upper().split("OK:")[-1]).rstrip("\n") - self.UserId = only_resp.split(":")[0] - if only_resp.find(":ADMIN") > 0: - self.StaffMember = True - # - self.Logged_in = True - self.retrieve_proposal_investigations() + self.Logged_in = False + resp = self.CheckCredentials([self.UserLogin,password]) + only_resp = (resp.upper().split("OK:")[-1]).rstrip("\n") + self.UserId = only_resp.split(":")[0] + if only_resp.find(":ADMIN") > 0: + self.StaffMember = True + self.log_action("Authenticated user is staff member") + self.Logged_in = True + self.retrieve_proposal_investigations() self.memorize_status() #------------------------------------------------------------------ @@ -341,8 +346,25 @@ class Experiment_Details(PyTango.Device_4Impl): self.ProposalList = [] self.InvestigationList = [] self.StaffMember = False + self.log_action("Authenticated user logout") self.memorize_status() +#------------------------------------------------------------------ +# Login() +#------------------------------------------------------------------ + def CheckCredentials(self, argin): + if self.StorageMngrDev == None: + self.connect_to_storage_manager() + UserLogin = argin[0] + password = argin[1] + arg_in = [UserLogin,password,self.TAG] + self.log_action("CheckCredentials user %s" % UserLogin) + resp = self.StorageMngrDev.Authenticate(arg_in) + self.log_action("CheckCredentials reply %s" % resp.strip()) + if resp.find("OK:") < 0: + raise Exception("User authentication failed!") + return resp.strip() + #------------------------------------------------------------------ # Dump status into DB @@ -360,7 +382,7 @@ class Experiment_Details(PyTango.Device_4Impl): #------------------------------------------------------------------ def retrieve_proposal_investigations(self): if self.StorageMngrDev == None: - self.connect_to_storage_manager() + self.connect_to_storage_manager() resp = self.StorageMngrDev.ListProposal([self.UserId, self.TAG]) if resp.upper().find("OK:") >= 0: self.ProposalList = resp.split(":") @@ -383,28 +405,62 @@ class Experiment_Details(PyTango.Device_4Impl): # Set Active Investigation #------------------------------------------------------------------ def set_active_investigation(self): - - arg_in = [self.UserId, self.TAG, self.ActiveInvestigation, self.ActiveInvestigation] - + self.log_action("set_active_investigation %s" % self.ActiveInvestigation) + self.retrieve_proposal_investigations() if self.ActiveInvestigation in self.InvestigationList: - # Investigation already created - res = 'OK' - elif self.ActiveInvestigation in self.ProposalList: - arg_in.pop() - res=self.StorageMngrDev.command_inout("CreateInvestigationFromProposal",arg_in) - else: - res=self.StorageMngrDev.command_inout("CreateInvestigation",arg_in) + # Investigation already created + res = 'OK' + self.log_action("investigation already exists") + return + arg_in = [self.UserId, self.TAG, self.ActiveInvestigation, self.ActiveInvestigation] + proposalFound = False + for proposal in self.ProposalList: + if self.ActiveInvestigation.startswith(proposal): + arg_in[2] = proposal + proposalFound = True + self.log_action("found an existing proposal: %s" % proposal) + break + if not proposalFound and self.ActiveInvestigation[:8].isdigit(): + # VUO proposals with a corresponding Investigation are not listed in + # self.ProposalList, let's suppose that the first part is a propsal ID + proposal = self.ActiveInvestigation[:8] + if self.StaffMember: + # special case of a staff memeber + arg_in[2] = proposal + proposalFound = True + self.log_action("staff member will try this proposal: %s" % proposal) + else: + # normal case of an external memeber + for Investigation in self.InvestigationList: + if Investigation.startswith(proposal): + arg_in[2] = proposal + self.log_action("user will try this proposal: %s" % proposal) + proposalFound = True + break + if proposalFound: + res=self.StorageMngrDev.command_inout("CreateInvestigationFromProposal",arg_in) + self.log_action("CreateInvestigationFromProposal() reply %s" % res) + if res[:2] =='OK': + return + res = self.StorageMngrDev.command_inout("CreateInvestigation",arg_in) + self.log_action("CreateInvestigation() reply %s" % res) if res[:2]!='OK': - print res - self.ActiveInvestigation = "" - raise Exception("Create Investigation Failed!") + self.ActiveInvestigation = "" + raise Exception("Create Investigation Failed!") +#------------------------------------------------------------------ +# Action internal log +#------------------------------------------------------------------ + def log_action(self, msg): + self.ActionLog.append(msg) + self.ActionLog = self.ActionLog[-100:] #------------------------------------------------------------------ # Storage manager connection #------------------------------------------------------------------ def connect_to_storage_manager(self): - self.StorageMngrDev = PyTango.DeviceProxy(self.StorageManagerDevice) + self.StorageMngrDev = PyTango.DeviceProxy(self.StorageManagerDevice) + self.StorageMngrDev.set_timeout_millis(10000) #------------------------------------------------------------------ # Update disk usage info @@ -451,6 +507,9 @@ class Experiment_DetailsClass(PyTango.DeviceClass): # Command definitions cmd_list = { + 'CheckCredentials': + [[PyTango.DevVarStringArray,"Username,Password"], + [PyTango.DevString,""]], 'Login': [[PyTango.DevString,"Password"], [PyTango.DevVoid,""]], @@ -538,7 +597,11 @@ class Experiment_DetailsClass(PyTango.DeviceClass): 'unit':"TB", 'standard unit':"TB", 'display unit':"TB", - } ] + } ], + 'ActionLog': + [[PyTango.DevString, + PyTango.SPECTRUM, + PyTango.READ,100]] } @@ -548,7 +611,6 @@ class Experiment_DetailsClass(PyTango.DeviceClass): def __init__(self, name): PyTango.DeviceClass.__init__(self, name) self.set_type(name); - print "In Experiment_DetailsClass constructor" #================================================================== # @@ -564,7 +626,7 @@ if __name__ == '__main__': U.server_init() U.server_run() - except PyTango.DevFailed,e: - print '-------> Received a DevFailed exception:',e - except Exception,e: - print '-------> An unforeseen exception occured....',e + except PyTango.DevFailed as e: + print ('-------> Received a DevFailed exception:',e) + except Exception as e: + print ('-------> An unforeseen exception occured....',e)