256 lines
6.3 KiB
Python
256 lines
6.3 KiB
Python
import os
|
|
import os.path
|
|
import sys
|
|
import gc
|
|
import importlib
|
|
|
|
import types
|
|
|
|
import hserver.api
|
|
|
|
from simplelog import log
|
|
|
|
|
|
def new_module(modname, path = None, file = None):
|
|
mod = types.ModuleType( modname )
|
|
if not path is None:
|
|
mod.__path__ = path
|
|
if not file is None:
|
|
mod.__file__ = file
|
|
|
|
sys.modules[ modname ] = mod
|
|
|
|
return mod
|
|
|
|
|
|
class Package:
|
|
|
|
def __init__(self, pm, path, pname):
|
|
self.__pm = pm
|
|
self.__path = path
|
|
|
|
self.__modpath = "packages.%s" % (pname,)
|
|
self.__mod = new_module( self.__modpath )
|
|
self.__allowed_modules = [ "hserver", "hserver.api" ]
|
|
|
|
self.__modules = {}
|
|
|
|
self.__builtins = dict(__builtins__)
|
|
self.__builtins["__import__"] = self.__mod_import
|
|
self.__builtins["export"] = self.__export
|
|
|
|
self.__exports = {}
|
|
|
|
self.__load()
|
|
|
|
def module(self):
|
|
return self.__mod
|
|
|
|
def __load(self):
|
|
print("Package.__load(): Path=%s" % (self.__path,))
|
|
setattr( self.__mod, "Templates", hserver.TemplateModule("%s/templates" % (self.__path,)) )
|
|
self.__modules["%s.Templates" % (self.__modpath,)] = self.__mod.Templates
|
|
|
|
if os.path.exists("%s/package.conf" % (self.__path,)):
|
|
pcn = "%s/package.conf" % (self.__path,)
|
|
self.__config = new_module( "package.conf", file=pcn )
|
|
self.__mod_refresh( self.__config )
|
|
|
|
|
|
if (hasattr(self.__config,"modules")):
|
|
for mname in self.__config.modules:
|
|
self.__allowed_modules.append( mname )
|
|
|
|
files = os.listdir( self.__path )
|
|
for fn in files:
|
|
if (fn.endswith(".py")):
|
|
self.__mod_create( fn[:-3] )
|
|
|
|
print("Package: Modules: %s" % (self.__modules,))
|
|
|
|
|
|
def __mod_create(self, localname):
|
|
"Erstelle/Lade ein Modul aus diesem Package"
|
|
modname = "%s.%s" % (self.__modpath,localname)
|
|
|
|
if modname in self.__modules:
|
|
return self.__modules[ modname ]
|
|
|
|
modpath = localname.split(".")
|
|
localfile = modpath[-1]
|
|
del modpath[-1]
|
|
|
|
if len(modpath)==0 :
|
|
modparent = self.__mod
|
|
else:
|
|
modparent = self.__mod_create( ".".join(modpath) )
|
|
|
|
|
|
mfile = ("%s/%s/%s.py" % (self.__path,"/".join(modpath),localfile)).replace("//","/")
|
|
mpath = ("%s/%s" % (self.__path,"/".join(modpath))).replace("//","/")
|
|
|
|
print("__mod_create( %s ): Check: F=%s , P=%s" % (localname, mfile, mpath))
|
|
if not (os.path.exists(mfile)):
|
|
mfile = ("%s/%s/%s/__init__.py" % (self.__path,"/".join(modpath),localfile)).replace("//","/")
|
|
mpath = ("%s/%s/%s" % (self.__path,"/".join(modpath), localfile)).replace("//","/")
|
|
|
|
print("__mod_create( %s ): Check: F=%s , P=%s" % (localname, mfile, mpath))
|
|
|
|
if os.path.exists(mpath):
|
|
if not (os.path.exists(mfile)):
|
|
mfile = None
|
|
else:
|
|
raise Exception("Package: module '%s'not found" % (localname,))
|
|
|
|
print("__mod_create( %s ): Result: F=%s , P=%s" % (localname, mfile, mpath))
|
|
|
|
mod = new_module( modname, path=mpath, file=mfile )
|
|
self.__modules[ modname ] = mod
|
|
setattr( modparent, localfile, mod)
|
|
|
|
mod.__builtins__ = self.__builtins
|
|
|
|
self.__mod_refresh( mod )
|
|
|
|
return mod
|
|
|
|
def exports(self):
|
|
return dict(self.__exports)
|
|
|
|
def modules(self):
|
|
return dict(self.__modules)
|
|
|
|
def reload(self):
|
|
|
|
for modname in list(self.__modules.keys()):
|
|
mod = self.__modules[ modname ]
|
|
self.__mod_refresh( mod )
|
|
self.__update_classes( modname )
|
|
|
|
files = os.listdir( self.__path )
|
|
for fn in files:
|
|
if (fn.endswith(".py")):
|
|
if not fn[:-3] in self.__modules:
|
|
self.__mod_create( fn[:-3] )
|
|
|
|
def __update_classes(self, modname):
|
|
for o in gc.get_objects():
|
|
if (isinstance( o, object )):
|
|
if o.__class__.__module__ == modname:
|
|
c = getattr( self.__modules[modname], o.__class__.__name__, None )
|
|
if not c is None:
|
|
try:
|
|
o.__class__ = c
|
|
except Exception as ex:
|
|
print("__update_classes(): Exception: %s" % (ex,))
|
|
|
|
|
|
|
|
def __mod_import(self,name,globals=None,locals=None,fromlist=(),level=0):
|
|
print("import(%s,%s,%s,%s,%s)" % (name,"...","...",fromlist,level))
|
|
|
|
bname = name.split(".")[0]
|
|
|
|
if (name in self.__allowed_modules):
|
|
mod = importlib.import_module( name )
|
|
self.__modules[ name ] = mod
|
|
bmod = sys.modules[ bname ]
|
|
else:
|
|
mod = self.__mod_create( name )
|
|
if bname == name:
|
|
bmod = mod
|
|
else:
|
|
bmod = self.__modules[ "%s.%s" % (self.__modpath,bname) ]
|
|
|
|
if (not fromlist is None) and (len(fromlist) > 0):
|
|
return mod
|
|
|
|
return bmod
|
|
|
|
def __mod_refresh(self, mod):
|
|
if not hasattr(mod, "__file__"):
|
|
return
|
|
|
|
print("__mod_refresh: %s [%s]" % (mod.__name__,mod.__file__))
|
|
|
|
if not os.path.exists( mod.__file__ ):
|
|
del self.__modules[ mod.__name__ ]
|
|
return
|
|
|
|
f = open(mod.__file__, "r")
|
|
src = f.read()
|
|
f.close()
|
|
|
|
co = compile( src, mod.__file__, "exec" )
|
|
exec( co, mod.__dict__ )
|
|
|
|
def __export(self, name, o, glob=False):
|
|
self.__exports[ name ] = o
|
|
if glob:
|
|
self.__pm.export( name, o )
|
|
|
|
def __getattr__(self, name):
|
|
if name in self.__modules:
|
|
return self.__modules[ name ]
|
|
if name in self.__exports:
|
|
return self.__exports[ name ]
|
|
raise AttributeError("%s not found in %s" % (name,self))
|
|
|
|
class PackageManager:
|
|
|
|
def __init__(self, path ):
|
|
self.__path = os.path.abspath( path )
|
|
self.__packagesmod = new_module( "packages" )
|
|
|
|
self.__packages = {}
|
|
self.__exports = {}
|
|
|
|
print("PackageManager loads from %s" % (self.__path,))
|
|
self.__load()
|
|
|
|
def loadPackageFromPath(self,path, name = None):
|
|
log("PackageManager: manually load Package from path {0}".format(path))
|
|
if name is None:
|
|
name = os.path.basename(path)
|
|
p = Package( self, path, name)
|
|
self.__add( name, p )
|
|
|
|
def __load(self):
|
|
plist = os.listdir( self.__path )
|
|
for pname in plist:
|
|
ppath = "%s/%s" % (self.__path,pname)
|
|
|
|
if (os.path.isdir(ppath)):
|
|
print("PackageManager loads %s" % (pname,))
|
|
p = Package( self, ppath, pname )
|
|
|
|
self.__add( pname, p )
|
|
|
|
def __add(self,name,package):
|
|
self.__packages[ name ] = package
|
|
setattr( self.__packagesmod, name, package.module() )
|
|
|
|
|
|
|
|
def export(self, name, o):
|
|
self.__exports[ name ] = o
|
|
|
|
def imp(self, modname):
|
|
if modname in self.__exports:
|
|
return self.__exports[ modname ]
|
|
return None
|
|
|
|
def list_exports(self):
|
|
return list( self.__exports.keys() )
|
|
|
|
def exports(self):
|
|
return self.__exports
|
|
|
|
def packages(self):
|
|
return self.__packages
|
|
|
|
def __getattr__(self, name):
|
|
if name in self.__packages:
|
|
return self.__packages[ name ]
|
|
raise AttributeError("%s not found in %s" % (name,self))
|