From 64ea9055d7c5908f8cbf1fb572fc50d8b3f44b95 Mon Sep 17 00:00:00 2001 From: Lakshmi Vyasarajan Date: Fri, 29 Apr 2011 13:28:01 +0530 Subject: [PATCH 1/8] Fixed expando to_dict() --- hyde/model.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hyde/model.py b/hyde/model.py index 3854eee..a4effbd 100644 --- a/hyde/model.py +++ b/hyde/model.py @@ -67,6 +67,10 @@ class Expando(object): for k, v in d.iteritems(): if isinstance(v, Expando): d[k] = v.to_dict() + elif isinstance(v, (tuple, list, set, frozenset)): + seq = type(v) + d[k] = seq(item.to_dict() if isinstance(item, Expando) + else item for item in v) return d From 9fde5a741611da359a5a772f6b6661a8809eb693 Mon Sep 17 00:00:00 2001 From: Ryan Kelly Date: Sat, 30 Apr 2011 09:36:03 +1000 Subject: [PATCH 2/8] bump nose req to 1.0.0 --- dev-req.txt | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dev-req.txt b/dev-req.txt index 210c297..4356410 100644 --- a/dev-req.txt +++ b/dev-req.txt @@ -9,7 +9,7 @@ Jinja2==2.5.5 pyquery==0.6.1 unittest2==0.5.1 mock==0.7.0b4 -nose==0.11.4 +nose==1.0.0 pep8==0.6.1 pylint==0.22.0 pysmell==0.7.3 diff --git a/requirements.txt b/requirements.txt index 0795680..6f5fa6d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,4 +5,4 @@ Markdown MarkupSafe smartypants -e git://github.com/hyde/typogrify.git#egg=typogrify -Jinja2 \ No newline at end of file +Jinja2 From 0d15885573a2586defe83ea9f6f5d926b1e90bdf Mon Sep 17 00:00:00 2001 From: Ryan Kelly Date: Sat, 30 Apr 2011 09:47:44 +1000 Subject: [PATCH 3/8] LessCSSPlugin: return original text if not a .less file --- hyde/ext/plugins/less.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyde/ext/plugins/less.py b/hyde/ext/plugins/less.py index 575072a..4acf6bb 100644 --- a/hyde/ext/plugins/less.py +++ b/hyde/ext/plugins/less.py @@ -34,7 +34,7 @@ class LessCSSPlugin(CLTransformer): """ if not resource.source_file.kind == 'less': - return + return text import_finder = re.compile( '^\\s*@import\s+(?:\'|\")([^\'\"]*)(?:\'|\")\s*\;\s*$', re.MULTILINE) From e6d48b4ad6ba6d7dbceb95e7b80e092feb5a80ad Mon Sep 17 00:00:00 2001 From: Ryan Kelly Date: Sat, 30 Apr 2011 09:58:49 +1000 Subject: [PATCH 4/8] {% syntax %} tag: optionally disable generation of
container --- hyde/ext/templates/jinja.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hyde/ext/templates/jinja.py b/hyde/ext/templates/jinja.py index 5fa3f51..6e86e1a 100644 --- a/hyde/ext/templates/jinja.py +++ b/hyde/ext/templates/jinja.py @@ -131,6 +131,9 @@ def syntax(env, value, lexer=None, filename=None): code = pygments.highlight(value, pyg, formatter) code = code.replace('\n\n', '\n \n').replace('\n', '
') caption = filename if filename else pyg.name + if hasattr(env.config, 'syntax'): + if not getattr(env.config.syntax, 'use_figure', True): + return Markup(code) return Markup( '
%s
%s
\n\n' % (code, caption)) From e483d0e90831949ef55406664138e4eb397ac75a Mon Sep 17 00:00:00 2001 From: Ryan Kelly Date: Sat, 30 Apr 2011 14:40:03 +1000 Subject: [PATCH 5/8] add basic support for publishing to a PyFS object --- hyde/ext/publishers/pyfs.py | 55 +++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 hyde/ext/publishers/pyfs.py diff --git a/hyde/ext/publishers/pyfs.py b/hyde/ext/publishers/pyfs.py new file mode 100644 index 0000000..bf64691 --- /dev/null +++ b/hyde/ext/publishers/pyfs.py @@ -0,0 +1,55 @@ +""" +Contains classes and utilities that help publishing a hyde website to +a filesystem using PyFilesystem FS objects. +""" + +import getpass + +from hyde.fs import File, Folder +from hyde.publisher import Publisher + +from hyde.util import getLoggerWithNullHandler +logger = getLoggerWithNullHandler('hyde.ext.publishers.pyfs') + + +from fs.osfs import OSFS +from fs.path import pathjoin +from fs.opener import fsopendir + + + +class PyFS(Publisher): + + def initialize(self, settings): + self.settings = settings + self.url = settings.url + self.prompt_for_credentials() + self.fs = fsopendir(self.url) + + def prompt_for_credentials(self): + credentials = {} + if "%(username)s" in self.url: + print "Username: ", + credentials["username"] = raw_input().strip() + if "%(password)s" in self.url: + credentials["password"] = getpass.getpass("Password: ") + if credentials: + self.url = self.url % credentials + + def publish(self): + super(PyFS, self).publish() + deploy_fs = OSFS(self.site.config.deploy_root_path.path) + for (dirnm,filenms) in deploy_fs.walk(): + logger.info("Making directory: %s",dirnm) + self.fs.makedir(dirnm,allow_recreate=True) + for filenm in filenms: + filepath = pathjoin(dirnm,filenm) + logger.info("Uploading file: %s",filepath) + with deploy_fs.open(filepath,"rb") as f: + self.fs.setcontents(filepath,f) + for filenm in self.fs.listdir(dirnm,files_only=True): + filepath = pathjoin(dirnm,filenm) + if filenm not in filenms: + logger.info("Removing file: %s",filepath) + self.fs.remove(filepath) + From 12c679572aab55e2f4268dcee1623464ae0dc782 Mon Sep 17 00:00:00 2001 From: Ryan Kelly Date: Mon, 9 May 2011 11:26:13 +1000 Subject: [PATCH 6/8] add mtime/etag support to PyFS publisher --- hyde/ext/publishers/pyfs.py | 52 ++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/hyde/ext/publishers/pyfs.py b/hyde/ext/publishers/pyfs.py index bf64691..9431afb 100644 --- a/hyde/ext/publishers/pyfs.py +++ b/hyde/ext/publishers/pyfs.py @@ -1,9 +1,18 @@ """ Contains classes and utilities that help publishing a hyde website to a filesystem using PyFilesystem FS objects. + +This publisher provides an easy way to publish to FTP, SFTP, WebDAV or other +servers by specifying a PyFS filesystem URL. For example, the following +are valid URLs that can be used with this publisher: + + ftp://my.server.com/~username/my_blog/ + dav:https://username:password@my.server.com/path/to/my/site + """ import getpass +import hashlib from hyde.fs import File, Folder from hyde.publisher import Publisher @@ -23,6 +32,10 @@ class PyFS(Publisher): def initialize(self, settings): self.settings = settings self.url = settings.url + self.check_mtime = getattr(settings,"check_mtime",False) + self.check_etag = getattr(settings,"check_etag",False) + if self.check_etag and not isinstance(self.check_etag,basestring): + raise ValueError("check_etag must name the etag algorithm") self.prompt_for_credentials() self.fs = fsopendir(self.url) @@ -39,17 +52,48 @@ class PyFS(Publisher): def publish(self): super(PyFS, self).publish() deploy_fs = OSFS(self.site.config.deploy_root_path.path) - for (dirnm,filenms) in deploy_fs.walk(): + for (dirnm,local_filenms) in deploy_fs.walk(): logger.info("Making directory: %s",dirnm) self.fs.makedir(dirnm,allow_recreate=True) - for filenm in filenms: + remote_fileinfos = self.fs.listdirinfo(dirnm,files_only=True) + # Process each local file, to see if it needs updating. + for filenm in local_filenms: filepath = pathjoin(dirnm,filenm) + # Try to find an existing remote file, to compare metadata. + for (nm,info) in remote_fileinfos: + if nm == filenm: + break + else: + info = {} + # Skip it if the etags match + if self.check_etag and "etag" in info: + with deploy_fs.open(filepath,"rb") as f: + local_etag = self._calculate_etag(f) + if info["etag"] == local_etag: + logger.info("Skipping file [etag]: %s",filepath) + continue + # Skip it if the mtime is more recent remotely. + if self.check_mtime and "modified_time" in info: + local_mtime = deploy_fs.getinfo(filepath)["modified_time"] + if info["modified_time"] > local_mtime: + logger.info("Skipping file [mtime]: %s",filepath) + continue + # Upload it to the remote filesystem. logger.info("Uploading file: %s",filepath) with deploy_fs.open(filepath,"rb") as f: self.fs.setcontents(filepath,f) - for filenm in self.fs.listdir(dirnm,files_only=True): + # Process each remote file, to see if it needs deleting. + for (filenm,info) in remote_fileinfos: filepath = pathjoin(dirnm,filenm) - if filenm not in filenms: + if filenm not in local_filenms: logger.info("Removing file: %s",filepath) self.fs.remove(filepath) + def _calculate_etag(self,f): + hasher = getattr(hashlib,self.check_etag.lower())() + data = f.read(1024*64) + while data: + hasher.update(data) + data = f.read(1024*64) + return hasher.hexdigest() + From e78cb1db0408023029f897195ee6aef996600dc6 Mon Sep 17 00:00:00 2001 From: Lakshmi Vyasarajan Date: Mon, 9 May 2011 22:09:39 +0530 Subject: [PATCH 7/8] Fixed a failing test --- hyde/tests/test_jinja2template.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hyde/tests/test_jinja2template.py b/hyde/tests/test_jinja2template.py index f41ed93..734fd70 100644 --- a/hyde/tests/test_jinja2template.py +++ b/hyde/tests/test_jinja2template.py @@ -85,6 +85,7 @@ def test_typogrify(): """ t = Jinja2Template(JINJA2.path) t.configure(None) + t.env.filters['dateformat'] = dateformat html = t.render(source, {}).strip() assert html == u'One & two' @@ -110,6 +111,7 @@ def test_spaceless(): """ t = Jinja2Template(JINJA2.path) t.configure(None) + t.env.filters['dateformat'] = dateformat html = t.render(source, {}).strip() expected = u"""
  • @@ -146,6 +148,7 @@ def test_markdown_with_extensions(): c = Config(JINJA2.path, config_dict=dict(markdown=dict(extensions=['headerid']))) s.config = c t.configure(s) + t.env.filters['dateformat'] = dateformat html = t.render(source, {}).strip() assert html == u'

    Heading 3

    ' @@ -162,6 +165,7 @@ def test_line_statements(): c = Config(JINJA2.path, config_dict=dict(markdown=dict(extensions=['headerid']))) s.config = c t.configure(s) + t.env.filters['dateformat'] = dateformat html = t.render(source, {}).strip() assert html == u'

    Heading 3

    ' @@ -184,6 +188,7 @@ def test_line_statements_with_config(): s = Site(JINJA2.path) s.config = Config(JINJA2.path, config_dict=yaml.load(config)) t.configure(s) + t.env.filters['dateformat'] = dateformat html = t.render(source, {}).strip() assert html == u'

    Heading 3

    ' @@ -221,6 +226,7 @@ class TestJinjaTemplate(object): def test_depends(self): t = Jinja2Template(JINJA2.path) t.configure(None) + t.env.filters['dateformat'] = dateformat deps = list(t.get_dependencies('index.html')) assert len(deps) == 2 @@ -258,6 +264,7 @@ class TestJinjaTemplate(object): gen = Generator(site) gen.load_template_if_needed() template = gen.template + template.env.filters['dateformat'] = dateformat html = template.render(text, {}).strip() assert html @@ -538,6 +545,7 @@ two: """ t = Jinja2Template(JINJA2.path) t.configure(None) + t.env.filters['dateformat'] = dateformat html = t.render(text, {}).strip() actual = PyQuery(html) assert actual("ul").length == 2 @@ -580,6 +588,7 @@ item_list: """ t = Jinja2Template(JINJA2.path) t.configure(None) + t.env.filters['dateformat'] = dateformat html = t.render(text, {}).strip() print html actual = PyQuery(html) From c792c18103a2b8c6ec0182f9ab288a45c0290da0 Mon Sep 17 00:00:00 2001 From: Lakshmi Vyasarajan Date: Tue, 10 May 2011 10:11:47 +0530 Subject: [PATCH 8/8] Added AUTHORS, upped version to 0.8.1 --- AUTHORS | 24 ++++++++++++++++++++++++ CHANGELOG.rst | 9 +++++++++ README.rst | 13 +++++++++++-- hyde/version.py | 2 +- 4 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 AUTHORS diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..9dca441 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,24 @@ +Hyde is primarily developed and maintained by [Lakshmi Vyasarajan][1]. The new +version of Hyde is sponsored by [Flowplayer][2] and [Tero Piirainen][3]. + +This version would not exist without the contributions for the +[original hyde project][4]. + +Contributors +============= + + +- @rfk + + * Bug fixes + * Pyfs publisher with mimetype and etags support + +- @tinnet + + * Bug fixes (Default template, Syntax template tag) + + +[1]: http://twitter.com/lakshmivyas +[2]: http://flowplayer.org +[3]: http://cloudpanic.com +[4]: http://github.com/lakshmivyas/hyde diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e045f20..a6148c8 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,12 @@ +Version 0.8.1 +============= + +Thanks to @rfk. + +* Updated to use nose 1.0 +* Bug fixes to Less CSS +* PyFS publisher with mimetypes and etags support. + Version 0.8 ============== diff --git a/README.rst b/README.rst index e31c48c..3bb8952 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -Version 0.8 +Version 0.8.1 A brand new **hyde** ==================== @@ -112,8 +112,17 @@ Next Steps - Text Compressor (CSS, JS, HTML) ✓ - Image optimizer ✓ +Links +----- + +1. `Changelog`_ +2. `Authors`_ + + .. _hyde: https://github.com/lakshmivyas/hyde .. _here: http://hyde.github.com .. _Hyde Documentation: https://github.com/hyde/docs .. _Cloudpanic: https://github.com/tipiirai/cloudpanic -.. _Ringce: https://github.com/lakshmivyas/ringce/tree/v3.0 \ No newline at end of file +.. _Ringce: https://github.com/lakshmivyas/ringce/tree/v3.0 +.. _Authors: https://github.com/hyde/hyde/blob/master/AUTHORS +.. _Changelog: https://github.com/hyde/hyde/blob/master/CHANGELOG.rst diff --git a/hyde/version.py b/hyde/version.py index 12ad27a..1ef1b37 100644 --- a/hyde/version.py +++ b/hyde/version.py @@ -3,4 +3,4 @@ Handles hyde version TODO: Use fabric like versioning scheme """ -__version__ = '0.8' +__version__ = '0.8.1'