changeset 78:5b1259424c51

merge commit; as usual, i have no idea what i did
author Jeff Hammel <jhammel@mozilla.com>
date Mon, 27 Sep 2010 21:08:04 -0700
parents 3da163e44b8a (current diff) c690198a2625 (diff)
children 4df927b0d847
files
diffstat 4 files changed, 78 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- 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 = '<br/>\n'.join(lines)
-            
-
+        """renders a string with restructured text"""            
+        body = utils.ReST2html(string)
         retval = '<div class="blog-body">%s</div>' % body
         return retval
 
--- 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':
--- 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),
--- 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 = '<br/>\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'