From 85d236889cca8447f02393cd52043b075b510099 Mon Sep 17 00:00:00 2001 From: whtsky Date: Thu, 7 Nov 2013 23:05:00 +0800 Subject: [PATCH 01/52] Correct the url for Twitter Card Support. --- catsup/templates/utils.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/catsup/templates/utils.html b/catsup/templates/utils.html index 8b313d2..894ee03 100644 --- a/catsup/templates/utils.html +++ b/catsup/templates/utils.html @@ -49,7 +49,7 @@ {% macro meta(post) %} - + {% endmacro %} \ No newline at end of file From 3e48d78bded9a08915c72a88d72de089a6e75d25 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 9 Nov 2013 16:21:39 +0800 Subject: [PATCH 02/52] update changelog --- docs/changelog.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 6a3b407..4c23b59 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,6 +1,11 @@ Changelog ========== +Version 0.3.0 +-------------- + ++ Correct the url for Twitter Card Support + Version 0.2.1 -------------- From f2f1b5d2610fb84b9d6125781974e24ced08cd6a Mon Sep 17 00:00:00 2001 From: whtsky Date: Fri, 22 Nov 2013 22:32:50 +0800 Subject: [PATCH 03/52] requires pip-tools --- dev-requirements.txt | 1 + setup.py | 1 + 2 files changed, 2 insertions(+) diff --git a/dev-requirements.txt b/dev-requirements.txt index d9a7625..8398a65 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -3,3 +3,4 @@ cov-core==1.7 coverage==3.6 nose-cov==1.6 nose==1.3.0 +pip-tools==0.3.4 diff --git a/setup.py b/setup.py index 31e1b6f..9660921 100644 --- a/setup.py +++ b/setup.py @@ -2,6 +2,7 @@ import catsup + setup( name='catsup', version=catsup.__version__, From 1101e2f9e12cf2ea098d9f1ba350069935ec0b11 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 23 Nov 2013 16:56:42 +0800 Subject: [PATCH 04/52] Adds support for Open Graph --- catsup/templates/utils.html | 8 ++++++++ docs/changelog.rst | 1 + 2 files changed, 9 insertions(+) diff --git a/catsup/templates/utils.html b/catsup/templates/utils.html index 894ee03..8bd8a31 100644 --- a/catsup/templates/utils.html +++ b/catsup/templates/utils.html @@ -48,6 +48,14 @@ {% macro meta(post) %} + + + + +{# #} + + + diff --git a/docs/changelog.rst b/docs/changelog.rst index 4c23b59..259065b 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -4,6 +4,7 @@ Changelog Version 0.3.0 -------------- ++ Adds support for Open Graph + Correct the url for Twitter Card Support Version 0.2.1 From ac2511385f1e633443ad2fc98d8401386390855a Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 23 Nov 2013 16:56:51 +0800 Subject: [PATCH 05/52] Bump version to 0.3.0 --- catsup/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/catsup/__init__.py b/catsup/__init__.py index e9ff7db..3068153 100644 --- a/catsup/__init__.py +++ b/catsup/__init__.py @@ -2,4 +2,4 @@ Catsup, a lightweight static blog generator """ -__version__ = '0.2.1' +__version__ = '0.3.0' From 68cb13b3181d94cf3d3d1a03710653e0a4aa5bc9 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 23 Nov 2013 17:47:47 +0800 Subject: [PATCH 06/52] add `remove_cache_path` func --- catsup/cache.py | 6 ++++++ catsup/cli.py | 9 +++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/catsup/cache.py b/catsup/cache.py index f98b34d..4821410 100644 --- a/catsup/cache.py +++ b/catsup/cache.py @@ -1,4 +1,5 @@ import os +import shutil from jinja2 import BytecodeCache from catsup.options import g @@ -16,6 +17,11 @@ def get_cache_path(name): ) +def remove_cache_path(): + if os.path.exists(".catsup-cache"): + shutil.rmtree(".catsup-cache") + + class CatsupJinjaCache(BytecodeCache): def __init__(self): self.directory = get_cache_path("jinja2") diff --git a/catsup/cli.py b/catsup/cli.py index 6eb767c..3bb1c67 100644 --- a/catsup/cli.py +++ b/catsup/cli.py @@ -214,12 +214,13 @@ def clean(settings): -s --settings= specify a setting file. [default: config.json] -h --help Show this screen and exit. """ - import catsup.parser.config import shutil + import catsup.parser.config + import catsup.cache config = catsup.parser.config(settings) - if os.path.exists(".catsup-cache"): - shutil.rmtree(".catsup-cache") - logger.info("Removed cache folder.") + + catsup.cache.remove_cache_path() + logger.info("Removed cache folder.") output_path = config.config.output if os.path.exists(output_path): shutil.rmtree(output_path) From ad546c09ef0ce917b47d9c56388dfacc682cde0a Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 23 Nov 2013 17:50:56 +0800 Subject: [PATCH 07/52] Don't use cache when running `catsup server` --- catsup/generator/__init__.py | 11 ++++++++--- catsup/generator/renderer.py | 8 ++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/catsup/generator/__init__.py b/catsup/generator/__init__.py index ce4be83..62b91b4 100644 --- a/catsup/generator/__init__.py +++ b/catsup/generator/__init__.py @@ -14,9 +14,13 @@ class Generator(object): def __init__(self, config_path, local=False, base_url=None): self.config_path = config_path self.local = local - if local: + + if not local: from catsup.cache import bytecode_cache - bytecode_cache.clear() + self.bytecode_cache = bytecode_cache + else: + self.bytecode_cache = None + self.base_url = base_url g.generator = self @@ -73,7 +77,8 @@ def load_renderer(self): ] self.renderer = Renderer( templates_path=templates_path, - generator=self + generator=self, + bytecode_cache=self.bytecode_cache ) def generate_feed(self): diff --git a/catsup/generator/renderer.py b/catsup/generator/renderer.py index 06848a5..49f56ed 100644 --- a/catsup/generator/renderer.py +++ b/catsup/generator/renderer.py @@ -1,18 +1,18 @@ import os from jinja2 import Environment, FileSystemLoader, TemplateNotFound -from catsup.cache import bytecode_cache from catsup.options import g from catsup.utils import mkdir, static_url, url_for, urljoin class Renderer(object): - def __init__(self, templates_path, generator): + def __init__(self, templates_path, generator, bytecode_cache=None): self.env = Environment( loader=FileSystemLoader(templates_path), - autoescape=False, - bytecode_cache=bytecode_cache + autoescape=False ) + if bytecode_cache is not None: + self.env.bytecode_cache = bytecode_cache config = generator.config self.env.globals.update( From 3e125cfd57671ae757ae1b23a65ee2bbbb4e40c7 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 23 Nov 2013 17:59:47 +0800 Subject: [PATCH 08/52] Oops. I should read the official doc. --- catsup/templates/utils.html | 7 ------- docs/changelog.rst | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/catsup/templates/utils.html b/catsup/templates/utils.html index 8bd8a31..df1a414 100644 --- a/catsup/templates/utils.html +++ b/catsup/templates/utils.html @@ -49,13 +49,6 @@ {% macro meta(post) %} - - - -{# #} - - - diff --git a/docs/changelog.rst b/docs/changelog.rst index 259065b..8c4bebf 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -4,8 +4,8 @@ Changelog Version 0.3.0 -------------- -+ Adds support for Open Graph + Correct the url for Twitter Card Support ++ Don't use cache when running `catsup server` Version 0.2.1 -------------- From 268f6de542f03828f3e0fbe3883d7f53dafccecd Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 23 Nov 2013 18:11:35 +0800 Subject: [PATCH 09/52] add g.enable_cache var --- catsup/cli.py | 2 ++ catsup/options.py | 1 + 2 files changed, 3 insertions(+) diff --git a/catsup/cli.py b/catsup/cli.py index 3bb1c67..5ca2612 100644 --- a/catsup/cli.py +++ b/catsup/cli.py @@ -145,6 +145,8 @@ def server(settings, port): -p --port= specify the server port. [default: 8888] """ import catsup.server + from catsup.options import g + g.enable_cache = False server = catsup.server.PreviewServer(settings, port) server.run() diff --git a/catsup/options.py b/catsup/options.py index 2afe12d..bec4f7b 100644 --- a/catsup/options.py +++ b/catsup/options.py @@ -1,3 +1,4 @@ from catsup.utils import ObjectDict g = ObjectDict() +g.enable_cache = True \ No newline at end of file From 79d6a55d299b678710cc6e117ad59108cb9ea3ff Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 23 Nov 2013 18:12:02 +0800 Subject: [PATCH 10/52] improved decription creator --- catsup/generator/models.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/catsup/generator/models.py b/catsup/generator/models.py index 6b0a59b..99f2f76 100644 --- a/catsup/generator/models.py +++ b/catsup/generator/models.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + import os import re import pickle @@ -159,6 +161,21 @@ def add_archive_and_tags(self): def get_permalink_args(self): return self.meta + def create_description(self): + description = self.meta.get( + "description", + self.md + ) + if "***" in description: + description = description.split("***")[0] + description.replace("\n", " ") + else: + description = description.split("\n")[0] + if len(description) > 150: + description = description[:150] + description = description.strip() + return escape_html(description) + def parse(self, path): cache_path = get_cache_path(path) st_ctime = os.stat(path).st_ctime @@ -210,10 +227,7 @@ def invailed_post(): else: self.datetime = datetime.fromtimestamp(st_ctime) self.date = self.datetime.strftime("%Y-%m-%d") - self.description = escape_html(self.meta.get( - "description", - self.md[:200] - )) + self.description = self.create_description() if self.meta.get("comment", None) == "disabled": self.allow_comment = False else: From 1a9f41558916fecec17bb9fadf08055671a2e8e5 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 23 Nov 2013 18:12:22 +0800 Subject: [PATCH 11/52] Update changelog --- docs/changelog.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 8c4bebf..6ab5a2f 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -6,6 +6,7 @@ Version 0.3.0 + Correct the url for Twitter Card Support + Don't use cache when running `catsup server` ++ Improve description creator Version 0.2.1 -------------- From dce14e0aa69f1149dbab140c012021e2182aa99b Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 23 Nov 2013 18:15:32 +0800 Subject: [PATCH 12/52] Don't load post cache when running ``catsup server`` --- catsup/generator/models.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/catsup/generator/models.py b/catsup/generator/models.py index 99f2f76..45dcaa3 100644 --- a/catsup/generator/models.py +++ b/catsup/generator/models.py @@ -168,7 +168,7 @@ def create_description(self): ) if "***" in description: description = description.split("***")[0] - description.replace("\n", " ") + description = description.replace("\n", " ") else: description = description.split("\n")[0] if len(description) > 150: @@ -177,18 +177,19 @@ def create_description(self): return escape_html(description) def parse(self, path): - cache_path = get_cache_path(path) st_ctime = os.stat(path).st_ctime - cache_folder = os.path.dirname(cache_path) - if os.path.exists(cache_folder): - if os.path.exists(cache_path): - with open(cache_path, "rb") as f: - cache = pickle.load(f) - if cache["st_ctime"] == st_ctime: - self.__dict__.update(cache["post"]) - return - else: - os.makedirs(cache_folder) + if g.enable_cache: + cache_path = get_cache_path(path) + cache_folder = os.path.dirname(cache_path) + if os.path.exists(cache_folder): + if os.path.exists(cache_path): + with open(cache_path, "rb") as f: + cache = pickle.load(f) + if cache["st_ctime"] == st_ctime: + self.__dict__.update(cache["post"]) + return + else: + os.makedirs(cache_folder) try: with open(path, "r") as f: @@ -239,8 +240,9 @@ def invailed_post(): "st_ctime": st_ctime, "post": self.__dict__ } - with open(cache_path, "wb") as f: - pickle.dump(cache, f) + if g.enable_cache: + with open(cache_path, "wb") as f: + pickle.dump(cache, f) return invailed_post() From bbdbd6d424dcfd0b08448e862525485d7c30c26b Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 23 Nov 2013 18:15:38 +0800 Subject: [PATCH 13/52] Update changelog --- docs/changelog.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 6ab5a2f..8fb5244 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -5,7 +5,8 @@ Version 0.3.0 -------------- + Correct the url for Twitter Card Support -+ Don't use cache when running `catsup server` ++ Don't use cache when running ``catsup server`` ++ Don't load post cache when running ``catsup server`` + Improve description creator Version 0.2.1 From de494a06931af7b3f6b604146631982f7e918f96 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 23 Nov 2013 18:20:44 +0800 Subject: [PATCH 14/52] Update Twitter Card metas --- catsup/templates/utils.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/catsup/templates/utils.html b/catsup/templates/utils.html index df1a414..c69a8ab 100644 --- a/catsup/templates/utils.html +++ b/catsup/templates/utils.html @@ -49,8 +49,9 @@ {% macro meta(post) %} - - + + + {% endmacro %} \ No newline at end of file From 9b87e4a574ef175abf6c11f64d1a2a7dbf70d64e Mon Sep 17 00:00:00 2001 From: whtsky Date: Fri, 6 Dec 2013 22:32:26 +0800 Subject: [PATCH 15/52] pep8 passed on deploy.py --- catsup/deploy.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/catsup/deploy.py b/catsup/deploy.py index 44fbb9a..6958ea5 100644 --- a/catsup/deploy.py +++ b/catsup/deploy.py @@ -1,10 +1,15 @@ import os import datetime +import shutil from catsup.logger import logger from catsup.utils import call +RSYNC_COMMAND = "rsync -avze 'ssh -p {ssh_port}' {args}" \ + " {deploy_dir}/ {ssh_user}@{ssh_host}:{document_root}" + + def git(config): logger.info("Deploying your site via git") @@ -18,7 +23,6 @@ def _call(*args, **kwargs): if os.path.exists(dot_git_path) and \ _call('git remote -v | grep %s' % config.deploy.git.repo) == 0: if os.path.exists(dot_git_path): - import shutil shutil.rmtree(dot_git_path) _call('git init', silence=True) _call('git remote add origin %s' % config.deploy.git.repo) @@ -44,8 +48,7 @@ def rsync(config): args = "--delete" else: args = "" - cmd = "rsync -avze 'ssh -p {ssh_port}' {args}" \ - " {deploy_dir}/ {ssh_user}@{ssh_host}:{document_root}".format( + cmd = RSYNC_COMMAND.format( ssh_port=config.deploy.rsync.ssh_port, args=args, deploy_dir=config.config.output, From f07a5a7bbf7595ddda0858599a27f823562336b8 Mon Sep 17 00:00:00 2001 From: whtsky Date: Fri, 6 Dec 2013 22:41:47 +0800 Subject: [PATCH 16/52] drop file-based cache system --- catsup/cache.py | 42 ------------------------------------ catsup/cli.py | 36 +++---------------------------- catsup/generator/__init__.py | 9 +------- catsup/generator/models.py | 23 +------------------- catsup/generator/renderer.py | 4 +--- catsup/options.py | 1 - docs/changelog.rst | 3 +-- 7 files changed, 7 insertions(+), 111 deletions(-) delete mode 100644 catsup/cache.py diff --git a/catsup/cache.py b/catsup/cache.py deleted file mode 100644 index 4821410..0000000 --- a/catsup/cache.py +++ /dev/null @@ -1,42 +0,0 @@ -import os -import shutil - -from jinja2 import BytecodeCache -from catsup.options import g -from catsup.utils import mkdir - - -def get_cache_path(name): - """ - Return the cache file path to the given name. - """ - return os.path.join( - g.cwdpath, - ".catsup-cache", - name - ) - - -def remove_cache_path(): - if os.path.exists(".catsup-cache"): - shutil.rmtree(".catsup-cache") - - -class CatsupJinjaCache(BytecodeCache): - def __init__(self): - self.directory = get_cache_path("jinja2") - mkdir(self.directory) - - def load_bytecode(self, bucket): - filename = os.path.join(self.directory, bucket.key) - if os.path.exists(filename): - with open(filename, 'rb') as f: - bucket.load_bytecode(f) - - def dump_bytecode(self, bucket): - filename = os.path.join(self.directory, bucket.key) - with open(filename, 'wb') as f: - bucket.write_bytecode(f) - - -bytecode_cache = CatsupJinjaCache() diff --git a/catsup/cli.py b/catsup/cli.py index 5ca2612..20ffc40 100644 --- a/catsup/cli.py +++ b/catsup/cli.py @@ -15,11 +15,7 @@ g.public_templates_path = os.path.join(g.catsup_path, 'templates') g.cwdpath = os.path.abspath('.') -try: - import catsup -except ImportError: - import site - site.addsitedir(os.path.dirname(g.catsup_path)) +import catsup doc = """catsup v%s @@ -33,7 +29,6 @@ catsup webhook [-s |--settings=] [-p |--port=] catsup watch [-s |--settings=] catsup themes - catsup clean [-s |--settings=] catsup install catsup -h | --help catsup --version @@ -145,10 +140,8 @@ def server(settings, port): -p --port= specify the server port. [default: 8888] """ import catsup.server - from catsup.options import g - g.enable_cache = False - server = catsup.server.PreviewServer(settings, port) - server.run() + preview_server = catsup.server.PreviewServer(settings, port) + preview_server.run() @parguments.command @@ -206,29 +199,6 @@ def themes(): catsup.parser.themes.list() -@parguments.command -def clean(settings): - """ - Usage: - catsup clean [-s |--settings=] - - Options: - -s --settings= specify a setting file. [default: config.json] - -h --help Show this screen and exit. - """ - import shutil - import catsup.parser.config - import catsup.cache - config = catsup.parser.config(settings) - - catsup.cache.remove_cache_path() - logger.info("Removed cache folder.") - output_path = config.config.output - if os.path.exists(output_path): - shutil.rmtree(output_path) - logger.info("Removed output folder.") - - @parguments.command def install(theme): """ diff --git a/catsup/generator/__init__.py b/catsup/generator/__init__.py index 62b91b4..371d443 100644 --- a/catsup/generator/__init__.py +++ b/catsup/generator/__init__.py @@ -15,12 +15,6 @@ def __init__(self, config_path, local=False, base_url=None): self.config_path = config_path self.local = local - if not local: - from catsup.cache import bytecode_cache - self.bytecode_cache = bytecode_cache - else: - self.bytecode_cache = None - self.base_url = base_url g.generator = self @@ -77,8 +71,7 @@ def load_renderer(self): ] self.renderer = Renderer( templates_path=templates_path, - generator=self, - bytecode_cache=self.bytecode_cache + generator=self ) def generate_feed(self): diff --git a/catsup/generator/models.py b/catsup/generator/models.py index 45dcaa3..442d3e2 100644 --- a/catsup/generator/models.py +++ b/catsup/generator/models.py @@ -2,12 +2,10 @@ import os import re -import pickle from datetime import datetime from houdini import escape_html -from catsup.cache import get_cache_path from catsup.logger import logger from catsup.options import g from catsup.parser import markdown @@ -174,23 +172,11 @@ def create_description(self): if len(description) > 150: description = description[:150] description = description.strip() + description = to_unicode(description) return escape_html(description) def parse(self, path): st_ctime = os.stat(path).st_ctime - if g.enable_cache: - cache_path = get_cache_path(path) - cache_folder = os.path.dirname(cache_path) - if os.path.exists(cache_folder): - if os.path.exists(cache_path): - with open(cache_path, "rb") as f: - cache = pickle.load(f) - if cache["st_ctime"] == st_ctime: - self.__dict__.update(cache["post"]) - return - else: - os.makedirs(cache_folder) - try: with open(path, "r") as f: lines = f.readlines() @@ -236,13 +222,6 @@ def invailed_post(): self.type = self.meta.pop("type", "post") self.tags = [] - cache = { - "st_ctime": st_ctime, - "post": self.__dict__ - } - if g.enable_cache: - with open(cache_path, "wb") as f: - pickle.dump(cache, f) return invailed_post() diff --git a/catsup/generator/renderer.py b/catsup/generator/renderer.py index 49f56ed..72a7e8f 100644 --- a/catsup/generator/renderer.py +++ b/catsup/generator/renderer.py @@ -6,13 +6,11 @@ class Renderer(object): - def __init__(self, templates_path, generator, bytecode_cache=None): + def __init__(self, templates_path, generator): self.env = Environment( loader=FileSystemLoader(templates_path), autoescape=False ) - if bytecode_cache is not None: - self.env.bytecode_cache = bytecode_cache config = generator.config self.env.globals.update( diff --git a/catsup/options.py b/catsup/options.py index bec4f7b..2afe12d 100644 --- a/catsup/options.py +++ b/catsup/options.py @@ -1,4 +1,3 @@ from catsup.utils import ObjectDict g = ObjectDict() -g.enable_cache = True \ No newline at end of file diff --git a/docs/changelog.rst b/docs/changelog.rst index 8fb5244..9317f2b 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -5,8 +5,7 @@ Version 0.3.0 -------------- + Correct the url for Twitter Card Support -+ Don't use cache when running ``catsup server`` -+ Don't load post cache when running ``catsup server`` ++ Drop file-based cache system. + Improve description creator Version 0.2.1 From 06d1fe4adfe68cda7eeefb87b3a7905355b5c74a Mon Sep 17 00:00:00 2001 From: whtsky Date: Fri, 6 Dec 2013 23:02:26 +0800 Subject: [PATCH 17/52] improve parse func. --- catsup/generator/models.py | 67 +++++++++++++++++++++++--------------- catsup/generator/utils.py | 14 ++++++++ 2 files changed, 55 insertions(+), 26 deletions(-) diff --git a/catsup/generator/models.py b/catsup/generator/models.py index 442d3e2..c9e4473 100644 --- a/catsup/generator/models.py +++ b/catsup/generator/models.py @@ -10,7 +10,7 @@ from catsup.options import g from catsup.parser import markdown from catsup.utils import to_unicode, ObjectDict -from .utils import Pagination +from .utils import cached_func, Pagination class CatsupPage(object): @@ -140,9 +140,9 @@ class Post(CatsupPage): def __init__(self, filename, ext): self.meta = ObjectDict() - path = os.path.join(g.source, "%s%s" % (filename, ext)) + self.path = os.path.join(g.source, "%s%s" % (filename, ext)) self.filename = filename - self.parse(path) + self.parse() self.add_archive_and_tags() def add_archive_and_tags(self): @@ -159,7 +159,28 @@ def add_archive_and_tags(self): def get_permalink_args(self): return self.meta - def create_description(self): + @property + @cached_func + def datetime(self): + if "time" in self.meta: + return datetime.strptime( + self.meta.pop('time'), "%Y-%m-%d %H:%M") + elif self.DATE_RE.match(self.filename[:10]): + return datetime.strptime( + self.filename[:10], "%Y-%m-%d" + ) + else: + st_ctime = os.stat(self.path).st_ctime + return datetime.fromtimestamp(st_ctime) + + @property + @cached_func + def date(self): + return self.datetime.strftime("%Y-%m-%d") + + @property + @cached_func + def description(self): description = self.meta.get( "description", self.md @@ -172,16 +193,27 @@ def create_description(self): if len(description) > 150: description = description[:150] description = description.strip() - description = to_unicode(description) return escape_html(description) - def parse(self, path): - st_ctime = os.stat(path).st_ctime + @property + @cached_func + def allow_comment(self): + if self.meta.get("comment", None) == "disabled": + return False + else: + return g.config.comment.allow + + @property + @cached_func + def type(self): + return self.meta.get("type", "post") + + def parse(self): try: - with open(path, "r") as f: + with open(self.path, "r") as f: lines = f.readlines() except IOError: - logger.error("Can't open file %s" % path) + logger.error("Can't open file %s" % self.path) exit(1) def invailed_post(): @@ -204,23 +236,6 @@ def invailed_post(): self.md = to_unicode('\n'.join(lines[i + 1:])) self.content = markdown(self.md) - if "time" in self.meta: - self.datetime = datetime.strptime( - self.meta.pop('time'), "%Y-%m-%d %H:%M") - elif self.DATE_RE.match(self.filename[:10]): - self.datetime = datetime.strptime( - self.filename[:10], "%Y-%m-%d" - ) - else: - self.datetime = datetime.fromtimestamp(st_ctime) - self.date = self.datetime.strftime("%Y-%m-%d") - self.description = self.create_description() - if self.meta.get("comment", None) == "disabled": - self.allow_comment = False - else: - self.allow_comment = g.config.comment.allow - - self.type = self.meta.pop("type", "post") self.tags = [] return diff --git a/catsup/generator/utils.py b/catsup/generator/utils.py index 81428f9..04a781a 100644 --- a/catsup/generator/utils.py +++ b/catsup/generator/utils.py @@ -1,3 +1,17 @@ +def cached_func(f): + """ + Used for cache property funcs in class to work with Jinja2. + """ + func_name = f.__name__ + property_name = "_%s" % func_name + + def wraps(self): + if not hasattr(self, property_name): + setattr(self, property_name, f(self)) + return getattr(self, property_name) + return wraps + + class Pagination(object): def __init__(self, page, posts, per_page, get_permalink): self.total_items = posts From 61805ed5c08c5f7789586908f106b27c431666c0 Mon Sep 17 00:00:00 2001 From: whtsky Date: Fri, 6 Dec 2013 23:14:56 +0800 Subject: [PATCH 18/52] generate description from content instead of md --- catsup/generator/models.py | 31 ++++++++++++++++++------------- catsup/utils.py | 8 ++++++++ 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/catsup/generator/models.py b/catsup/generator/models.py index c9e4473..54890d8 100644 --- a/catsup/generator/models.py +++ b/catsup/generator/models.py @@ -9,7 +9,7 @@ from catsup.logger import logger from catsup.options import g from catsup.parser import markdown -from catsup.utils import to_unicode, ObjectDict +from catsup.utils import html_to_raw_text, to_unicode, ObjectDict from .utils import cached_func, Pagination @@ -183,17 +183,16 @@ def date(self): def description(self): description = self.meta.get( "description", - self.md - ) - if "***" in description: - description = description.split("***")[0] - description = description.replace("\n", " ") - else: - description = description.split("\n")[0] + self.content + ).replace("\n", "") + description = html_to_raw_text(description) + if " 150: description = description[:150] - description = description.strip() - return escape_html(description) + return description.strip() @property @cached_func @@ -203,6 +202,11 @@ def allow_comment(self): else: return g.config.comment.allow + @property + @cached_func + def title(self): + return self.meta.get("title", "") + @property @cached_func def type(self): @@ -222,7 +226,7 @@ def invailed_post(): title = lines.pop(0) if title.startswith("#"): - self.title = escape_html(title[1:].strip()) + self.meta["title"] = escape_html(title[1:].strip()) else: invailed_post() @@ -233,8 +237,9 @@ def invailed_post(): self.meta[name] = value.strip() elif line.strip().startswith('---'): - self.md = to_unicode('\n'.join(lines[i + 1:])) - self.content = markdown(self.md) + self.content = markdown( + to_unicode('\n'.join(lines[i + 1:])) + ) self.tags = [] return diff --git a/catsup/utils.py b/catsup/utils.py index a8645c5..148a774 100644 --- a/catsup/utils.py +++ b/catsup/utils.py @@ -1,4 +1,5 @@ import os +import re import sys import subprocess @@ -18,6 +19,13 @@ unicode = str +HTML_TAG_RE = re.compile("<.*?>") + + +def html_to_raw_text(html): + return "".join(HTML_TAG_RE.split(html)) + + def static_url(f): from catsup.options import g caches_class = g.generator.caches["static_url"] From 0fdadef4ed706e671154bc5f5a5f9b00e2d635c5 Mon Sep 17 00:00:00 2001 From: whtsky Date: Fri, 6 Dec 2013 23:40:52 +0800 Subject: [PATCH 19/52] Add multi-format post support --- catsup/generator/__init__.py | 22 ++++----- catsup/generator/models.py | 70 ++++++++------------------- catsup/parser/__init__.py | 6 --- catsup/reader/__init__.py | 18 +++++++ catsup/{parser => reader}/markdown.py | 45 +++++++++++++++++ docs/changelog.rst | 1 + 6 files changed, 96 insertions(+), 66 deletions(-) create mode 100644 catsup/reader/__init__.py rename catsup/{parser => reader}/markdown.py (51%) diff --git a/catsup/generator/__init__.py b/catsup/generator/__init__.py index 371d443..2d53c3b 100644 --- a/catsup/generator/__init__.py +++ b/catsup/generator/__init__.py @@ -5,6 +5,7 @@ from catsup.logger import logger from catsup.generator.renderer import Renderer +from catsup.reader import get_reader from catsup.options import g from catsup.utils import smart_copy from .models import * @@ -36,15 +37,6 @@ def load_config(self): base_url=self.base_url ) - def load_post(self, filename, ext): - logger.info('Loading file %s' % filename) - - post = Post(filename, ext) - if post.type == "page": - self.pages.append(post) - else: - self.posts.append(post) - def load_posts(self): self.posts = [] self.pages = [] @@ -55,8 +47,16 @@ def load_posts(self): if f.startswith("."): # hidden file continue filename, ext = os.path.splitext(f) - if ext.lower() in ['.md', '.markdown']: - self.load_post(filename, ext) + ext = ext.lower()[1:] + reader = get_reader(ext) + if reader is not None: + logger.info('Loading file %s' % filename) + path = os.path.join(g.source, f) + post = reader(path) + if post.type == "page": + self.pages.append(post) + else: + self.posts.append(post) else: self.static_files.append(f) self.posts.sort( diff --git a/catsup/generator/models.py b/catsup/generator/models.py index 54890d8..0c61d3a 100644 --- a/catsup/generator/models.py +++ b/catsup/generator/models.py @@ -4,12 +4,9 @@ import re from datetime import datetime -from houdini import escape_html -from catsup.logger import logger from catsup.options import g -from catsup.parser import markdown -from catsup.utils import html_to_raw_text, to_unicode, ObjectDict +from catsup.utils import html_to_raw_text from .utils import cached_func, Pagination @@ -138,11 +135,11 @@ def __iter__(self): class Post(CatsupPage): DATE_RE = re.compile('\d{4}\-\d{2}\-\d{2}') - def __init__(self, filename, ext): - self.meta = ObjectDict() - self.path = os.path.join(g.source, "%s%s" % (filename, ext)) - self.filename = filename - self.parse() + def __init__(self, path, meta, content): + self.path = path + self.meta = meta + self.content = content + self.tags = [] self.add_archive_and_tags() def add_archive_and_tags(self): @@ -164,14 +161,23 @@ def get_permalink_args(self): def datetime(self): if "time" in self.meta: return datetime.strptime( - self.meta.pop('time'), "%Y-%m-%d %H:%M") - elif self.DATE_RE.match(self.filename[:10]): - return datetime.strptime( - self.filename[:10], "%Y-%m-%d" + self.meta["time"], "%Y-%m-%d %H:%M" + ) + elif "date" in self.meta: + return datetime.strftime( + self.meta["date"], "%Y-%m-%d" ) else: - st_ctime = os.stat(self.path).st_ctime - return datetime.fromtimestamp(st_ctime) + if "-" in self.path: + import os.path + filename, _ = os.path.splitext(self.path) + filename = os.path.basename(filename) + if self.DATE_RE.match(filename[:10]): + return datetime.strptime( + filename[:10], "%Y-%m-%d" + ) + st_ctime = os.stat(self.path).st_ctime + return datetime.fromtimestamp(st_ctime) @property @cached_func @@ -212,40 +218,6 @@ def title(self): def type(self): return self.meta.get("type", "post") - def parse(self): - try: - with open(self.path, "r") as f: - lines = f.readlines() - except IOError: - logger.error("Can't open file %s" % self.path) - exit(1) - - def invailed_post(): - logger.error("%s is not a vailed catsup post" % self.filename) - exit(1) - - title = lines.pop(0) - if title.startswith("#"): - self.meta["title"] = escape_html(title[1:].strip()) - else: - invailed_post() - - for i, line in enumerate(lines): - if ':' in line: # property - name, value = line.split(':', 1) - name = name.strip().lstrip('-').strip().lower() - self.meta[name] = value.strip() - - elif line.strip().startswith('---'): - self.content = markdown( - to_unicode('\n'.join(lines[i + 1:])) - ) - - self.tags = [] - return - - invailed_post() - class Page(CatsupPage): def __init__(self, posts): diff --git a/catsup/parser/__init__.py b/catsup/parser/__init__.py index 12af9da..0b46201 100644 --- a/catsup/parser/__init__.py +++ b/catsup/parser/__init__.py @@ -1,10 +1,4 @@ from .config import load -from .markdown import md - - -def markdown(content, **kwargs): - html = md.render(content, **kwargs) - return html def config(*args, **kwargs): diff --git a/catsup/reader/__init__.py b/catsup/reader/__init__.py new file mode 100644 index 0000000..137ff5a --- /dev/null +++ b/catsup/reader/__init__.py @@ -0,0 +1,18 @@ +from .markdown import markdown_reader + +READERS = dict() + + +def register_reader(ext, f): + if isinstance(ext, (list, tuple)): + for e in ext: + READERS[e.lower()] = f + else: + READERS[ext.lower()] = f + + +def get_reader(ext): + return READERS.get(ext, None) + + +register_reader(["md", "markdown"], markdown_reader) diff --git a/catsup/parser/markdown.py b/catsup/reader/markdown.py similarity index 51% rename from catsup/parser/markdown.py rename to catsup/reader/markdown.py index c7728f6..517b99a 100644 --- a/catsup/parser/markdown.py +++ b/catsup/reader/markdown.py @@ -6,6 +6,10 @@ from pygments.lexers import get_lexer_by_name from pygments.util import ClassNotFound +from catsup.logger import logger +from catsup.generator.models import Post +from catsup.utils import to_unicode, ObjectDict + class CatsupRender(m.HtmlRenderer, m.SmartyPants): def block_code(self, text, lang): @@ -33,3 +37,44 @@ def autolink(self, link, is_email): m.EXT_AUTOLINK | m.EXT_STRIKETHROUGH | m.EXT_SUPERSCRIPT) + + +def markdown_reader(path): + meta = ObjectDict() + + try: + with open(path, "r") as f: + lines = f.readlines() + except IOError: + logger.error("Can't open file %s" % path) + exit(1) + + def invailed_post(): + logger.error("%s is not a vailed catsup post" % self.filename) + exit(1) + + title = lines.pop(0) + if title.startswith("#"): + meta["title"] = escape_html(title[1:].strip()) + else: + invailed_post() + + for i, line in enumerate(lines): + if ':' in line: # property + name, value = line.split(':', 1) + name = name.strip().lstrip('-').strip().lower() + meta[name] = value.strip() + + elif line.strip().startswith('---'): + content = md.render( + to_unicode('\n'.join(lines[i + 1:])) + ) + + return Post( + path=path, + meta=meta, + content=content + ) + + invailed_post() + diff --git a/docs/changelog.rst b/docs/changelog.rst index 9317f2b..5a57443 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -4,6 +4,7 @@ Changelog Version 0.3.0 -------------- ++ Add multi-format post support + Correct the url for Twitter Card Support + Drop file-based cache system. + Improve description creator From 976e8aa2d9bc744e15ca5b1d7417b0d33f8c4127 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 4 Jan 2014 16:53:40 +0800 Subject: [PATCH 20/52] Bring ``catsup clean`` command back. Deleted by mistake. --- catsup/cli.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/catsup/cli.py b/catsup/cli.py index 20ffc40..26e64f9 100644 --- a/catsup/cli.py +++ b/catsup/cli.py @@ -28,6 +28,7 @@ catsup server [-s |--settings=] [-p |--port=] catsup webhook [-s |--settings=] [-p |--port=] catsup watch [-s |--settings=] + catsup clean [-s |--settings=] catsup themes catsup install catsup -h | --help @@ -186,6 +187,24 @@ def watch(settings): pass +@parguments.command +def clean(settings): + """ + Usage: + catsup clean [-s |--settings=] + + Options: + -h --help Show this screen and exit. + -s --settings= specify a setting file. [default: config.json] + """ + import shutil + import catsup.parser.config + config = catsup.parser.config(settings) + + for path in [config.config.static_output, config.config.output]: + if os.path.exists(path): + shutil.rmtree(path) + @parguments.command def themes(): """ From 9a0840b0ceba02e83a81c4a618d1a8045237746b Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 4 Jan 2014 16:54:00 +0800 Subject: [PATCH 21/52] Improved static file support + Add ``config.config.static_source`` + Add ``config.config.static_output`` --- catsup/generator/__init__.py | 42 ++++++++++++++++++++---------------- catsup/templates/config.json | 3 ++- docs/changelog.rst | 2 ++ 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/catsup/generator/__init__.py b/catsup/generator/__init__.py index 2d53c3b..8956e45 100644 --- a/catsup/generator/__init__.py +++ b/catsup/generator/__init__.py @@ -19,7 +19,20 @@ def __init__(self, config_path, local=False, base_url=None): self.base_url = base_url g.generator = self + self.posts = [] + self.pages = [] + self.non_post_files = [] + self.archives = [] + self.tags = [] + self.caches = [] + self.config = {} + self.renderer = None + self.reset() + def reset(self): + self.posts = [] + self.pages = [] + self.non_post_files = [] self.archives = g.archives = Archives() self.tags = g.tags = Tags() self.load_config() @@ -38,11 +51,6 @@ def load_config(self): ) def load_posts(self): - self.posts = [] - self.pages = [] - - self.static_files = [] - for f in os.listdir(g.source): if f.startswith("."): # hidden file continue @@ -58,7 +66,7 @@ def load_posts(self): else: self.posts.append(post) else: - self.static_files.append(f) + self.non_post_files.append(f) self.posts.sort( key=lambda x: x.datetime, reverse=True @@ -98,25 +106,21 @@ def generate_other_pages(self): NotFound().render(self.renderer) def copy_static_files(self): - static_path = os.path.join( - self.config.config.output, - "static" - ) + static_path = self.config.config.static_output smart_copy( os.path.join(g.theme.path, 'static'), static_path ) - for f in self.static_files: - source = os.path.join( - self.config.config.source, - f - ) - target = os.path.join( - self.config.config.output, - f + smart_copy( + self.config.config.static_source, + static_path + ) + for f in self.non_post_files: + smart_copy( + os.path.join(g.source, f), + os.path.join(self.config.config.output, f) ) - smart_copy(source, target) def generate(self): started_loading = time.time() diff --git a/catsup/templates/config.json b/catsup/templates/config.json index 36a3a4c..82b9051 100644 --- a/catsup/templates/config.json +++ b/catsup/templates/config.json @@ -13,7 +13,9 @@ "config": { "source": "posts", + "static_source": "static", "output": "deploy", + "static_output": "deploy/static", "static_prefix": "/static/", "analytics": "" }, @@ -55,7 +57,6 @@ "theme": { "name": "sealscript", "vars": { - "description": "a blog", "github": "whtsky", "links": [ { diff --git a/docs/changelog.rst b/docs/changelog.rst index 5a57443..98530d9 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -8,6 +8,8 @@ Version 0.3.0 + Correct the url for Twitter Card Support + Drop file-based cache system. + Improve description creator ++ Add ``config.config.static_source`` ++ Add ``config.config.static_output`` Version 0.2.1 -------------- From bea4d1734ce4dc67c13fc4c1ddd06d558242d156 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 4 Jan 2014 16:56:58 +0800 Subject: [PATCH 22/52] Fix a bug on ``catsup.reader.markdown`` --- catsup/reader/markdown.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/catsup/reader/markdown.py b/catsup/reader/markdown.py index 517b99a..6ea44de 100644 --- a/catsup/reader/markdown.py +++ b/catsup/reader/markdown.py @@ -50,7 +50,7 @@ def markdown_reader(path): exit(1) def invailed_post(): - logger.error("%s is not a vailed catsup post" % self.filename) + logger.error("%s is not a vailed catsup post" % path) exit(1) title = lines.pop(0) @@ -77,4 +77,3 @@ def invailed_post(): ) invailed_post() - From 79a9469c165d0450fcec3dab776044912be35664 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 4 Jan 2014 17:00:56 +0800 Subject: [PATCH 23/52] =?UTF-8?q?Don=E2=80=99t=20copy=20folder=20when=20th?= =?UTF-8?q?e=20source=20folder=20is=20not=20exist.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catsup/cli.py | 1 + catsup/utils.py | 3 +++ 2 files changed, 4 insertions(+) diff --git a/catsup/cli.py b/catsup/cli.py index 26e64f9..b638208 100644 --- a/catsup/cli.py +++ b/catsup/cli.py @@ -205,6 +205,7 @@ def clean(settings): if os.path.exists(path): shutil.rmtree(path) + @parguments.command def themes(): """ diff --git a/catsup/utils.py b/catsup/utils.py index 148a774..4b6878f 100644 --- a/catsup/utils.py +++ b/catsup/utils.py @@ -112,6 +112,9 @@ def mkdir(path): def smart_copy(source, target): + if not os.path.exists(source): + return + def copy_file(source, target): if os.path.exists(target): if os.path.getsize(source) == os.path.getsize(target): From efb9dc0f4df85b08614c7e3781b790af415c97bc Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 4 Jan 2014 17:03:20 +0800 Subject: [PATCH 24/52] Prepare for rewriting tests. Remove all the test. --- test/blog/.gitignore | 1 - test/blog/config.json | 64 ------------------------------ test/blog/posts/2013-01-21-test.md | 13 ------ test/test.py | 19 --------- 4 files changed, 97 deletions(-) delete mode 100644 test/blog/.gitignore delete mode 100644 test/blog/config.json delete mode 100644 test/blog/posts/2013-01-21-test.md delete mode 100644 test/test.py diff --git a/test/blog/.gitignore b/test/blog/.gitignore deleted file mode 100644 index 9c1f902..0000000 --- a/test/blog/.gitignore +++ /dev/null @@ -1 +0,0 @@ -deploy/ \ No newline at end of file diff --git a/test/blog/config.json b/test/blog/config.json deleted file mode 100644 index ac884cd..0000000 --- a/test/blog/config.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "site": { - "name": "blogname", - "url": "http://blog.com" - }, - - "author": { - "name": "name", - "twitter": "twitter" - }, - - "config": { - "source": "posts", - "output": "deploy", - "static": "deploy/static", - "static_prefix": "/static/", - "feed": "/feed.xml", - "per_page": 3, - "posts_on_feed": 5, - "analytics": "", - "display_summary": false, - "escape_md": false - }, - - "comment": { - "allow": true, - "system": "disqus", - "disqus": "catsup", - "duoshuo": "catsup" - }, - - "deploy": { - "default": "rsync", - - "git": { - "repo": "repo url here", - "branch": "master", - "delete": true - }, - - "rsync": { - "ssh_port": 22, - "ssh_user": "username", - "ssh_host": "123.45.6.78", - "document_root": "~/website.com/", - "delete": true - } - }, - - "theme": { - "name": "sealscript", - "vars": { - "description": "a blog", - "github": "whtsky", - "links": [ - { - "name": "catsup", - "url": "https://github.com/whtsky/catsup", - "description": "Awesome!" - } - ] - } - } -} \ No newline at end of file diff --git a/test/blog/posts/2013-01-21-test.md b/test/blog/posts/2013-01-21-test.md deleted file mode 100644 index 050e849..0000000 --- a/test/blog/posts/2013-01-21-test.md +++ /dev/null @@ -1,13 +0,0 @@ -# Test - -- tags: catsup, python -- comment: disabled -- summary: this is a test post - ---- - -this is a test post - -```python -print "Hello World!" -``` diff --git a/test/test.py b/test/test.py deleted file mode 100644 index 610bfb7..0000000 --- a/test/test.py +++ /dev/null @@ -1,19 +0,0 @@ -import os - -CWD = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'blog') - -import catsup.utils - - -def call(cmd): - assert catsup.utils.call(cmd, silence=True, cwd=CWD) == 0 - - -def test(): - call('catsup build') - call('catsup themes') - call('catsup install git://github.com/whtsky/catsup-theme-sealscript.git') - call('catsup install sealscript') - call('catsup -h') - call('catsup --version') - call('rm -rf themes') From 632aac92428587427ef0f6eb94a0284283cb8622 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 4 Jan 2014 20:29:38 +0800 Subject: [PATCH 25/52] Make ``catsup server`` work properly. Yes, I fixed a bug.. --- catsup/generator/__init__.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/catsup/generator/__init__.py b/catsup/generator/__init__.py index 8956e45..0916c42 100644 --- a/catsup/generator/__init__.py +++ b/catsup/generator/__init__.py @@ -1,6 +1,5 @@ import time import os -import tempfile import catsup.parser from catsup.logger import logger @@ -130,8 +129,6 @@ def generate(self): "Loaded config and %s posts in %.3fs" % (len(self.posts), finish_loading - started_loading) ) - if self.local: - g.output = self.config.config.output = tempfile.mkdtemp() if self.posts: self.generate_feed() self.generate_pages() From 9ed139f465c22d64125cacf0fdcb43a931cba792 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 4 Jan 2014 20:31:34 +0800 Subject: [PATCH 26/52] Add txt format support(Untested) --- catsup/reader/__init__.py | 2 ++ catsup/reader/markdown.py | 51 ++++++++------------------------- catsup/reader/txt.py | 59 +++++++++++++++++++++++++++++++++++++++ catsup/reader/utils.py | 14 ++++++++++ 4 files changed, 86 insertions(+), 40 deletions(-) create mode 100644 catsup/reader/txt.py create mode 100644 catsup/reader/utils.py diff --git a/catsup/reader/__init__.py b/catsup/reader/__init__.py index 137ff5a..bbdc08c 100644 --- a/catsup/reader/__init__.py +++ b/catsup/reader/__init__.py @@ -1,4 +1,5 @@ from .markdown import markdown_reader +from .txt import txt_reader READERS = dict() @@ -16,3 +17,4 @@ def get_reader(ext): register_reader(["md", "markdown"], markdown_reader) +register_reader("txt", txt_reader) diff --git a/catsup/reader/markdown.py b/catsup/reader/markdown.py index 6ea44de..0619d32 100644 --- a/catsup/reader/markdown.py +++ b/catsup/reader/markdown.py @@ -1,14 +1,15 @@ import misaka as m -from houdini import escape_html from pygments import highlight from pygments.formatters import HtmlFormatter from pygments.lexers import get_lexer_by_name from pygments.util import ClassNotFound +from houdini import escape_html -from catsup.logger import logger from catsup.generator.models import Post -from catsup.utils import to_unicode, ObjectDict +from catsup.utils import to_unicode + +from catsup.reader.txt import text_reader class CatsupRender(m.HtmlRenderer, m.SmartyPants): @@ -40,40 +41,10 @@ def autolink(self, link, is_email): def markdown_reader(path): - meta = ObjectDict() - - try: - with open(path, "r") as f: - lines = f.readlines() - except IOError: - logger.error("Can't open file %s" % path) - exit(1) - - def invailed_post(): - logger.error("%s is not a vailed catsup post" % path) - exit(1) - - title = lines.pop(0) - if title.startswith("#"): - meta["title"] = escape_html(title[1:].strip()) - else: - invailed_post() - - for i, line in enumerate(lines): - if ':' in line: # property - name, value = line.split(':', 1) - name = name.strip().lstrip('-').strip().lower() - meta[name] = value.strip() - - elif line.strip().startswith('---'): - content = md.render( - to_unicode('\n'.join(lines[i + 1:])) - ) - - return Post( - path=path, - meta=meta, - content=content - ) - - invailed_post() + meta, raw_content = text_reader(path) + html = md.render(to_unicode(raw_content)) + return Post( + path=path, + meta=meta, + content=html + ) diff --git a/catsup/reader/txt.py b/catsup/reader/txt.py new file mode 100644 index 0000000..d113ae1 --- /dev/null +++ b/catsup/reader/txt.py @@ -0,0 +1,59 @@ +from houdini import escape_html + +from catsup.utils import ObjectDict +from catsup.reader.utils import open_file, not_valid + + +def parse_meta(lines, path): + if lines[0].startswith("#"): + return parse_catsup_meta(lines, path) + elif lines[0].startswith("---"): + return parse_liquid_meta(lines, path) + else: + not_valid(path) + return False + + +def parse_liquid_meta(lines, path): + meta = ObjectDict() + return meta + + +def parse_catsup_meta(lines, path): + meta = ObjectDict() + meta.title = escape_html(lines.pop(0)[1:].strip()) + for line in lines: + if ":" not in line: + not_valid(path) + name, value = line.split(':', 1) + name = name.strip().lstrip('-').strip().lower() + meta[name] = value.strip() + return meta + + +def text_reader(path): + post_file = open_file(path) + + lines = [] + firstline = post_file.readline().strip() + lines.append(firstline) + for l in post_file: + l = l.strip() + if l.startswith("---"): + break + elif l: + lines.append(l) + else: + not_valid(path) + meta = parse_meta(lines, path) + content = "".join(post_file) + return meta, content + + +def txt_reader(path): + meta, content = text_reader(path) + return Post( + path=path, + meta=meta, + content=content + ) diff --git a/catsup/reader/utils.py b/catsup/reader/utils.py new file mode 100644 index 0000000..089ebba --- /dev/null +++ b/catsup/reader/utils.py @@ -0,0 +1,14 @@ +from catsup.logger import logger + + +def open_file(path): + try: + return open(path, "r") + except IOError: + logger.error("Can't open file %s" % path) + exit(1) + + +def not_valid(path): + logger.error("%s is not a valid post." % path) + exit(1) From ed491383b183d9001872591554d218603983ae35 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 4 Jan 2014 20:33:26 +0800 Subject: [PATCH 27/52] Add tests for ``get_reader`` func --- tests/test_reader.py | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/test_reader.py diff --git a/tests/test_reader.py b/tests/test_reader.py new file mode 100644 index 0000000..83c1668 --- /dev/null +++ b/tests/test_reader.py @@ -0,0 +1,8 @@ +from catsup.reader import get_reader, markdown_reader, txt_reader + + +def test_reader_choser(): + assert get_reader("md") == markdown_reader + assert get_reader("markdown") == markdown_reader + assert get_reader("txt") == txt_reader + From d7c6e1381729162adaf04ded0875a286270eb8f4 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 4 Jan 2014 20:42:07 +0800 Subject: [PATCH 28/52] =?UTF-8?q?Escape=20txt=20post=E2=80=99s=20content?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catsup/reader/txt.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/catsup/reader/txt.py b/catsup/reader/txt.py index d113ae1..1d748d4 100644 --- a/catsup/reader/txt.py +++ b/catsup/reader/txt.py @@ -4,7 +4,8 @@ from catsup.reader.utils import open_file, not_valid -def parse_meta(lines, path): +def parse_meta(lines, path=None): + lines = [l.strip() for l in lines if l] if lines[0].startswith("#"): return parse_catsup_meta(lines, path) elif lines[0].startswith("---"): @@ -14,15 +15,17 @@ def parse_meta(lines, path): return False -def parse_liquid_meta(lines, path): +def parse_liquid_meta(lines, path=None): meta = ObjectDict() return meta -def parse_catsup_meta(lines, path): +def parse_catsup_meta(lines, path=None): meta = ObjectDict() meta.title = escape_html(lines.pop(0)[1:].strip()) for line in lines: + if not line: + continue if ":" not in line: not_valid(path) name, value = line.split(':', 1) @@ -52,6 +55,7 @@ def text_reader(path): def txt_reader(path): meta, content = text_reader(path) + content = escape_html(content).replace("\n", "
") return Post( path=path, meta=meta, From d298d97c75b6e34bd1d5c39c566fba2d87a18e82 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 4 Jan 2014 20:47:41 +0800 Subject: [PATCH 29/52] Only give posts archive and tags. --- catsup/generator/__init__.py | 1 + catsup/generator/models.py | 18 ++++++++---------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/catsup/generator/__init__.py b/catsup/generator/__init__.py index 0916c42..51fa486 100644 --- a/catsup/generator/__init__.py +++ b/catsup/generator/__init__.py @@ -91,6 +91,7 @@ def generate_pages(self): def generate_posts(self): for post in self.posts: + post.add_archive_and_tags() post.render(self.renderer) for page in self.pages: page.render(self.renderer) diff --git a/catsup/generator/models.py b/catsup/generator/models.py index 0c61d3a..f7d3f0c 100644 --- a/catsup/generator/models.py +++ b/catsup/generator/models.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- -import os import re from datetime import datetime @@ -140,18 +139,16 @@ def __init__(self, path, meta, content): self.meta = meta self.content = content self.tags = [] - self.add_archive_and_tags() def add_archive_and_tags(self): - if self.type != "page": - year = self.datetime.strftime("%Y") - g.archives.get(year).add_post(self) + year = self.datetime.strftime("%Y") + g.archives.get(year).add_post(self) - for tag in self.meta.pop("tags", "").split(","): - tag = tag.strip() - tag = g.tags.get(tag) - tag.add_post(self) - self.tags.append(tag) + for tag in self.meta.pop("tags", "").split(","): + tag = tag.strip() + tag = g.tags.get(tag) + tag.add_post(self) + self.tags.append(tag) def get_permalink_args(self): return self.meta @@ -159,6 +156,7 @@ def get_permalink_args(self): @property @cached_func def datetime(self): + import os if "time" in self.meta: return datetime.strptime( self.meta["time"], "%Y-%m-%d %H:%M" From 71abf53e66dc5d15c540f01d4b70bd1cff7e18d5 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 4 Jan 2014 20:48:20 +0800 Subject: [PATCH 30/52] Forgot to import Post in ``catsup.reader.txt`` --- catsup/reader/txt.py | 1 + 1 file changed, 1 insertion(+) diff --git a/catsup/reader/txt.py b/catsup/reader/txt.py index 1d748d4..b65ceae 100644 --- a/catsup/reader/txt.py +++ b/catsup/reader/txt.py @@ -1,5 +1,6 @@ from houdini import escape_html +from catsup.generator.models import Post from catsup.utils import ObjectDict from catsup.reader.utils import open_file, not_valid From ba3257118ac02e48332fa8cab7469ef54ddcf610 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 4 Jan 2014 20:53:37 +0800 Subject: [PATCH 31/52] Move ``catsup.generator.models`` and ``catsup.generator.utils`` to top level --- catsup/generator/utils.py | 65 -------------------------------- catsup/{generator => }/models.py | 16 +++++++- catsup/reader/markdown.py | 5 +-- catsup/reader/txt.py | 2 +- catsup/utils.py | 55 ++++++++++++++++++++++++++- 5 files changed, 72 insertions(+), 71 deletions(-) rename catsup/{generator => }/models.py (94%) diff --git a/catsup/generator/utils.py b/catsup/generator/utils.py index 04a781a..e69de29 100644 --- a/catsup/generator/utils.py +++ b/catsup/generator/utils.py @@ -1,65 +0,0 @@ -def cached_func(f): - """ - Used for cache property funcs in class to work with Jinja2. - """ - func_name = f.__name__ - property_name = "_%s" % func_name - - def wraps(self): - if not hasattr(self, property_name): - setattr(self, property_name, f(self)) - return getattr(self, property_name) - return wraps - - -class Pagination(object): - def __init__(self, page, posts, per_page, get_permalink): - self.total_items = posts - self.page = page - self.per_page = per_page - self.get_permalink = get_permalink - - def iter_pages(self, edge=4): - if self.page <= edge: - return range(1, min(self.pages, 2 * edge + 1) + 1) - if self.page + edge > self.pages: - return range(max(self.pages - 2 * edge, 1), self.pages + 1) - return range(self.page - edge, min(self.pages, self.page + edge) + 1) - - @property - def pages(self): - return int((self.total - 1) / self.per_page) + 1 - - @property - def has_prev(self): - return self.page > 1 - - @property - def prev_permalink(self): - return self.get_permalink(self.prev_num) - - @property - def prev_num(self): - return self.page - 1 - - @property - def has_next(self): - return self.page < self.pages - - @property - def next_permalink(self): - return self.get_permalink(self.next_num) - - @property - def next_num(self): - return self.page + 1 - - @property - def total(self): - return len(self.total_items) - - @property - def items(self): - start = (self.page - 1) * self.per_page - end = self.page * self.per_page - return self.total_items[start:end] diff --git a/catsup/generator/models.py b/catsup/models.py similarity index 94% rename from catsup/generator/models.py rename to catsup/models.py index f7d3f0c..1dcbe1f 100644 --- a/catsup/generator/models.py +++ b/catsup/models.py @@ -6,7 +6,21 @@ from catsup.options import g from catsup.utils import html_to_raw_text -from .utils import cached_func, Pagination +from .utils import Pagination + + +def cached_func(f): + """ + Used for cache property funcs in class to work with Jinja2. + """ + func_name = f.__name__ + property_name = "_%s" % func_name + + def wraps(self): + if not hasattr(self, property_name): + setattr(self, property_name, f(self)) + return getattr(self, property_name) + return wraps class CatsupPage(object): diff --git a/catsup/reader/markdown.py b/catsup/reader/markdown.py index 0619d32..27277bf 100644 --- a/catsup/reader/markdown.py +++ b/catsup/reader/markdown.py @@ -1,14 +1,13 @@ import misaka as m +from houdini import escape_html from pygments import highlight from pygments.formatters import HtmlFormatter from pygments.lexers import get_lexer_by_name from pygments.util import ClassNotFound -from houdini import escape_html -from catsup.generator.models import Post +from catsup.models import Post from catsup.utils import to_unicode - from catsup.reader.txt import text_reader diff --git a/catsup/reader/txt.py b/catsup/reader/txt.py index b65ceae..863d594 100644 --- a/catsup/reader/txt.py +++ b/catsup/reader/txt.py @@ -1,6 +1,6 @@ from houdini import escape_html -from catsup.generator.models import Post +from catsup.models import Post from catsup.utils import ObjectDict from catsup.reader.utils import open_file, not_valid diff --git a/catsup/utils.py b/catsup/utils.py index 4b6878f..21beabd 100644 --- a/catsup/utils.py +++ b/catsup/utils.py @@ -58,7 +58,7 @@ def url_for(obj): caches_class = g.generator.caches["url_for"] key = id(obj) if key not in caches_class: - from catsup.generator.models import CatsupPage + from catsup.models import CatsupPage url = '' if obj == 'index': @@ -132,3 +132,56 @@ def copy_file(source, target): copy_file(sourcefile, targetfile) else: smart_copy(sourcefile, targetfile) + + +class Pagination(object): + def __init__(self, page, posts, per_page, get_permalink): + self.total_items = posts + self.page = page + self.per_page = per_page + self.get_permalink = get_permalink + + def iter_pages(self, edge=4): + if self.page <= edge: + return range(1, min(self.pages, 2 * edge + 1) + 1) + if self.page + edge > self.pages: + return range(max(self.pages - 2 * edge, 1), self.pages + 1) + return range(self.page - edge, min(self.pages, self.page + edge) + 1) + + @property + def pages(self): + return int((self.total - 1) / self.per_page) + 1 + + @property + def has_prev(self): + return self.page > 1 + + @property + def prev_permalink(self): + return self.get_permalink(self.prev_num) + + @property + def prev_num(self): + return self.page - 1 + + @property + def has_next(self): + return self.page < self.pages + + @property + def next_permalink(self): + return self.get_permalink(self.next_num) + + @property + def next_num(self): + return self.page + 1 + + @property + def total(self): + return len(self.total_items) + + @property + def items(self): + start = (self.page - 1) * self.per_page + end = self.page * self.per_page + return self.total_items[start:end] From cff5d595768291f74912784807d7284c9f7049fa Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 4 Jan 2014 21:30:20 +0800 Subject: [PATCH 32/52] Support Non-meta post --- catsup/reader/txt.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/catsup/reader/txt.py b/catsup/reader/txt.py index 863d594..5d790bb 100644 --- a/catsup/reader/txt.py +++ b/catsup/reader/txt.py @@ -1,7 +1,7 @@ from houdini import escape_html from catsup.models import Post -from catsup.utils import ObjectDict +from catsup.utils import ObjectDict, to_unicode from catsup.reader.utils import open_file, not_valid @@ -13,7 +13,6 @@ def parse_meta(lines, path=None): return parse_liquid_meta(lines, path) else: not_valid(path) - return False def parse_liquid_meta(lines, path=None): @@ -23,7 +22,10 @@ def parse_liquid_meta(lines, path=None): def parse_catsup_meta(lines, path=None): meta = ObjectDict() - meta.title = escape_html(lines.pop(0)[1:].strip()) + title_line = lines.pop(0) + if title_line[0] != "#": + not_valid(path) + meta.title = escape_html(title_line[1:].strip()) for line in lines: if not line: continue @@ -40,6 +42,9 @@ def text_reader(path): lines = [] firstline = post_file.readline().strip() + + no_meta = False + lines.append(firstline) for l in post_file: l = l.strip() @@ -48,9 +53,18 @@ def text_reader(path): elif l: lines.append(l) else: - not_valid(path) - meta = parse_meta(lines, path) - content = "".join(post_file) + no_meta = True + if no_meta: + import os + p, _ = os.path.splitext(path) + filename = os.path.basename(p) + meta = ObjectDict( + title=filename + ) + content = "\n".join(lines) + else: + meta = parse_meta(lines, path) + content = "".join(post_file) return meta, content @@ -60,5 +74,5 @@ def txt_reader(path): return Post( path=path, meta=meta, - content=content + content=to_unicode(content) ) From 3e2b904b4f5fcbcf355d2ddd54abaf9627ad25df Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 4 Jan 2014 21:30:46 +0800 Subject: [PATCH 33/52] Update change log --- docs/changelog.rst | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 98530d9..8caa2fb 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -5,11 +5,15 @@ Version 0.3.0 -------------- + Add multi-format post support ++ Add ``config.config.static_source`` ++ Add ``config.config.static_output`` ++ Support Non-meta post. ++ Support TXT format post. + Correct the url for Twitter Card Support + Drop file-based cache system. + Improve description creator -+ Add ``config.config.static_source`` -+ Add ``config.config.static_output`` + ++ Reorganize code. Version 0.2.1 -------------- From 66bb871ec9d1b5dada1ab6e33e92501565d8f826 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sat, 4 Jan 2014 21:31:02 +0800 Subject: [PATCH 34/52] Add tests for catsup.parser --- .gitignore | 3 ++- catsup/generator/__init__.py | 2 +- get_coverage_report.sh | 8 ++++++ tests/2013-02-11-test.md | 15 +++++++++++ tests/no_meta.txt | 1 + tests/post.txt | 10 ++++++++ tests/test_meta_parser.py | 48 ++++++++++++++++++++++++++++++++++++ tests/test_reader.py | 48 +++++++++++++++++++++++++++++++++++- 8 files changed, 132 insertions(+), 3 deletions(-) create mode 100755 get_coverage_report.sh create mode 100644 tests/2013-02-11-test.md create mode 100644 tests/no_meta.txt create mode 100644 tests/post.txt create mode 100644 tests/test_meta_parser.py diff --git a/.gitignore b/.gitignore index c7f864e..e902015 100644 --- a/.gitignore +++ b/.gitignore @@ -43,4 +43,5 @@ docs/_build/ #Virtualenv .Python lib/ -include/ \ No newline at end of file +include/ +htmlcov diff --git a/catsup/generator/__init__.py b/catsup/generator/__init__.py index 51fa486..34439c4 100644 --- a/catsup/generator/__init__.py +++ b/catsup/generator/__init__.py @@ -7,7 +7,7 @@ from catsup.reader import get_reader from catsup.options import g from catsup.utils import smart_copy -from .models import * +from catsup.models import * class Generator(object): diff --git a/get_coverage_report.sh b/get_coverage_report.sh new file mode 100755 index 0000000..ec505c4 --- /dev/null +++ b/get_coverage_report.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +coverage run --source=catsup setup.py -q nosetests +if [ $? != 0 ]; then + exit 1 +fi +coverage html +open htmlcov/index.html \ No newline at end of file diff --git a/tests/2013-02-11-test.md b/tests/2013-02-11-test.md new file mode 100644 index 0000000..1aa71d0 --- /dev/null +++ b/tests/2013-02-11-test.md @@ -0,0 +1,15 @@ +# Hello, World! Markdown! + +- tags: Hello, World + +--- + +Hi! +I'm happy to use Catsup! +中文测试 + +*** + +```python +print("Hello, World!") +``` diff --git a/tests/no_meta.txt b/tests/no_meta.txt new file mode 100644 index 0000000..7fd0751 --- /dev/null +++ b/tests/no_meta.txt @@ -0,0 +1 @@ +fjsdklfjskdal \ No newline at end of file diff --git a/tests/post.txt b/tests/post.txt new file mode 100644 index 0000000..8d6e67e --- /dev/null +++ b/tests/post.txt @@ -0,0 +1,10 @@ +# Hello, World! + +- tags: Hello, World +- time: 2014-01-04 20:56 + +--- + +Hi! +I'm happy to use Catsup! +中文测试 diff --git a/tests/test_meta_parser.py b/tests/test_meta_parser.py new file mode 100644 index 0000000..1099ae6 --- /dev/null +++ b/tests/test_meta_parser.py @@ -0,0 +1,48 @@ +from nose.tools import raises + + +def test_catsup_meta_parser(): + from catsup.reader.txt import parse_catsup_meta + + meta_txt = """ + # Hello, world! + + - tags: hello, world + """ + lines = [l.strip() for l in meta_txt.splitlines() if l] + meta = parse_catsup_meta(lines) + assert meta.title == "Hello, world!" + assert meta.tags == "hello, world" + + +@raises(SystemExit) +def test_catsup_meta_parser_error_1(): + from catsup.reader.txt import parse_catsup_meta + parse_catsup_meta(["fsdaf-,-,-,-", "fdsa- 0,"]) + + +@raises(SystemExit) +def test_catsup_meta_parser_error_2(): + from catsup.reader.txt import parse_catsup_meta + parse_catsup_meta(["#fsdaf-,-,-,-", "fdsa- 0,"]) + + +def test_meta_parser(): + from catsup.reader.txt import parse_meta + + meta_txt = """ + # Hello, world! + + - tags: hello, world + """ + + lines = [l.strip() for l in meta_txt.splitlines() if l] + meta = parse_meta(lines) + assert meta.title == "Hello, world!" + assert meta.tags == "hello, world" + + +@raises(SystemExit) +def test_parse_unknown_meta(): + from catsup.reader.txt import parse_meta + parse_meta(["fdsjaklfdsjaklfdsjaklfjdsklfjsa"]) \ No newline at end of file diff --git a/tests/test_reader.py b/tests/test_reader.py index 83c1668..3202fcb 100644 --- a/tests/test_reader.py +++ b/tests/test_reader.py @@ -1,8 +1,54 @@ -from catsup.reader import get_reader, markdown_reader, txt_reader +#coding: utf-8 + +import os + +from nose.tools import raises +from catsup.utils import to_unicode + +BASE_DIR = os.path.abspath(os.path.dirname(__file__)) def test_reader_choser(): + from catsup.reader import get_reader, markdown_reader, txt_reader assert get_reader("md") == markdown_reader assert get_reader("markdown") == markdown_reader assert get_reader("txt") == txt_reader + +@raises(SystemExit) +def test_open_unexist_file(): + from catsup.reader.utils import open_file + open_file(">_<") + + +def test_txt_reader(): + import datetime + from catsup.reader import txt_reader + post_path = os.path.join(BASE_DIR, "post.txt") + post = txt_reader(post_path) + assert post.path == post_path + assert post.date == "2014-01-04" + assert post.datetime == datetime.datetime(2014, 1, 4, 20, 56) + assert post.title == "Hello, World!" + assert post.content == to_unicode("
Hi!
I'm happy to use Catsup!
中文测试
") + + +def test_read_txt_without_meta(): + from catsup.reader import txt_reader + post_path = os.path.join(BASE_DIR, "no_meta.txt") + post = txt_reader(post_path) + assert post.title == "no_meta", post.title + + +def test_md_reader(): + from catsup.reader import markdown_reader + post_path = os.path.join(BASE_DIR, "2013-02-11-test.md") + post = markdown_reader(post_path) + assert post.path == post_path + assert post.content.strip() == to_unicode("""

Hi! +I'm happy to use Catsup! +中文测试

+ +
+
print("Hello, World!")
+
""").strip() From a98eab163943109998382c3d073f6dd80ebccfbf Mon Sep 17 00:00:00 2001 From: whtsky Date: Sun, 5 Jan 2014 00:03:57 +0800 Subject: [PATCH 35/52] Add more tests --- .gitignore | 1 + catsup/parser/config.py | 15 ++----- catsup/parser/utils.py | 7 +-- tests/config.json | 13 ++++++ tests/site/config.json | 70 ++++++++++++++++++++++++++++++ tests/site/posts/.should-not-exist | 0 tests/site/posts/hh.txt | 7 +++ tests/site/posts/should-exist | 0 tests/test_parser.py | 9 ++++ tests/test_with_cli.py | 41 +++++++++++++++++ 10 files changed, 149 insertions(+), 14 deletions(-) create mode 100644 tests/config.json create mode 100644 tests/site/config.json create mode 100644 tests/site/posts/.should-not-exist create mode 100644 tests/site/posts/hh.txt create mode 100644 tests/site/posts/should-exist create mode 100644 tests/test_parser.py create mode 100644 tests/test_with_cli.py diff --git a/.gitignore b/.gitignore index e902015..256289b 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,4 @@ docs/_build/ lib/ include/ htmlcov +tests/site/deploy diff --git a/catsup/parser/config.py b/catsup/parser/config.py index 9dc0ec3..1970f7d 100644 --- a/catsup/parser/config.py +++ b/catsup/parser/config.py @@ -1,14 +1,11 @@ -import sys import os import ujson -from parguments.cli import prompt_bool - from catsup.logger import logger from catsup.options import g from catsup.utils import update_nested_dict, urljoin, ObjectDict -from .utils import add_slash, create_config_file +from .utils import add_slash import catsup.parser.themes @@ -20,13 +17,9 @@ def parse(path): try: f = open(path, 'r') except IOError: - print("Can't find config file %s" % path) - - if prompt_bool("Create a new config file", default=True): - create_config_file() - else: - logger.error("Can't find config file. Exiting..") - sys.exit(0) + logger.error("Can't find config file." + "Run `catsup init` to generate a new config file.") + exit(1) return update_nested_dict(ObjectDict(), ujson.load(f)) diff --git a/catsup/parser/utils.py b/catsup/parser/utils.py index bfbf1c4..36c1fba 100644 --- a/catsup/parser/utils.py +++ b/catsup/parser/utils.py @@ -23,11 +23,12 @@ def create_config_file(path=None): config_path = os.path.join(current_dir, 'config.json') if os.path.exists(config_path): - print('These is a config.json in current directory(%s), ' - 'Have you run `catsup init` before?' % current_dir) - return + from catsup.logger import logger + logger.warning("Config file already exist.") + exit(1) mkdir("posts") + mkdir("static") template = get_template() diff --git a/tests/config.json b/tests/config.json new file mode 100644 index 0000000..8f2a127 --- /dev/null +++ b/tests/config.json @@ -0,0 +1,13 @@ +{ + "site": { + "name": "blogname", + "description": "Just another catsup blog", + "url": "http://blog.com/" + }, + + "author": { + "name": "nickname", + "email": "name@exmaple.com", + "twitter": "twitter" + } +} \ No newline at end of file diff --git a/tests/site/config.json b/tests/site/config.json new file mode 100644 index 0000000..82b9051 --- /dev/null +++ b/tests/site/config.json @@ -0,0 +1,70 @@ +{ + "site": { + "name": "blogname", + "description": "Just another catsup blog", + "url": "http://blog.com/" + }, + + "author": { + "name": "nickname", + "email": "name@exmaple.com", + "twitter": "twitter" + }, + + "config": { + "source": "posts", + "static_source": "static", + "output": "deploy", + "static_output": "deploy/static", + "static_prefix": "/static/", + "analytics": "" + }, + + "permalink": { + "page": "/page/{page}/", + "post": "/{title}/", + "tag": "/tag/{name}/", + "tags": "/tag/index.html", + "archive": "/archive/{year}/", + "archives": "/archive/index.html", + "feed": "/feed.xml" + }, + + "comment": { + "allow": true, + "system": "disqus", + "shortname": "catsup" + }, + + "deploy": { + "default": "rsync", + + "git": { + "repo": "repo url here", + "branch": "master", + "delete": true + }, + + "rsync": { + "ssh_port": 22, + "ssh_user": "username", + "ssh_host": "123.45.6.78", + "document_root": "~/website.com/", + "delete": true + } + }, + + "theme": { + "name": "sealscript", + "vars": { + "github": "whtsky", + "links": [ + { + "name": "catsup", + "url": "https://github.com/whtsky/catsup", + "description": "Awesome!" + } + ] + } + } +} \ No newline at end of file diff --git a/tests/site/posts/.should-not-exist b/tests/site/posts/.should-not-exist new file mode 100644 index 0000000..e69de29 diff --git a/tests/site/posts/hh.txt b/tests/site/posts/hh.txt new file mode 100644 index 0000000..e81e0cb --- /dev/null +++ b/tests/site/posts/hh.txt @@ -0,0 +1,7 @@ +# Hello + +- time: 2014-01-04 23:12 + +--- + +Hello! diff --git a/tests/site/posts/should-exist b/tests/site/posts/should-exist new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_parser.py b/tests/test_parser.py new file mode 100644 index 0000000..be29d85 --- /dev/null +++ b/tests/test_parser.py @@ -0,0 +1,9 @@ +import os +BASE_DIR = os.path.abspath(os.path.dirname(__file__)) + + +def test_config_parser(): + from catsup.parser.config import parse + from catsup.utils import ObjectDict + config = parse(os.path.join(BASE_DIR, "config.json")) + assert config == ObjectDict({u'site': {u'url': u'http://blog.com/', u'name': u'blogname', u'description': u'Just another catsup blog'}, u'author': {u'twitter': u'twitter', u'name': u'nickname', u'email': u'name@exmaple.com'}}) diff --git a/tests/test_with_cli.py b/tests/test_with_cli.py new file mode 100644 index 0000000..1f0b9f7 --- /dev/null +++ b/tests/test_with_cli.py @@ -0,0 +1,41 @@ +import os + +BASE_DIR = os.path.abspath(os.path.dirname(__file__)) +SITE_DIR = os.path.join(BASE_DIR, "site") + +os.chdir(SITE_DIR) + +from nose.tools import raises +from catsup.options import g +g.cwdpath = SITE_DIR + + +def output_exist(path): + return os.path.exists(os.path.join( + SITE_DIR, + "deploy", + path + )) + + +def test_build(): + from catsup.cli import clean, build + clean(settings="config.json") + build(settings="config.json") + assert output_exist("feed.xml") + assert output_exist("index.html") + assert output_exist("sitemap.txt") + assert output_exist("should-exist") + assert not output_exist(".should-not-exist") + + +def test_init(): + from catsup.cli import init + os.remove("config.json") + init("./") + + +@raises(SystemExit) +def test_reinit(): + from catsup.cli import init + init("./") From 83462a25cac64467b5172dd66cde12c55c9bb832 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sun, 5 Jan 2014 00:10:10 +0800 Subject: [PATCH 36/52] Support customize permalink for post --- catsup/models.py | 6 ++++++ docs/changelog.rst | 1 + tests/site/posts/page.markdown | 8 ++++++++ tests/test_with_cli.py | 1 + 4 files changed, 16 insertions(+) create mode 100644 tests/site/posts/page.markdown diff --git a/catsup/models.py b/catsup/models.py index 1dcbe1f..75d32a5 100644 --- a/catsup/models.py +++ b/catsup/models.py @@ -164,6 +164,12 @@ def add_archive_and_tags(self): tag.add_post(self) self.tags.append(tag) + @property + def permalink(self): + if "permalink" in self.meta: + return self.meta.permalink + return super(Post, self).permalink + def get_permalink_args(self): return self.meta diff --git a/docs/changelog.rst b/docs/changelog.rst index 8caa2fb..496ed4a 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -8,6 +8,7 @@ Version 0.3.0 + Add ``config.config.static_source`` + Add ``config.config.static_output`` + Support Non-meta post. ++ Support customize permalink for post + Support TXT format post. + Correct the url for Twitter Card Support + Drop file-based cache system. diff --git a/tests/site/posts/page.markdown b/tests/site/posts/page.markdown new file mode 100644 index 0000000..e421d58 --- /dev/null +++ b/tests/site/posts/page.markdown @@ -0,0 +1,8 @@ +# Page + +- time: 2014-01-05 00:05 +- permalink: /page.html + +--- + +This is a single Page. \ No newline at end of file diff --git a/tests/test_with_cli.py b/tests/test_with_cli.py index 1f0b9f7..378d99b 100644 --- a/tests/test_with_cli.py +++ b/tests/test_with_cli.py @@ -24,6 +24,7 @@ def test_build(): build(settings="config.json") assert output_exist("feed.xml") assert output_exist("index.html") + assert output_exist("page.html") assert output_exist("sitemap.txt") assert output_exist("should-exist") assert not output_exist(".should-not-exist") From 9f8a70696111547d0eca7b791288ca1c88f570c5 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sun, 5 Jan 2014 00:23:02 +0800 Subject: [PATCH 37/52] Add more tests --- tests/site/config2.json | 70 ++++++++++++++++++++++++++++++++++ tests/site/noposts/.gitkeep | 0 tests/site/posts/page.markdown | 1 + tests/test_parser.py | 8 ++++ tests/test_with_cli.py | 7 ++++ 5 files changed, 86 insertions(+) create mode 100644 tests/site/config2.json create mode 100644 tests/site/noposts/.gitkeep diff --git a/tests/site/config2.json b/tests/site/config2.json new file mode 100644 index 0000000..fff2381 --- /dev/null +++ b/tests/site/config2.json @@ -0,0 +1,70 @@ +{ + "site": { + "name": "blogname", + "description": "Just another catsup blog", + "url": "http://blog.com/" + }, + + "author": { + "name": "nickname", + "email": "name@exmaple.com", + "twitter": "twitter" + }, + + "config": { + "source": "noposts", + "static_source": "static", + "output": "deploy", + "static_output": "deploy/static", + "static_prefix": "/static/", + "analytics": "" + }, + + "permalink": { + "page": "/page/{page}/", + "post": "/{title}/", + "tag": "/tag/{name}/", + "tags": "/tag/index.html", + "archive": "/archive/{year}/", + "archives": "/archive/index.html", + "feed": "/feed.xml" + }, + + "comment": { + "allow": true, + "system": "disqus", + "shortname": "catsup" + }, + + "deploy": { + "default": "rsync", + + "git": { + "repo": "repo url here", + "branch": "master", + "delete": true + }, + + "rsync": { + "ssh_port": 22, + "ssh_user": "username", + "ssh_host": "123.45.6.78", + "document_root": "~/website.com/", + "delete": true + } + }, + + "theme": { + "name": "sealscript", + "vars": { + "github": "whtsky", + "links": [ + { + "name": "catsup", + "url": "https://github.com/whtsky/catsup", + "description": "Awesome!" + } + ] + } + } +} \ No newline at end of file diff --git a/tests/site/noposts/.gitkeep b/tests/site/noposts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/site/posts/page.markdown b/tests/site/posts/page.markdown index e421d58..96c38a6 100644 --- a/tests/site/posts/page.markdown +++ b/tests/site/posts/page.markdown @@ -2,6 +2,7 @@ - time: 2014-01-05 00:05 - permalink: /page.html +- type: page --- diff --git a/tests/test_parser.py b/tests/test_parser.py index be29d85..97e0558 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -1,9 +1,17 @@ import os BASE_DIR = os.path.abspath(os.path.dirname(__file__)) +from nose.tools import raises + def test_config_parser(): from catsup.parser.config import parse from catsup.utils import ObjectDict config = parse(os.path.join(BASE_DIR, "config.json")) assert config == ObjectDict({u'site': {u'url': u'http://blog.com/', u'name': u'blogname', u'description': u'Just another catsup blog'}, u'author': {u'twitter': u'twitter', u'name': u'nickname', u'email': u'name@exmaple.com'}}) + + +@raises(SystemExit) +def test_parser_non_exist_file(): + from catsup.parser.config import parse + parse("fd") diff --git a/tests/test_with_cli.py b/tests/test_with_cli.py index 378d99b..42446ce 100644 --- a/tests/test_with_cli.py +++ b/tests/test_with_cli.py @@ -40,3 +40,10 @@ def test_init(): def test_reinit(): from catsup.cli import init init("./") + + +def test_generate_without_post(): + from catsup.cli import clean, build + clean(settings="config2.json") + build(settings="config2.json") + assert not output_exist("page.html") From 77361983fe56bb80a4b49c7f4df83e8b060c551c Mon Sep 17 00:00:00 2001 From: whtsky Date: Sun, 5 Jan 2014 00:42:13 +0800 Subject: [PATCH 38/52] Add support for HTML format post. --- catsup/reader/__init__.py | 2 + catsup/reader/html.py | 73 +++++++++++++++++++++++ catsup/reader/markdown.py | 15 ++--- catsup/reader/txt.py | 84 ++++----------------------- docs/changelog.rst | 2 +- tests/site/posts/2013-12-12-html.html | 7 +++ tests/test_meta_parser.py | 10 ++-- 7 files changed, 105 insertions(+), 88 deletions(-) create mode 100644 catsup/reader/html.py create mode 100644 tests/site/posts/2013-12-12-html.html diff --git a/catsup/reader/__init__.py b/catsup/reader/__init__.py index bbdc08c..31389ce 100644 --- a/catsup/reader/__init__.py +++ b/catsup/reader/__init__.py @@ -1,5 +1,6 @@ from .markdown import markdown_reader from .txt import txt_reader +from .html import html_reader READERS = dict() @@ -18,3 +19,4 @@ def get_reader(ext): register_reader(["md", "markdown"], markdown_reader) register_reader("txt", txt_reader) +register_reader(["htm", "html"], html_reader) \ No newline at end of file diff --git a/catsup/reader/html.py b/catsup/reader/html.py new file mode 100644 index 0000000..f3b30b8 --- /dev/null +++ b/catsup/reader/html.py @@ -0,0 +1,73 @@ +from houdini import escape_html + +from catsup.models import Post +from catsup.utils import ObjectDict, to_unicode +from catsup.reader.utils import open_file, not_valid + + +def parse_meta(lines, path=None): + lines = [l.strip() for l in lines if l] + if lines[0].startswith("#"): + return parse_catsup_meta(lines, path) + elif lines[0].startswith("---"): + return parse_liquid_meta(lines, path) + else: + not_valid(path) + + +def parse_liquid_meta(lines, path=None): + meta = ObjectDict() + return meta + + +def parse_catsup_meta(lines, path=None): + meta = ObjectDict() + title_line = lines.pop(0) + if title_line[0] != "#": + not_valid(path) + meta.title = escape_html(title_line[1:].strip()) + for line in lines: + if not line: + continue + if ":" not in line: + not_valid(path) + name, value = line.split(':', 1) + name = name.strip().lstrip('-').strip().lower() + meta[name] = value.strip() + return meta + + +def html_reader(path): + post_file = open_file(path) + + lines = [] + firstline = post_file.readline().strip() + + no_meta = False + + lines.append(firstline) + for l in post_file: + l = l.strip() + if l.startswith("---"): + break + elif l: + lines.append(l) + else: + no_meta = True + if no_meta: + import os + + p, _ = os.path.splitext(path) + filename = os.path.basename(p) + meta = ObjectDict( + title=filename + ) + content = "\n".join(lines) + else: + meta = parse_meta(lines, path) + content = "".join(post_file) + return Post( + path=path, + meta=meta, + content=to_unicode(content) + ) diff --git a/catsup/reader/markdown.py b/catsup/reader/markdown.py index 27277bf..015ee52 100644 --- a/catsup/reader/markdown.py +++ b/catsup/reader/markdown.py @@ -6,9 +6,7 @@ from pygments.lexers import get_lexer_by_name from pygments.util import ClassNotFound -from catsup.models import Post -from catsup.utils import to_unicode -from catsup.reader.txt import text_reader +from catsup.reader.html import html_reader class CatsupRender(m.HtmlRenderer, m.SmartyPants): @@ -40,10 +38,7 @@ def autolink(self, link, is_email): def markdown_reader(path): - meta, raw_content = text_reader(path) - html = md.render(to_unicode(raw_content)) - return Post( - path=path, - meta=meta, - content=html - ) + post = html_reader(path) + post.content = md.render(post.content) + return post + diff --git a/catsup/reader/txt.py b/catsup/reader/txt.py index 5d790bb..92a0aa7 100644 --- a/catsup/reader/txt.py +++ b/catsup/reader/txt.py @@ -1,78 +1,18 @@ -from houdini import escape_html - -from catsup.models import Post -from catsup.utils import ObjectDict, to_unicode -from catsup.reader.utils import open_file, not_valid - - -def parse_meta(lines, path=None): - lines = [l.strip() for l in lines if l] - if lines[0].startswith("#"): - return parse_catsup_meta(lines, path) - elif lines[0].startswith("---"): - return parse_liquid_meta(lines, path) - else: - not_valid(path) - - -def parse_liquid_meta(lines, path=None): - meta = ObjectDict() - return meta +#coding: utf-8 +from houdini import escape_html -def parse_catsup_meta(lines, path=None): - meta = ObjectDict() - title_line = lines.pop(0) - if title_line[0] != "#": - not_valid(path) - meta.title = escape_html(title_line[1:].strip()) - for line in lines: - if not line: - continue - if ":" not in line: - not_valid(path) - name, value = line.split(':', 1) - name = name.strip().lstrip('-').strip().lower() - meta[name] = value.strip() - return meta - - -def text_reader(path): - post_file = open_file(path) - - lines = [] - firstline = post_file.readline().strip() - - no_meta = False - - lines.append(firstline) - for l in post_file: - l = l.strip() - if l.startswith("---"): - break - elif l: - lines.append(l) - else: - no_meta = True - if no_meta: - import os - p, _ = os.path.splitext(path) - filename = os.path.basename(p) - meta = ObjectDict( - title=filename - ) - content = "\n".join(lines) - else: - meta = parse_meta(lines, path) - content = "".join(post_file) - return meta, content +from catsup.utils import to_unicode +from catsup.reader.html import html_reader def txt_reader(path): - meta, content = text_reader(path) - content = escape_html(content).replace("\n", "
") - return Post( - path=path, - meta=meta, - content=to_unicode(content) + post = html_reader(path) + content = post.content.encode("utf-8") + content = escape_html(content) + content = content.replace( + "\n", + "
" ) + post.content = to_unicode(content) + return post diff --git a/docs/changelog.rst b/docs/changelog.rst index 496ed4a..af134b0 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -10,10 +10,10 @@ Version 0.3.0 + Support Non-meta post. + Support customize permalink for post + Support TXT format post. ++ Support HTML format post. + Correct the url for Twitter Card Support + Drop file-based cache system. + Improve description creator - + Reorganize code. Version 0.2.1 diff --git a/tests/site/posts/2013-12-12-html.html b/tests/site/posts/2013-12-12-html.html new file mode 100644 index 0000000..9f1ce59 --- /dev/null +++ b/tests/site/posts/2013-12-12-html.html @@ -0,0 +1,7 @@ +# HTML Page + +- type: page + +--- + +

Hi, I'm writing in HTML!

diff --git a/tests/test_meta_parser.py b/tests/test_meta_parser.py index 1099ae6..0139aa4 100644 --- a/tests/test_meta_parser.py +++ b/tests/test_meta_parser.py @@ -2,7 +2,7 @@ def test_catsup_meta_parser(): - from catsup.reader.txt import parse_catsup_meta + from catsup.reader.html import parse_catsup_meta meta_txt = """ # Hello, world! @@ -17,18 +17,18 @@ def test_catsup_meta_parser(): @raises(SystemExit) def test_catsup_meta_parser_error_1(): - from catsup.reader.txt import parse_catsup_meta + from catsup.reader.html import parse_catsup_meta parse_catsup_meta(["fsdaf-,-,-,-", "fdsa- 0,"]) @raises(SystemExit) def test_catsup_meta_parser_error_2(): - from catsup.reader.txt import parse_catsup_meta + from catsup.reader.html import parse_catsup_meta parse_catsup_meta(["#fsdaf-,-,-,-", "fdsa- 0,"]) def test_meta_parser(): - from catsup.reader.txt import parse_meta + from catsup.reader.html import parse_meta meta_txt = """ # Hello, world! @@ -44,5 +44,5 @@ def test_meta_parser(): @raises(SystemExit) def test_parse_unknown_meta(): - from catsup.reader.txt import parse_meta + from catsup.reader.html import parse_meta parse_meta(["fdsjaklfdsjaklfdsjaklfjdsklfjsa"]) \ No newline at end of file From d00188a307cb3eadcc3a6788e861c2550f618ffa Mon Sep 17 00:00:00 2001 From: whtsky Date: Thu, 9 Jan 2014 00:10:55 +0800 Subject: [PATCH 39/52] Submit coverage reports to coveralls. --- .coveragerc | 5 +++++ .travis.yml | 6 ++++-- dev-requirements.txt | 2 ++ get_coverage_report.sh | 4 ++-- 4 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 .coveragerc diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..a04c90b --- /dev/null +++ b/.coveragerc @@ -0,0 +1,5 @@ +[run] +include = catsup/* +omit = + deploy + server \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 16b84ca..3df8cda 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,9 @@ python: install: python setup.py install -script: nosetests +script: coverage run setup.py -q nosetests + +after_success: coveralls notifications: - email: false \ No newline at end of file + email: false diff --git a/dev-requirements.txt b/dev-requirements.txt index 8398a65..908fc06 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,6 +1,8 @@ -r requirements.txt cov-core==1.7 coverage==3.6 +coveralls==0.4 nose-cov==1.6 nose==1.3.0 pip-tools==0.3.4 +requests==2.1.0 diff --git a/get_coverage_report.sh b/get_coverage_report.sh index ec505c4..fb58cf7 100755 --- a/get_coverage_report.sh +++ b/get_coverage_report.sh @@ -1,8 +1,8 @@ #!/bin/sh -coverage run --source=catsup setup.py -q nosetests +coverage run setup.py -q nosetests if [ $? != 0 ]; then exit 1 fi coverage html -open htmlcov/index.html \ No newline at end of file +open htmlcov/index.html From 5e9ee609b588f8fcff7253d778920b544f427259 Mon Sep 17 00:00:00 2001 From: whtsky Date: Fri, 17 Jan 2014 14:44:32 +0800 Subject: [PATCH 40/52] add test themes --- tests/site/themes/test/templates/page.html | 17 +++++++++++++++ tests/site/themes/test/templates/post.html | 24 ++++++++++++++++++++++ tests/site/themes/test/theme.py | 5 +++++ 3 files changed, 46 insertions(+) create mode 100644 tests/site/themes/test/templates/page.html create mode 100644 tests/site/themes/test/templates/post.html create mode 100644 tests/site/themes/test/theme.py diff --git a/tests/site/themes/test/templates/page.html b/tests/site/themes/test/templates/page.html new file mode 100644 index 0000000..ac2f8d4 --- /dev/null +++ b/tests/site/themes/test/templates/page.html @@ -0,0 +1,17 @@ + + +
+ {% if pagination.has_prev %} + + {% endif %} + + Page {{ pagination.page }} of {{ pagination.pages }} + + {% if pagination.has_next %} + + {% endif %} +
diff --git a/tests/site/themes/test/templates/post.html b/tests/site/themes/test/templates/post.html new file mode 100644 index 0000000..d9db0bf --- /dev/null +++ b/tests/site/themes/test/templates/post.html @@ -0,0 +1,24 @@ + + +{% from 'utils.html' import render_comment, meta %} +{{ meta(post) }} +{{ post.title }} | {{ site.name }} + + + +

{{ post.title }}

+
+ {{ post.datetime.strftime("%b %d, %Y") }} +
+
+ {{ post.content }} +
+
+ Tags: + {% for tag in post.tags %} + {{ tag.name }} + {% endfor %} +
+ {{ render_comment(post) }} + + diff --git a/tests/site/themes/test/theme.py b/tests/site/themes/test/theme.py new file mode 100644 index 0000000..a01a5cc --- /dev/null +++ b/tests/site/themes/test/theme.py @@ -0,0 +1,5 @@ +name = 'test' +author = 'whtsky' +homepage = 'https://github.com/whtsky/catsup' +post_per_page = 2 +vars = {} From 84b53525608eddb5a2f0ab7bc1c25f986a711f6c Mon Sep 17 00:00:00 2001 From: whtsky Date: Fri, 17 Jan 2014 14:44:40 +0800 Subject: [PATCH 41/52] Update sealscript --- catsup/themes/sealscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/catsup/themes/sealscript b/catsup/themes/sealscript index 6cc092f..6e9e328 160000 --- a/catsup/themes/sealscript +++ b/catsup/themes/sealscript @@ -1 +1 @@ -Subproject commit 6cc092f5470443023623db4ee6b218de8f41e3d6 +Subproject commit 6e9e328a129b2c2a993d0c799a0c7bd341311293 From a3d189e20248632fa2e2b4f6a4ed834eb3a40f83 Mon Sep 17 00:00:00 2001 From: whtsky Date: Fri, 17 Jan 2014 15:02:59 +0800 Subject: [PATCH 42/52] Rewrite `catsup install` --- catsup/cli.py | 12 +++---- catsup/parser/themes.py | 66 ++++----------------------------------- catsup/themes/__init__.py | 1 + catsup/themes/install.py | 60 +++++++++++++++++++++++++++++++++++ catsup/themes/utils.py | 24 ++++++++++++++ docs/changelog.rst | 1 + docs/config.rst | 10 +++--- docs/theme.rst | 10 +----- tests/test_theme_utils.py | 7 +++++ 9 files changed, 112 insertions(+), 79 deletions(-) create mode 100644 catsup/themes/__init__.py create mode 100644 catsup/themes/install.py create mode 100644 catsup/themes/utils.py create mode 100644 tests/test_theme_utils.py diff --git a/catsup/cli.py b/catsup/cli.py index b638208..c6cc898 100644 --- a/catsup/cli.py +++ b/catsup/cli.py @@ -215,21 +215,21 @@ def themes(): Options: -h --help Show this screen and exit. """ - import catsup.parser.themes - catsup.parser.themes.list() + from catsup.parser.themes import list_themes + list_themes() @parguments.command -def install(theme): +def install(name): """ Usage: - catsup install + catsup install Options: -h --help Show this screen and exit. """ - import catsup.parser.themes - catsup.parser.themes.install(path=theme) + from catsup.themes.install import install_theme + install_theme(name=name) def main(): diff --git a/catsup/parser/themes.py b/catsup/parser/themes.py index 4256cb5..79fa8bd 100644 --- a/catsup/parser/themes.py +++ b/catsup/parser/themes.py @@ -3,7 +3,6 @@ import sys import os -import shutil from catsup.logger import logger from catsup.options import g @@ -34,7 +33,7 @@ def read_theme(path): return theme -def find(config=None, theme_name=''): +def find_theme(config=None, theme_name='', silence=False): if not theme_name: theme_name = config.theme.name theme_name = theme_name.lower() @@ -47,15 +46,17 @@ def find(config=None, theme_name=''): if theme: return theme - raise Exception("Can't find theme: %s" % theme_name) + if not silence: + logger.error("Can't find theme: {name}".format(name=theme_name)) + exit(1) -def list(): +def list_themes(): theme_gallery = [ os.path.abspath('themes'), os.path.join(g.catsup_path, 'themes'), ] - themes = set() + themes = () for path in theme_gallery: if not os.path.exists(path): continue @@ -74,58 +75,3 @@ def list(): 'HomePage: %s' % theme.homepage ])) print("\n--------\n".join(themes_text)) - - -def install(path): - try: - theme = find(theme_name=path) - except: - pass - else: - # Update theme - if not os.path.exists(os.path.join(theme.path, '.git')): - logger.warn("%s is not installed via git." - "Can't update it." % theme.name) - else: - logger.info("Updating theme %s" % theme.name) - call('git pull', cwd=theme.path) - sys.exit(0) - - themes_path = os.path.abspath('themes') - - logger.info('Installing theme from %s' % path) - - if not os.path.exists(themes_path): - os.makedirs(themes_path) - - if os.path.exists(path): - theme = read_theme(path) - if not theme: - sys.exit(1) - name = theme.name - logger.info("Found theme %s" % name) - - install_path = os.path.join(themes_path, name) - - shutil.copytree(path, install_path) - - elif path.lower().endswith('.git'): # a git repo - os.chdir(themes_path) - repo_folder = path.split('/')[-1][:-4] - if os.path.exists(repo_folder): - shutil.rmtree(repo_folder) - os.system('git clone %s' % path) - theme = read_theme(repo_folder) - if not theme: - shutil.rmtree(repo_folder) - sys.exit(0) - if os.path.exists(theme.name): - shutil.rmtree(theme.name) - - os.rename(repo_folder, theme.name) - - else: - logger.error("Can't install theme from %s." % path) - sys.exit(1) - - logger.info('Theme %s successfully installed' % theme.name) diff --git a/catsup/themes/__init__.py b/catsup/themes/__init__.py new file mode 100644 index 0000000..2877140 --- /dev/null +++ b/catsup/themes/__init__.py @@ -0,0 +1 @@ +__author__ = 'whtsky' diff --git a/catsup/themes/install.py b/catsup/themes/install.py new file mode 100644 index 0000000..5f07a79 --- /dev/null +++ b/catsup/themes/install.py @@ -0,0 +1,60 @@ +import os +import shutil +import tempfile + +from catsup.logger import logger +from catsup.parser.themes import find_theme, read_theme +from catsup.utils import call, mkdir +from catsup.themes.utils import search_github + +THEMES_PATH = os.path.abspath("themes") + + +def install_from_git(clone_url): + mkdir(THEMES_PATH) + os.chdir(THEMES_PATH) + tmp_dir = tempfile.mkdtemp() + os.system('git clone {clone_url} {tmp_dir}'.format( + clone_url=clone_url, + tmp_dir=tmp_dir + )) + theme = read_theme(tmp_dir) + if not theme: + logger.error("{clone_url} is not a Catsup theme repo.".format( + clone_url=clone_url + )) + shutil.rmtree(tmp_dir) + if os.path.exists(theme.name): + shutil.rmtree(theme.name) + + os.rename(tmp_dir, theme.name) + logger.info("Installed theme {name}".format(name=name)) + + +def search_and_install(name): + logger.info("Searching theme {name} on GitHub..".format(name=name)) + item = search_github(name=name) + if not item: + logger.error("Can't find theme {name}.".format(name=name)) + exit(1) + + logger.info("Fount {name} on GitHub.".format(name=item["name"])) + install_from_git(item["clone_url"]) + + +def install_theme(name): + theme = find_theme(theme_name=name, silence=True) + if theme: + # Update theme + if not os.path.exists(os.path.join(theme.path, '.git')): + logger.warn("%s is not installed via git." + "Can't update it." % theme.name) + else: + logger.info("Updating theme %s" % theme.name) + call("git pull", cwd=theme.path) + exit(0) + + if ".git" in name or "//" in name: + install_from_git(name) + else: + search_github(name) diff --git a/catsup/themes/utils.py b/catsup/themes/utils.py new file mode 100644 index 0000000..6ba7f22 --- /dev/null +++ b/catsup/themes/utils.py @@ -0,0 +1,24 @@ +import requests + +from catsup.logger import logger + + +def search_github(name): + repo_name = "catsup-theme-{name}".format(name=name) + response = requests.get("https://api.github.com/search/repositories?q={repo_name}".format(repo_name=repo_name), headers={ + "User-Agent": "Catsup Theme Finder" + }) + try: + response.raise_for_status() + except requests.HTTPError: + logger.warning("Error when connecting to GitHub.") + return None + json = response.json() + if json["total_count"] == 0: + return None + for item in json["items"]: + if item["name"] == repo_name: + return { + "name": item["name"], + "clone_url": item["clone_url"] + } diff --git a/docs/changelog.rst b/docs/changelog.rst index af134b0..e7d535d 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -11,6 +11,7 @@ Version 0.3.0 + Support customize permalink for post + Support TXT format post. + Support HTML format post. ++ Rewrite `catsup install` + Correct the url for Twitter Card Support + Drop file-based cache system. + Improve description creator diff --git a/docs/config.rst b/docs/config.rst index 6fe4f8d..b96e2a1 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -22,10 +22,12 @@ It’s easy enough to configure these by yourself. If you're using Google Analytics, remember to change ``config.analytics`` :: "config": { - "source": "posts", - "output": "deploy", - "static_prefix": "/static/", - "analytics": "UA-33275966-1" + "source": "posts", + "static_source": "static", + "output": "deploy", + "static_output": "deploy/static", + "static_prefix": "/static/", + "analytics": "" }, diff --git a/docs/theme.rst b/docs/theme.rst index 236892a..3ddc189 100644 --- a/docs/theme.rst +++ b/docs/theme.rst @@ -6,17 +6,9 @@ Overview Install a theme :: - catsup install git_repo - -For instance, install `Theme Clean `_ :: - - catsup install git@github.com:whtsky/catsup-theme-clean.git - -Update a installed theme :: - catsup install theme_name -For instance, update clean :: +For instance, install `Theme Clean `_ :: catsup install clean diff --git a/tests/test_theme_utils.py b/tests/test_theme_utils.py new file mode 100644 index 0000000..0385111 --- /dev/null +++ b/tests/test_theme_utils.py @@ -0,0 +1,7 @@ +from catsup.themes.utils import search_github + + +def test_search_github(): + theme = search_github("clean") + assert theme["name"] == "catsup-theme-clean" + assert theme["clone_url"] == "https://github.com/whtsky/catsup-theme-clean.git" From 298aa6af6f051046863e78fd1ecfc67988c1b63f Mon Sep 17 00:00:00 2001 From: whtsky Date: Fri, 17 Jan 2014 15:05:26 +0800 Subject: [PATCH 43/52] use `Catsup` instead of ` catsup` in README.rst --- README.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 09bd906..8078a64 100644 --- a/README.rst +++ b/README.rst @@ -2,7 +2,7 @@ catsup ---------------- .. image:: https://pypip.in/d/catsup/badge.png - :target: https://crate.io/packages/catsup/ + :target: https://pypi.python.org/pypi/catsup/ Catsup is a lightweight static website generator which aims to be simple and elegant. Documentation is available at RTFD: https://catsup.readthedocs.org/en/latest/ @@ -10,11 +10,11 @@ Documentation is available at RTFD: https://catsup.readthedocs.org/en/latest/ Quick Start =============== -First, install catsup via pip :: +First, install Catsup via pip :: $ pip install catsup -Then, craete a new catsup site :: +Then, create a new Catsup site :: $ mkdir site $ cd site @@ -41,4 +41,4 @@ Build your site and deploy :: catsup build && catsup deploy -For more information, please read the document: https://catsup.readthedocs.org/en/latest/ \ No newline at end of file +For more information, please read the document: https://catsup.readthedocs.org/en/latest/ From c754efe1921bdaab55f8e71241a87d12436c11ea Mon Sep 17 00:00:00 2001 From: whtsky Date: Fri, 17 Jan 2014 15:11:41 +0800 Subject: [PATCH 44/52] Update .travis.yml --- .travis.yml | 4 +++- README.rst | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3df8cda..d42824d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,9 @@ python: - 3.2 - 3.3 -install: python setup.py install +install: + - python setup.py install + - pip install -r dev-requirements.txt script: coverage run setup.py -q nosetests diff --git a/README.rst b/README.rst index 8078a64..4139c21 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -catsup +Catsup ---------------- .. image:: https://pypip.in/d/catsup/badge.png From 2c80e476bef1ceacd04151e1ca4aec264e3647dd Mon Sep 17 00:00:00 2001 From: whtsky Date: Fri, 17 Jan 2014 16:13:53 +0800 Subject: [PATCH 45/52] Complete yaml meta parser --- .pipignore | 2 - catsup/generator/__init__.py | 4 +- catsup/generator/renderer.py | 21 ++++---- catsup/models.py | 16 ++++++- catsup/parser/config.py | 5 +- catsup/reader/html.py | 69 +++------------------------ catsup/reader/markdown.py | 19 ++++++-- catsup/reader/utils.py | 61 +++++++++++++++++++++++ dev-requirements.txt | 7 ++- docs/changelog.rst | 1 + requirements.txt | 9 ++-- tests/post.txt | 9 ++-- tests/site/posts/2013-12-12-html.html | 6 +-- tests/site/posts/hh.txt | 6 +-- tests/test_meta_parser.py | 10 ++-- 15 files changed, 132 insertions(+), 113 deletions(-) delete mode 100644 .pipignore diff --git a/.pipignore b/.pipignore deleted file mode 100644 index 19c5e12..0000000 --- a/.pipignore +++ /dev/null @@ -1,2 +0,0 @@ -catsup -distribute \ No newline at end of file diff --git a/catsup/generator/__init__.py b/catsup/generator/__init__.py index 34439c4..2d30833 100644 --- a/catsup/generator/__init__.py +++ b/catsup/generator/__init__.py @@ -131,11 +131,11 @@ def generate(self): (len(self.posts), finish_loading - started_loading) ) if self.posts: - self.generate_feed() - self.generate_pages() self.generate_posts() self.generate_tags() self.generate_archives() + self.generate_feed() + self.generate_pages() else: logger.warning("Can't find any post.") self.generate_other_pages() diff --git a/catsup/generator/renderer.py b/catsup/generator/renderer.py index 72a7e8f..4029da3 100644 --- a/catsup/generator/renderer.py +++ b/catsup/generator/renderer.py @@ -49,21 +49,22 @@ def render(self, template, **kwargs): pass def render_to(self, template, permalink, **kwargs): + html = self.render(template, **kwargs) + if not html: + return permalink, output_name = urljoin( g.base_url, permalink ), permalink kwargs.setdefault("permalink", permalink) - html = self.render(template, **kwargs) - if html: - self.rendered_permalinks.append(permalink) - if output_name.endswith("/") or "." not in output_name: - output_name = output_name.rstrip("/") - output_name += '/index.html' - output_path = os.path.join(g.output, output_name.lstrip("/")) - mkdir(os.path.dirname(output_path)) - with open(output_path, "w") as f: - f.write(html) + self.rendered_permalinks.append(permalink) + if output_name.endswith("/") or "." not in output_name: + output_name = output_name.rstrip("/") + output_name += '/index.html' + output_path = os.path.join(g.output, output_name.lstrip("/")) + mkdir(os.path.dirname(output_path)) + with open(output_path, "w") as f: + f.write(html) def render_sitemap(self): with open(os.path.join(g.output, "sitemap.txt"), "w") as f: diff --git a/catsup/models.py b/catsup/models.py index 75d32a5..a3a2beb 100644 --- a/catsup/models.py +++ b/catsup/models.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- +import os import re from datetime import datetime @@ -171,7 +172,13 @@ def permalink(self): return super(Post, self).permalink def get_permalink_args(self): - return self.meta + args = self.meta.copy() + args.update( + title=self.title, + datetime=self.datetime, + type=self.type + ) + return args @property @cached_func @@ -229,7 +236,12 @@ def allow_comment(self): @property @cached_func def title(self): - return self.meta.get("title", "") + if "title" in self.meta: + return self.meta.get("title") + else: + p, _ = os.path.splitext(self.path) + filename = os.path.basename(p) + return filename @property @cached_func diff --git a/catsup/parser/config.py b/catsup/parser/config.py index 1970f7d..4d2eea0 100644 --- a/catsup/parser/config.py +++ b/catsup/parser/config.py @@ -4,11 +4,10 @@ from catsup.logger import logger from catsup.options import g from catsup.utils import update_nested_dict, urljoin, ObjectDict +from catsup.parser.themes import find_theme from .utils import add_slash -import catsup.parser.themes - def parse(path): """ @@ -34,7 +33,7 @@ def load(path=None, local=False, base_url=None): user_config = parse(path) config = update_nested_dict(config, user_config) os.chdir(os.path.abspath(os.path.dirname(path))) - g.theme = catsup.parser.themes.find(config) + g.theme = find_theme(config) g.source = config.config.source g.output = config.config.output g.permalink = config.permalink diff --git a/catsup/reader/html.py b/catsup/reader/html.py index f3b30b8..fa297a7 100644 --- a/catsup/reader/html.py +++ b/catsup/reader/html.py @@ -1,71 +1,14 @@ -from houdini import escape_html - from catsup.models import Post -from catsup.utils import ObjectDict, to_unicode -from catsup.reader.utils import open_file, not_valid - - -def parse_meta(lines, path=None): - lines = [l.strip() for l in lines if l] - if lines[0].startswith("#"): - return parse_catsup_meta(lines, path) - elif lines[0].startswith("---"): - return parse_liquid_meta(lines, path) - else: - not_valid(path) - - -def parse_liquid_meta(lines, path=None): - meta = ObjectDict() - return meta - - -def parse_catsup_meta(lines, path=None): - meta = ObjectDict() - title_line = lines.pop(0) - if title_line[0] != "#": - not_valid(path) - meta.title = escape_html(title_line[1:].strip()) - for line in lines: - if not line: - continue - if ":" not in line: - not_valid(path) - name, value = line.split(':', 1) - name = name.strip().lstrip('-').strip().lower() - meta[name] = value.strip() - return meta +from catsup.utils import to_unicode, ObjectDict +from catsup.reader.utils import split_content, parse_yaml_meta def html_reader(path): - post_file = open_file(path) - - lines = [] - firstline = post_file.readline().strip() - - no_meta = False - - lines.append(firstline) - for l in post_file: - l = l.strip() - if l.startswith("---"): - break - elif l: - lines.append(l) - else: - no_meta = True - if no_meta: - import os - - p, _ = os.path.splitext(path) - filename = os.path.basename(p) - meta = ObjectDict( - title=filename - ) - content = "\n".join(lines) + meta, content = split_content(path) + if not meta: + meta = ObjectDict() else: - meta = parse_meta(lines, path) - content = "".join(post_file) + meta = parse_yaml_meta(meta, path) return Post( path=path, meta=meta, diff --git a/catsup/reader/markdown.py b/catsup/reader/markdown.py index 015ee52..04722dd 100644 --- a/catsup/reader/markdown.py +++ b/catsup/reader/markdown.py @@ -1,4 +1,5 @@ import misaka as m + from houdini import escape_html from pygments import highlight @@ -6,7 +7,9 @@ from pygments.lexers import get_lexer_by_name from pygments.util import ClassNotFound -from catsup.reader.html import html_reader +from catsup.models import Post +from catsup.utils import ObjectDict +from catsup.reader.utils import split_content, parse_meta class CatsupRender(m.HtmlRenderer, m.SmartyPants): @@ -38,7 +41,13 @@ def autolink(self, link, is_email): def markdown_reader(path): - post = html_reader(path) - post.content = md.render(post.content) - return post - + meta, content = split_content(path) + if not meta: + meta = ObjectDict() + else: + meta = parse_meta(meta, path) + return Post( + path=path, + meta=meta, + content=md.render(content) + ) diff --git a/catsup/reader/utils.py b/catsup/reader/utils.py index 089ebba..6dfe3d8 100644 --- a/catsup/reader/utils.py +++ b/catsup/reader/utils.py @@ -1,4 +1,45 @@ +import yaml + +from houdini import escape_html + from catsup.logger import logger +from catsup.utils import update_nested_dict, ObjectDict, to_unicode + + +def parse_meta(lines, path=None): + lines = [l.strip() for l in lines if l] + if lines[0].startswith("#"): + return parse_catsup_meta(lines, path) + elif lines[0].startswith("---"): + return parse_yaml_meta(lines, path) + else: + not_valid(path) + + +def parse_yaml_meta(lines, path=None): + title_line = lines.pop(0) + if not title_line.startswith("---"): + print(title_line) + not_valid(path) + meta = yaml.load("\n".join(lines)) + return update_nested_dict(ObjectDict(), meta) + + +def parse_catsup_meta(lines, path=None): + meta = ObjectDict() + title_line = lines.pop(0) + if title_line[0] != "#": + not_valid(path) + meta.title = escape_html(title_line[1:].strip()) + for line in lines: + if not line: + continue + if ":" not in line: + not_valid(path) + name, value = line.split(':', 1) + name = name.strip().lstrip('-').strip().lower() + meta[name] = value.strip() + return meta def open_file(path): @@ -12,3 +53,23 @@ def open_file(path): def not_valid(path): logger.error("%s is not a valid post." % path) exit(1) + + +def split_content(path): + file = open_file(path) + + lines = [file.readline().strip()] + no_meta = False + + for l in file: + l = l.strip() + if l.startswith("---"): + break + elif l: + lines.append(l) + else: + no_meta = True + if no_meta: + return [], to_unicode("\n".join(lines)) + else: + return lines, to_unicode("".join(file)) diff --git a/dev-requirements.txt b/dev-requirements.txt index 908fc06..d241753 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,8 +1,7 @@ -r requirements.txt +bpython==0.12 cov-core==1.7 -coverage==3.6 -coveralls==0.4 +coverage==3.7.1 +coveralls==0.4.1 nose-cov==1.6 nose==1.3.0 -pip-tools==0.3.4 -requests==2.1.0 diff --git a/docs/changelog.rst b/docs/changelog.rst index e7d535d..bec1101 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -11,6 +11,7 @@ Version 0.3.0 + Support customize permalink for post + Support TXT format post. + Support HTML format post. ++ Support YAML format meta. + Rewrite `catsup install` + Correct the url for Twitter Card Support + Drop file-based cache system. diff --git a/requirements.txt b/requirements.txt index 9e828f9..ac2b861 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,13 +1,14 @@ -argh==0.23.3 +argh==0.24.1 docopt==0.6.1 houdini.py==0.1.0 -Jinja2==2.7 +Jinja2==2.7.2 MarkupSafe==0.18 misaka==1.0.2 parguments==0.3.2 pathtools==0.1.2 Pygments==1.6 PyYAML==3.10 -tornado==3.1 +tornado==3.2 ujson==1.33 -watchdog==0.6.0 +watchdog==0.7.0 +requests==2.2.0 diff --git a/tests/post.txt b/tests/post.txt index 8d6e67e..11c788a 100644 --- a/tests/post.txt +++ b/tests/post.txt @@ -1,8 +1,7 @@ -# Hello, World! - -- tags: Hello, World -- time: 2014-01-04 20:56 - +--- +title: Hello, World! +tags: Hello, World +time: 2014-01-04 20:56 --- Hi! diff --git a/tests/site/posts/2013-12-12-html.html b/tests/site/posts/2013-12-12-html.html index 9f1ce59..068aa8a 100644 --- a/tests/site/posts/2013-12-12-html.html +++ b/tests/site/posts/2013-12-12-html.html @@ -1,7 +1,5 @@ -# HTML Page - -- type: page - +--- +type: page ---

Hi, I'm writing in HTML!

diff --git a/tests/site/posts/hh.txt b/tests/site/posts/hh.txt index e81e0cb..821566d 100644 --- a/tests/site/posts/hh.txt +++ b/tests/site/posts/hh.txt @@ -1,7 +1,5 @@ -# Hello - -- time: 2014-01-04 23:12 - +--- +time: 2014-01-04 23:12 --- Hello! diff --git a/tests/test_meta_parser.py b/tests/test_meta_parser.py index 0139aa4..df4fbe7 100644 --- a/tests/test_meta_parser.py +++ b/tests/test_meta_parser.py @@ -2,7 +2,7 @@ def test_catsup_meta_parser(): - from catsup.reader.html import parse_catsup_meta + from catsup.reader.utils import parse_catsup_meta meta_txt = """ # Hello, world! @@ -17,18 +17,18 @@ def test_catsup_meta_parser(): @raises(SystemExit) def test_catsup_meta_parser_error_1(): - from catsup.reader.html import parse_catsup_meta + from catsup.reader.utils import parse_catsup_meta parse_catsup_meta(["fsdaf-,-,-,-", "fdsa- 0,"]) @raises(SystemExit) def test_catsup_meta_parser_error_2(): - from catsup.reader.html import parse_catsup_meta + from catsup.reader.utils import parse_catsup_meta parse_catsup_meta(["#fsdaf-,-,-,-", "fdsa- 0,"]) def test_meta_parser(): - from catsup.reader.html import parse_meta + from catsup.reader.utils import parse_meta meta_txt = """ # Hello, world! @@ -44,5 +44,5 @@ def test_meta_parser(): @raises(SystemExit) def test_parse_unknown_meta(): - from catsup.reader.html import parse_meta + from catsup.reader.utils import parse_meta parse_meta(["fdsjaklfdsjaklfdsjaklfjdsklfjsa"]) \ No newline at end of file From c4e0e1f57abdfba77423b8c94cfc56411cb98bc1 Mon Sep 17 00:00:00 2001 From: whtsky Date: Fri, 17 Jan 2014 16:19:19 +0800 Subject: [PATCH 46/52] Drop Python 3.2 support --- .travis.yml | 1 - setup.py | 1 - 2 files changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d42824d..29a3a66 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: python python: - 2.7 - - 3.2 - 3.3 install: diff --git a/setup.py b/setup.py index 9660921..42adf27 100644 --- a/setup.py +++ b/setup.py @@ -27,7 +27,6 @@ 'Operating System :: POSIX :: Linux', 'Programming Language :: Python', 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', ], tests_require=['nose'], From de703d2d9dd20d61e3876a7166e1dfa63cdcc5ee Mon Sep 17 00:00:00 2001 From: whtsky Date: Fri, 17 Jan 2014 16:27:31 +0800 Subject: [PATCH 47/52] Remove print codes --- .coveragerc | 3 ++- catsup/cli.py | 2 +- catsup/reader/utils.py | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.coveragerc b/.coveragerc index a04c90b..05922da 100644 --- a/.coveragerc +++ b/.coveragerc @@ -2,4 +2,5 @@ include = catsup/* omit = deploy - server \ No newline at end of file + server + logger diff --git a/catsup/cli.py b/catsup/cli.py index c6cc898..bf37987 100644 --- a/catsup/cli.py +++ b/catsup/cli.py @@ -17,7 +17,7 @@ import catsup -doc = """catsup v%s +doc = """Catsup v%s Usage: catsup init [] diff --git a/catsup/reader/utils.py b/catsup/reader/utils.py index 6dfe3d8..08919bf 100644 --- a/catsup/reader/utils.py +++ b/catsup/reader/utils.py @@ -19,7 +19,6 @@ def parse_meta(lines, path=None): def parse_yaml_meta(lines, path=None): title_line = lines.pop(0) if not title_line.startswith("---"): - print(title_line) not_valid(path) meta = yaml.load("\n".join(lines)) return update_nested_dict(ObjectDict(), meta) From 00dca413b41a2b7e3a48a6aa099c931b56c151e0 Mon Sep 17 00:00:00 2001 From: whtsky Date: Fri, 17 Jan 2014 16:39:00 +0800 Subject: [PATCH 48/52] Update README --- README.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.rst b/README.rst index 4139c21..f55692b 100644 --- a/README.rst +++ b/README.rst @@ -4,6 +4,12 @@ Catsup .. image:: https://pypip.in/d/catsup/badge.png :target: https://pypi.python.org/pypi/catsup/ +.. image:: https://travis-ci.org/whtsky/catsup.png?branch=develop + :target: https://travis-ci.org/whtsky/catsup + +.. image:: https://coveralls.io/repos/whtsky/catsup/badge.png?branch=develop + :target: https://coveralls.io/r/whtsky/catsup?branch=develop + Catsup is a lightweight static website generator which aims to be simple and elegant. Documentation is available at RTFD: https://catsup.readthedocs.org/en/latest/ From c6a7b7d1f10ca0b6c736e1005f02d1236295e4db Mon Sep 17 00:00:00 2001 From: whtsky Date: Sun, 19 Jan 2014 00:15:05 +0800 Subject: [PATCH 49/52] Update README --- README.rst | 3 +++ catsup/reader/markdown.py | 1 + 2 files changed, 4 insertions(+) diff --git a/README.rst b/README.rst index f55692b..7fa0349 100644 --- a/README.rst +++ b/README.rst @@ -10,6 +10,9 @@ Catsup .. image:: https://coveralls.io/repos/whtsky/catsup/badge.png?branch=develop :target: https://coveralls.io/r/whtsky/catsup?branch=develop +.. image:: https://badge.waffle.io/whtsky/catsup.png?label=ready + :target: http://waffle.io/whtsky/catsup + Catsup is a lightweight static website generator which aims to be simple and elegant. Documentation is available at RTFD: https://catsup.readthedocs.org/en/latest/ diff --git a/catsup/reader/markdown.py b/catsup/reader/markdown.py index 04722dd..2bfc40a 100644 --- a/catsup/reader/markdown.py +++ b/catsup/reader/markdown.py @@ -42,6 +42,7 @@ def autolink(self, link, is_email): def markdown_reader(path): meta, content = split_content(path) + content = content.replace("\n", " \n") if not meta: meta = ObjectDict() else: From e3ac894eb6cac1064bef3d002a86cc72425fa957 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sun, 19 Jan 2014 14:07:52 +0800 Subject: [PATCH 50/52] Update docs --- README.rst | 4 +- docs/install.rst | 6 +-- docs/post.rst | 99 +++++++++++++++++++++++++++++++++++++----------- 3 files changed, 81 insertions(+), 28 deletions(-) diff --git a/README.rst b/README.rst index 7fa0349..bee78d7 100644 --- a/README.rst +++ b/README.rst @@ -4,8 +4,8 @@ Catsup .. image:: https://pypip.in/d/catsup/badge.png :target: https://pypi.python.org/pypi/catsup/ -.. image:: https://travis-ci.org/whtsky/catsup.png?branch=develop - :target: https://travis-ci.org/whtsky/catsup +.. image:: https://travis-ci.org/whtsky/Catsup.png?branch=develop + :target: https://travis-ci.org/whtsky/Catsup .. image:: https://coveralls.io/repos/whtsky/catsup/badge.png?branch=develop :target: https://coveralls.io/r/whtsky/catsup?branch=develop diff --git a/docs/install.rst b/docs/install.rst index c0c401e..babf410 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -10,14 +10,14 @@ If you are using OS X , make sure you have installed the *Command Line Tools* . Install using pip ------------------------- -Install catsup via pip is easy :: +Install Catsup via pip is easy :: (sudo) pip install catsup Upgrade from older version ------------------------------- -It's also easy to upgrade your catsup :: +It's also easy to upgrade your Catsup :: (sudo) pip install catsup --upgrade @@ -38,7 +38,7 @@ Install with git can always have the latest code :: Cann’t find Python.h ? ----------------------- -Catsup uses misaka as the markdown engine.It requires C compiler.On Ubuntu, you may run :: +Catsup uses misaka as the markdown engine. It requires C compiler.On Ubuntu, you may run :: (sudo) apt-get install python-dev diff --git a/docs/post.rst b/docs/post.rst index 2de5294..ce19f7e 100644 --- a/docs/post.rst +++ b/docs/post.rst @@ -3,10 +3,17 @@ Post Syntax ============= +Catsup currently supports 3 types of post: :ref:`Markdown `, :ref:`Text ` and :ref:`HTML `. + +.. _post-markdown-syntax: + +Markdown Post +-------------- + Overview ------------ +~~~~~~~~~ -A post's extension should be either ``.md`` or ``.markdown`` . +Post's extension should be either ``.md`` or ``.markdown`` . A sample post looks like :: @@ -29,21 +36,80 @@ A sample post looks like :: A post consists of three parts: + Title -+ Meta ++ :ref:`Meta ` + Content Title --------- +~~~~~~~~~~~~~~~~~~~~~~ Title should always on the first line and starts with ``#`` +Content +~~~~~~~~~~~~~~~~~~~~~~ + +Everything below the separator is the content. Content should be written in Markdown. + +Code Highlight +~~~~~~~~~~~~~~~~~~~~~~ + +Catsup supports GitHub's style code highlight, like this :: + + ```python + print("Hello World!") + ``` + +.. _post-text-syntax: + +Text Post +-------------- + +Sometimes you may just want to write something without considering the syntax. Then you should use Text Post. + +Text post's extension should be ``.txt`` . + +The simplest text post looks like :: + + Hello! + This is a text post. + +If you want to write meta in a text post, write the meta in YAML format :: + + --- + title: Hello, World! + tags: Hello, World + time: 2014-01-04 20:56 + --- + + Hello, World! I'm a text post. + + +.. _post-html-syntax: + +HTML Post +-------------- + +HTML post is like :ref:`Text `, but you can use HTML in the content. + +HTML post's extension should be ``.txt`` . + +A HTML post looks like :: + + --- + title: Hello, World! + tags: Hello, World + time: 2014-01-04 20:56 + --- + +

I'm writing HTML in catsup

+ + .. _post-meta: Meta -------- - -Meta is some information about the post. It's below title and above the separator. +-------- +Meta is some information about the post. +Note that meta is optional, and if your post have meta, remember to put a :ref:`separator ` below the meta. + time: When the post is written. like ``2013-08-25 11:10`` + tags: Tags of the post. Separated by comma, like ``Python, Program`` @@ -52,8 +118,10 @@ Meta is some information about the post. It's below title and above the separato + comment: Set to ``disabled`` to forbid comment + permalink: Permalink to the post, link ``/this-post`` +.. _post-separator: + The separator ---------------- +---------------- The separator separates meta and content. It should be at least *three* ``-`` :: @@ -63,21 +131,6 @@ It's okay to make it longer :: ---------------- -Content ------------ - -Everything below the separator is the content. Content should be written in Markdown. - -Code Highlight ------------------ - -Catsup supports GitHub's style code highlight, like this :: - - ```python - print("Hello World!") - ``` - - Page -------- From 5172828b27b30394dff3de1fb8d90d73bc702665 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sun, 19 Jan 2014 14:12:46 +0800 Subject: [PATCH 51/52] Update docs --- docs/post.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/post.rst b/docs/post.rst index ce19f7e..5279d2b 100644 --- a/docs/post.rst +++ b/docs/post.rst @@ -88,7 +88,7 @@ If you want to write meta in a text post, write the meta in YAML format :: HTML Post -------------- -HTML post is like :ref:`Text `, but you can use HTML in the content. +HTML post is like :ref:`Text Post `, but you can use HTML in the content. HTML post's extension should be ``.txt`` . From f84a54a162cdfa6284221e292b4d0373498b8cc1 Mon Sep 17 00:00:00 2001 From: whtsky Date: Sun, 19 Jan 2014 14:14:38 +0800 Subject: [PATCH 52/52] Update URL --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 42adf27..4ff457f 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ version=catsup.__version__, author='whtsky', author_email='whtsky@me.com', - url='https://github.com/whtsky/catsup', + url='https://github.com/whtsky/Catsup', packages=find_packages(), description='Catsup: a lightweight static site generator', long_description=open('README.rst').read(),