import json import os.path import time import xmlrpclib import socket import netifaces import re class VariablesManager: VARIABLES_FILE="/var/lib/n4d/variables" LOCK_FILE="/tmp/.llxvarlock" INBOX="/var/lib/n4d/variables-inbox/" TRASH="/var/lib/n4d/variables-trash/" def __init__(self): self.variables={} if os.path.exists(VariablesManager.LOCK_FILE): os.remove(VariablesManager.LOCK_FILE) self.load_json(VariablesManager.VARIABLES_FILE) #print "\nVARIABLES FILE" #print "==============================" #self.listvars() self.read_inbox() #print "\nAFTER INBOX" #print "==============================" #print self.listvars(True) self.empty_trash() #print "\nAFTER TRASH" #print "==============================" #print self.listvars(True) self.add_volatile_info() #self.write_file() #def __init__ def listvars(self,extra_info=False): ret="" for variable in self.variables: value=self.get_variable(variable) ret+=variable+ "='" + value.encode("utf-8") + "';\n" if extra_info: ret+= "\tDescription: " + self.variables[variable][u"description"] + "\n" ret+="\tUsed by:\n" for depend in self.variables[variable][u"packages"]: ret+= "\t\t" + depend.encode("utf-8") + "\n" return ret.strip("\n") #def listvars def calculate_variable(self,value): pattern="_@START@_.*?_@END@_" variables=[] ret=re.findall(pattern,value) for item in ret: tmp=item.replace("_@START@_","") tmp=tmp.replace("_@END@_","") variables.append(tmp) for var in variables: value=value.replace("_@START@_"+var+"_@END@_",self.get_variable(var)) return value #def remove_calculated_chars def add_volatile_info(self): for item in self.variables: self.variables[item]["volatile"]=False #def add_volatile_info def showvars(self,var_list,extra_info=False): ret="" for var in var_list: ret+=var+"='" if self.variables.has_key(var): try: ret+=self.variables[var][u'value'].encode("utf-8")+"';\n" except Exception as e: #it's probably something old showvars couldn't have stored anyway ret+="';\n" if extra_info: ret+= "\tDescription: " + self.variables[var][u"description"] + "\n" ret+="\tUsed by:\n" for depend in self.variables[var][u"packages"]: ret+= "\t\t" + depend.encode("utf-8") + "\n" else: ret+="'\n" return ret.strip("\n") #def showvars def get_variables(self): return self.variables #def get_variables def load_json(self, file): try: if not os.path.exists(VariablesManager.VARIABLES_FILE): f=open(VariablesManager.VARIABLES_FILE,"w") f.write("{\n\n}\n") f.close() self.variables={} f=open(VariablesManager.VARIABLES_FILE,"r") data=json.load(f) f.close() self.variables=data return [True,""] except Exception as e: return [False,e.message] #def load_json def read_inbox(self): if os.path.exists(VariablesManager.INBOX): for file in os.listdir(VariablesManager.INBOX): file_path=VariablesManager.INBOX+file print "[VariablesManager] Adding " + file_path + " info..." try: f=open(file_path,"r") data=json.load(f) f.close() for item in data: if self.variables.has_key(item): for depend in data[item][u'packages']: if depend not in self.variables[item][u'packages']: self.variables[item][u'packages'].append(depend) if self.variables[item][u'value']==None or self.variables[item][u'value']=="": self.variables[item][u'value']=data[item][u'values'] else: self.variables[item]=data[item] #os.remove(file_path) except Exception as e: pass #return [False,e.message] os.remove(file_path) return [True,""] #def read_inbox def empty_trash(self): for file in os.listdir(VariablesManager.TRASH): file_path=VariablesManager.TRASH+file #print "[VariablesManager] Removing " + file_path + " info..." try: f=open(file_path,"r") data=json.load(f) f.close() for item in data: if self.variables.has_key(item): if data[item][u'packages'][0] in self.variables[item][u'packages']: count=0 for depend in self.variables[item][u'packages']: if depend==data[item][u'packages'][0]: self.variables[item][u'packages'].pop(count) if len(self.variables[item][u'packages'])==0: self.variables.pop(item) break else: count+=1 #os.remove(file_path) except Exception as e: print e pass #return [False,e.message] os.remove(file_path) return [True,''] #def empty_trash def get_ip(self): for item in netifaces.interfaces(): tmp=netifaces.ifaddresses(item) if tmp.has_key(netifaces.AF_INET): if tmp[netifaces.AF_INET][0].has_key("broadcast") and tmp[netifaces.AF_INET][0]["broadcast"]=="10.0.2.255": return tmp[netifaces.AF_INET][0]["addr"] return None #def get_ip def get_variable_list(self,variable_list,store=False,full_info=False): ret={} for item in variable_list: ret[item]=self.get_variable(item,store,full_info) return ret #def get_variable_list def get_variable(self,name,store=False,full_info=False): if name in self.variables: if not full_info: if self.variables[name][u"value"].find("_@START@_")!=-1: print "I have to ask for " + name + " which has value: " + self.variables[name][u'value'] value=self.calculate_variable(self.variables[name][u"value"]) else: value=self.variables[name][u"value"] return value.encode("utf-8") else: variable=self.variables[name].copy() if variable[u"value"].find("_@START@_")!=-1: variable["original_value"]=variable[u"value"] variable[u"value"]=self.calculate_variable(self.variables[name][u"value"]) variable["calculated"]=True return variable else: if self.variables.has_key("REMOTE_VARIABLES_SERVER") and self.variables["REMOTE_VARIABLES_SERVER"][u"value"]!="" and self.variables["REMOTE_VARIABLES_SERVER"][u"value"]!=None: server_ip=socket.gethostbyname(self.variables["REMOTE_VARIABLES_SERVER"][u"value"]) if self.get_ip()!=server_ip: try: server=xmlrpclib.ServerProxy("https://" + server_ip + ":9779") var=server.get_variable("","VariablesManager",name,False,True) if var!="" and store: self.add_variable(name,var[u"value"],var[u"description"],var[u"packages"],True) return self.get_variable(var[u"name"],store,full_info) except Exception as e: return "" else: return "" else: return "" #def get_variable def set_variable(self,name,value,depends=[]): if name in self.variables: self.variables[name][u"value"]=unicode(value).encode("utf-8") if len(depends)>0: for depend in depends: self.variables[unicode(name).encode("utf-8")][u"packages"].append(depend) self.write_file() return [True,""] else: return [False,"Variable not found. Use add_variable"] #def set_variable def add_variable(self,name,value,description,depends,volatile=False): if name not in self.variables: dic={} dic[u"value"]=unicode(value).encode("utf-8") dic[u"description"]=unicode(description).encode("utf-8") dic[u"packages"]=unicode(depends).encode("utf-8") dic["volatile"]=volatile self.variables[unicode(name)]=dic if not volatile: self.write_file() return [True,""] else: return [False,"Variable already exists. Use set_variable"] def write_file(self,fname=None): try: while os.path.exists(VariablesManager.LOCK_FILE): time.sleep(2) f=open(VariablesManager.LOCK_FILE,"w") f.close() tmp={} for item in self.variables: if self.variables[item]["volatile"]==False: tmp[item]=self.variables[item] if fname==None: f=open(VariablesManager.VARIABLES_FILE,"w") else: f=open(fname,"w") data=unicode(json.dumps(tmp,indent=4,encoding="utf-8",ensure_ascii=False)).encode("utf-8") f.write(data) f.close() os.remove(VariablesManager.LOCK_FILE) return True except Exception as e: print e return False #def write_file #class VariablesManager if __name__=="__main__": vm=VariablesManager() print vm.listvars() #print vm.get_variable("VARIABLE2",full_info=True) #print vm.get_variable("VARIABLE3",full_info=True) #print vm.showvars(var_list)