|
@@ -47,7 +47,8 @@ class ContextModuleError(ContextError):
|
47
|
47
|
pass
|
48
|
48
|
|
49
|
49
|
def dir_for_context(site_identifier):
|
50
|
|
- return os.path.join(lodelsites.__path__[0], site_identifier)
|
|
50
|
+ _, ctx_path = LodelContext.lodelsites_paths()
|
|
51
|
+ return os.path.join(ctx_path, site_identifier)
|
51
|
52
|
|
52
|
53
|
|
53
|
54
|
##@brief Designed to permit dynamic packages creation from the lodel package
|
|
@@ -79,7 +80,7 @@ class LodelMetaPathFinder(importlib.abc.MetaPathFinder):
|
79
|
80
|
#make a more educated guess about what spec to return
|
80
|
81
|
#@see https://docs.python.org/3/library/importlib.html#importlib.abc.MetaPathFinder
|
81
|
82
|
def find_spec(fullname, path, target = None):
|
82
|
|
- if fullname.startswith(CTX_PKG):
|
|
83
|
+ if fullname.startswith(CTX_PKG+'.'):
|
83
|
84
|
spl = fullname.split('.')
|
84
|
85
|
site_identifier = spl[1]
|
85
|
86
|
#creating a symlink to represent the lodel site package
|
|
@@ -89,6 +90,7 @@ class LodelMetaPathFinder(importlib.abc.MetaPathFinder):
|
89
|
90
|
#Cache invalidation after we "created" the new package
|
90
|
91
|
#importlib.invalidate_caches()
|
91
|
92
|
return None
|
|
93
|
+ #def invalidate_caches(): pass
|
92
|
94
|
|
93
|
95
|
|
94
|
96
|
##@brief Class designed to handle context switching and virtual module
|
|
@@ -170,7 +172,7 @@ site_id set to None when we are in MULTISITE beahavior")
|
170
|
172
|
else:
|
171
|
173
|
#More verification can be done here (singleton specs ? )
|
172
|
174
|
self.__class__._current = self.__class__._contexts = self
|
173
|
|
- self.__pkg_name = ''
|
|
175
|
+ self.__pkg_name = 'lodel'
|
174
|
176
|
self.__package = lodel
|
175
|
177
|
self.__instance_path = os.getcwd()
|
176
|
178
|
return
|
|
@@ -186,7 +188,7 @@ site_id when we are in MONOSITE beahvior")
|
186
|
188
|
raise ContextError(
|
187
|
189
|
"A context named '%s' allready exists." % site_id)
|
188
|
190
|
self.__id = site_id
|
189
|
|
- self.__pkg_name = '%s.%s.' % (CTX_PKG, site_id)
|
|
191
|
+ self.__pkg_name = '%s.%s' % (CTX_PKG, site_id)
|
190
|
192
|
|
191
|
193
|
if instance_path is None:
|
192
|
194
|
"""
|
|
@@ -199,7 +201,8 @@ a context without a path......")
|
199
|
201
|
else:
|
200
|
202
|
self.__instance_path = os.path.realpath(instance_path)
|
201
|
203
|
#Importing the site package to trigger its creation
|
202
|
|
- self.__package = importlib.import_module(self.__pkg_name)
|
|
204
|
+ self.__package = importlib.import_module(
|
|
205
|
+ self.__pkg_name)
|
203
|
206
|
self.__class__._contexts[site_id] = self
|
204
|
207
|
#Designed to be use by with statement
|
205
|
208
|
self.__previous_ctx = None
|
|
@@ -285,12 +288,6 @@ site_id set to None when we are in MULTISITE beahavior")
|
285
|
288
|
if cls.current_id != LOAD_CTX and site_id != LOAD_CTX:
|
286
|
289
|
raise ContextError("Not allowed to switch into a site context \
|
287
|
290
|
from another site context. You have to switch back to LOAD_CTX before")
|
288
|
|
- if site_id != LOAD_CTX and cls.__lodelsites_paths is None:
|
289
|
|
- #The paths are not set yet. That mean that we switch into another
|
290
|
|
- #context for the first time. We should be able to access the
|
291
|
|
- #LOAD_CTX settings (containing the sites_handler_name)
|
292
|
|
- cls._generate_lodelsites_path()
|
293
|
|
-
|
294
|
291
|
wanted_ctx = cls._contexts[site_id]
|
295
|
292
|
if hasattr(wanted_ctx, '__instance_path'):
|
296
|
293
|
os.chdir(self.__instance_path) #May cause problems and may be obsolete
|
|
@@ -385,13 +382,24 @@ initialize it anymore")
|
385
|
382
|
raise ContextError("Invalid flag given : %s" % type)
|
386
|
383
|
cls._type = type
|
387
|
384
|
if cls._type == cls.MULTISITE:
|
|
385
|
+ #Woot hardcoded stuff with no idea of what it implies :-P
|
|
386
|
+ lodelsites_path = os.getcwd() #Same assert in the loader
|
|
387
|
+ cls.__lodelsites_paths = (
|
|
388
|
+ os.path.join(lodelsites_path, buildconf.MULTISITE_DATADIR),
|
|
389
|
+ os.path.join(lodelsites_path, os.path.join(
|
|
390
|
+ buildconf.MULTISITE_CONTEXTDIR, 'lodelsites')))
|
|
391
|
+ #Now we are able to import lodelsites package
|
|
392
|
+ sys.path.append(os.path.dirname(cls.__lodelsites_paths[1]))
|
|
393
|
+ if 'lodelsites' not in sys.modules:
|
|
394
|
+ import lodelsites
|
|
395
|
+ globals()['lodelsites'] = sys.modules['lodelsites']
|
|
396
|
+ #End of Woot
|
388
|
397
|
cls._contexts = dict()
|
389
|
398
|
#Add custom MetaPathFinder allowing implementing custom imports
|
390
|
399
|
sys.meta_path = [LodelMetaPathFinder] + sys.meta_path
|
391
|
400
|
#Create and set __loader__ context
|
392
|
401
|
cls.new(LOAD_CTX)
|
393
|
402
|
cls.set(LOAD_CTX)
|
394
|
|
-
|
395
|
403
|
else:
|
396
|
404
|
#Add a single context with no site_id
|
397
|
405
|
cls._contexts = cls._current = cls(None)
|
|
@@ -407,7 +415,8 @@ initialize it anymore")
|
407
|
415
|
def context_dir(cls):
|
408
|
416
|
if cls._type == cls.MONOSITE:
|
409
|
417
|
return './'
|
410
|
|
- return dir_for_context(cls._current.__id)
|
|
418
|
+ return os.path.join(cls.__lodelsites_paths[1],
|
|
419
|
+ cls._current.__id)
|
411
|
420
|
|
412
|
421
|
|
413
|
422
|
##@brief Validate a context identifier
|
|
@@ -468,35 +477,10 @@ MONOSITE mode")
|
468
|
477
|
#in this order)
|
469
|
478
|
@classmethod
|
470
|
479
|
def lodelsites_paths(cls):
|
|
480
|
+ if cls.__lodelsites_paths is None:
|
|
481
|
+ raise ContextError('No paths available')
|
471
|
482
|
return copy.copy(cls.__lodelsites_paths)
|
472
|
483
|
|
473
|
|
- ##@brief Generate lodelsites paths from LOAD_CTX configuration
|
474
|
|
- #
|
475
|
|
- #@warning Handles import of the lodelsites package
|
476
|
|
- #
|
477
|
|
- #Called when the first context switch outside LOAD_CTX is done
|
478
|
|
- @classmethod
|
479
|
|
- def _generate_lodelsites_path(cls):
|
480
|
|
- if cls.__current.__id != LOAD_CTX:
|
481
|
|
- raise ContextError("Not allowed when not in LOAD_CTX !!!")
|
482
|
|
- if cls.__lodelsites_paths is not None:
|
483
|
|
- raise ContextError("Allready done !!!")
|
484
|
|
- load_ctx_settings = cls.module('lodel.settings.setting.SettingsRO')
|
485
|
|
- lodesites_name = load_ctx_settings.lodelsites.name
|
486
|
|
- del(globals()['lodel.settings.setting.SettingsRO']) #Not sure !
|
487
|
|
- lodelsites_path = os.path.join(
|
488
|
|
- buildconf.LODEL2VARDIR, lodelsites_name)
|
489
|
|
- cls.__lodelsites_paths = (
|
490
|
|
- os.path.join(lodelsites_path, buildconf.MULTISITE_DATADIR),
|
491
|
|
- os.path.join(lodelsites_path, os.path.join(
|
492
|
|
- buildconf.MULTISITE_CONTEXTDIR, 'lodelsites')))
|
493
|
|
- #Now we are able to import lodelsites package
|
494
|
|
- sys.path.append(cls.__lodelsites_paths[1])
|
495
|
|
- if 'lodelsites' not in sys.modules:
|
496
|
|
- import lodelsites
|
497
|
|
- else:
|
498
|
|
- globals()['lodelsites'] = sys.modules['lodelsites']
|
499
|
|
-
|
500
|
484
|
##@brief Utility method to expose a module with an alias name in globals
|
501
|
485
|
#@param globs globals() : concerned globals dict
|
502
|
486
|
#@param fullname str : module fullname
|
|
@@ -539,11 +523,12 @@ MONOSITE mode")
|
539
|
523
|
#@param module_fullname str : a module fullname
|
540
|
524
|
#@return The module name in the current context
|
541
|
525
|
def _translate(self, module_fullname):
|
542
|
|
- if not module_fullname.startswith('lodel') and \
|
543
|
|
- not module_fullname.startswith('leapi_dyncode'):
|
544
|
|
- raise ContextModuleError("Given module is not lodel nor dyncode \
|
|
526
|
+ if module_fullname.startswith('lodel'):
|
|
527
|
+ return module_fullname.replace('lodel', self.__pkg_name)
|
|
528
|
+ if module_fullname.startswith('leapi_dyncode'):
|
|
529
|
+ return self.__pkg_name+'.'+module_fullname
|
|
530
|
+ raise ContextModuleError("Given module is not lodel nor dyncode \
|
545
|
531
|
or any submodule : '%s'" % module_fullname)
|
546
|
|
- return self.__pkg_name+module_fullname
|
547
|
532
|
|
548
|
533
|
##@brief Implements the with statement behavior
|
549
|
534
|
#@see https://www.python.org/dev/peps/pep-0343/
|