diff --git a/logya/path.py b/logya/path.py deleted file mode 100644 index cd90b19..0000000 --- a/logya/path.py +++ /dev/null @@ -1,86 +0,0 @@ -# -*- coding: utf-8 -*- -# FIXME make this module obsolete -# Wrappers for functions from os.path. -import os -import re - -from logya import allowed_exts - -re_url_replace = re.compile(r'[\/\s_]+') - - -class PathResourceError(Exception): - pass - - -def canonical_filename(name): - """Get file name from given path or file. - - If name is not recognized as a file name a /index.html is added. To be - recognized as a file name it must end with an allowed extension. - Leading slashes are stripped off. - """ - - # Paths for generated indexes do not start with a slash. - if not name.startswith('/'): - name = '/' + name - - # Only allowed extension will be written to a file, otherwise a - # directory with the name is created and content written to index.html. - ext = os.path.splitext(name)[1] - if not ext or ext.lstrip('.') not in allowed_exts: - name = os.path.join(name, 'index.html') - - return name.lstrip('/') - - -def join(basedir, *args, **kwargs): - """Get joined name relative to basedir for file or path name. - - Raises an exception if resource is required and doesn't exist. - """ - - path = os.path.join(basedir, *args) - if kwargs.get('required') and not os.path.exists(path): - raise PathResourceError( - 'Resource at path {} does not exist.'.format(path)) - return path - - -def parent_dirs(url): - """Returns a list of parent directories for url without the root /.""" - - return url.strip('/').split('/')[:-1] - - -def parent_paths(dirs): - """Returns a list of absolute parent directory paths for given dirs.""" - - return ('/'.join(dirs[:i + 1]) for i, _ in enumerate(dirs)) - - -def slugify(path): - return re.sub(re_url_replace, '-', path.strip()).lower() - - -def target_file(basedir, url): - """Determine the absolute filename to create and return it. - - If a URL points to a directory 'index.html' will be appended. - """ - - filename = canonical_filename(url) - return os.path.join(basedir, filename) - - -def url_from_filename(filename, basedir=None): - """Creates a URL to be used in docs from basedir and filename.""" - - ext = os.path.splitext(filename)[1] - if ext: - filename = filename.replace(ext, '/') - - if basedir: - filename = filename.replace(basedir, '') - - return filename diff --git a/logya/serve.py b/logya/serve.py deleted file mode 100644 index e3c764e..0000000 --- a/logya/serve.py +++ /dev/null @@ -1,139 +0,0 @@ -# -*- coding: utf-8 -*- -import os -import shutil -import logging - -from logya.core import Logya -from logya.compat import unquote, urlparse -from logya.compat import HTTPServer -from logya.compat import SimpleHTTPRequestHandler -from logya.writer import DocWriter - - -class Serve(Logya): - """Serve files from deploy directory.""" - - def __init__(self, **kwargs): - super(Serve, self).__init__() - - # If not passed as command arguments host and port are set to None. - self.host = kwargs.get('host') or 'localhost' - self.port = kwargs.get('port') or 8080 - - Server(self).serve() - - def init_env(self): - super(Serve, self).init_env() - - # Override base_url so resources linked with absolute internal URLs - # in templates are served locally. - base_url = 'http://{}:{:d}'.format(self.host, self.port) - self.template.vars['base_url'] = base_url - - # Set debug var to true in serve mode. - self.template.vars['debug'] = True - - def update_file(self, src, dst): - """Copy source file to destination file if source is newer. - - Creates destination directory and file if they don't exist. - """ - - # Make sure destination directory exists. - dir_deploy = os.path.dirname(dst) - os.makedirs(dir_deploy, exist_ok=True) - - if not os.path.isfile(dst): - shutil.copy(src, dir_deploy) - return True - - if os.path.getmtime(src) > os.path.getmtime(dst): - shutil.copyfile(src, dst) - return True - - return False - - def refresh_resource(self, path): - """Refresh resource corresponding to given path. - - Static files are updated if necessary, documents are read, parsed and - written to the corresponding destination in the deploy directory.""" - - # Keep track of configuration changes. - self.init_env() - - # If a static file is requested update it and return. - path_rel = path.lstrip('/') - # Use only the URL path and ignore possible query params issue #3. - src = unquote(urlparse(os.path.join(self.dir_static, path_rel)).path) - - if os.path.isfile(src): - dst = os.path.join(self.dir_deploy, path_rel) - - if self.update_file(src, dst): - logging.info('Copied file %s to %s', src, dst) - return - - logging.info('%s not newer than %s', src, dst) - return - - # Newly build generated docs and index for HTML page requests. - if path.endswith(('/', '.html', '.htm')): - self.build_index(mode='serve') - - # Try to get doc at path, regenerate it and return. - doc = None - if path in self.docs: - doc = self.docs[path] - else: - # If a path like /index.html is requested also try to find /. - alt_path = os.path.dirname(path) - if not alt_path.endswith('/'): - alt_path = '{}/'.format(alt_path) - if alt_path in self.docs: - doc = self.docs[alt_path] - - if doc: - docwriter = DocWriter(self.dir_deploy, self.template) - docwriter.write(doc, self.get_doc_template(doc)) - self.write_index_files() - logging.info('Refreshed doc at URL: %s', path) - else: - # Try to refresh auto-generated index file. - path_index = path.strip('/') - if path_index in self.index: - self.write_index(path_index, self.index[path_index]) - - -class Server(HTTPServer): - """Logya HTTPServer based class to serve generated site.""" - - def __init__(self, logya): - """Initialize HTTPServer listening on the specified host and port.""" - - self.logya = logya - self.logya.init_env() - - logging.basicConfig(level=logging.INFO) - - HTTPServer.__init__( - self, (self.logya.host, self.logya.port), HTTPRequestHandler) - - def serve(self): - """Serve static files from logya deploy directory.""" - - os.chdir(self.logya.dir_deploy) - print('Serving on http://{}:{}/' - .format(self.logya.host, self.logya.port)) - self.serve_forever() - - -class HTTPRequestHandler(SimpleHTTPRequestHandler): - """Logya SimpleHTTPRequestHandler based class to return resources.""" - - def do_GET(self): - """Return refreshed resource.""" - - logging.info('Requested resource: %s', self.path) - self.server.logya.refresh_resource(self.path) - SimpleHTTPRequestHandler.do_GET(self) diff --git a/logya/writer.py b/logya/writer.py deleted file mode 100644 index c1de592..0000000 --- a/logya/writer.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -import io -import os - -from logya import path - -from yaml import dump -try: - from yaml import CDumper as Dumper -except ImportError: - from yaml import Dumper - - -def encode_content(headers, body): - """Encode headers and body in content format.""" - - return '---\n{}\n---\n{}'.format(dump(headers, Dumper=Dumper).strip(), body) - - -def write(filename, content, create_dirs=True): - """Write content to file. - - If create_dirs is true the parent directories of the file are created, if - they do not exist yet. - """ - - if create_dirs: - target = os.path.dirname(filename) - os.makedirs(target, exist_ok=True) - - with io.open(filename, 'w', encoding='utf-8') as f: - f.write(content) - - -def write_content(dir_target, headers, body): - """Write a file that can be parsed as content. - - This is can be used in scripts that extend Logya, but is not used in core - at the moment. - """ - - write(path.target_file(dir_target, headers['url']), encode_content(headers, body)) - - -class DocWriter(): - """Class for writing site documents.""" - - def __init__(self, dir_target, template): - """Set required properties.""" - - self.dir_target = dir_target - self.template = template - - def write(self, doc, template): - """Render and write document to created file.""" - - # Make a copy so no previous doc attributes are retained, that don't - # exist in current doc. - tpl_vars = self.template.vars.copy() - tpl_vars.update(doc) - - # Set additional template variables. - tpl_vars['canonical'] = tpl_vars['base_url'] + tpl_vars['url'] - - # Pre-render doc body so Jinja2 template tags can be used in content. - body = '' - if tpl_vars.get('body'): - body = self.template.env.from_string(tpl_vars['body']).render(tpl_vars) - tpl_vars['body'] = body - - page = self.template.env.get_template(template) - content = page.render(tpl_vars) - - write(path.target_file(self.dir_target, doc['url']), content)