#! python: #w#VIC process.py module # # Copyright 2002, 2003 by Timothy Rue <3seas@threeseas.net> # # VIC process.py module: version 0.5.1.python (BETA) # # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation version 2 # of the License. http://www.gnu.org/copyleft/gpl.html # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Or access http://www.gnu.org/copyleft/gpl.html ########################################################################## #August 29, 2003 made file IQ parseable 0.5.1 #July 24, 2003 initial release 0.5 # ########################################################################## #s#system modules import os import os.path import string #s#local modules import files from vic_mutex import * #w#class Process class Process: "Complete VIC State" #s#def __init__ def __init__(self,name,id,room_path): ### create the new default state self.id = id self.name = name if (self.name == ''): self.name = 'vic' self.room_path = room_path if (self.room_path[-1] != os.sep): self.room_path = self.room_path + os.sep self.default_values = self.setOfDefaultValues() self.values = self.setOfDefaultValues() self.vars = {} self.var_tags = {} self.script_path = "" self.script = [] self.script_line = 0 self.pending_commands = [] ### Get the directories created and disk files stored if (self.name == ""): self.room_name = "vic." + self.id ### Room name is also the 'name' of this VIC else: self.room_name = self.name + "." + self.id self.full_room_path = self.room_path + self.room_name + os.sep files.makeDir(self.full_room_path) self.values['AI'] = [ self.room_name , self.full_room_path + "default.pk" , self.full_room_path ] self.saveFiles() ### ----------------------------------------------------------------- #s#def getRoomName def getRoomName(self): return self.room_name #s#def getRoom def getRoomPath(self): return self.full_room_path #s#def getName def getName(self): return self.name #s#def getNumber def getNumber(self): return self.id #s#def savePKFile def savePKFile(self,filename=None): if (filename == None): filename = self.values['PK'][0] if (files.isPlainFilename(filename)): filename = self.full_room_path+filename return self.saveValuesTo(filename) #s#def saveOIFile def saveOIFile(self,filename=None): if (filename == None): filename = self.values['PK'][0] filename = self.values['OI'][0] if (files.isPlainFilename(filename)): filename = self.full_room_path+filename return self.saveVarsTo(filename) #s#def reloadOIFile def reloadOIFile(self,filename=None): self.eraseAllVars() if (filename == None): filename = self.values['OI'][0] if (files.isPlainFilename(filename)): filename = self.full_room_path+filename return self.loadVarsFrom(filename) #s#def saveFiles def saveFiles(self): errors = 0 errors = errors + self.savePKFile() errors = errors + self.saveOIFile() return (errors != 0) #s#def saveOI def saveOI(self): return self.saveOIFile() ### ----------------------------------------------------------------- #s#def adPendingCommand def addPendingCommand(self,command): self.pending_commands.append(command) #s#def getPendingCommand def getPendingCommand(self): command = None if (len(self.pending_commands) > 0): command = self.pending_commands[0] del self.pending_commands[0] return command #s#def anyPendingCommands def anyPendingCommands(self): return len(self.pending_commands) #s#def getPendingCommands def getPendingCommands(self): return self.pending_commands ### ----------------------------------------------------------------- #s#def HandleOutPut def handleOutput(self,output): ### Extract and logging flags & filename from SF sf_flags = self.values['SF'][0] tee_file = "" if (string.count(sf_flags,'T ') > 0): tee_file = sf_flags.split('T ',1)[1] redirect_file = "" if (string.count(sf_flags,'R ') > 0): tee_file = sf_flags.split('R ',1)[1] ### If we need to do anything with the output, do it here if (tee_file != ""): f = open(self.full_room_path + tee_file,"a") ### Write to file as well as output if (f): f.write(output) f.close() if (redirect_file != ""): f = open(self.full_room_path + redirect_file,"a") if (f): f.write(output) f.close() output = "" ### Supposed to 'redirect', so consume the input return output ### ----------------------------------------------------------------- #s#def getFieldDefault def getFieldDefault(self,tag): return self.default[tag][2] #s#def getFieldAlternate def getFieldAlternate(self,tag): return self.default[tag][1] #s#def getFieldCurrent def getFieldCurrent(self,tag): return self.default[tag][0] #s#def getFieldStrCurrent def getFieldStrCurrent(self,tag): return self.getFieldStr(tag,0) #s#def getFieldStrDefault def getFieldStrDefault(self,tag): return self.getFieldStr(tag,2) #s#def getFieldStrAlternate def getFieldStrAlternate(self,tag): return self.getFieldStr(tag,1) #s#def getFieldStr def getFieldStr(self,tag,index): tuple = self.values[tag][index] if (tag in ['AI','PK','OI']): return tuple elif (tag in ['IP','OP']): return tuple[0]+","+tuple[1]+","+tuple[2]+","+tuple[3]+","+tuple[4] elif (tag in ['SF','IQ','ID']): if (index in [0,1,2]): return tuple else: file_names = self.values[tag][3] file_lines = self.values[tag][4] result = "" for i in range(len(file_names)): if (i > 0): result = result + "," result = result + file_names[i]+"@"+str(file_lines[i]) return result else: ### KE if (index in [0,1,2,3]): return tuple #s#def setRowDefault def setRowDefault(self,tag): self.values[tag] = self.default_values[tag] #s#def setOfDefaultValues def setOfDefaultValues(self): return { 'AI': ['', '', ''], 'PK': ['default.pk','','default.pk' ], 'OI': ['default.oi','','default.oi' ], 'IP': [[ 'stdin','','','','' ], [ '','','','','' ], [ 'stdin','','','','' ]], 'OP': [[ 'stdout','','','','' ], [ '','','','','' ], [ 'stdout','','','','' ]], 'SF': ['I E +V +C','','',[],[]], 'IQ': ['','','',[],[]], 'ID': ['','','',[],[]], 'KE': ['','','',''] } ### ----------------------------------------------------------- #s#def eraseAllVars def eraseAllVars(self): self.vars = {} self.var_tags = {} #s#def getVarValues ### ###Lookup a variable by it's name ### Return it or an empty string ### def getVarValue(self,varname): if (self.hasVar(varname)): ### If the variable content is stored in a file, read & return it if (len(self.vars[var_name]) > 0 and self.vars[var_name][0] == '@'): filename = self.vars[var_name] filename = filename[1:len(filename)] return files.gulpFile(filename) else: return self.vars[varname] else: return '' #s#def hasVar def hasVar(self,var_name): return self.vars.has_key(var_name) #s#def hasVarTag def hasVarTag(self,var_name): return self.var_tags.has_key(var_name) #s#def removeVar def removeVar(self,var_name): if (self.hasVar(var_name)): ### If the variable content is stored in a file, - remove the file too if (len(self.vars[var_name]) > 0 and self.vars[var_name][0] == '@'): try: filename = self.vars[var_name] files.delFile(filename[1:len(filename)]) except: pass del self.vars[var_name] if (self.hasVarTag(var_name)): del self.var_tags[var_name] #s#def removeVarTag def removeVarTag(self,var_name): if (self.hasVarTag(var_name)): del self.var_tags[var_name] #s#def addVar def addVar(self,name,content): self.vars[name] = content #s#def addVarTag def addVarTag(self,name,content): self.var_tags[name] = content #s#def getVar def getVar(self,name): if (not self.hasVar(name)): return '' else: return self.vars[name] #s#def getVarTag def getVarTag(self,name): if (not self.hasVarTag(name)): return '' else: return self.var_tags[name] #s#def getVarAndTag def getVarAndTag(self,name): v = self.getVar(name) t = self.getVarTag(name) return v,t #s#def setVarAndTag def setVarAndTag(self,name,value,tag): self.addVar(name,value) self.addVarTag(name,tag) #s#def saveVarsTo def saveVarsTo(self,filename): try: out = open(filename,"w") out.write("### OI Variable file\n"); out.write("### Format: $;;\n"); out.write("### \n"); for var,val in self.vars.items(): if (var != '__VIC_NAME__' and var != '__VIC_ROOM__'): out.write("$"+var+";"+self.getVarTag(var)+";"+str(len(val))+"\n") out.write(val) out.write("\n") out.close() return 1 except: return 0 #s#def loadVarsFrom def loadVarsFrom(self,filename): try: fin = open(filename,"r") line = "!" while (line != ""): line = fin.readline() try: if (line != "" and line[0] == '$'): var,tag,val_size = string.split(line,';',2) var = var[1:len(var)] # skip leading '$' val = fin.read(int(val_size)) self.setVarAndTag(var,val,tag) rubbish = fin.readline() ### consume the end-of-line after the block except: pass fin.close() return 1 except: return 0 ### ----------------------------------------------------------------- #s#def getLine def getLine(self,tag): if (tag in ['AI','PK','OI','IP','OP']): return tag+": "+self.getFieldStr(tag,0)+";"+self.getFieldStr(tag,1)+";"+self.getFieldStr(tag,2) elif (tag in ['SF','IQ','ID','KE']): return tag+": "+self.getFieldStr(tag,0)+";"+self.getFieldStr(tag,1)+";"+self.getFieldStr(tag,2)+";"+self.getFieldStr(tag,3) #s#def saveValuesTo def saveValuesTo(self,filename,path_mods=1): ### AI section contains a self-referring path, so determine this ### from the filename path = self.full_room_path base_filename = filename if (path_mods): path,base_filename = os.path.split(filename) if (path == ''): ### plain filename path = self.full_room_path filename = self.full_room_path + filename else: ### some kind of path prefixed ### Try to determine if it's being written inside $HOME, and ### turn the path relative so it looks proper in the PK file home = os.path.abspath(os.getcwd()) ### we're always cwd()'d to $HOME full_path = os.path.abspath(path) ### see if full_path begins with home, and if so then make it relative if (full_path[0:len(home)] == home): full_path = full_path[1+len(home):len(full_path)] ### trim $HOME prefix else: path = full_path ### not in $HOME, make it absolute if (path[-1] != os.sep): path = path + os.sep if(1): out = open(filename,"w") #out.write(self.getLine('AI')+"\n") out.write("AI: "+self.name+"."+self.id+";"+path+base_filename+";"+path+"\n") out.write(self.getLine('PK')+"\n") out.write(self.getLine('OI')+"\n") out.write(self.getLine('IP')+"\n") out.write(self.getLine('OP')+"\n") out.write(self.getLine('SF')+"\n") out.write(self.getLine('IQ')+"\n") out.write(self.getLine('ID')+"\n") out.write(self.getLine('KE')+"\n") out.close() return 1 else: return 0 #s#def setFromTagAndString def setFromTagAndString(self,tag,str): line = string.strip(str) if (tag in ['AI','PK','OI']): self.values[tag] = str.split(";",3) if (tag == 'AI'): self.room_name = self.values['AI'][0] self.pk_full_path = self.values['AI'][1] self.full_room_path = self.values['AI'][2] elif (tag in ['IP','OP']): tuple1,tuple2,tuple3 = str.split(";",3) self.values[tag] = [ tuple1.split(',') , tuple2.split(',') , tuple3.split(',') ] elif (tag in ['SF','IQ','ID']): flags,alt_flags,def_file,files = str.split(";",4) file = [] line = [] for f in files.split(","): try: ### may or may-not be anythgin in the file list fname,fline = f.split("@",2) line.append(int(fline)) file.append(fname) except: pass self.values[tag] = [flags,alt_flags,def_file,file,line] elif (tag == 'KE'): bits = str.split(";",3) line2 = self.values[tag][3] self.values[tag] = [bits[0],bits[1],bits[2],line2] #s#def loadValuesFrom def loadValuesFrom(self,filename): self.clearCurrentScript() try: fin = open(filename,"r") line = "!" while (line != ""): line = fin.readline() line = string.strip(line) if (line != "" and line != '\n' and line != '\r' and line != '\r\n' and line != '\n\r' and line[0] != '#'): tag,settings = line.split(": ",1) self.setFromTagAndString(tag,settings) return 1 except: return 0 #s#def clearCurrentScript ### ### Erase the currently running script ### def clearCurrentScript(self): self.script_line = 0 self.script = [] self.script_path = "" #s#def loadScript ### ### Given a script filename (an '.sf' file), load it into ### the process, resetting the line number etc. ### def loadScript(self,filename,start_line=1): try: fin = open(filename,"r") rows = fin.readlines() fin.close() for i in range(len(rows)): rows[i] = string.strip(rows[i]) self.script_path = filename self.script = rows if (len(rows) > 0): if (start_line > 0 and start_line <= len(rows)): self.script_line = start_line else: self.script_line = 1 else: self.script_line = 0 return 1 except: return 0 #s#def currentScriptIsFinished ### ### Is the current script done? ### def currentScriptIsFinished(self): if (len(self.script) == 0 or self.script_line > len(self.script)): return 1 else: return 0 #s#def getScriptLine ### ### Get the current line the script is up to ### def getScriptLine(self): if (len(self.script) == 0 or self.script_line > len(self.script)): return 0 else: return self.script_line + 1