diff bitsyblog/bitsyblog.py @ 15:36698624435b

blog page mostly works
author k0s <k0scist@gmail.com>
date Sun, 25 Oct 2009 17:25:58 -0400
parents 645aa0f3279f
children 2bd6b2b543dc
line wrap: on
line diff
--- a/bitsyblog/bitsyblog.py	Wed Oct 07 17:26:13 2009 -0400
+++ b/bitsyblog/bitsyblog.py	Sun Oct 25 17:25:58 2009 -0400
@@ -31,11 +31,13 @@
 from blog import FileBlog
 from cStringIO import StringIO
 from docutils.utils import SystemMessage
+from genshi.builder import Markup
 from genshi.template import TemplateLoader
 from lxml import etree
 from markup.form import Form
 from paste.fileapp import FileApp
 from pkg_resources import resource_filename
+from urlparse import urlparse
 from user import FilespaceUsers
 from webob import Request, Response, exc
 
@@ -55,10 +57,13 @@
                  'subject': '[ %(date)s ]:',
                  'n_links': 5, # number of links for navigation
                  'site_name': 'bitsyblog',
-                 'auto_reload': 'False',
+                 'auto_reload': 'True',
                  'help_file': None,
                  }
 
+
+    cooked_bodies = {}
+
     def __init__(self, **kw):
         for key in self.defaults:
             setattr(self, key, kw.get(key, self.defaults[key]))
@@ -386,41 +391,37 @@
             name = None
         return name, path
 
-    def user_url(self, request, user, *args, **kw):
-        permalink = kw.get('permalink')
-        if permalink:
-            _args = [ request.host_url, user ]
-        else:
-            _args = [ user ]
-        _args.extend(args)
-        return '/'.join([str(arg) for arg in _args])
+    ### methods 
 
-    ### 
-
-    def isentry(self, string): # TODO -> blog.py
-        return (len(string) == len(''.join(utils.timeformat))) and string.isdigit()
-
-    def permalink(self, request, blogentry):
-        return self.user_url(request, blogentry.user, blogentry.datestamp(), permalink=True)
-
-    def link(self, request, path, permanant=False):
+    def link(self, request, path=(), permanant=False):
         if isinstance(path, basestring):
             path = [ path ]
         path = [ i.strip('/') for i in path ]
         if permanant:
-            path = [ request.application_url ] + list(path)
-            return '/'.join(path)
+            application_url = request.application_url
         else:
-            if request.path:
-                path = [ request.path ] + list(path)
-            return '/%s' % ('/'.join(path))
+            
+            application_url = urlparse(request.application_url)[2]
+        path = [ application_url ] + list(path)
+        return '/'.join(path)
 
-    ### mangled URLs
+    def user_url(self, request, user, *args, **kw):
+        """link to a user resource"""
+        permalink = kw.get('permalink', False)
+        path = [ user ]
+        path.extend(args)
+        return self.link(request, path, permalink)
+
+    def permalink(self, request, blogentry):
+        """permalink for a blog entry"""
+        return self.user_url(request, blogentry.user, blogentry.datestamp(), permalink=True)
 
     def mangledurl(self, request, blogentry):
+        """return a mangled url for obfuscated sharing"""
         return self.user_url(request, blogentry.user, 'x%x' % (int(blogentry.datestamp()) * self.users.secret(blogentry.user)), permalink=True)
 
     def unmangleurl(self, url, user):
+        """unmangle a url for obfuscated sharing"""
         url = url.strip('x')
         try:
             value = int(url, 16)
@@ -436,6 +437,10 @@
         
     ### blog retrival methods
 
+    def isentry(self, string): # TODO -> blog.py
+        """returns whether the string is a blog entry"""
+        return (len(string) == len(''.join(utils.timeformat))) and string.isdigit()
+
     def number_of_posts(self, request, user=None):
         """return the number of blog posts to display"""
         # determine number of posts to display (None -> all)
@@ -451,7 +456,6 @@
 
     def number_of_links(self, request, user=None):
         """return the number of links to display in the navigation"""
-        # determine number of navigation links to display
         n_links = request.GET.get('n')
         if n_links == 'all':
             return -1
@@ -525,25 +529,28 @@
         if feedtitle:
             head_markup = ( '<link rel="alternate" type="application/atom+xml" title="%s" href="atom" />' % feedtitle, 
                             '<link rel="alternate" type="application/rss+xml" title="%s" href="rss" />' % feedtitle,)
