#! python: #w#VIC state.py module # # Copyright 2002, 2003 by Timothy Rue <3seas@threeseas.net> # # VIC state.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 re #s#processing modules import variables from vic import * from redirect import * from terminal import * import files import options #w#class State class State: "State Maintainer" #s#def __init__ def __init__(self,home_arg,room_arg,next_vic_id): self.vic_list = [] self.home_dir=home_arg self.room_dir=room_arg self.vic_id_number = next_vic_id self.current_vic =-1 self.global_vars = Vic("global_vars","0",self.home_dir) ### holds the pan-vic variables self.global_vars.setVariable("__VIC_HOME__",home_arg) self.global_vars.setVariable("__VIC_ROOM__",room_arg) self.exit = 0 #s#def getName def getName(self): return "State Maintainer" #s#def shouldExit def shouldExit(self): return (self.exit != 0) #s#def setNoVIC def setNoVIC(self): self.current_vic =-1 #s#def setCurrentVIC def setCurrentVIC(self,index): if (index >= 0 and index < len(self.vic_list)): self.current_vic = index #s#def getCurrentVicIndex def getCurrentVicIndex(self): return self.current_vic #s#def getCurrentVIC def getCurrentVIC(self): if (self.current_vic >= 0 and self.current_vic < len(self.vic_list)): return self.vic_list[self.current_vic] else: return None #s#def getVIC def getVic(self,index=0): if (index >= 0 and index < len(self.vic_list) and len(self.vic_list) != 0): return self.vic_list[index] else: return None #s#def getVicIndex def getVicIndex(self,name,id=0): for i in range(len(self.vic_list)): #print "COMPARE: "+str(name)+"."+str(id)+" Vs "+str(self.vic_list[i].getName())+"."+str(self.vic_list[i].getID()) if (id == int(self.vic_list[i].getID()) or (id == 0 and name == self.vic_list[i].getName())): return i return -1 #s#def getVicByName def getVicByNameID(self,name_id): try: name,id = string.split(name_id,".",1) name = string.lower(name) for i in range(len(self.vic_list)): if ((id == self.vic_list[i].getID() and name == string.lower(self.vic_list[i].getName())) or \ (id == '0' and name == string.lower(self.vic_list[i].getName()))): return self.vic_list[i] except: pass return None #s#def getVicIndexByRE ### ### Given a regular expression string ### def getVicIndexByRE(self,expression): ### a RE of just '*' breaks python 2.2.2 REs - It's probably invalid, but it's nice if (expression == '*'): if (len(self.vic_list) > 0): return 0 else: re_exp = re.compile(expression) for i in range(len(self.vic_list)): if (re_exp.match(self.vic_list[i].getNameID())): return i return -1 #s#def getVicNameListByRE def getVicNameListByRE(self,expression): output = [] ### a RE of just '*' breaks python 2.2.2 REs - It's probably invalid, but it's nice if (expression == '*'): for i in range(len(self.vic_list)): output.append(self.vic_list[i].getNameID()) else: re_exp = re.compile(expression) for i in range(len(self.vic_list)): if (re_exp.match(self.vic_list[i].getNameID())): output.append(self.vic_list[i].getNameID()) return output #s#def exitVic ### ### Remove the given VIC from all existance ### Including removing anything in the Room directory ### def exitVic(self,index): if (index >= 0 and index < len(self.vic_list)): room = self.vic_list[index].getRoom() files.safeRecursiveDelete(self.home_dir,room) del(self.vic_list[index]) self.current_vic = -1 #s#def vicCount ### ### Get the number of VICs ### def vicCount(self): return len(self.vic_list); #s#def getNextVic ### ### Return the next valid VIC Id number ### def getNextVicID(self): self.vic_id_number = self.vic_id_number + 1 return self.vic_id_number -1 #s#def setNextVicID ### ### Set the next VIC Id number ### def setNextVicID(self,N): self.vic_id_number = N #s#def getRoomDir def getRoomDir(self): return self.room_dir #s#def getHomeDir def getHomeDir(self): return self.home_dir #s#def addVIC def addVIC(self,new_vic): self.vic_list.append(new_vic) ### New VIC gets focus self.current_vic = len(self.vic_list)-1 ### Only switch context to new VIC if we don't have one already # if (self.current_vic == -1): # self.current_vic = len(self.vic_list)-1 return self.vic_list[-1] #s#def delVIC def delVIC(self): if (self.current_vic >= 0 and self.current_vic < len(self.vic_list)): del (self.vic_list[self.current_vic]) else: raise NoCurrentVIC,"There is no Current VIC" #s#def pathIsRoom def pathIsRoom(self,room_path): result = 0 for i in range(len(vic_list)): vic_room = vic_list[i].getRoom() if (os.name == "posix" and room_path == vic_room): result = 1 elif (string.lower(vic_room) == string.lower(room_path)): result = 1 if (result): break return result #s#def replaceVariables ### ### Given a command line, replace the variable names with the ### variables from the global and vic-local dictionary ### def replaceVariables(self,command_line): vic = self.getCurrentVIC() if (vic == None): var_dict = self.global_vars.getVariableDictionary() else: ### User can turn off variable processing if (vic.isProcessingVars()): var_dict = vic.getVariableDictionary() var_dict["__VIC_ROOM__"] = vic.getRoomPath() var_dict["__VIC_NAME__"] = vic.getRoomName() else: var_dict = vic.getEmptyVariableDictionary() ### Global vars are replaced, no matter what the vic flags say return variables.replaceVars(command_line,var_dict,self.global_vars.getVariableDictionary()) #s#def routeCommand def routeCommand(self,command): vic = self.getCurrentVIC() if (vic == None): return 0 else: vic.addCommand(command) return 1 #s#def executeCommand #def executeCommand(self,this_state,vic,stdscr,config,command,command_modules): def executeCommand(self,arg_pack,vic,command): this_state = arg_pack.state stdscr = arg_pack.stdscr config = arg_pack.config command_modules = arg_pack.modules if (command != None and len(command) > 0): ### Replace any $variables with those from the current VIC command = self.replaceVariables(command) command_list = options.splitOnPipes(command) ### extract redirections from command line command_list,stdin,stdout_file,appending,error,error_near = getAnyRedirections(command_list) if (error): writeToConsole(stdscr,error_near) else: for j in range(len(command_list)): command = command_list[j] handled = 0 for i in range(len(command_modules)): ### Give each module a chance to claim the command handled,stdout,error = command_modules[i].parseRun(this_state,vic,config,command,stdin) if (handled): ### Write any error messages to the console if (error != errors.ok): writeToConsole(stdscr,errors.getName(error)) if (vic != None): vic.setErrorMode() else: if (j == len(command_list)-1): ### Process any output if (stdout_file != ""): mode = "w" if (appending): mode = "a" try: outfile = open(stdout_file,mode) for line in stdout: outfile.write(line) outfile.write(os.linesep) outfile.close() except: writeToConsole(stdscr,"Error writing to '"+stdout_file) else: for line in stdout: if (vic != None): line = vic.handleOutput(line) ### Allow the VIC to process any output if (line != ""): writeToConsole(stdscr,line) else: ### stdin must be piped to next command stdin = "" for line in stdout: stdin = stdin + line + os.linesep ### Command was handled, don't try other modules break if (not handled and not command in ['quit','exit']): ### Unrecognised command writeToConsole(stdscr,errors.getName(errors.unknown_command)+" in '"+command+"'") if (vic != None): vic.setErrorMode() break #s#def processingEngine ### ### Execute a single pending command from every non-step-mode VIC ### def processingEngine(self,arg_pack): this_state = arg_pack.state stdscr = arg_pack.stdscr config = arg_pack.config command_modules = arg_pack.modules did_something = 1 while (did_something): did_something = 0 for i in range(len(self.vic_list)): if (not self.vic_list[i].inStepMode()): command = self.vic_list[i].getNextCommand() if (command != None): old_len = len(self.vic_list) #self.executeCommand(this_state,self.vic_list[i],stdscr,config,command,command_modules) self.executeCommand(arg_pack,self.vic_list[i],command) did_something = 1 if (old_len != len(self.vic_list)): break #w#class StateEnginePack class StateEnginePack: "State Engine Argument Pack" #s#def __init__ def __init__(self,me,console,conf,modules): self.state = me self.stdscr = console self.config = conf self.modules = modules