123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- ##@brief This module contains usefull functions to handle lodelsites on FS
-
- import os
- import os.path
- import shutil
-
- from lodel.context import LodelContext
- from lodel import buildconf #No need to protect it in Contexts
-
- LodelContext.expose_modules(globals(), {
- 'lodel.logger' : 'logger',
- 'lodel.plugin.datasource_plugin': ['AbstractDatasource', 'DatasourcePlugin'],
- 'lodel.exceptions': ['LodelFatalError'],
- 'lodel.settings': ['Settings']})
-
- from .exceptions import *
-
- LODELSITE_DATA_PATH, LODELSITE_CONTEXTS_PATH = LodelContext.lodelsites_paths()
-
-
- ##@brief Define directories architecture
- #
- #@note useless because a lot of those stuff would be hardcoded
- LODELSITE_INSTALL_MODEL = {
- 'datas' : ['uploads', 'conf.d'], #For datadir
- 'ctx': ['leapi_dyncode'] #for context dir
- }
-
- CONF_MODELS = os.path.join(os.path.dirname(__file__),'model_conf.d/')
- CONF_AUTOCONF_FILENAME = 'lodelsites_autoconfig.ini'
-
- ##@brief Util function that returns both datadir and contextdir paths
- #@param name str : the site shortname
- #@return a tuple (datadir, contextdir)
- def name2path(name):
- return (os.path.join(LODELSITE_DATA_PATH, name),
- os.path.join(LODELSITE_CONTEXTS_PATH, name))
- ##@brief Util function that indicates if a site exists or not
- #
- #This function only checks that both paths returned by name2path are
- #existing directories
- #@param name str : site shortname
- #@return a bool
- #@throws LodelSiteDatasourceInconsistency if inconsistency detected on FS
- def site_exists(name):
- paths = name2paths(name)
-
- if name == Settings.sitename:
- msg = 'Site shortname "%s" is conflicting with the Lodelsites instance name' % name
- raise LodelSiteDatasourceError(msg)
-
- for path in paths:
- if os.path.isfile(path):
- msg = 'Will trying to determine if a lodesite "%s" exists we \
- found that "%s" is a file, but a directory was expected' % (name, path)
- raise LodelSiteDatasourceInconsistency(msg)
-
- res = [False, False]
- res = [os.path.isdir(paths[0]),
- os.path.isdir(paths[1])]
- if res[0] != res[1]:
- msg = 'Inconsistency detected on filesystem will trying to determine \
- wether a lodelsite exists or not : '
- if res[0]:
- msg += 'datadir was found but no contextdir'
- else:
- msg += 'contextdir found but no datadir'
- raise LodelSiteDatasourceInconsistency(msg)
- return res[0]
-
- ##@brief Create sites directory on filesystem
- #@param name str : site shortname
- #@return None
- #@throws LodelSiteDatasourceError if something fails
- #@throws LodelSiteDatasourceError if the site already exists
- #@todo make uploads directory name configurable
- def site_directories_creation(name):
- if site_exists(name):
- raise LodelSiteDatasourceError('This site identified by "%s" \
- already exists' % name)
-
- data_path, ctx_path = name2paths(name)
- #Starting by creating both directories
- #Datadir
- try:
- os.mkdir(data_path)
- except FileExistsError:
- logger.critical('This should never happen ! We just checked that this \
- directory does not exist. BAILOUT !')
- raise LodelFatalError('Unable to create data directory for lodelsite \
- "%s", file exists')
- except Exception as e:
- raise LodelFatalError('Unable to create data directory for lodelsite \
- "%s" : %s' % (name,e))
- #Context dir
- try:
- os.mkdir(ctx_path)
- except FileExistsError:
- logger.critical('This should never happen ! We just checked that this \
- directory does not exist. BAILOUT !')
- raise LodelFatalError('Unable to create context directory for \
- lodelsite "%s", file exists' % name)
- except Exception as e:
- raise LodelFatalError('Unable to create context directory for \
- lodelsite "%s" : %s' % (name, e))
-
- #Creates lodel site data subdirectories
- for data_subdirectory in LODELSITE_INSTALL_MODEL['datas']:
- to_create = os.path.join(data_path, data_subdirectory)
- try:
- os.mkdir(to_create)
- except FileExistsError:
- logger.critical('This should never happen ! We just checked that this \
- directory does not exist. BAILOUT !')
- except Exception as e:
- raise LodelFatalError('Unable to create %s directory for \
- lodelsite "%s" : %s' % (d,name, e))
-
-
- def site_lodelpkg_link_creation(name):
- dst_path = os.path.join(name2path(name)[1], lodel)
- src_path = LODEL_PKG_PATH
-
- try:
- os.symlink(src_path, dst_path)
- except FileExistsError:
- logger.critical('This should never happen ! We just checked that this \
- directory does not exist. BAILOUT !')
- raise LodelFatalError('Unable to create lodel package symlink for \
- lodelsite "%s", link exists in dir %s' % (name, directory))
- except Exception as e:
- raise LodelFatalError('Unable to create lodel package symlink for \
- lodelsite "%s" : %s' % (name, e))
-
- def site_context_init_creation(name):
- directory = name2path(name)[1]
- try:
- open('x', os.path.join(directory, '__init__.py')).close()
- except FileExistsError:
- logger.critical('This should never happen ! We just checked that this \
- directory does not exist. BAILOUT !')
- raise LodelFatalError('Unable to create python __init__ file for \
- lodelsite context "%s", file exists in dir %s' % (name, directory))
- except Exception as e:
- raise LodelFatalError('Unable to create python _init__ file for \
- lodelsite "%s" : %s' % (name, e))
-
-
- ##@brief Generate conffile containing informations set by lodelsites EM
- #
- #@param sitename str : site shortname
- #@param em_groups list : list of str -> selected em_groups
- #@param extensions list : list of str -> activated extensions
- #@return config file content
- def generate_conf(sitename, groups, extensions):
- tpl = """
- [lodel2]
- sitename = {sitename}
- extensions = {extensions}
-
- [lodel2.editorialmodel]
- groups = {em_groups}
- """
- return tpl.format(
- sitename = sitename,
- extensions = ', '.join(extensions),
- em_groups = ', '.join(groups))
-
- ##@brief Delete generated conf and generate a new one
- #@param sitename str : site shortname
- #@param em_groups list : list of str -> selected em_groups
- #@param extensions list : list of str -> activated extensions
- #@return None
- def update_conf(sitename, groups, extensions):
- data_path, _ = name2path(sitename)
- conf_dir = os.path.join(data_path, 'conf.d') #Booo hardcoded
- autoconf = os.path.join(conf_dir, CONF_AUTOCONF_FILENAME)
- try:
- os.unlink(autoconf)
- except Exception as e:
- #Dropping error on deletion
- logger.warning('Unable to delete generated conf %s when trying to \
- update it %s' % (autoconf, e))
- with open(autoconf, 'w+') as cfp:
- cfp.write(generate_conf(sitename, groups, extensions))
- logger.info('Generated configuration file update for %s' % sitename)
-
- ##@brief Copies conffile from model and generates a conffile from given info
- #@param sitename str : site shortname
- #@param em_groups list : list of str -> selected em_groups
- #@param extensions list : list of str -> activated extensions
- #@return None
- def make_confs(sitename, groups, extensions):
- data_path, _ = name2path(sitename)
- conf_dir = os.path.join(data_path, 'conf.d') #Booo hardcoded
- #Config copy & forge
- for conffile in os.listdir(CONF_MODELS):
- if conffile.endswith('.ini'):
- conffile = os.path.join(CONF_MODELS, conffile)
- target_conffile = os.path.join(conf_dir, conffile)
- logger.info(
- "Copying conffile %s -> %s" % (conffile, target_conffile))
- shutil.copyfile(conffile, target_conffile)
- #Creating generated conf
- autoconf = os.path.join(conf_dir, CONF_AUTOCONF_FILENAME)
- with open(autoconf, 'w+') as cfp:
- cfp.write(generate_conf(sitename, groups, extensions))
- logger.info("Configuration file %s generated" % (autoconf))
-
- ##@brief Deletes all files related to a site
- #@warning can lead to dirty bugs if the site is running...
- def purge(sitename):
- for todel in name2paths(sitename):
- try:
- shutil.rmtree(todel)
- except Exception as e:
- logger.error('Unable to delete "%s" folder' % todel)
- logger.info('"%s" files are deleted' % sitename)
|