+        
         return markup.wrap(self.site_nav(request)+body, title, stylesheets, head_markup=head_markup)
 
     def site_nav(self, request):
         """returns HTML for site navigation"""
-        links = [('/',), ]
+
+        links = [(self.link(request), '/'), ]
         user = self.authenticated(request)
         if user:
-            links.extend([('/%s' % user, user),
-                          ('/%s/post' % user, 'post'),
-                          ('/%s/preferences' % user, 'preferences'),
-                          ('/logout', 'logout')])
+            links.extend([(self.user_url(request, user), user),
+                          (self.user_url(request, user, 'post'), user),
+                          (self.user_url(request, user, 'preferences'), 'preferences'),
+                          (self.link(request, 'logout'), 'logout')])
         else:
-            links.extend([('/login', 'login'), ('/join', 'join')])
+            links.extend([(self.link(request, 'login'), 'login'), 
+                          (self.link(request, 'join'), 'join')])
 
         if hasattr(self, 'help'):
-            links.append(('/help', 'help'))
+            links.append((self.link(request, 'help'), 'help'))
 
-        links = [ markup.link(*i) for i in links ]
-        return markup.listify(links, ordered=False, **{ 'class': 'site-nav'})
+        request.environ['data']['links'] = links
+
 
     def index(self, n_links):
         retval = StringIO()
@@ -597,60 +604,90 @@
         print >> retval, '</div>'
         return retval.getvalue()
 
-    def blog_entry(self, request, user, entry):
-        """given the content string, return a marked-up blog entry"""
-        # XXX no need to pass user
+#     def blog_entry(self, request, user, entry):
+#         """given the content string, return a marked-up blog entry"""
+#         # XXX no need to pass user
 
-        # user preferences
-        prefs = request.user.settings
-        format = prefs.get('Date format', self.date_format)
-        subject = prefs.get('Subject', self.subject)
+#         # user preferences
+#         prefs = request.user.settings
+#         format = prefs.get('Date format', self.date_format)
+#         subject = prefs.get('Subject', self.subject)
 
-        role = self.role(user, request)
+#         role = self.role(user, request)
         
-        subject = subject % { 'date' : entry.date.strftime(format) }
-        subject = cgi.escape(subject)
-        html = StringIO()
-        blog_id = entry.datestamp()
-        print >> html, '<div id="%s" class="blog-entry">' % blog_id
-        print >> html, '<a name="%s" />' % blog_id
-        print >> html, '<div class="subject">'
-        print >> html, '<a href="/%s">%s</a>' % (self.user_url(request, user, blog_id), subject)
-        if (entry.privacy == 'secret') and (role == 'friend'):
-            print >> html, '<em>secret</em>'
-        print >> html, '</div>'
-        print >> html, self.cooker(entry.body)
+#         subject = subject % { 'date' : entry.date.strftime(format) }
+#         subject = cgi.escape(subject)
+#         html = StringIO()
+#         blog_id = entry.datestamp()
+#         print >> html, '<div id="%s" class="blog-entry">' % blog_id
+#         print >> html, '<a name="%s" />' % blog_id
+#         print >> html, '<div class="subject">'
+#         print >> html, '<a href="/%s">%s</a>' % (self.user_url(request, user, blog_id), subject)
+#         if (entry.privacy == 'secret') and (role == 'friend'):
+#             print >> html, '<em>secret</em>'
+#         print >> html, '</div>'
+#         print >> html, self.cooker(entry.body)
 
-        if role == 'author':
-            print >> html, '<div><form action="/%s" method="post">' % self.user_url(request, entry.user, blog_id)
-            print >> html, self.privacy_settings(entry.privacy)
-            print >> html, '<input type="submit" name="submit" value="Change Privacy" />'
-            print >> html, '</form></div>'
-            if entry.privacy != 'public':
-                title = "You can give this URL so people may see this %s post without logging in" % entry.privacy
-                print >> html, '<div>'
-                print >> html, '<span title="%s">Mangled URL:</span>' % title
-                print >> html, markup.link(self.mangledurl(request, entry))
-                print >> html, '</div>'
+#         if role == 'author':
+#             print >> html, '<div><form action="/%s" method="post">' % self.user_url(request, entry.user, blog_id)
+#             print >> html, self.privacy_settings(entry.privacy)
+#             print >> html, '<input type="submit" name="submit" value="Change Privacy" />'
+#             print >> html, '</form></div>'
+#             if entry.privacy != 'public':
+#                 title = "You can give this URL so people may see this %s post without logging in" % entry.privacy
+#                 print >> html, '<div>'
+#                 print >> html, '<span title="%s">Mangled URL:</span>' % title
+#                 print >> html, markup.link(self.mangledurl(request, entry))
+#                 print >> html, '</div>'
         
