No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

fs_utils.py 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. ##@brief This module contains usefull function to handle lodelsites on FS
  2. import os
  3. import os.path
  4. import shutil
  5. from lodel.context import LodelContext
  6. from lodel import buildconf #No need to protect it in Contexts
  7. LodelContext.expose_module(globals(), {
  8. 'lodel.plugin.datasource_plugin': ['AbstractDatasource', 'DatasourcePlugin'],
  9. 'lodel.exceptions': ['LodelFatalError'],
  10. 'lodel.settings': 'Settings'})
  11. from .exceptions import *
  12. LODELSITE_DATAS_PATH = os.path.join(buildconf.LODEL2VARDIR,'sites_datas')
  13. LODELSITE_CONTEXTS_PATH = os.path.join(
  14. buildconf.LODEL2VARDIRE, '.sites_contexts')
  15. ##@brief Define directories architecture
  16. #
  17. #@note useless because a lot of those stuff would be hardcoded
  18. LODELSITE_INSTALL_MODEL = {
  19. 'datas' : ['uploads', 'conf.d'], #For datadir
  20. 'ctx': ['lodel_pkg'] #for context dir
  21. }
  22. CONF_MODELS = os.path.join(os.path.dirname(__file__),'model_conf.d/')
  23. CONF_AUTOCONF_FILENAME = 'lodelsites_autoconfig.ini'
  24. ##@brief Util function that returns both datadir and contextdir paths
  25. #@param name str : the site shortname
  26. #@return a tuple (datadir, contextdir)
  27. def name2paths(name):
  28. return (os.path.join(LODELSITE_DATAS_PATH, name),
  29. os.path.join(LODELSITE_CONTEXTS_PATH, name))
  30. ##@brief Util function that indicate if a site exists or not
  31. #
  32. #This function only checks that both paths returned by name2path are
  33. #existing directories
  34. #@param name str : site shortname
  35. #@return a bool
  36. #@throws LodelSiteDatasourceInconsistency if inconsistency detected on FS
  37. def site_exists(name):
  38. paths = name2paths(name)
  39. for path in paths:
  40. if os.path.is_file(path):
  41. msg = 'Will trying to determine if a lodesite "%s" exists we \
  42. found that "%s" is a file, but a directory was expected' % (name, path)
  43. raise LodelSiteDatasourceInconsistency(msg)
  44. res = [False, False]
  45. res = [os.is_dir(paths[0]),
  46. os.is_dir(paths[1])]
  47. if res[0] != res[1]:
  48. msg = 'Inconsistency detected on filesystem will trying to determine \
  49. wether a lodelsite exists or not : '
  50. if res[0]:
  51. msg += 'datadir was found but no contextdir'
  52. else:
  53. msg += 'contextdir found but no datadir'
  54. raise LodelSiteDatasourceInconsistency(msg)
  55. return res[0]
  56. ##@brief Create sites directory on filesystem
  57. #@param name str : site shortname
  58. #@return None
  59. #@throws LodelSiteDatasourceError if something fails
  60. #@throws LodelSiteDatasourceError if the site allready exists
  61. #@todo make uploads directory name configurable
  62. def site_directories_creation(name):
  63. if site_exists(name):
  64. raise LodelSiteDatasourceError('This site identified by "%s" \
  65. allready exists' % name)
  66. data_path, ctx_path = name2paths(name)
  67. #Starting by creating both directories
  68. #Datadir
  69. try:
  70. os.mkdir(data_path)
  71. except FileExistsError:
  72. logger.fatal('This should never append ! We just checked that this \
  73. directory do not exists. BAILOUT !')
  74. raise LodelFatalError('Unable to create data directory for lodelsite \
  75. "%s", file exists')
  76. except Exception as e:
  77. raise LodelFataError(('Unable to create data directory for lodelsite \
  78. "%s" : ' % name) + e)
  79. #Context dir
  80. try:
  81. os.mkdir(ctx_path)
  82. except FileExistsErrpr:
  83. logger.fatal('This should never append ! We just checked that this \
  84. directory do not exists. BAILOUT !')
  85. raise LodelFatalError('Unable to create context directory for \
  86. lodelsite "%s", file exists')
  87. except Exception as e:
  88. raise LodelFataError(('Unable to create context directory for \
  89. lodelsite "%s" : ' % name) + e)
  90. #Child directories
  91. for mname, ccd in (('datas', data_path), ('ctx', ctx_path)):
  92. ccd = data_path
  93. for d in LODELSITE_INSTALL_MODEL[mname]:
  94. to_create = os.path.join(ccd, d)
  95. try:
  96. os.mkdir(to_create)
  97. except FileExistsError:
  98. logger.fatal('This should never append ! We just created parent \
  99. directory. BAILOUT !')
  100. except Exception as e:
  101. raise LodelFatalError(('Unable to create %s directory for \
  102. lodelsite "%s" : ' % (d,name)) + e)
  103. ##@brief Generate conffile containing informations set by lodelsites EM
  104. #
  105. #@param sitename str : site shortname
  106. #@param em_groups list : list of str -> selected em_groups
  107. #@param extensions list : list of str -> activated extensions
  108. #@return config file content
  109. def generate_conf(sitename, groups, extensions):
  110. tpl = """
  111. [lodel2]
  112. sitename = {sitename}
  113. extensions = {extensions}
  114. [lodel2.editorialmodel]
  115. groups = {em_groups}
  116. """
  117. return tpl.format(
  118. sitename = sitename,
  119. extensions = ', '.join(extensions),
  120. em_groups = ', '.join(groups))
  121. ##@brief Delete generated conf and generate a new one
  122. #@param sitename str : site shortname
  123. #@param em_groups list : list of str -> selected em_groups
  124. #@param extensions list : list of str -> activated extensions
  125. #@return None
  126. def update_conf(sitename, groups, extensions):
  127. data_path, _ = name2path(sitename)
  128. conf_dir = os.path.join(data_path, 'conf.d') #Booo hardcoded
  129. autoconf = os.path.join(conf_dir, CONF_AUTOCONF_FILENAME)
  130. try:
  131. os.unlink(autoconf)
  132. except Exception as e:
  133. #Dropping error on deletion
  134. logger.warning('Unable to delete generated conf %s when trying to \
  135. update it %s' % (autoconf, e))
  136. with open(autoconf, 'w+') as cfp:
  137. cfp.write(generate_conf(sitename, groups, extensions))
  138. logger.info('Generated configuration file update for %s' % sitename)
  139. ##@brief Copy conffile from model and generate a conffile from given infos
  140. #@param sitename str : site shortname
  141. #@param em_groups list : list of str -> selected em_groups
  142. #@param extensions list : list of str -> activated extensions
  143. #@return None
  144. def make_confs(sitename, groups, extensions):
  145. data_path, _ = name2path(sitename)
  146. conf_dir = os.path.join(data_path, 'conf.d') #Booo hardcoded
  147. #Config copy & forge
  148. for conffile in os.listdir(CONF_MODELS):
  149. if conffile.endswith('.ini'):
  150. conffile = os.path.join(CONF_MODELS, conffile)
  151. target_conffile = os.path.join(conf_dir, conffile)
  152. logger.info(
  153. "Copying conffile %s -> %s" % (conffile, target_conffile))
  154. shutil.copyfile(conffile, target_conffile)
  155. #Creating generated conf
  156. autoconf = os.path.join(conf_dir, CONF_AUTOCONF_FILENAME)
  157. with open(autoconf, 'w+') as cfp:
  158. cfp.write(generate_conf(sitename, groups, extensions))
  159. logger.info("Configuration file %s generated" % (autoconf))
  160. ##@brief Delete all files related to a site
  161. #@warning can lead to dirty bugs if the site is running...
  162. def purge(sitename):
  163. for todel in name2paths:
  164. try:
  165. shutil.rmtree(todel)
  166. except Exception as e:
  167. logger.error('Unable to delete "%s" folder' % todel)
  168. logger.info('"%s" files are deleted' % sitename)