Coverage for lino/utils/config.py : 35%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# -*- coding: UTF-8 -*- # Copyright 2009-2015 Luc Saffre # License: BSD (see file COPYING for details)
and installs as :attr:`SITE.confdirs <lino.core.site.Site.confdirs>`.
It creates a list `config_dirs` of all configuration directories by looping through :attr:`lino.core.site.Site.installed_plugins` and taking those whose source directory has a :xfile:`config` subdir.
The mechanism in this module emulates the behaviour of Django's and Jinja's template loaders.
We cannot use the Jinja loader because Jinja's `get_template` method returns a `Template`, and Jinja templates don't know their filename. One possibility might be to write a special Jinja Template class...
"""
"""A directory that may contain configuration files.
"""
return "ConfigDir %s" % self.name + iif( self.writeable, " (writeable)", "")
raise Exception("Oops, ConfigDirCache was already instantiated!")
config_dirs.append(ConfigDir(pth.decode(fs_encoding), False))
# logger.info("add_config_dir %s %s", name, pth) # config_dirs.append(ConfigDir(pth.decode(fs_encoding), False))
self.LOCAL_CONFIG_DIR = ConfigDir(p, True) config_dirs.append(self.LOCAL_CONFIG_DIR) # print "20140625 Local config directory %s." % p # else: # print "20140625 No local config directory.", p # else: # print "20140625 Not a local project directory."
# logger.info('config_dirs:\n%s', '\n'.join([ # repr(cd) for cd in config_dirs]))
""" Return the full path of the first occurence within the :class:`lino.utils.config.ConfigDirCache` of a file named `filename`
""" if os.path.isabs(fn): return fn if len(groups) == 0: groups = [''] for group in groups: if group: prefix = join(*(group.split('/'))) else: prefix = '' for cd in self.config_dirs: ffn = join(cd.name, prefix, fn) if os.path.exists(ffn): return ffn
""" Returns a dict of `filename` -> `config_dir` entries for each config file on this site that matches the pattern. Loops through `config_dirs` and collects matching files. When a filename is provided by more than one app, then the latest app gets it.
`groups` is a tuple of strings, e.g. '', 'foo', 'foo/bar', ...
""" files = {} for group in groups: if group: prefix = os.path.sep + join(*(group.split('/'))) else: prefix = '' for cd in self.config_dirs: pth = cd.name + prefix if isdir(pth): for fn in os.listdir(pth): if fnmatch(fn, pattern): files.setdefault(fn, cd) return files
""" Like :func:`find_config_files`, but ignore babel variants: e.g. ignore "foo_fr.html" if "foo.html" exists. Note: but don't ignore "my_template.html" """ files = self.find_config_files('*' + template_ext, *groups) l = [] template_ext for name in list(files.keys()): basename = name[:-len(template_ext)] chunks = basename.split('_') if len(chunks) > 1: basename = '_'.join(chunks[:-1]) if basename + template_ext in files: continue l.append(name) l.sort() if not l: logger.warning( "find_template_config_files() : no matches for (%r, %r)", '*' + template_ext, groups) return l
""" Currently not used. Naming conventions for :xfile:`*.dtl` files are:
- the first detail is called appname.Model.dtl - If there are more Details, then they are called appname.Model.2.dtl, appname.Model.3.dtl etc.
The `sort()` below must remove the filename extension (".dtl") because otherwise the frist Detail would come last. """ files = list(self.find_config_files(pattern, *groups).items())
def fcmp(a, b): return cmp(a[0][:-4], b[0][:-4]) files.sort(fcmp) for group in groups: prefix = group.replace("/", os.sep) for filename, cd in files: filename = join(prefix, filename) ffn = join(cd.name, filename) logger.debug("Loading %s...", ffn) s = codecs.open(ffn, encoding='utf-8').read() loader(s, cd, filename)
"returns True if src is newer than target" try: src_st = os.stat(src) src_mt = src_st.st_mtime except OSError: # self.error("os.stat() failed: ",e) return False
try: target_st = os.stat(target) target_mt = target_st.st_mtime except OSError: # self.error("os.stat() failed: %s", e) return True
if src_mt - target_mt > MODIFY_WINDOW: return True return False
""" Write a dummy `.py` source file containing translatable messages that getmessages will find. """ raise Exception("Never used") target_fn = src_fn + '.py' if not must_make(src_fn, target_fn): logger.debug("%s is up-to-date.", target_fn) return try: f = file(target_fn, 'w') except IOError as e: logger.warning("Could not write file %s : %s", target_fn, e) return f.write("# this file is generated by Lino\n") f.write("from django.utils.translation import ugettext\n") for m in messages: f.write("ugettext(%r)\n" % m) f.close() logger.info("Wrote %d dummy messages to %s.", len(messages), target_fn) |