-        print >> html, '</div>'
-        return html.getvalue()
+#         print >> html, '</div>'
+#         return html.getvalue()
         
     def write_blog(self, user, blog, path, n_links, request):
         """return the user's blog in HTML"""
-        # XXX no need to pass path or user!
-        retval = StringIO()
-        print >> retval,  self.navigation(user, blog, path, n_links, 0)
+
+        # XXX probably should go elsewhere
         for entry in blog:
-            print >> retval, self.blog_entry(request, user, entry)
-        feedtitle=None
-        if request.path_info.strip('/') == user:
-            feedtitle = "%s's blog" % user
-        title = None
-        if len(blog) == 1:
-            format = request.user.settings.get('Date format', self.date_format)
-            title = blog[0].date.strftime(format)
-        return self.render(request, retval.getvalue(), title=title, feedtitle=feedtitle)
+            if (user, entry.datestamp()) not in self.cooked_bodies:
+                self.cooked_bodies[(user, entry.datestamp())] = self.cooker(entry.body)
+            entry.cooked_body = Markup(self.cooked_bodies[(user, entry.datestamp())])
+
+        # site nav 
+        # XXX def site_nav() puts directly in request.environ['data']
+        # should return instead
+        self.site_nav(request)
+
+        # user data -> should be moved up the chain
+        data = request.environ['data']
+        data['user'] = user
+        data['role'] = self.role(user, request)
+        data['stylesheets'] = () # TODO
+        data['subject'] = request.user.settings.get('Subject', self.subject)
+        data['date_format'] = request.user.settings.get('Date format', self.date_format)
+        data['user_url'] = self.user_url
+        data['mangledurl'] = self.mangledurl
+
+        # blog data
+        data['blog'] = blog
+        data['n_links'] = n_links
+
+        # render the template
+        template = self.loader.load('blog.html')
+        return template.generate(**data).render()
+
+#         # XXX no need to pass path or user!
+#         retval = StringIO()
+#         print >> retval,  self.navigation(user, blog, path, n_links, 0)
+#         for entry in blog:
+#             print >> retval, self.blog_entry(request, user, entry)
+#         feedtitle=None
+#         if request.path_info.strip('/') == user:
+#             feedtitle = "%s's blog" % user
+#         title = None
+#         if len(blog) == 1:
+#             format = request.user.settings.get('Date format', self.date_format)
+#             title = blog[0].date.strftime(format)
+#         return self.render(request, retval.getvalue(), title=title, feedtitle=feedtitle)
                            
     def restructuredText(self, string):
         origstring = string
@@ -781,7 +818,7 @@
         return self.render(request, retval.getvalue())
 
     def preferences_form(self, request, user):
-        prefs = self.request.user.settings
+        prefs = request.user.settings
         form = Form()
 
         # date format
@@ -863,31 +900,26 @@
         return self.user, path
 
     def user_url(self, request, user, *args, **kw):
-        permalink = kw.get('permalink')
-        if permalink:
-            _args = [ request.host_url ]
-        else:
-            _args = [ ]
-        _args.extend(args)
-        return '/'.join([str(arg) for arg in _args])
+        permalink = kw.get('permalink', False)
+        return self.link(request, args, permalink)
 
     def passwords(self):
         return { self.user: self.users.password(self.user) }
 
     def site_nav(self, request):
         """returns HTML for site navigation"""
-        links = [('/', self.user), ]
+        links = [(self.user_url(request, self.user), self.user), ]
         user = self.authenticated(request)
         if user:
-            links.extend([
-                          ('/post', 'post'),
-                          ('/preferences', 'preferences'),
-                          ('/logout', 'logout')])
+            links.extend([(self.user_url(request, user, 'post'), 'post'),
+                          (self.user_url(request, user, 'preferences'), 'preferences'),
+                          (self.link(request, 'logout'), 'logout')])
         else:
-            links.append(('/login', 'login'))
+            links.append((self.link(request, 'login'), 'login'))
 
         if hasattr(self, 'help'):
-            links.append(('/help', 'help'))
+            links.append((self.link(request, 'help'), 'about'))
+
 
-        links = [ markup.link(*i) for i in links ]
-        return markup.listify(links, ordered=False, **{ 'class': 'site-nav'})
+        request.environ['data']['links'] = links
+