# HG changeset patch # User Jeff Hammel # Date 1285646884 25200 # Node ID 5b1259424c51380c5172e8902b62b45867c00b9f # Parent 3da163e44b8a5ee724856f6dbbea375e75e01f47# Parent c690198a2625659180ff70066f6dafc7dfcda95b merge commit; as usual, i have no idea what i did diff -r 3da163e44b8a -r 5b1259424c51 bitsyblog/bitsyblog.py --- a/bitsyblog/bitsyblog.py Mon Aug 02 07:14:33 2010 -0700 +++ b/bitsyblog/bitsyblog.py Mon Sep 27 21:08:04 2010 -0700 @@ -10,7 +10,6 @@ import dateutil.parser -import cgi import datetime import docutils import docutils.core @@ -27,6 +26,7 @@ from genshi.builder import Markup from genshi.template import TemplateLoader from paste.fileapp import FileApp +from pkg_resources import iter_entry_points from pkg_resources import resource_filename from StringIO import StringIO from urlparse import urlparse @@ -55,12 +55,13 @@ 'auto_reload': 'True', # reload the genshi templates 'help_file': None, # help to display 'feed_items': 10, # number of RSS/atom items to display + 'post_handlers': '' # post handlers } cooked_bodies = {} - def __init__(self, **kw): + def __init__(self, kw, handler_args): for key in self.defaults: setattr(self, key, kw.get(key, self.defaults[key])) self.n_links = int(self.n_links) # could be a string from the .ini @@ -105,6 +106,18 @@ # for BitsyAuth self.newuser = self.users.new + # post handlers + self.post_handlers = [ i for i in self.post_handlers.split() if i ] + self.handlers = [] # handlers for blog post event + for entry_point in iter_entry_points('bitsyblog.listeners'): + if entry_point.name in self.post_handlers: + try: + handler = entry_point.load()(self, **handler_args.get(entry_point.name, {})) + self.handlers.append(handler) + except: + print 'Cant load entry point %s' % entry_point.name + raise + ### methods dealing with HTTP def __call__(self, environ, start_response): @@ -325,8 +338,16 @@ # write the file now = utils.datestamp(datetime.datetime.now()) - location = self.user_url(request, user, now) - self.blog.post(user, now, body, privacy) + location = self.user_url(request, user, now, permalink=True) + blog_entry = self.blog.post(user, now, body, privacy) + + # fire event handlers + # XXX could be done asynchronously + for handler in self.handlers: + try: + handler(blog_entry, location) + except: + pass # point the user at the post return exc.HTTPSeeOther("Post blogged by bitsy", location=location) @@ -429,7 +450,6 @@ if permanant: application_url = request.application_url else: - application_url = urlparse(request.application_url)[2] path = [ application_url ] + list(path) return '/'.join(path) @@ -636,21 +656,8 @@ return buffer.getvalue() def restructuredText(self, string): - """renders a string with restructured text""" - - settings = { 'report_level': 5 } - string = string.strip() - try: - - parts = docutils.core.publish_parts(string, - writer_name='html', - settings_overrides=settings) - body = parts['body'] - except (SystemMessage, UnicodeError), e: - lines = [ cgi.escape(i.strip()) for i in string.split('\n') ] - body = '
\n'.join(lines) - - + """renders a string with restructured text""" + body = utils.ReST2html(string) retval = '
%s
' % body return retval diff -r 3da163e44b8a -r 5b1259424c51 bitsyblog/blog.py --- a/bitsyblog/blog.py Mon Aug 02 07:14:33 2010 -0700 +++ b/bitsyblog/blog.py Mon Sep 27 21:08:04 2010 -0700 @@ -5,6 +5,7 @@ from cStringIO import StringIO from glob import glob +from pkg_resources import iter_entry_points class BlogEntry(object): """interface class for a blog entry""" @@ -78,7 +79,7 @@ def post(self, user, date, text, privacy): """post a new blog entry""" - + return BlogEntry(date, text, privacy, user) def delete(self, user, datestamp): """remove a blog entry""" @@ -147,6 +148,7 @@ def post(self, user, datestamp, body, privacy): blog = file(self.location(user, privacy, datestamp), 'w') print >> blog, body + return Blog.post(self, user, datestamp, body, privacy) def delete(self, user, datestamp): for permission in 'public', 'secret', 'private': diff -r 3da163e44b8a -r 5b1259424c51 bitsyblog/factory.py --- a/bitsyblog/factory.py Mon Aug 02 07:14:33 2010 -0700 +++ b/bitsyblog/factory.py Mon Sep 27 21:08:04 2010 -0700 @@ -4,21 +4,37 @@ from paste.httpexceptions import HTTPExceptionHandler # accepted configuration keys, e.g. 'bitsyblog.file_dir' -config = set(['file_dir', - 'date_format', - 'subject', - 'n_links', - 'help_file', - 'header', - 'template_directories', - 'feed_items']) +config = set(BitsyBlog.defaults.keys()) +# config = set(['file_dir', +# 'date_format', +# 'subject', +# 'n_links', +# 'help_file', +# 'header', +# 'template_directories', +# 'feed_items', +# ]) + +def get_args(app_conf): + """return arguments for bitsyblog and its handlers""" + key_str = 'bitsyblog.' + bitsyblog_args = {} + handler_args = {} + for key, value in app_conf.items(): + if key.startswith(key_str): + key = key.split(key_str, 1)[-1] + if key in config: + bitsyblog_args[key] = value + else: + if '.' in key: + section, key = key.split('.', 1) + handler_args.setdefault(section, {})[key] = value + return bitsyblog_args, handler_args def factory(global_conf, **app_conf): """make bitsyauth app and wrap it in middleware""" - key_str = 'bitsyblog.%s' - args = dict([ (key, app_conf[ key_str % key]) for key in config - if app_conf.has_key(key_str % key) ]) - app = BitsyBlog(**args) + bitsyblog_args, handler_args = get_args(app_conf) + app = BitsyBlog(bitsyblog_args, handler_args) secret = app_conf.get('secret', 'secret') return BitsyAuth(HTTPExceptionHandler(app), global_conf, @@ -30,11 +46,9 @@ def bitsierfactory(global_conf, **app_conf): """make single-user bitsyblog""" - key_str = 'bitsyblog.%s' - args = dict([ (key, app_conf[ key_str % key]) for key in config - if app_conf.has_key(key_str % key) ]) - user = app_conf['bitsyblog.user'] - app = BitsierBlog(**args) + bitsyblog_args, handler_args = get_args(app_conf) + user = app_conf['bitsyblog.user'] # ensure this exist + app = BitsierBlog(bitsyblog_args, handler_args) app.user = user secret = app_conf.get('secret', 'secret') auth = BitsyAuth(HTTPExceptionHandler(app), diff -r 3da163e44b8a -r 5b1259424c51 bitsyblog/utils.py --- a/bitsyblog/utils.py Mon Aug 02 07:14:33 2010 -0700 +++ b/bitsyblog/utils.py Mon Sep 27 21:08:04 2010 -0700 @@ -1,5 +1,6 @@ """utlity functions for bitsyblog""" +import cgi import datetime import os import urllib @@ -9,6 +10,22 @@ timeformat = ( 'YYYY', 'MM', 'DD', 'HH', 'MM', 'SS' ) timestamp = '%Y%m%d%H%M%S' # strftime representation +def ReST2html(string): + """renders a string with restructured text""" + + settings = { 'report_level': 5 } + string = string.strip() + try: + + parts = docutils.core.publish_parts(string, + writer_name='html', + settings_overrides=settings) + body = parts['body'] + except (SystemMessage, UnicodeError), e: + lines = [ cgi.escape(i.strip()) for i in string.split('\n') ] + body = '
\n'.join(lines) + return body + def validate_css(css): """use a webservice to determine if the argument is valid css""" url = 'http://jigsaw.w3.org/css-validator/validator?text=%s'