source: n4d/trunk/fuentes/install-files/usr/share/n4d/python-plugins/VariablesManager.py

Last change on this file was 7784, checked in by hectorgh, 15 months ago

seems there could be a thread checking clients that are no longer in the list

File size: 19.8 KB
Line 
1import json
2import os.path
3import os
4import time
5import xmlrpclib
6import socket
7import netifaces
8import re
9import importlib
10import sys
11import tarfile
12import threading
13import subprocess
14import time
15import string
16
17class VariablesManager:
18
19        VARIABLES_FILE="/var/lib/n4d/variables"
20        VARIABLES_DIR="/var/lib/n4d/variables-dir/"
21        LOCK_FILE="/tmp/.llxvarlock"
22        INBOX="/var/lib/n4d/variables-inbox/"
23        TRASH="/var/lib/n4d/variables-trash/"
24        CUSTOM_INSTALLATION_DIR="/usr/share/n4d/variablesmanager-funcs/"
25        LOG="/var/log/n4d/variables-manager"
26       
27        def __init__(self):
28               
29                self.instance_id="".join(random.sample(string.letters+string.digits, 50))
30                self.server_instance_id=None
31                self.variables={}
32                self.variables_ok=False
33                self.variables_clients={}
34                self.variables_triggers={}
35                self.failed_servers={}
36                t=threading.Thread(target=self.check_clients,args=())
37                t.daemon=True
38                t.start()
39               
40                if os.path.exists(VariablesManager.LOCK_FILE):
41                        os.remove(VariablesManager.LOCK_FILE)
42                       
43                       
44                if os.path.exists(VariablesManager.VARIABLES_FILE):
45                        self.variables_ok,ret=self.load_json(VariablesManager.VARIABLES_FILE)
46                        try:
47                                os.remove(VariablesManager.VARIABLES_FILE)
48                        except:
49                                pass
50                else:
51                        self.variables_ok,ret=self.load_json(None)
52                       
53                if self.variables_ok:
54                        #print "\nVARIABLES FILE"
55                        #print "=============================="
56                        #self.listvars()
57                        self.read_inbox(False)
58                        #print "\nAFTER INBOX"
59                        #print "=============================="
60                        #print self.listvars(True)
61                        self.empty_trash(False)
62                        #print "\nAFTER TRASH"
63                        #print "=============================="
64                        #print self.listvars(True)
65                        self.add_volatile_info()
66                        self.write_file()
67                else:
68                        print("[VariablesManager] Loading variables failed because: " + str(ret))
69
70               
71        #def __init__
72       
73       
74        def startup(self,options):
75
76                if "REMOTE_VARIABLES_SERVER" in self.variables:
77                        t=threading.Thread(target=self.register_n4d_instance_to_server)
78                        t.daemon=True
79                        t.start()
80                       
81        #def startup
82       
83       
84        def is_ip_in_range(self,ip,network):
85               
86                try:
87                        return netaddr.ip.IPAddress(ip) in netaddr.IPNetwork(network).iter_hosts()
88                except:
89                        return False
90                       
91        #def is_ip_in_range
92       
93
94        def get_net_size(self,netmask):
95               
96                netmask=netmask.split(".")
97                binary_str=""
98                for octet in netmask:
99                        binary_str += bin(int(octet))[2:].zfill(8)
100                       
101                return str(len(binary_str.rstrip('0')))
102               
103        #def get_net_size
104
105
106        def get_ip(self):
107               
108                for item in netifaces.interfaces():
109                        tmp=netifaces.ifaddresses(item)
110                        if tmp.has_key(netifaces.AF_INET):
111                                if tmp[netifaces.AF_INET][0].has_key("broadcast") and tmp[netifaces.AF_INET][0]["broadcast"]=="10.0.2.255":
112                                        return tmp[netifaces.AF_INET][0]["addr"]
113                return None
114               
115        #def get_ip
116       
117
118        def route_get_ip(self,ip):
119               
120                p=subprocess.Popen(["ip route get %s"%ip],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()
121                if "dev" in p[0]:
122                        dev=p[0].split("dev ")[1].split(" ")[0]
123                else:
124                        dev=None
125                return dev
126               
127        #def route_get_ip
128               
129
130        def get_mac_from_device(self,dev):
131
132                for item in netifaces.interfaces():
133                       
134                        try:
135                                i=netifaces.ifaddresses(item)
136                                mac=i[17][0]["addr"]
137                                broadcast=i[2][0]["broadcast"]
138                                network=broadcast
139                                netmask=i[2][0]["netmask"]
140                                network+="/%s"%self.get_net_size(netmask)
141                                ip=i[2][0]["addr"]
142                        except Exception as e:
143                                continue
144                       
145                        if dev=="lo":
146                                return mac
147                       
148                        if item==dev:
149                                return mac
150                               
151                return None
152
153        #def get_mac_from_device_in_server_network
154       
155       
156        def register_instance(self,autocompleted_secured_ip,mac):
157
158                client={}
159                client["last_check"]=int(time.time())
160                client["missed_pings"]=0
161                client["ip"]=autocompleted_secured_ip
162                self.variables_clients[mac]=client
163               
164                return self.instance_id
165
166        #def register_instance
167       
168
169        def register_n4d_instance_to_server(self):
170               
171                while True:
172               
173                        try:
174                                server_ip=socket.gethostbyname(self.variables["REMOTE_VARIABLES_SERVER"][u"value"])
175                                if self.get_ip()!=server_ip:
176                               
177                                        c=xmlrpclib.ServerProxy("https://%s:9779"%server_ip)
178                                        mac=self.get_mac_from_device(self.route_get_ip(server_ip))
179                                        self.server_instance_id=c.register_instance("","VariablesManager","",mac)
180                               
181                        except Exception as e:
182
183                                self.server_instance_id=None
184                                return None
185                               
186                        time.sleep(60*3)
187
188        #def register_n4d_instance_to_server
189       
190       
191        def check_clients(self):
192               
193                while True:
194                       
195                        for mac in self.variables_clients:
196                               
197                                ip=self.variables_clients[mac]["ip"]
198                                t=threading.Thread(target=self.check_single_client,args=(mac,ip,))
199                                t.daemon=True
200                                t.start()
201                       
202                        time.sleep(60*3)
203               
204               
205        #def check_clients
206
207        def manual_client_list_check(self):
208
209                for mac in self.variables_clients:
210                        ip=self.variables_clients[mac]["ip"]
211                        t=threading.Thread(target=self.check_single_client,args=(mac,ip,))
212                        t.daemon=True
213                        t.start()
214
215        #def manual_client_list_check
216       
217       
218        def check_single_client(self,mac,ip):
219               
220                max_pings=3
221               
222                print("[VariablesManager] Checking client { MAC:%s IP:%s } ... "%(mac,ip))
223                c=xmlrpclib.ServerProxy("https://%s:9779"%ip)
224                try:
225                        c.get_methods()
226                        if mac in self.variables_clients:
227                                self.variables_clients[mac]["last_check"]=time.time()
228                                self.variables_clients[mac]["missed_pings"]=0
229                except:
230                        if mac in self.variables_clients:
231                                self.variables_clients[mac]["missed_pings"]+=1
232                                if self.variables_clients[mac]["missed_pings"] >=max_pings:
233                                        print "[VariablesManager] Removing client %s:%s after %s missed pings."%(mac,ip,max_pings)
234                                        self.variables_clients.pop(mac)
235               
236        #def check_single_client
237       
238       
239       
240        def get_client_list(self):
241               
242                return self.variables_clients
243               
244        #def get_client_list
245       
246        def notify_changes(self,variable):
247               
248                if len(self.variables_clients) > 0:
249               
250                        print "[VariablesManager] Notifying changes... "
251                        for mac in self.variables_clients:
252                               
253                                ip=self.variables_clients[mac]["ip"]
254                                c=xmlrpclib.ServerProxy("https://%s:9779"%ip)
255                                try:
256                                        c.server_changed("","VariablesManager","",self.instance_id,variable)
257                                       
258                                except:
259                                        self.variables_clients[mac]["missed_pings"]+=1
260                                       
261                                self.variables_clients[mac]["last_check"]=time.time()
262               
263        #def announce_changes
264       
265       
266        def server_changed(self,autocompleted_server_ip,server_instance_id,variable_name):
267
268                if server_instance_id==self.server_instance_id:
269
270                        print "[VariablesManager] Server instance ID validated"
271                        t=threading.Thread(target=self.execute_trigger,args=(variable_name,))
272                        t.daemon=True
273                        t.start()
274                       
275                        return True
276                       
277                else:
278                       
279                        if autocompleted_server_ip not in self.failed_servers:
280                                self.failed_servers[autocompleted_server_ip]={}
281                                self.failed_servers[autocompleted_server_ip]["failed_count"]=0
282                       
283                        sleep_time=0.1
284                        self.failed_servers[autocompleted_server_ip]["failed_count"]+=1
285                        time.sleep(sleep_time*self.failed_servers[autocompleted_server_ip]["failed_count"])
286                        return False
287               
288        #def server_changed
289       
290       
291        def execute_trigger(self,variable_name):
292               
293                if variable_name in self.variables_triggers:
294                        for i in self.variables_triggers[variable_name]:
295                                class_name,function=i
296                                try:
297                                        print "[VariablesManager] Executing %s.%s trigger..."%(class_name,function.im_func.func_name)
298                                        function(self.get_variable(variable_name))
299                                except Exception as e:
300                                        print e
301               
302        #def execute_trigger
303       
304       
305        def register_trigger(self,variable_name,class_name,function):
306               
307                if variable_name not in self.variables_triggers:
308                        self.variables_triggers[variable_name]=[]
309                       
310                self.variables_triggers[variable_name].append((class_name,function))
311               
312        #def register_trigger
313       
314       
315        def backup(self,dir="/backup"):
316               
317                try:
318               
319                        #file_path=dir+"/"+self.get_time()+"_VariablesManager.tar.gz"
320                        file_path=dir+"/"+get_backup_name("VariablesManager")
321                        tar=tarfile.open(file_path,"w:gz")
322                        tar.add(VariablesManager.VARIABLES_DIR)
323                        tar.close()
324                       
325                        return [True,file_path]
326                       
327                except Exception as e:
328                        return [False,str(e)]
329               
330        #def backup
331
332       
333        def restore(self,file_path=None):
334
335
336                if file_path==None:
337                        for f in sorted(os.listdir("/backup"),reverse=True):
338                                if "VariablesManager" in f:
339                                        file_path="/backup/"+f
340                                        break
341
342                try:
343
344                        if os.path.exists(file_path):
345                               
346                                tmp_dir=tempfile.mkdtemp()
347                                tar=tarfile.open(file_path)
348                                tar.extractall(tmp_dir)
349                                tar.close()
350                               
351                                if not os.path.exists(VariablesManager.VARIABLES_DIR):
352                                        os.mkdir(VariablesManager.VARIABLES_DIR)
353                               
354                                for f in os.listdir(tmp_dir+VariablesManager.VARIABLES_DIR):
355                                        tmp_path=tmp_dir+VariablesManager.VARIABLES_DIR+f
356                                        shutil.copy(tmp_path,VariablesManager.VARIABLES_DIR)
357                                       
358                                self.load_json(None)
359                                               
360                                return [True,""]
361                               
362                except Exception as e:
363                               
364                        return [False,str(e)]
365               
366        #def restore
367       
368        def log(self,txt):
369               
370                try:
371                        f=open(VariablesManager.LOG,"a")
372                        txt=str(txt)
373                        f.write(txt+"\n")
374                        f.close()
375                except Exception as e:
376                        pass
377               
378        #def log
379       
380        def listvars(self,extra_info=False,custom_dic=None):
381                ret=""
382               
383                try:
384               
385                        if custom_dic==None:
386                                custom_dic=self.variables
387                        for variable in custom_dic:
388                                if type(custom_dic[variable])==type({}) and "root_protected" in custom_dic[variable] and custom_dic[variable]["root_protected"]:
389                                        continue
390                                value=self.get_variable(variable)
391                                if value==None:
392                                        continue
393                                ret+=variable+ "='" + str(value).encode("utf-8") + "';\n"
394                                if extra_info:
395                                        ret+= "\tDescription: " + self.variables[variable][u"description"] + "\n"
396                                        ret+="\tUsed by:\n"
397                                        for depend in self.variables[variable][u"packages"]:
398                                                ret+= "\t\t" + depend.encode("utf-8") + "\n"
399                       
400                        return ret.strip("\n")
401                except Exception as e:
402                        return str(e)
403                                       
404        #def listvars
405       
406        def calculate_variable(self,value):
407               
408                pattern="_@START@_.*?_@END@_"
409                variables=[]
410               
411                ret=re.findall(pattern,value)
412               
413                for item in ret:
414                        tmp=item.replace("_@START@_","")
415                        tmp=tmp.replace("_@END@_","")
416                        variables.append(tmp)
417               
418                for var in variables:
419                        value=value.replace("_@START@_"+var+"_@END@_",self.get_variable(var))
420                       
421                return value
422               
423        #def remove_calculated_chars
424       
425        def add_volatile_info(self):
426               
427                for item in self.variables:
428               
429                        if not self.variables[item].has_key("volatile"):
430                                self.variables[item]["volatile"]=False
431               
432        #def add_volatile_info
433
434       
435        def showvars(self,var_list,extra_info=False):
436               
437                ret=""
438               
439                for var in var_list:
440                        ret+=var+"='"
441                        if self.variables.has_key(var):
442                                try:
443                                        ret+=self.variables[var][u'value'].encode("utf-8")+"';\n"
444                                except Exception as e:
445                                        #it's probably something old showvars couldn't have stored anyway
446                                        ret+="';\n"
447                                if extra_info:
448                                        ret+= "\tDescription: " + self.variables[var][u"description"] + "\n"
449                                        ret+="\tUsed by:\n"
450                                        for depend in self.variables[var][u"packages"]:
451                                                ret+= "\t\t" + depend.encode("utf-8") + "\n"
452                        else:
453                                ret+="'\n"
454                                               
455                return ret.strip("\n")
456               
457        #def  showvars
458
459       
460        def get_variables(self):
461
462                return self.variables
463               
464        #def get_variables
465               
466       
467        def load_json(self, file=None):
468
469                self.variables={}
470               
471                if file!=None:
472               
473                        try:
474                               
475                                f=open(file,"r")
476                                data=json.load(f)
477                                f.close()
478                                self.variables=data
479                                #return [True,""]
480                               
481                        except Exception as e:
482                                print(str(e))
483                                #return [False,e.message]
484                               
485                for file in os.listdir(VariablesManager.VARIABLES_DIR):
486                        try:
487                                sys.stdout.write("\t[VariablesManager] Loading " + file + " ... ")
488                                f=open(VariablesManager.VARIABLES_DIR+file)     
489                                data=json.load(f)
490                                f.close()
491                                self.variables[file]=data[file]
492                                print("OK")
493                        except Exception as e:
494                                print("FAILED ["+str(e)+"]")
495                               
496                return [True,""]
497               
498        #def load_json
499       
500        def read_inbox(self, force_write=False):
501               
502               
503                if self.variables_ok:
504               
505                        if os.path.exists(VariablesManager.INBOX):
506                               
507                                for file in os.listdir(VariablesManager.INBOX):
508                                        file_path=VariablesManager.INBOX+file
509                                        print "[VariablesManager] Adding " + file_path + " info..."
510                                        try:
511                                                f=open(file_path,"r")
512                                                data=json.load(f)
513                                                f.close()
514                                               
515                                                for item in data:
516                                                        if self.variables.has_key(item):
517                                                                for key in data[item].keys():
518                                                                        if not self.variables[item].has_key(unicode(key)):
519                                                                                self.variables[item][unicode(key)] = data[item][key]
520                                                                if data[item].has_key(unicode('function')):
521                                                                        self.variables[item][unicode('function')] = data[item][u'function']
522                                                                for depend in data[item][u'packages']:
523                                                                        if depend not in self.variables[item][u'packages']:
524                                                                                self.variables[item][u'packages'].append(depend)
525                                                               
526                                                                if "force_update" in data[item] and data[item]["force_update"]:
527                                                                        self.variables[item][u'value']=data[item][u'value']
528                                                        else:
529                                                                self.variables[item]=data[item]
530
531                                       
532                                        except Exception as e:
533                                                print e
534                                                #return [False,e.message]
535                                        os.remove(file_path)
536                               
537                                if force_write:
538                                        try:
539                                                self.add_volatile_info()
540                                                self.write_file()
541                                        except Exception as e:
542                                                print(e)
543                                               
544               
545                return [True,""]
546                               
547        #def read_inbox
548
549       
550        def empty_trash(self,force_write=False):
551               
552               
553                if self.variables_ok:
554               
555                        for file in os.listdir(VariablesManager.TRASH):
556                                file_path=VariablesManager.TRASH+file
557                                #print "[VariablesManager] Removing " + file_path + " info..."
558                                try:
559                                        f=open(file_path,"r")
560                                        data=json.load(f)
561                                        f.close()
562                                       
563                                        for item in data:
564                                                if self.variables.has_key(item):
565                                                        if data[item][u'packages'][0] in self.variables[item][u'packages']:
566                                                                count=0
567                                                                for depend in self.variables[item][u'packages']:
568                                                                        if depend==data[item][u'packages'][0]:
569                                                                                self.variables[item][u'packages'].pop(count)
570                                                                                if len(self.variables[item][u'packages'])==0:
571                                                                                        self.variables.pop(item)
572                                                                                break
573                                                                        else:
574                                                                                count+=1
575                                       
576                                except Exception as e:
577                                        print e
578                                        #return [False,e.message]
579                                       
580                                os.remove(file_path)
581                       
582                        if force_write:
583                                try:   
584                                        self.write_file()
585                                except Exception as e:
586                                        print(e)
587                               
588                return [True,'']
589                       
590               
591        #def empty_trash
592       
593
594        def get_variable_list(self,variable_list,store=False,full_info=False):
595               
596                ret={}
597                if variable_list!=None:
598                        for item in variable_list:
599                                try:
600                                        ret[item]=self.get_variable(item,store,full_info)
601                                except Exception as e:
602                                        print e
603
604                return ret
605               
606        #def get_variable_list
607       
608
609        def get_variable(self,name,store=False,full_info=False,key=None):
610       
611                global master_password
612               
613                if name in self.variables and self.variables[name].has_key("root_protected") and self.variables[name]["root_protected"] and key!=master_password:
614                        return None
615                       
616                if name in self.variables and self.variables[name].has_key("function"):
617                        try:
618                                if not full_info:
619                                        if (type(self.variables[name][u"value"])==type("") or  type(self.variables[name][u"value"])==type(u"")) and self.variables[name][u"value"].find("_@START@_")!=-1:
620                                                #print "I have to ask for " + name + " which has value: " + self.variables[name][u'value']
621                                                value=self.calculate_variable(self.variables[name][u"value"])
622                                        else:
623                                                value=self.variables[name][u"value"]
624
625                                        if type(value)==type(u""):
626                                                try:
627                                                        ret=value.encode("utf-8")
628                                                        return ret
629                                                except:
630                                                        return value
631                                        else:
632                                                return value
633                                else:
634                                        variable=self.variables[name].copy()
635                                        variable["remote"]=False
636                                        if type(variable[u"value"])==type(""):
637                                                if variable[u"value"].find("_@START@_")!=-1:
638                                                        variable["original_value"]=variable[u"value"]
639                                                        variable[u"value"]=self.calculate_variable(self.variables[name][u"value"])
640                                                        variable["calculated"]=True
641                                        return variable
642                        except:
643                                return None
644                else:
645                        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:
646                                try:
647                                        server_ip=socket.gethostbyname(self.variables["REMOTE_VARIABLES_SERVER"][u"value"])
648                                except:
649                                        return None
650                                if self.get_ip()!=server_ip:
651                                        for count in range(0,3):
652                                                try:
653
654                                                        server=xmlrpclib.ServerProxy("https://"+server_ip+":9779",allow_none=True)
655                                                        var=server.get_variable("","VariablesManager",name,True,True)
656                                                       
657                                                        if var==None:
658                                                                return None
659                                                        if (var!=""  or type(var)!=type("")) and store:
660
661                                                                self.add_variable(name,var[u"value"],var[u"function"],var[u"description"],var[u"packages"],False)
662                                                                return self.get_variable(name,store,full_info)
663                                                        else:
664                                                                if full_info:
665                                                                        var["remote"]=True
666                                                                        return var
667                                                                else:
668                                                                        return var["value"]
669                                                               
670                                                except Exception as e:
671                                                        time.sleep(1)
672                                       
673                                        return None
674                                else:
675                                        return None
676                        else:
677                               
678                                return None
679                       
680        #def get_variable
681
682       
683        def set_variable(self,name,value,depends=[],force_volatile_flag=False):
684
685                if name in self.variables:
686                       
687                        if value == self.variables[name][u"value"]:
688                                return [True,"Variable already contained that value"]
689                       
690                        if type(value)==type(""):
691                                self.variables[name][u"value"]=unicode(value).encode("utf-8")
692                        else:
693                                self.variables[name][u"value"]=value
694
695                        if len(depends)>0:
696                                for depend in depends:
697                                        self.variables[unicode(name).encode("utf-8")][u"packages"].append(depend)
698                       
699                        if not force_volatile_flag:
700                                self.write_file()
701                        else:
702                               
703                                self.variables[name]["volatile"]=True
704                                if "function" not in self.variables["name"]:
705                                        self.variables[name]["function"]=""
706                                if "description" not in self.variables["name"]:
707                                        self.variables[name]["description"]=""
708                       
709                        t=threading.Thread(target=self.notify_changes,args=(name,))
710                        t.daemon=True
711                        t.start()
712                       
713                        # local trigger call
714                        self.execute_trigger(name)
715                       
716                        return [True,""]
717                else:
718                        return [False,"Variable not found. Use add_variable"]
719               
720               
721        #def set_variable
722
723       
724        def add_variable(self,name,value,function,description,depends,volatile=False,root_protected=False):
725
726                if name not in self.variables:
727                        dic={}
728                        if type(value)==type(""):
729                                dic[u"value"]=unicode(value).encode("utf-8")
730                        else:
731                                dic[u"value"]=value
732                        dic[u"function"]=function
733                        dic[u"description"]=unicode(description).encode("utf-8")
734                        if type(depends)==type(""):
735                                dic[u"packages"]=[unicode(depends).encode("utf-8")]
736                        elif type(depends)==type([]):
737                                dic[u"packages"]=depends
738                        else:
739                                dic[u"packages"]=[]
740                        dic["volatile"]=volatile
741                        dic["root_protected"]=root_protected
742                        self.variables[unicode(name)]=dic
743                        if not volatile:
744                                self.write_file()
745                        return [True,""]
746                else:
747                        return [False,"Variable already exists. Use set_variable"]
748                       
749        #def add_variable
750
751
752        def write_file(self,fname=None):
753               
754                try:
755                        while os.path.exists(VariablesManager.LOCK_FILE):
756                                time.sleep(2)
757                               
758                        f=open(VariablesManager.LOCK_FILE,"w")
759                        f.close()
760                        tmp_vars={}
761                        for item in self.variables:
762                                if self.variables[item].has_key("volatile") and self.variables[item]["volatile"]==False:
763                                        tmp_vars[item]=self.variables[item]
764                                       
765                        for item in tmp_vars:
766                               
767                                tmp={}
768                                tmp[item]=tmp_vars[item]
769                                f=open(VariablesManager.VARIABLES_DIR+item,"w")
770                                data=unicode(json.dumps(tmp,indent=4,encoding="utf-8",ensure_ascii=False)).encode("utf-8")
771                                f.write(data)
772                                f.close()
773                               
774                                if "root_protected" in tmp_vars[item]:
775                                        if tmp_vars[item]["root_protected"]:
776                                                self.chmod(VariablesManager.VARIABLES_DIR+item,0600)
777                                               
778                                               
779                        os.remove(VariablesManager.LOCK_FILE)
780                        return True
781                               
782                       
783                except Exception as e:
784                        os.remove(VariablesManager.LOCK_FILE)
785                        print (e)
786                        return False
787               
788        #def write_file
789
790
791        def chmod(self,file,mode):
792                prevmask = os.umask(0)
793                try:
794                        os.chmod(file,mode)
795                        os.umask(prevmask)
796                        return True
797                except Exception as e:
798                        print e
799                        os.umask(prevmask)
800                        return False
801                       
802        #def chmod
803       
804       
805        def init_variable(self,variable,args={},force=False,full_info=False):
806
807                try:
808                        funct=self.variables[variable]["function"]
809                        mod_name=funct[:funct.rfind(".")]
810                        funct_name=funct[funct.rfind(".")+1:]
811                        funct_name=funct_name.replace("(","")
812                        funct_name=funct_name.replace(")","")
813                        mod=importlib.import_module(mod_name)
814                        ret=getattr(mod,funct_name)(args)
815                        ok,exc=self.set_variable(variable,ret)
816                        if ok:
817                                return (True,ret)
818                        else:
819                                return (False,ret)
820                except Exception as e:
821                        return (False,e)
822               
823        #def init_variable
824       
825       
826#class VariablesManager
827
828
829if __name__=="__main__":
830       
831        vm=VariablesManager()
832       
833       
834               
835               
836               
837       
838       
839       
Note: See TracBrowser for help on using the repository browser.