comparison bitsyblog/bitsyblog.py @ 12:dd8c1c8ae0da

more removing of self.request and general cleanup
author k0s <k0scist@gmail.com>
date Wed, 07 Oct 2009 17:19:32 -0400
parents e4f28fde518a
children 645aa0f3279f
comparison
equal deleted inserted replaced
11:ebe8dc33c871 12:dd8c1c8ae0da
95 request = Request(environ) 95 request = Request(environ)
96 res = self.response_functions.get(request.method, self.error())(request) 96 res = self.response_functions.get(request.method, self.error())(request)
97 return res(environ, start_response) 97 return res(environ, start_response)
98 98
99 def get_response(self, text, content_type='text/html'): 99 def get_response(self, text, content_type='text/html'):
100 # XXX to deprecate
100 res = Response(content_type=content_type, body=text) 101 res = Response(content_type=content_type, body=text)
101 res.content_length = len(res.body)
102 return res 102 return res
103 103
104 def get_index(self, request): 104 def get_index(self, request):
105 """returns material pertaining to the root of the site""" 105 """returns material pertaining to the root of the site"""
106 106
117 117
118 # site rss 118 # site rss
119 if path == 'rss': 119 if path == 'rss':
120 if n_posts is None: 120 if n_posts is None:
121 n_posts = 10 121 n_posts = 10
122 return self.get_response(self.site_rss(n_posts), content_type='text/xml') 122 return self.get_response(self.site_rss(request, n_posts), content_type='text/xml')
123 123
124 # site atom 124 # site atom
125 if path == 'atom': 125 if path == 'atom':
126 if n_posts is None: 126 if n_posts is None:
127 n_posts = 10 127 n_posts = 10
128 return self.get_response(self.atom(self.blog.latest(self.users.users(), n_posts)), content_type='text/xml') 128 return self.get_response(self.atom(request, self.blog.latest(self.users.users(), n_posts)), content_type='text/xml')
129 129
130 ### help 130 ### help
131 if path == 'help' and hasattr(self, 'help'): 131 if path == 'help' and hasattr(self, 'help'):
132 return self.get_response(self.help) 132 return self.get_response(self.help)
133 133
159 return self.get_response(self.form_post(request, user)) 159 return self.get_response(self.form_post(request, user))
160 160
161 if path == [ 'preferences' ]: 161 if path == [ 'preferences' ]:
162 if check is not None: 162 if check is not None:
163 return check 163 return check
164 return self.get_response(self.preferences(user)) 164 return self.get_response(self.preferences(request, user))
165 165
166 if path == [ 'rss' ]: 166 if path == [ 'rss' ]:
167 feed = 'rss' 167 feed = 'rss'
168 path = [] 168 path = []
169 if n_posts is None: 169 if n_posts is None:
193 return exc.HTTPNotFound(str(e)) 193 return exc.HTTPNotFound(str(e))
194 except exc.HTTPException, e: 194 except exc.HTTPException, e:
195 return e.wsgi_response 195 return e.wsgi_response
196 196
197 if feed == 'rss': 197 if feed == 'rss':
198 content = self.rss(user, blog) # XXX different signatures 198 content = self.rss(request, user, blog) # XXX different signatures
199 return self.get_response(content, content_type='text/xml') 199 return self.get_response(content, content_type='text/xml')
200 200
201 if feed == 'atom': 201 if feed == 'atom':
202 content = self.atom(blog, user) # XXX different signatures 202 content = self.atom(request, blog, user) # XXX different signatures
203 return self.get_response(content, content_type='text/xml') 203 return self.get_response(content, content_type='text/xml')
204 204
205 # reverse the blog if necessary 205 # reverse the blog if necessary
206 if request.GET.get('sort') == 'forward': 206 if request.GET.get('sort') == 'forward':
207 blog = list(reversed(blog)) 207 blog = list(reversed(blog))
220 def get(self, request): 220 def get(self, request):
221 """ 221 """
222 display the blog or respond to a get request 222 display the blog or respond to a get request
223 """ 223 """
224 224
225 # GENSHI: global data dictionary 225 # GENSHI: data dictionary
226 request.environ['data'] = { 'site_name': self.site_name } 226 request.environ['data'] = { 'site_name': self.site_name,
227 'request': request,
228 'link': self.liin}
227 229
228 # front matter of the site 230 # front matter of the site
229 index = self.get_index() 231 index = self.get_index()
230 if index is not None: 232 if index is not None:
231 return index 233 return index
265 settings['CSS file'] = request.POST.get('CSS file') 267 settings['CSS file'] = request.POST.get('CSS file')
266 settings['Friends'] = ', '.join(request.POST.getall('Friends')) 268 settings['Friends'] = ', '.join(request.POST.getall('Friends'))
267 269
268 errors = self.users.write_settings(user, **settings) 270 errors = self.users.write_settings(user, **settings)
269 if errors: # re-display form with errors 271 if errors: # re-display form with errors
270 return self.get_response(self.preferences(user, errors)) 272 return self.get_response(self.preferences(request, user, errors))
271 273
272 return self.get_response(self.preferences(user, message='Changes saved')) 274 return self.get_response(self.preferences(request, user, message='Changes saved'))
273 elif len(path) == 1 and self.isentry(path[0]): 275 elif len(path) == 1 and self.isentry(path[0]):
274 entry = self.blog.entry(user, path[0], roles['author']) 276 entry = self.blog.entry(user, path[0], roles['author'])
275 if entry is None: 277 if entry is None:
276 return exc.HTTPNotFound("Blog entry %s not found %s" % path[0]) 278 return exc.HTTPNotFound("Blog entry %s not found %s" % path[0])
277 privacy = request.POST.get('privacy') 279 privacy = request.POST.get('privacy')
290 if not body: 292 if not body:
291 return exc.HTTPSeeOther("Your post has no content! No blog for you", 293 return exc.HTTPSeeOther("Your post has no content! No blog for you",
292 location='/%s' % self.user_url(request, user, 'post')) 294 location='/%s' % self.user_url(request, user, 'post'))
293 295
294 # determine if the post is secret or private 296 # determine if the post is secret or private
295 privacy = request.GET.get('privacy') or self.request.POST.get('privacy') or 'public' 297 privacy = request.GET.get('privacy') or request.POST.get('privacy') or 'public'
296 298
297 # write the file 299 # write the file
298 now = utils.datestamp(datetime.datetime.now()) 300 now = utils.datestamp(datetime.datetime.now())
299 location = "/%s" % self.user_url(request, user, now) 301 location = "/%s" % self.user_url(request, user, now)
300 self.blog.post(user, now, body, privacy) 302 self.blog.post(user, now, body, privacy)
336 """deal with non-supported methods""" 338 """deal with non-supported methods"""
337 methods = ', '.join(self.response_functions.keys()[:1]) 339 methods = ', '.join(self.response_functions.keys()[:1])
338 methods += ' and %s' % self.response_functions.keys()[-1] 340 methods += ' and %s' % self.response_functions.keys()[-1]
339 return exc.HTTPMethodNotAllowed("Only %s operations are allowed" % methods) 341 return exc.HTTPMethodNotAllowed("Only %s operations are allowed" % methods)
340 342
341 ### auth functions 343 ### auth/auth functions
342 344
343 def passwords(self): 345 def passwords(self):
344 return self.users.passwords() 346 return self.users.passwords()
345 347
346 def authenticated(self, request): 348 def authenticated(self, request):
347 """return authenticated user""" 349 """return authenticated user"""
350 # XXX needed?
348 return request.environ.get('REMOTE_USER') 351 return request.environ.get('REMOTE_USER')
349 352
350 def check_user(self, user, request): 353 def check_user(self, user, request):
351 """ 354 """
352 determine authenticated user 355 determine authenticated user
383 path = path[1:] 386 path = path[1:]
384 if not name: 387 if not name:
385 name = None 388 name = None
386 return name, path 389 return name, path
387 390
388 ### date methods
389
390 def isentry(self, string): # TODO -> blog.py
391 return (len(string) == len(''.join(utils.timeformat))) and string.isdigit()
392
393 def user_url(self, request, user, *args, **kw): 391 def user_url(self, request, user, *args, **kw):
394 permalink = kw.get('permalink') 392 permalink = kw.get('permalink')
395 if permalink: 393 if permalink:
396 _args = [ request.host_url, user ] 394 _args = [ request.host_url, user ]
397 else: 395 else:
398 _args = [ user ] 396 _args = [ user ]
399 _args.extend(args) 397 _args.extend(args)
400 return '/'.join([str(arg) for arg in _args]) 398 return '/'.join([str(arg) for arg in _args])
401 399
400 ###
401
402 def isentry(self, string): # TODO -> blog.py
403 return (len(string) == len(''.join(utils.timeformat))) and string.isdigit()
404
402 def permalink(self, request, blogentry): 405 def permalink(self, request, blogentry):
403 return self.user_url(request, blogentry.user, blogentry.datestamp(), permalink=True) 406 return self.user_url(request, blogentry.user, blogentry.datestamp(), permalink=True)
404 407
405 def entry_subject(self, blogentry): 408 def link(self, request, path, permanant=False):
406 if hasattr(self.request, 'user') and self.request.user.name == blogentry.user: 409 if isinstance(path, basestring):
407 prefs = self.request.user.settings 410 path = [ path ]
411 path = [ i.strip('/') for i in path ]
412 if permanant:
413 path = [ request.application_url ] + list(path)
414 return '/'.join(path)
408 else: 415 else:
409 prefs = self.users[blogentry.user].settings 416 if request.path:
410 subject = prefs.get('Subject', self.subject) 417 path = [ request.path ] + list(path)
411 date_format = prefs.get('Date format', self.date_format) 418 return '/%s' % ('/'.join(path))
412 return subject % { 'date': blogentry.date.strftime(date_format) } 419
420 ### mangled URLs
413 421
414 def mangledurl(self, request, blogentry): 422 def mangledurl(self, request, blogentry):
415 return self.user_url(request, blogentry.user, 'x%x' % (int(blogentry.datestamp()) * self.users.secret(blogentry.user)), permalink=True) 423 return self.user_url(request, blogentry.user, 'x%x' % (int(blogentry.datestamp()) * self.users.secret(blogentry.user)), permalink=True)
416 424
417 def unmangleurl(self, url, user): 425 def unmangleurl(self, url, user):
576 more = '<a href="%s?n=all">more</a>' % path 584 more = '<a href="%s?n=all">more</a>' % path
577 blog = blog[:n_links] 585 blog = blog[:n_links]
578 586
579 entries = [] 587 entries = []
580 for entry in blog: 588 for entry in blog:
581 id = entry.datestamp() 589 blog_id = entry.datestamp()
582 format = prefs.get('Date format', self.date_format) 590 format = prefs.get('Date format', self.date_format)
583 datestamp = entry.date.strftime(format) 591 datestamp = entry.date.strftime(format)
584 synopsis = entry.title() 592 synopsis = entry.title()
585 if synopsis: 593 if synopsis:
586 synopsis = ': %s' % cgi.escape(synopsis) 594 synopsis = ': %s' % cgi.escape(synopsis)
587 entries.append(markup.link("%s#%s" % (path, id), datestamp) + synopsis) 595 entries.append(markup.link("%s#%s" % (path, blog_id), datestamp) + synopsis)
588 596
589 print >> retval, markup.listify(entries) 597 print >> retval, markup.listify(entries)
590 print >> retval, more 598 print >> retval, more
591 print >> retval, '</div>' 599 print >> retval, '</div>'
592 return retval.getvalue() 600 return retval.getvalue()
674 if dict(i.items()).get('class') == 'system-message': 682 if dict(i.items()).get('class') == 'system-message':
675 i.clear() 683 i.clear()
676 684
677 return etree.tostring(foo) 685 return etree.tostring(foo)
678 686
687
679 ### feeds 688 ### feeds
680 689
681 def site_rss(self, n_items=10): 690 def site_rss(self, request, n_items=10):
682 blog = self.blog.latest(list(self.users.users()), n_items) 691 blog = self.blog.latest(list(self.users.users()), n_items)
683 title = self.site_name + ' - rss' 692 title = self.site_name + ' - rss'
684 link = self.request.host_url # XXX should be smarter 693 link = request.application_url
685 description = "latest scribblings on %s" % self.site_name 694 description = "latest scribblings on %s" % self.site_name
686 lastBuildDate = datetime.datetime.now() 695 lastBuildDate = datetime.datetime.now()
687 items = [ self.rss_item(entry.user, entry) for entry in blog ] 696 items = [ self.rss_item(request, entry.user, entry) for entry in blog ]
688 rss = PyRSS2Gen.RSS2(title=title, 697 rss = PyRSS2Gen.RSS2(title=title,
689 link=link, 698 link=link,
690 description=description, 699 description=description,
691 lastBuildDate=lastBuildDate, 700 lastBuildDate=lastBuildDate,
692 items=items) 701 items=items)
693 return rss.to_xml() 702 return rss.to_xml()
694 703
695 def rss(self, user, blog): 704 def rss(self, request, user, blog):
696 """ 705 """
697 rss feed for a user's blog 706 rss feed for a user's blog
698 done with PyRSS2Gen: 707 done with PyRSS2Gen:
699 http://www.dalkescientific.com/Python/PyRSS2Gen.html 708 http://www.dalkescientific.com/Python/PyRSS2Gen.html
700 """ 709 """
701 title = "%s's blog" % user 710 title = "%s's blog" % user
702 link = os.path.split(self.request.url)[0] 711 link = os.path.split(request.url)[0]
703 description = "latest blog entries for %s on %s" % (user, self.site_name) 712 description = "latest blog entries for %s on %s" % (user, self.site_name)
704 lastBuildDate = datetime.datetime.now() # not sure what this means 713 lastBuildDate = datetime.datetime.now() # not sure what this means
705 714
706 items = [ self.rss_item(user, entry) for entry in blog ] 715 items = [ self.rss_item(request, user, entry) for entry in blog ]
707 rss = PyRSS2Gen.RSS2(title=title, 716 rss = PyRSS2Gen.RSS2(title=title,
708 link=link, 717 link=link,
709 description=description, 718 description=description,
710 lastBuildDate=lastBuildDate, 719 lastBuildDate=lastBuildDate,
711 items=items) 720 items=items)
712 return rss.to_xml() 721 return rss.to_xml()
713 722
714 def rss_item(self, user, entry): 723 def rss_item(self, request, user, entry):
715 if hasattr(self.request, 'user') and self.request.user.name == user: 724 if hasattr(request, 'user') and request.user.name == user:
716 prefs = self.request.user.settings 725 prefs = request.user.settings
717 else: 726 else:
718 prefs = self.users[user].settings 727 prefs = self.users[user].settings
719 subject = prefs.get('Subject', self.subject) 728 subject = prefs.get('Subject', self.subject)
720 date_format = prefs.get('Date format', self.date_format) 729 date_format = prefs.get('Date format', self.date_format)
721 title = entry.title() 730 title = entry.title()
725 author=user, 734 author=user,
726 guid=PyRSS2Gen.Guid(self.permalink(entry)), 735 guid=PyRSS2Gen.Guid(self.permalink(entry)),
727 pubDate=entry.date) 736 pubDate=entry.date)
728 737
729 738
730 def atom(self, blog, author=None): 739 def atom(self, request, blog, author=None):
731 retval = StringIO() 740 retval = StringIO()
732 print >> retval, """<?xml version="1.0" encoding="utf-8"?> 741 print >> retval, """<?xml version="1.0" encoding="utf-8"?>
733 <feed xmlns="http://www.w3.org/2005/Atom"> 742 <feed xmlns="http://www.w3.org/2005/Atom">
734 """ 743 """
735 if author: 744 if author:
736 title = "%s's blog" % author 745 title = "%s's blog" % author
737 link = self.request.host_url + '/' + author 746 link = request.host_url + '/' + author
738 else: 747 else:
739 title = self.site_name + ' - atom' 748 title = self.site_name + ' - atom'
740 link = self.request.host_url 749 link = request.application_url
741 750
742 date = blog[0].date.isoformat() 751 date = blog[0].date.isoformat()
743 752
744 print >> retval, '<title>%s</title>' % title 753 print >> retval, '<title>%s</title>' % title
745 print >> retval, '<link href="%s" />' % link 754 print >> retval, '<link href="%s" />' % link
771 print >> retval, self.privacy_settings() 780 print >> retval, self.privacy_settings()
772 print >> retval, '<input type="submit" name="submit" value="Post" />' 781 print >> retval, '<input type="submit" name="submit" value="Post" />'
773 print >> retval, '</form>' 782 print >> retval, '</form>'
774 return self.render(request, retval.getvalue()) 783 return self.render(request, retval.getvalue())
775 784
776 def preferences_form(self, user): 785 def preferences_form(self, request, user):
777 prefs = self.request.user.settings 786 prefs = self.request.user.settings
778 form = Form() 787 form = Form()
779 788
780 # date format 789 # date format
781 format = prefs.get('Date format', self.date_format) 790 format = prefs.get('Date format', self.date_format)
814 users, prefs.get('Friends', set()), 823 users, prefs.get('Friends', set()),
815 help='friends can see your secret posts') 824 help='friends can see your secret posts')
816 825
817 return form 826 return form
818 827
819 def preferences(self, user, errors=None, message=None): 828 def preferences(self, request, user, errors=None, message=None):
820 """user preferences form""" 829 """user preferences form"""
821 body = self.preferences_form(user)(errors) 830 body = self.preferences_form(request, user)(errors)
822 if message: 831 if message:
823 body = '%s\n%s' % ( markup.p(markup.strong(message)), body ) 832 body = '%s\n%s' % ( markup.p(markup.strong(message)), body )
824 return self.render(request, body, title='preferences') 833 return self.render(request, body, title='preferences')
825 834
826 def privacy_settings(self, default='public'): 835 def privacy_settings(self, default='public'):
835 """single user version of bitsyblog""" 844 """single user version of bitsyblog"""
836 845
837 def get(self, request): 846 def get(self, request):
838 847
839 # GENSHI: global data dictionary 848 # GENSHI: global data dictionary
840 request.environ['data'] = { 'site_name': self.site_name } 849 request.environ['data'] = { 'site_name': self.site_name,
850 'request': request,
851 'link': self.link }
841 852
842 ### user space 853 ### user space
843 user, path = self.userpath(request) 854 user, path = self.userpath(request)
844 if user not in self.users: 855 if user not in self.users:
845 return exc.HTTPNotFound("Blog entry not found") 856 return exc.HTTPNotFound("Blog entry not found")