From 487d76ba614282f8948a8444ad256ef748b92ddf Mon Sep 17 00:00:00 2001 From: posativ Date: Sat, 20 Oct 2012 18:12:02 +0200 Subject: [PATCH] add API for different markup languages --- isso/__init__.py | 11 +++++++---- isso/comment.py | 6 +++--- isso/markup.py | 34 ++++++++++++++++++++++++++++++++++ isso/utils.py | 12 +++++++----- 4 files changed, 51 insertions(+), 12 deletions(-) create mode 100644 isso/markup.py diff --git a/isso/__init__.py b/isso/__init__.py index 841f178..700d890 100644 --- a/isso/__init__.py +++ b/isso/__init__.py @@ -31,11 +31,12 @@ from werkzeug.serving import run_simple from werkzeug.wrappers import Request, Response from werkzeug.exceptions import HTTPException, NotFound, InternalServerError -from isso import admin, comment, db, utils +from isso import admin, comment, db +from isso.utils import determine, import_object, RegexConverter, IssoEncoder # override default json :func:`dumps`. _dumps = json.dumps -setattr(json, 'dumps', lambda obj, **kw: _dumps(obj, cls=utils.IssoEncoder, **kw)) +setattr(json, 'dumps', lambda obj, **kw: _dumps(obj, cls=IssoEncoder, **kw)) # yep. lazy. url = lambda path, endpoint, methods: Rule(path, endpoint=endpoint, methods=methods) @@ -50,7 +51,7 @@ url_map = Map([ url('/comment//new', 'comment.create', ['POST']), url('/comment//', 'comment.get', ['GET']), url('/comment//', 'comment.modify', ['PUT', 'DELETE']), -], converters={'re': utils.RegexConverter}) +], converters={'re': RegexConverter}) class Isso: @@ -67,11 +68,13 @@ class Isso: self.__dict__.update(dict((k, v) for k, v in conf.iteritems() if k.isupper())) self.signer = URLSafeTimedSerializer(self.SECRET_KEY) - self.HOST = utils.determine(self.HOST) + self.HOST = determine(self.HOST) if self.SQLITE: self.db = db.SQLite(self) + self.markup = import_object(conf.get('MARKUP', 'isso.markup.Markdown'))(conf) + def sign(self, obj): return self.signer.dumps(obj) diff --git a/isso/comment.py b/isso/comment.py index fa0bbb7..a30d2ff 100644 --- a/isso/comment.py +++ b/isso/comment.py @@ -21,7 +21,7 @@ def create(app, environ, request, path): except ValueError: return abort(400) - rv.text = utils.markdown(rv.text) + rv.text = app.markup.convert(rv.text) response = Response(json.dumps(rv), 201, content_type='application/json') response.set_cookie('session', app.signer.dumps([path, rv.id]), max_age=app.MAX_AGE) return response @@ -35,9 +35,9 @@ def get(app, environ, request, path, id=None): if isinstance(rv, list): for item in rv: - item.text = utils.markdown(item.text) + item.text = app.markup.convert(item.text) else: - rv.text = utils.markdown(rv.text) + rv.text = app.markup.convert(rv.text) return Response(json.dumps(rv), 200, content_type='application/json') diff --git a/isso/markup.py b/isso/markup.py new file mode 100644 index 0000000..b6e7f9c --- /dev/null +++ b/isso/markup.py @@ -0,0 +1,34 @@ +# XXX: BBCode -- http://pypi.python.org/pypi/bbcode + +import abc + +try: + import misaka +except ImportError: + misaka = None # NOQA + + +class Markup: + + __metaclass__ = abc.ABCMeta + + @abc.abstractmethod + def __init__(self, conf): + return + + @abc.abstractmethod + def convert(self, text): + return text + + +class Markdown(Markup): + + def __init__(self, conf): + if misaka is None: + raise ImportError("Markdown requires 'misaka' lib!") + return + + def convert(self, text): + return misaka.html(text, extensions = misaka.EXT_STRIKETHROUGH \ + | misaka.EXT_SUPERSCRIPT | misaka.EXT_AUTOLINK \ + | misaka.HTML_SKIP_HTML | misaka.HTML_SKIP_IMAGES | misaka.HTML_SAFELINK) diff --git a/isso/utils.py b/isso/utils.py index 155b35e..8fcbc16 100644 --- a/isso/utils.py +++ b/isso/utils.py @@ -9,7 +9,6 @@ import httplib import urlparse import contextlib -import misaka import werkzeug.routing from isso.models import Comment @@ -48,7 +47,10 @@ def determine(host): return (rv.netloc + ':443') if rv.scheme == 'https' else rv.netloc -def markdown(text): - return misaka.html(text, - extensions = misaka.EXT_STRIKETHROUGH | misaka.EXT_SUPERSCRIPT | misaka.EXT_AUTOLINK \ - | misaka.HTML_SKIP_HTML | misaka.HTML_SKIP_IMAGES | misaka.HTML_SAFELINK) +def import_object(name): + if '.' not in name: + return __import__(name) + + parts = name.split('.') + obj = __import__('.'.join(parts[:-1]), None, None, [parts[-1]], 0) + return getattr(obj, parts[-1])