| Index: third_party/pystache/src/locator.py
|
| diff --git a/third_party/pystache/src/locator.py b/third_party/pystache/src/locator.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..30c5b01e0106b6be1f776f9f159ee1aee45217f6
|
| --- /dev/null
|
| +++ b/third_party/pystache/src/locator.py
|
| @@ -0,0 +1,171 @@
|
| +# coding: utf-8
|
| +
|
| +"""
|
| +This module provides a Locator class for finding template files.
|
| +
|
| +"""
|
| +
|
| +import os
|
| +import re
|
| +import sys
|
| +
|
| +from pystache.common import TemplateNotFoundError
|
| +from pystache import defaults
|
| +
|
| +
|
| +class Locator(object):
|
| +
|
| + def __init__(self, extension=None):
|
| + """
|
| + Construct a template locator.
|
| +
|
| + Arguments:
|
| +
|
| + extension: the template file extension, without the leading dot.
|
| + Pass False for no extension (e.g. to use extensionless template
|
| + files). Defaults to the package default.
|
| +
|
| + """
|
| + if extension is None:
|
| + extension = defaults.TEMPLATE_EXTENSION
|
| +
|
| + self.template_extension = extension
|
| +
|
| + def get_object_directory(self, obj):
|
| + """
|
| + Return the directory containing an object's defining class.
|
| +
|
| + Returns None if there is no such directory, for example if the
|
| + class was defined in an interactive Python session, or in a
|
| + doctest that appears in a text file (rather than a Python file).
|
| +
|
| + """
|
| + if not hasattr(obj, '__module__'):
|
| + return None
|
| +
|
| + module = sys.modules[obj.__module__]
|
| +
|
| + if not hasattr(module, '__file__'):
|
| + # TODO: add a unit test for this case.
|
| + return None
|
| +
|
| + path = module.__file__
|
| +
|
| + return os.path.dirname(path)
|
| +
|
| + def make_template_name(self, obj):
|
| + """
|
| + Return the canonical template name for an object instance.
|
| +
|
| + This method converts Python-style class names (PEP 8's recommended
|
| + CamelCase, aka CapWords) to lower_case_with_underscords. Here
|
| + is an example with code:
|
| +
|
| + >>> class HelloWorld(object):
|
| + ... pass
|
| + >>> hi = HelloWorld()
|
| + >>>
|
| + >>> locator = Locator()
|
| + >>> locator.make_template_name(hi)
|
| + 'hello_world'
|
| +
|
| + """
|
| + template_name = obj.__class__.__name__
|
| +
|
| + def repl(match):
|
| + return '_' + match.group(0).lower()
|
| +
|
| + return re.sub('[A-Z]', repl, template_name)[1:]
|
| +
|
| + def make_file_name(self, template_name, template_extension=None):
|
| + """
|
| + Generate and return the file name for the given template name.
|
| +
|
| + Arguments:
|
| +
|
| + template_extension: defaults to the instance's extension.
|
| +
|
| + """
|
| + file_name = template_name
|
| +
|
| + if template_extension is None:
|
| + template_extension = self.template_extension
|
| +
|
| + if template_extension is not False:
|
| + file_name += os.path.extsep + template_extension
|
| +
|
| + return file_name
|
| +
|
| + def _find_path(self, search_dirs, file_name):
|
| + """
|
| + Search for the given file, and return the path.
|
| +
|
| + Returns None if the file is not found.
|
| +
|
| + """
|
| + for dir_path in search_dirs:
|
| + file_path = os.path.join(dir_path, file_name)
|
| + if os.path.exists(file_path):
|
| + return file_path
|
| +
|
| + return None
|
| +
|
| + def _find_path_required(self, search_dirs, file_name):
|
| + """
|
| + Return the path to a template with the given file name.
|
| +
|
| + """
|
| + path = self._find_path(search_dirs, file_name)
|
| +
|
| + if path is None:
|
| + raise TemplateNotFoundError('File %s not found in dirs: %s' %
|
| + (repr(file_name), repr(search_dirs)))
|
| +
|
| + return path
|
| +
|
| + def find_file(self, file_name, search_dirs):
|
| + """
|
| + Return the path to a template with the given file name.
|
| +
|
| + Arguments:
|
| +
|
| + file_name: the file name of the template.
|
| +
|
| + search_dirs: the list of directories in which to search.
|
| +
|
| + """
|
| + return self._find_path_required(search_dirs, file_name)
|
| +
|
| + def find_name(self, template_name, search_dirs):
|
| + """
|
| + Return the path to a template with the given name.
|
| +
|
| + Arguments:
|
| +
|
| + template_name: the name of the template.
|
| +
|
| + search_dirs: the list of directories in which to search.
|
| +
|
| + """
|
| + file_name = self.make_file_name(template_name)
|
| +
|
| + return self._find_path_required(search_dirs, file_name)
|
| +
|
| + def find_object(self, obj, search_dirs, file_name=None):
|
| + """
|
| + Return the path to a template associated with the given object.
|
| +
|
| + """
|
| + if file_name is None:
|
| + # TODO: should we define a make_file_name() method?
|
| + template_name = self.make_template_name(obj)
|
| + file_name = self.make_file_name(template_name)
|
| +
|
| + dir_path = self.get_object_directory(obj)
|
| +
|
| + if dir_path is not None:
|
| + search_dirs = [dir_path] + search_dirs
|
| +
|
| + path = self._find_path_required(search_dirs, file_name)
|
| +
|
| + return path
|
|
|