hserver-fahrradboerse/hServer/hserver/packages/package.py

243 lines
6.0 KiB
Python

import os
import os.path
import sys
import gc
import importlib
import types
import hserver.api
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 __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.__packages[ pname ] = p
setattr( self.__packagesmod, pname, p.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))