def test_depends(self): s = Site(TEST_SITE) s.config.plugins = ['hyde.ext.plugins.meta.MetaPlugin', 'hyde.ext.plugins.depends.DependsPlugin'] text = """ === depends: index.html === """ inc = File(TEST_SITE.child('content/inc.md')) inc.write(text) gen = Generator(s) gen.load_site_if_needed() gen.load_template_if_needed() def dateformat(x): return x.strftime('%Y-%m-%d') gen.template.env.filters['dateformat'] = dateformat gen.generate_resource_at_path(inc.name) res = s.content.resource_from_relative_path(inc.name) assert len(res.depends) == 1 assert 'index.html' in res.depends deps = list(gen.get_dependencies(res)) assert len(deps) == 3 assert 'helpers.html' in deps assert 'layout.html' in deps assert 'index.html' in deps
def text_resource_complete(self, resource, text): """ Save the file to a temporary place and run less compiler. Read the generated file and return the text as output. Set the target path to have a css extension. """ if not resource.source_file.kind == 'less' or not \ self._should_parse_resource(resource): return supported = [ "verbose", ("silent", "s"), ("compress", "x"), "O0", "O1", "O2", "include-path=" ] less = self.app source = File.make_temp(text) target = File.make_temp('') args = [unicode(less)] args.extend(self.process_args(supported)) args.extend([unicode(source), unicode(target)]) try: self.call_app(args) except subprocess.CalledProcessError: raise self.template.exception_class( "Cannot process %s. Error occurred when " "processing [%s]" % (self.app.name, resource.source_file)) return target.read_all()
def test_url_cleaner(self): s = Site(TEST_SITE) cfg = """ plugins: - hyde.ext.plugins.urls.UrlCleanerPlugin urlcleaner: index_file_names: - about.html strip_extensions: - html append_slash: true """ s.config = Config(TEST_SITE, config_dict=yaml.load(cfg)) text = """ {% extends "base.html" %} {% block main %} <a id="index" href="{{ content_url('about.html') }}"></a> <a id="blog" href="{{ content_url('blog/2010/december/merry-christmas.html') }}"></a> {% endblock %} """ about2 = File(TEST_SITE.child('content/test.html')) about2.write(text) gen = Generator(s) gen.generate_all() from pyquery import PyQuery target = File(Folder(s.config.deploy_root_path).child('test.html')) text = target.read_all() q = PyQuery(text) assert q('a#index').attr("href") == '/' assert q('a#blog').attr("href") == '/blog/2010/december/merry-christmas'
def test_pages_of_one_content(self): expected_page1_content = dedent('''\ Another Sad Post page2/pages_of_one.txt''') expected_page2_content = dedent('''\ A Happy Post pages_of_one.txt page3/pages_of_one.txt''') expected_page3_content = dedent('''\ An Angry Post page2/pages_of_one.txt page4/pages_of_one.txt''') expected_page4_content = dedent('''\ A Sad Post page3/pages_of_one.txt ''') page1 = self.deploy.child('pages_of_one.txt') content = File(page1).read_all() assert expected_page1_content == content page2 = self.deploy.child('page2/pages_of_one.txt') content = File(page2).read_all() assert expected_page2_content == content page3 = self.deploy.child('page3/pages_of_one.txt') content = File(page3).read_all() assert expected_page3_content == content page4 = self.deploy.child('page4/pages_of_one.txt') content = File(page4).read_all() assert expected_page4_content == content
def text_resource_complete(self, resource, text): """ Save the file to a temporary place and run less compiler. Read the generated file and return the text as output. Set the target path to have a css extension. """ if not resource.source_file.kind == 'less': return supported = [ "verbose", ("silent", "s"), ("compress", "x"), "O0", "O1", "O2" ] less = self.app source = File.make_temp(text) target = File.make_temp('') args = [unicode(less)] args.extend(self.process_args(supported)) args.extend([unicode(source), unicode(target)]) try: self.call_app(args) except subprocess.CalledProcessError: raise self.template.exception_class( "Cannot process %s. Error occurred when " "processing [%s]" % (self.app.name, resource.source_file)) return target.read_all()
def test_ignores_pattern_in_content(self): text = """ {% markdown %} Heading 1 === Heading 2 === {% endmarkdown %} """ about2 = File(TEST_SITE.child("content/about2.html")) about2.write(text) s = Site(TEST_SITE) s.load() res = s.content.resource_from_path(about2.path) assert res.is_processable s.config.plugins = ["hyde.ext.plugins.meta.MetaPlugin"] gen = Generator(s) gen.generate_all() target = File(Folder(s.config.deploy_root_path).child("about2.html")) text = target.read_all() q = PyQuery(text) assert q("h1").length == 2 assert q("h1:eq(0)").text().strip() == "Heading 1" assert q("h1:eq(1)").text().strip() == "Heading 2"
def has_resource_changed(self, resource): """ Checks if the given resource has changed since the last generation. """ logger.debug("Checking for changes in %s" % resource) self.load_site_if_needed() self.load_template_if_needed() target = File(self.site.config.deploy_root_path.child( resource.relative_deploy_path)) if not target.exists or target.older_than(resource.source_file): logger.debug("Found changes in %s" % resource) return True if resource.source_file.is_binary: logger.debug("No Changes found in %s" % resource) return False deps = self.get_dependencies(resource) if not deps or None in deps: logger.debug("No changes found in %s" % resource) return False content = self.site.content.source_folder layout = Folder(self.site.sitepath).child_folder('layout') logger.debug("Checking for changes in dependents:%s" % deps) for dep in deps: if not dep: return True source = File(content.child(dep)) if not source.exists: source = File(layout.child(dep)) if not source.exists: return True if target.older_than(source): return True logger.debug("No changes found in %s" % resource) return False
def test_depends(self): s = Site(TEST_SITE) s.config.plugins = [ 'hyde.ext.plugins.meta.MetaPlugin', 'hyde.ext.plugins.depends.DependsPlugin' ] text = """ === depends: index.html === """ inc = File(TEST_SITE.child('content/inc.md')) inc.write(text) gen = Generator(s) gen.load_site_if_needed() gen.load_template_if_needed() def dateformat(x): return x.strftime('%Y-%m-%d') gen.template.env.filters['dateformat'] = dateformat gen.generate_resource_at_path(inc.name) res = s.content.resource_from_relative_path(inc.name) assert len(res.depends) == 1 assert 'index.html' in res.depends deps = list(gen.get_dependencies(res)) assert len(deps) == 3 assert 'helpers.html' in deps assert 'layout.html' in deps assert 'index.html' in deps
def test_context(self): site = Site(TEST_SITE, Config(TEST_SITE, config_dict={ "context": { "data": { "abc": "def" } } })) text = """ {% extends "base.html" %} {% block main %} abc = {{ abc }} Hi! I am a test template to make sure jinja2 generation works well with hyde. {{resource.name}} {% endblock %} """ site.load() resource = site.content.resource_from_path(TEST_SITE.child('content/about.html')) gen = Generator(site) resource.source_file.write(text) gen.generate_all() target = File(site.config.deploy_root_path.child(resource.name)) assert "abc = def" in target.read_all()
def text_resource_complete(self, resource, text): """ Save the file to a temporary place and run less compiler. Read the generated file and return the text as output. Set the target path to have a css extension. """ if not resource.source_file.kind == 'less': return if not (hasattr(self.site.config, 'less') and hasattr(self.site.config.less, 'app')): raise self.template.exception_class( "Less css path not configured. " "This plugin expects `less.app` to point " "to the `lessc` executable.") less = File(self.site.config.less.app) if not File(less).exists: raise self.template.exception_class( "Cannot find the less executable. The given path [%s] " "is incorrect" % less) source = File.make_temp(text) target = File.make_temp('') try: subprocess.check_call([str(less), str(source), str(target)]) except subprocess.CalledProcessError, error: self.logger.error(traceback.format_exc()) self.logger.error(error.output) raise self.template.exception_class( "Cannot process less css. Error occurred when " "processing [%s]" % resource.source_file)
def test_context(self): site = Site( TEST_SITE, Config(TEST_SITE, config_dict={"context": { "data": { "abc": "def" } }})) text = """ {% extends "base.html" %} {% block main %} abc = {{ abc }} Hi! I am a test template to make sure jinja2 generation works well with hyde. {{resource.name}} {% endblock %} """ site.load() resource = site.content.resource_from_path( TEST_SITE.child('content/about.html')) gen = Generator(site) resource.source_file.write(text) gen.generate_all() target = File(site.config.deploy_root_path.child(resource.name)) assert "abc = def" in target.read_all()
def add_resource(self, a_file): """ Adds a file to the parent node. Also adds to to the hashtable of path to resource associations for quick lookup. """ afile = File(a_file) resource = self.resource_from_path(afile) if resource: logger.debug("Resource exists at [%s]" % resource.relative_path) return resource if not afile.is_descendant_of(self.source_folder): raise HydeException("The given file [%s] does not reside" " in this hierarchy [%s]" % (afile, self.source_folder)) node = self.node_from_path(afile.parent) if not node: node = self.add_node(afile.parent) resource = node.add_child_resource(afile) self.resource_map[unicode(afile)] = resource logger.debug("Added resource [%s] to [%s]" % (resource.relative_path, self.source_folder)) return resource
def test_textlinks(self): d = { 'objects': 'template/variables', 'plugins': 'plugins/metadata', 'sorter': 'plugins/sorter' } text = u""" {%% markdown %%} [[!!img/hyde-logo.png]] * [Rich object model][hyde objects] and [overridable hierarchical metadata]([[ %(plugins)s ]]) thats available for use in templates. * Configurable [sorting][], filtering and grouping support. [hyde objects]: [[ %(objects)s ]] [sorting]: [[%(sorter)s]] {%% endmarkdown %%} """ site = Site(TEST_SITE) site.config.plugins = ['hyde.ext.plugins.textlinks.TextlinksPlugin'] site.config.base_url = 'http://example.com/' site.config.media_url = '/media' tlink = File(site.content.source_folder.child('tlink.html')) tlink.write(text % d) gen = Generator(site) gen.generate_all() f = File(site.config.deploy_root_path.child(tlink.name)) assert f.exists html = f.read_all() assert html for name, path in d.items(): assert quote(site.config.base_url + path) in html assert '/media/img/hyde-logo.png' in html
def __generate_resource__(self, resource): if not resource.is_processable: logger.debug("Skipping [%s]", resource) return 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) except Exception: logger.error("Error occurred when" " processing template:[%s]" % resource) raise text = self.events.text_resource_complete( resource, text) or text target = File(self.site.config.deploy_root_path.child( resource.relative_deploy_path)) target.parent.make() target.write(text) else: logger.debug("Copying binary file [%s]", resource) self.events.begin_binary_resource(resource) target = File(self.site.config.deploy_root_path.child( resource.relative_deploy_path)) target.parent.make() resource.source_file.copy_to(target) self.events.binary_resource_complete(resource)
def import_to_include(match): """ Converts a css import statement to include statemnt. """ if not match.lastindex: return '' path = match.groups(1)[0] afile = File( File(resource.source_file.parent.child( path)).fully_expanded_path) if len(afile.kind.strip()) == 0: afile = File(afile.path + '.styl') ref = self.site.content.resource_from_path(afile.path) if not ref: try: include = self.settings.args.include except AttributeError: include = False if not include: raise self.template.exception_class( "Cannot import from path [%s]" % afile.path) else: ref.is_processable = False return "\n" + \ self.template.get_include_statement(ref.relative_path) + \ "\n" return '@import "' + path + '"\n'
def add_resource(self, a_file): """ Adds a file to the parent node. Also adds to to the hashtable of path to resource associations for quick lookup. """ afile = File(a_file) resource = self.resource_from_path(afile) if resource: logger.debug("Resource exists at [%s]" % resource.relative_path) return resource if not afile.is_descendant_of(self.source_folder): raise HydeException("The given file [%s] does not reside" " in this hierarchy [%s]" % (afile, self.source_folder)) node = self.node_from_path(afile.parent) if not node: node = self.add_node(afile.parent) resource = node.add_child_resource(afile) self.resource_map[str(afile)] = resource logger.debug("Added resource [%s] to [%s]" % (resource.relative_path, self.source_folder)) return resource
def test_plugins(self): text = """ --- title: Hey author: Me twitter: @me --- {%% extends "base.html" %%} {%% block main %%} Hi! I am a test template to make sure jinja2 generation works well with hyde. <span class="title">{{resource.meta.title}}</span> <span class="author">{{resource.meta.author}}</span> <span class="twitter">{{resource.meta.twitter}}</span> {%% endblock %%} """ index = File(self.SITE_PATH.child("content/blog/index.html")) index.write(text) self.setup_config(["**/*.html", "media/css/*.css"]) conf = {"plugins": ["hyde.ext.plugins.meta.MetaPlugin"]} conf.update(self.config.to_dict()) s = Site(self.SITE_PATH, Config(sitepath=self.SITE_PATH, config_dict=conf)) g = Generator(s) g.generate_all() source = s.content.resource_from_relative_path("blog/index.html") target = File(s.config.deploy_root_path.child(source.relative_deploy_path)) left = source.source_file.read_all() right = target.read_all() assert left == right
def setup_class(cls): cls.SITE_PATH = File(__file__).parent.child_folder('sites/test_jinja_with_config') cls.SITE_PATH.make() TEST_SITE_ROOT.copy_contents_to(cls.SITE_PATH) cls.config_file = File(cls.SITE_PATH.child('alternate.yaml')) with open(cls.config_file.path) as config: cls.config = Config(sitepath=cls.SITE_PATH, config_dict=yaml.load(config)) cls.SITE_PATH.child_folder('content').rename_to(cls.config.content_root)
def __init__(self, sitepath, depends_file_name='.hyde_deps'): self.sitepath = Folder(sitepath) self.deps_file = File(self.sitepath.child(depends_file_name)) self.data = {} if self.deps_file.exists: self.data = yaml.load(self.deps_file.read_all()) import atexit atexit.register(self.save)
def test_time_functions(): f1 = File(__file__) t1 = f1.last_modified f2 = File.make_temp("I am new") t2 = f2.last_modified assert t1 < t2 assert f2.has_changed_since(t1) assert f1.older_than(f2)
def _generate_site_with_meta(self, meta): self.site.config.mode = "production" self.site.config.plugins = ['hyde.ext.plugins.meta.MetaPlugin', 'hyde.ext.plugins.images.ImageThumbnailsPlugin'] mlink = File(self.image_folder.child('meta.yaml')) meta_text = yaml.dump(meta, default_flow_style=False) mlink.write(meta_text) gen = Generator(self.site) gen.generate_all()
def fix_generated_filenames(self): suffix = self.config().get("source_suffix", ".rst") for resource in self.__node.walk_resources(): if resource.source_file.path.endswith(suffix): new_name = resource.source_file.name_without_extension + ".html" target_folder = File(resource.relative_deploy_path).parent resource.relative_deploy_path = target_folder.child(new_name) if self.__settings.get("block_map", None): resource.meta.default_block = None
def begin_site(self): """ Find all the less css files and set their relative deploy path. """ for resource in self.site.content.walk_resources(): if resource.source_file.kind == 'less': new_name = resource.source_file.name_without_extension + ".css" target_folder = File(resource.relative_deploy_path).parent resource.relative_deploy_path = target_folder.child(new_name)
def test_generator(self): self.setup_config(["**/*.html", "media/css/*.css"]) s = Site(self.SITE_PATH, self.config) g = Generator(s) g.generate_all() source = s.content.resource_from_relative_path("blog/2010/december/merry-christmas.html") target = File(s.config.deploy_root_path.child(source.relative_deploy_path)) left = source.source_file.read_all() right = target.read_all() assert left == right
def test_generate_resource_from_path(self): site = Site(TEST_SITE) site.load() gen = Generator(site) gen.generate_resource_at_path(TEST_SITE.child('content/about.html')) about = File(Folder(site.config.deploy_root_path).child('about.html')) assert about.exists text = about.read_all() q = PyQuery(text) assert about.name in q("div#main").text()
def test_can_execute_stylus(self): s = Site(TEST_SITE) s.config.plugins = ['hyde.ext.plugins.stylus.StylusPlugin'] paths = [ '/usr/local/share/npm/bin/stylus', '~/local/bin/stylus', '~/bin/stylus' ] stylus = [path for path in paths if File(path).exists] if not stylus: assert False, "Cannot find the stylus executable" stylus = stylus[0] s.config.stylus = Expando(dict(app=stylus)) source = TEST_SITE.child('content/media/css/site.styl') target = File( Folder(s.config.deploy_root_path).child('media/css/site.css')) gen = Generator(s) gen.generate_resource_at_path(source) assert target.exists text = target.read_all() expected_text = File( STYLUS_SOURCE.child('expected-site.css')).read_all() print text.strip() print "=" * 80 print expected_text.strip() assert text.strip() == expected_text.strip()
def begin_site(self): """ Find all the coffee files and set their relative deploy path. """ for resource in self.site.content.walk_resources(): if resource.source_file.kind == 'coffee': #and \ #self._should_parse_resource(resource): new_name = resource.source_file.name_without_extension + ".js" target_folder = File(resource.relative_deploy_path).parent resource.relative_deploy_path = target_folder.child(new_name) resource.uses_template==False
def test_can_execute_optipng(self): s = Site(TEST_SITE) s.config.mode = "production" s.config.plugins = ['hyde.ext.plugins.optipng.OptiPNGPlugin'] s.config.optipng = Expando(dict(args=dict(quiet=""))) source =File(TEST_SITE.child('content/media/images/hyde-lt-b.png')) target = File(Folder(s.config.deploy_root_path).child('media/images/hyde-lt-b.png')) gen = Generator(s) gen.generate_resource_at_path(source) assert target.exists assert target.size < source.size
def test_plugin_chaining(self): self.site.config.plugins = [ 'hyde.tests.test_plugin.ConstantReturnPlugin', 'hyde.tests.test_plugin.NoReturnPlugin' ] path = self.site.content.source_folder.child('about.html') gen = Generator(self.site) gen.generate_resource_at_path(path) about = File( Folder(self.site.config.deploy_root_path).child('about.html')) assert about.read_all() == "Jam"
def test_plugin_chaining(self): self.site.config.plugins = [ 'hyde.tests.test_plugin.ConstantReturnPlugin', 'hyde.tests.test_plugin.NoReturnPlugin' ] path = self.site.content.source_folder.child('about.html') gen = Generator(self.site) gen.generate_resource_at_path(path) about = File(Folder( self.site.config.deploy_root_path).child('about.html')) assert about.read_all() == "Jam"
def test_pages_of_one(self): pages = [ 'pages_of_one.txt', 'page2/pages_of_one.txt', 'page3/pages_of_one.txt', 'page4/pages_of_one.txt' ] files = [File(self.deploy.child(p)) for p in pages] for f in files: assert f.exists page5 = File(self.deploy.child('page5/pages_of_one.txt')) assert not page5.exists
def setUp(self): TEST_SITE.make() TEST_SITE.parent.child_folder('sites/test_jinja').copy_contents_to( TEST_SITE) TEST_SITE.child_folder('content/media/js').make() JS = TEST_SITE.child_folder('content/scripts').make() S1 = JS.child_folder('s1').make() S2 = JS.child_folder('s2').make() S3 = JS.child_folder('s3').make() File(COMBINE_SOURCE.child('script.1.js')).copy_to(S1) File(COMBINE_SOURCE.child('script.2.js')).copy_to(S2) File(COMBINE_SOURCE.child('script.3.js')).copy_to(S3)
def _generic_test_image(self, text): self.site.config.mode = "production" self.site.config.plugins = ['hyde.ext.plugins.images.ImageSizerPlugin'] tlink = File(self.site.content.source_folder.child('timg.html')) tlink.write(text) gen = Generator(self.site) gen.generate_all() f = File(self.site.config.deploy_root_path.child(tlink.name)) assert f.exists html = f.read_all() assert html return html
def test_generate_resource_from_path_with_uses_template_false(self): site = Site(TEST_SITE) site.load() resource = site.content.resource_from_path(TEST_SITE.child('content/about.html')) resource.uses_template = False gen = Generator(site) gen.generate_resource_at_path(TEST_SITE.child('content/about.html')) about = File(Folder(site.config.deploy_root_path).child('about.html')) assert about.exists text = about.read_all() expected = resource.source_file.read_all() assert text == expected
def test_generator(self): self.setup_config(['**/*.html', 'media/css/*.css']) s = Site(self.SITE_PATH, self.config) g = Generator(s) g.generate_all() source = s.content.resource_from_relative_path( 'blog/2010/december/merry-christmas.html') target = File( s.config.deploy_root_path.child(source.relative_deploy_path)) left = source.source_file.read_all() right = target.read_all() assert left == right
def import_to_include(match): if not match.lastindex: return '' path = match.groups(1)[0] afile = File(resource.source_file.parent.child(path)) if len(afile.kind.strip()) == 0: afile = File(afile.path + '.less') ref = self.site.content.resource_from_path(afile.path) if not ref: raise self.template.exception_class( "Cannot import from path [%s]" % afile.path) ref.is_processable = False return self.template.get_include_statement(ref.relative_path)
def test_generate_resource_from_path_with_uses_template_false(self): site = Site(TEST_SITE) site.load() resource = site.content.resource_from_path( TEST_SITE.child('content/about.html')) resource.uses_template = False gen = Generator(site) gen.generate_resource_at_path(TEST_SITE.child('content/about.html')) about = File(Folder(site.config.deploy_root_path).child('about.html')) assert about.exists text = about.read_all() expected = resource.source_file.read_all() assert text == expected
def test_can_uglify(self): s = Site(TEST_SITE) s.config.plugins = ['hyde.ext.plugins.uglify.UglifyPlugin'] s.config.mode = "production" source = TEST_SITE.child('content/media/js/jquery.js') target = File(Folder(s.config.deploy_root_path).child('media/js/jquery.js')) gen = Generator(s) gen.generate_resource_at_path(source) assert target.exists expected = File(UGLIFY_SOURCE.child('expected-jquery.js')) # TODO: Very fragile. Better comparison needed. assert target.read_all() == expected.read_all()
def test_can_execute_rjs(self): s = Site(TEST_SITE) s.config.plugins = ['hyde.ext.plugins.requirejs.RequireJSPlugin'] source = TEST_SITE.child('content/media/js/rjs.conf') target = File(Folder(s.config.deploy_root_path).child('media/js/app.js')) gen = Generator(s) gen.generate_resource_at_path(source) assert target.exists text = target.read_all() expected_text = File(RJS_SOURCE.child('app.js')).read_all() assert text == expected_text return
def test_cant_find_depends_with_reference_tag_var(self): site = Site(TEST_SITE) JINJA2.copy_contents_to(site.content.source) inc = File(TEST_SITE.child('content/inc.md')) inc.write("{% set ind = 'index.html' %}{% refer to ind as index %}") site.load() gen = Generator(site) gen.load_template_if_needed() t = gen.template deps = list(t.get_dependencies('inc.md')) assert len(deps) == 1 assert not deps[0]
def test_can_execute_less(self): s = Site(TEST_SITE) s.config.plugins = ['hyde.ext.plugins.less.LessCSSPlugin'] source = TEST_SITE.child('content/media/css/site.less') target = File(Folder(s.config.deploy_root_path).child('media/css/site.css')) gen = Generator(s) gen.generate_resource_at_path(source) assert target.exists text = target.read_all() expected_text = File(LESS_SOURCE.child('expected-site.css')).read_all() assert text == expected_text return
def test_rename_folder(): DATA_JUNK = DATA_ROOT.child_folder('junk') assert not DATA_JUNK.exists JINJA2.copy_contents_to(DATA_JUNK) for f in [HELPERS, INDEX, LAYOUT]: assert File(DATA_JUNK.child(f.name)).exists DATA_JUNK2 = DATA_ROOT.child_folder('junk2') assert DATA_JUNK.exists assert not DATA_JUNK2.exists DATA_JUNK.rename_to('junk2') assert not DATA_JUNK.exists assert DATA_JUNK2.exists for f in [HELPERS, INDEX, LAYOUT]: assert File(DATA_JUNK2.child(f.name)).exists
def load(sitepath, ctx): """ Load context from config data and providers. """ context = {} try: context.update(ctx.data.__dict__) for provider_name, resource_name in ctx.providers.__dict__.items(): res = File(Folder(sitepath).child(resource_name)) if res.exists: context[provider_name] = yaml.load(res.read_all()) except AttributeError: # No context data found pass return context
def test_uglify_with_extra_options(self): s = Site(TEST_SITE) s.config.plugins = ['hyde.ext.plugins.uglify.UglifyPlugin'] s.config.mode = "production" s.config.uglify = Expando(dict(args={"nc":""})) source = TEST_SITE.child('content/media/js/jquery.js') target = File(Folder(s.config.deploy_root_path).child('media/js/jquery.js')) gen = Generator(s) gen.generate_resource_at_path(source) assert target.exists expected = File(UGLIFY_SOURCE.child('expected-jquery-nc.js')) # TODO: Very fragile. Better comparison needed. text = target.read_all() assert text.startswith("(function(")
def _test_combine(self, content): s = Site(TEST_SITE) s.config.plugins = [ 'hyde.ext.plugins.meta.MetaPlugin', 'hyde.ext.plugins.combine.CombinePlugin'] source = TEST_SITE.child('content/media/js/script.js') target = File(Folder(s.config.deploy_root_path).child('media/js/script.js')) File(source).write(content) gen = Generator(s) gen.generate_resource_at_path(source) assert target.exists text = target.read_all() return text, s
def test_can_execute_less(self): s = Site(TEST_SITE) s.config.plugins = ['hyde.ext.plugins.less.LessCSSPlugin'] source = TEST_SITE.child('content/media/css/site.less') target = File( Folder(s.config.deploy_root_path).child('media/css/site.css')) gen = Generator(s) gen.generate_resource_at_path(source) assert target.exists text = target.read_all() expected_text = File(LESS_SOURCE.child('expected-site.css')).read_all() assert text == expected_text return
def text_resource_complete(self, resource, text): """ If the site is in development mode, just return. Otherwise, save the file to a temporary place and run the uglify app. Read the generated file and return the text as output. """ try: mode = self.site.config.mode except AttributeError: mode = "production" if not resource.source_file.kind == 'js': return if mode.startswith('dev'): self.logger.debug("Skipping uglify in development mode.") return supported = [ ("beautify", "b"), ("indent", "i"), ("quote-keys", "q"), ("mangle-toplevel", "mt"), ("no-mangle", "nm"), ("no-squeeze", "ns"), "no-seqs", "no-dead-code", ("no-copyright", "nc"), "overwrite", "verbose", "unsafe", "max-line-len", "reserved-names", "ascii" ] uglify = self.app source = File.make_temp(text) target = File.make_temp('') args = [str(uglify)] args.extend(self.process_args(supported)) args.extend(["-o", str(target), str(source)]) self.call_app(args) out = target.read_all() return out
def test_context_providers(self): site = Site( TEST_SITE, Config(TEST_SITE, config_dict={ "context": { "data": { "abc": "def" }, "providers": { "nav": "nav.yaml" } } })) nav = """ main: - home - articles - projects """ text = """ {% extends "base.html" %} {% block main %} {{nav}} {% for item in nav.main %} {{item}} {% endfor %} abc = {{ abc }} Hi! I am a test template to make sure jinja2 generation works well with hyde. {{resource.name}} {% endblock %} """ File(TEST_SITE.child('nav.yaml')).write(nav) site.load() resource = site.content.resource_from_path( TEST_SITE.child('content/about.html')) gen = Generator(site) resource.source_file.write(text) gen.generate_all() target = File(site.config.deploy_root_path.child(resource.name)) out = target.read_all() assert "abc = def" in out assert "home" in out assert "articles" in out assert "projects" in out
def text_resource_complete(self, resource, text): """ If the site is in development mode, just return. Otherwise, save the file to a temporary place and run the uglify app. Read the generated file and return the text as output. """ try: mode = self.site.config.mode except AttributeError: mode = "production" if not resource.source_file.kind == 'js': return if mode.startswith('dev'): self.logger.debug("Skipping uglify in development mode.") return supported = [ ("beautify", "b"), ("indent", "i"), ("quote-keys", "q"), ("mangle-toplevel", "mt"), ("no-mangle", "nm"), ("no-squeeze", "ns"), "no-seqs", "no-dead-code", ("no-copyright", "nc"), "overwrite", "verbose", "unsafe", "max-line-len", "reserved-names", "ascii" ] uglify = self.app source = File.make_temp(text) target = File.make_temp('') args = [unicode(uglify)] args.extend(self.process_args(supported)) args.extend(["-o", unicode(target), unicode(source)]) self.call_app(args) out = target.read_all() return out
def contains_resource(self, resource_name): """ Returns True if the given resource name exists as a file in this node's source folder. """ return File(self.source_folder.child(resource_name)).exists
def binary_resource_complete(self, resource): """ If the site is in development mode, just return. Otherwise, run optipng to compress the png file. """ try: mode = self.site.config.mode except AttributeError: mode = "production" if not resource.source_file.kind == 'png': return if mode.startswith('dev'): self.logger.debug("Skipping optipng in development mode.") return supported = [ "o", "fix", "force", "preserve", "quiet", "log", "f", "i", "zc", "zm", "zs", "zw", "full", "nb", "nc", "np", "nz" ] target = File( self.site.config.deploy_root_path.child( resource.relative_deploy_path)) optipng = self.app args = [str(optipng)] args.extend(self.process_args(supported)) args.extend([str(target)]) self.call_app(args)
def thumb(self, defaults={}, width=None, height=None): """ Generate a thumbnail for the given image """ if width is None and height is None: width, height = defaults['width'], defaults['height'] im = Image.open(self.path) if im.mode != 'RGBA': im = im.convert('RGBA') # Convert to a thumbnail if width is None: # height is not None width = im.size[0]*height/im.size[1] + 1 elif height is None: # width is not None height = im.size[1]*width/im.size[0] + 1 im.thumbnail((width, height), Image.ANTIALIAS) # Prepare path path = os.path.join(os.path.dirname(self.get_relative_deploy_path()), "%s%s" % (defaults['prefix'], self.name)) target = File(Folder(self.site.config.deploy_root_path).child(path)) target.parent.make() if self.name.endswith(".jpg"): im.save(target.path, "JPEG", optimize=True, quality=75) else: im.save(target.path, "PNG", optimize=True) return Thumb(path, width=im.size[0], height=im.size[1])
def test_can_create_temp_file(): text = "A for apple" f = File.make_temp(text) assert f.exists assert text == f.read_all() f.delete() assert not f.exists
def test_depends_with_reference_tag(self): site = Site(TEST_SITE) JINJA2.copy_contents_to(site.content.source) inc = File(TEST_SITE.child('content/inc.md')) inc.write("{% refer to 'index.html' as index%}") site.load() gen = Generator(site) gen.load_template_if_needed() t = gen.template deps = list(t.get_dependencies('inc.md')) assert len(deps) == 3 assert 'helpers.html' in deps assert 'layout.html' in deps assert 'index.html' in deps
def app(self): """ Gets the application path from the site configuration. If the path is not configured, attempts to guess the path from the sytem path environment variable. """ try: app_path = getattr(self.settings, 'app') except AttributeError: app_path = self.executable_name # Honour the PATH environment variable. if app_path is not None and not os.path.isabs(app_path): app_path = discover_executable(app_path) if app_path is None: raise self.template.exception_class( self.executable_not_found_message) app = File(app_path) if not app.exists: raise self.template.exception_class( self.executable_not_found_message) return app