# HG changeset patch # User k0s # Date 1256505958 14400 # Node ID 36698624435bd5b41b3c9a90a3990e8663c51c67 # Parent 645aa0f3279fd7de742149779acea43f5093c279 blog page mostly works diff -r 645aa0f3279f -r 36698624435b bitsyblog/bitsyblog.py --- 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 = ( '' % feedtitle, '' % 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, '' 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, '
' % blog_id - print >> html, '' % blog_id - print >> html, '
' - print >> html, '%s' % (self.user_url(request, user, blog_id), subject) - if (entry.privacy == 'secret') and (role == 'friend'): - print >> html, 'secret' - print >> html, '
' - 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, '
' % blog_id +# print >> html, '' % blog_id +# print >> html, '
' +# print >> html, '%s' % (self.user_url(request, user, blog_id), subject) +# if (entry.privacy == 'secret') and (role == 'friend'): +# print >> html, 'secret' +# print >> html, '
' +# print >> html, self.cooker(entry.body) - if role == 'author': - print >> html, '
' % self.user_url(request, entry.user, blog_id) - print >> html, self.privacy_settings(entry.privacy) - print >> html, '' - print >> html, '
' - if entry.privacy != 'public': - title = "You can give this URL so people may see this %s post without logging in" % entry.privacy - print >> html, '
' - print >> html, 'Mangled URL:' % title - print >> html, markup.link(self.mangledurl(request, entry)) - print >> html, '
' +# if role == 'author': +# print >> html, '
' % self.user_url(request, entry.user, blog_id) +# print >> html, self.privacy_settings(entry.privacy) +# print >> html, '' +# print >> html, '
' +# if entry.privacy != 'public': +# title = "You can give this URL so people may see this %s post without logging in" % entry.privacy +# print >> html, '
' +# print >> html, 'Mangled URL:' % title +# print >> html, markup.link(self.mangledurl(request, entry)) +# print >> html, '
' - print >> html, '
' - return html.getvalue() +# print >> html, '
' +# 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 + diff -r 645aa0f3279f -r 36698624435b bitsyblog/templates/blog.html --- a/bitsyblog/templates/blog.html Wed Oct 07 17:26:13 2009 -0400 +++ b/bitsyblog/templates/blog.html Sun Oct 25 17:25:58 2009 -0400 @@ -8,8 +8,8 @@ ${user} - ${site_name} - - + @@ -19,13 +19,16 @@ - - + -