diff --git a/.gitignore b/.gitignore index 2775dcf..9a08bf3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *~ *.pyc .DS_Store +deploy deploy/* *.cprof *.profile diff --git a/hyde/ext/plugins/meta.py b/hyde/ext/plugins/meta.py index fd517d5..ba151de 100644 --- a/hyde/ext/plugins/meta.py +++ b/hyde/ext/plugins/meta.py @@ -78,7 +78,7 @@ class MetaPlugin(Plugin): """ self.logger.info("Trying to load metadata from resource [%s]" % resource) yaml_finder = re.compile( - r"^\s*(?:---|===)\s*\n((?:.|\n)+?)\n\s*(?:---|===)\s*\n", + r"^\s*(?:---|===)\s*\n((?:.|\n)+?)\n\s*(?:---|===)\s*\n?", re.MULTILINE) match = re.match(yaml_finder, text) if not match: diff --git a/hyde/ext/templates/jinja.py b/hyde/ext/templates/jinja.py index eacddb1..13d8c2c 100644 --- a/hyde/ext/templates/jinja.py +++ b/hyde/ext/templates/jinja.py @@ -8,8 +8,7 @@ import re from hyde.fs import File, Folder from hyde.model import Expando from hyde.template import HtmlWrap, Template -from hyde.site import Resource -from hyde.util import getLoggerWithNullHandler, getLoggerWithConsoleHandler +from hyde.util import getLoggerWithNullHandler from jinja2 import contextfunction, Environment from jinja2 import FileSystemLoader, FileSystemBytecodeCache @@ -17,7 +16,7 @@ from jinja2 import environmentfilter, Markup, Undefined, nodes from jinja2.ext import Extension from jinja2.exceptions import TemplateError -logger = getLoggerWithNullHandler('Jinja2') +logger = getLoggerWithNullHandler('hyde.engine.Jinja2') class SilentUndefined(Undefined): """ @@ -54,7 +53,7 @@ def markdown(env, value): Markdown filter with support for extensions. """ try: - import markdown + import markdown as md except ImportError: logger.error(u"Cannot load the markdown library.") raise TemplateError("Cannot load the markdown library") @@ -65,8 +64,8 @@ def markdown(env, value): d['extension_configs'] = getattr(env.config.markdown, 'extension_configs', Expando({})).to_dict() - md = markdown.Markdown(**d) - return md.convert(output) + marked = md.Markdown(**d) + return marked.convert(output) @environmentfilter def syntax(env, value, lexer=None, filename=None): @@ -78,7 +77,8 @@ def syntax(env, value, lexer=None, filename=None): from pygments import lexers from pygments import formatters except ImportError: - logger.error(u"pygments library is required to use syntax highlighting tags.") + logger.error(u"pygments library is required to" + " use syntax highlighting tags.") raise TemplateError("Cannot load pygments") pyg = (lexers.get_lexer_by_name(lexer) @@ -176,8 +176,9 @@ class YamlVar(Extension): nodes.Const({}) ).set_lineno(lineno), nodes.CallBlock( - self.call_method('_set_yaml', args=[nodes.Name(var, 'load')]), - [], [], body).set_lineno(lineno) + self.call_method('_set_yaml', + args=[nodes.Name(var, 'load')]), + [], [], body).set_lineno(lineno) ] @@ -197,6 +198,9 @@ class YamlVar(Extension): return '' def parse_kwargs(parser): + """ + Parses keyword arguments in tags. + """ name = parser.stream.expect('name').value parser.stream.expect('assign') if parser.stream.current.test('string'): @@ -220,18 +224,12 @@ class Syntax(Extension): lex = nodes.Const(None) filename = nodes.Const(None) - def fail_syntax(): - parser.fail( - 'Invalid syntax tag. Expected:' - '{% syntax lex=yaml, filename=abc.yaml %} or' - '{% syntax yaml, \'abc.yaml\' %}') - if not parser.stream.current.test('block_end'): if parser.stream.look().test('assign'): - name = value = name1 = value1 = None + name = value = value1 = None (name, value) = parse_kwargs(parser) if parser.stream.skip_if('comma'): - (name1, value1) = parse_kwargs(parser) + (_, value1) = parse_kwargs(parser) (lex, filename) = (value, value1) \ if name == 'lex' \ @@ -314,6 +312,9 @@ class Reference(Extension): def _render_output(self, markings, name, caller=None): + """ + Assigns the result of the contents to the markings variable. + """ if not caller: return '' out = caller() @@ -334,7 +335,6 @@ class Refer(Extension): """ token = parser.stream.next() lineno = token.lineno - tag = token.value parser.stream.expect('name:to') template = parser.parse_expression() parser.stream.expect('name:as') @@ -387,12 +387,16 @@ class Refer(Extension): ] def _push_resource(self, namespace, site, resource, template, caller): + """ + Saves the current references in a stack. + """ namespace['parent_resource'] = resource if not hasattr(resource, 'depends'): resource.depends = [] if not template in resource.depends: resource.depends.append(template) - namespace['resource'] = site.content.resource_from_relative_path(template) + namespace['resource'] = site.content.resource_from_relative_path( + template) return '' def _assign_reference(self, markings, namespace, caller): @@ -415,17 +419,17 @@ class HydeLoader(FileSystemLoader): """ def __init__(self, sitepath, site, preprocessor=None): - config = site.config if hasattr(site, 'config') else None - if config: - super(HydeLoader, self).__init__([ - str(config.content_root_path), - str(config.layout_root_path), - ]) - else: - super(HydeLoader, self).__init__(str(sitepath)) + config = site.config if hasattr(site, 'config') else None + if config: + super(HydeLoader, self).__init__([ + str(config.content_root_path), + str(config.layout_root_path), + ]) + else: + super(HydeLoader, self).__init__(str(sitepath)) - self.site = site - self.preprocessor = preprocessor + self.site = site + self.preprocessor = preprocessor def get_source(self, environment, template): """ @@ -573,9 +577,16 @@ class Jinja2Template(Template): """ return '{{ media_url(\'%s\') }}' % url - def render(self, text, context): + def render_resource(self, resource, context): """ Renders the given resource using the context """ + template = self.env.get_template(resource.relative_path) + return template.render(context) + + def render(self, text, context): + """ + Renders the given text using the context + """ template = self.env.from_string(text) return template.render(context) diff --git a/hyde/generator.py b/hyde/generator.py index 620bbdd..d28d436 100644 --- a/hyde/generator.py +++ b/hyde/generator.py @@ -283,16 +283,18 @@ class Generator(object): logger.debug("Processing [%s]", resource) with self.context_for_resource(resource) as context: if resource.source_file.is_text: - text = resource.source_file.read_all() - text = self.events.begin_text_resource(resource, text) or text if resource.uses_template: logger.debug("Rendering [%s]", resource) try: - text = self.template.render(text, context) + text = self.template.render_resource(resource, + context) except Exception: logger.error("Error occurred when" " processing template:[%s]" % resource) raise + else: + text = resource.source_file.read_all() + text = self.events.begin_text_resource(resource, text) or text text = self.events.text_resource_complete( resource, text) or text diff --git a/hyde/layouts/basic/content/blog/index.html b/hyde/layouts/basic/content/blog/index.html index d57cb74..04ba0d7 100644 --- a/hyde/layouts/basic/content/blog/index.html +++ b/hyde/layouts/basic/content/blog/index.html @@ -4,4 +4,3 @@ extends: listing.j2 default_block: test listable: false --- -A diff --git a/hyde/layouts/basic/layout/base.j2 b/hyde/layouts/basic/layout/base.j2 index 43b3ff9..5b04ab9 100644 --- a/hyde/layouts/basic/layout/base.j2 +++ b/hyde/layouts/basic/layout/base.j2 @@ -66,7 +66,8 @@ + Powered by hyde. + {% endblock container %} {% endblock content%} diff --git a/hyde/plugin.py b/hyde/plugin.py index b4b7569..6369eca 100644 --- a/hyde/plugin.py +++ b/hyde/plugin.py @@ -63,7 +63,8 @@ class Plugin(object): def __init__(self, site): super(Plugin, self).__init__() self.site = site - self.logger = getLoggerWithNullHandler(self.__class__.__name__) + self.logger = getLoggerWithNullHandler( + 'hyde.engine.%s' % self.__class__.__name__) self.template = None diff --git a/hyde/server.py b/hyde/server.py index 493b2e6..e6165a5 100644 --- a/hyde/server.py +++ b/hyde/server.py @@ -57,6 +57,7 @@ class HydeRequestHandler(SimpleHTTPRequestHandler): result = urlparse.urlparse(self.path) logger.debug("Trying to load file based on request:[%s]" % result.path) path = result.path.lstrip('/') + res = None if path.strip() == "" or File(path).kind.strip() == "": deployed = site.config.deploy_root_path.child(path) deployed = Folder.file_or_folder(deployed) @@ -67,7 +68,6 @@ class HydeRequestHandler(SimpleHTTPRequestHandler): res = site.content.resource_from_relative_deploy_path(path) if not res: - # Check if its a new request if self.server.request_time > self.server.regeneration_time: # Cannot find the source file using the given path. @@ -148,11 +148,33 @@ class HydeWebServer(HTTPServer): logger.error('Error occured when regenerating the site [%s]' % exception.message) + def generate_node(self, node): + """ + Generates the given node. + """ + + deploy = self.site.config.deploy_root_path + if not deploy.exists: + return self.regenerate() + + try: + logger.info('Generating node [%s]' % node) + self.generator.generate_node(node, incremental=True) + except Exception, exception: + logger.error( + 'Error [%s] occured when generating the node [%s]' + % (repr(exception), node)) def generate_resource(self, resource): """ Regenerates the given resource. """ + deploy = self.site.config.deploy_root_path + if not deploy.exists: + return self.regenerate() + dest = deploy.child_folder(resource.node.relative_path) + if not dest.exists: + return self.generate_node(resource.node) try: logger.info('Generating resource [%s]' % resource) self.generator.generate_resource(resource, incremental=True) diff --git a/hyde/tests/test_plugin.py b/hyde/tests/test_plugin.py index 3953fee..c412f8b 100644 --- a/hyde/tests/test_plugin.py +++ b/hyde/tests/test_plugin.py @@ -276,7 +276,8 @@ class TestPlugins(object): gen.generate_all() begin_text_resource_stub.reset_mock() path = self.site.content.source_folder.child('about.html') - gen.generate_resource_at_path(path) + gen = Generator(self.site) + gen.generate_resource_at_path(path, incremental=True) called_with_resources = sorted([arg[0][0].path for arg in begin_text_resource_stub.call_args_list]) assert begin_text_resource_stub.call_count == 1 diff --git a/hyde/util.py b/hyde/util.py index e6bde93..020148f 100644 --- a/hyde/util.py +++ b/hyde/util.py @@ -21,12 +21,18 @@ except: def getLoggerWithConsoleHandler(logger_name): logger = logging.getLogger(logger_name) logger.setLevel(logging.INFO) - handler = logging.StreamHandler(sys.stdout) - formatter = ColorFormatter(fmt="$RESET %(asctime)s " + if not logger.handlers: + handler = logging.StreamHandler(sys.stdout) + if sys.platform == 'win32': + formatter = logging.Formatter( + fmt="%(asctime)s %(name)s %(message)s", + datefmt='%H:%M:%S') + else: + formatter = ColorFormatter(fmt="$RESET %(asctime)s " "$BOLD$COLOR%(name)s$RESET " "%(message)s", datefmt='%H:%M:%S') - handler.setFormatter(formatter) - logger.addHandler(handler) + handler.setFormatter(formatter) + logger.addHandler(handler) return logger @@ -36,7 +42,8 @@ def getLoggerWithNullHandler(logger_name): and a NullHandler. """ logger = logging.getLogger(logger_name) - logger.addHandler(NullHandler()) + if not logger.handlers: + logger.addHandler(NullHandler()) return logger