Permalink
Browse files

picoblog

  • Loading branch information...
1 parent 21d25da commit 0eebe6aa63d5b6fbb0efc8068539b70ae1ed341e @bmc committed Aug 8, 2008
View
114 admin.py
@@ -0,0 +1,114 @@
+# $Id$
+
+import cgi
+
+from google.appengine.api import users
+from google.appengine.ext import webapp
+from google.appengine.ext.webapp import util
+
+from models import *
+import request
+
+# -----------------------------------------------------------------------------
+# Classes
+# -----------------------------------------------------------------------------
+
+class ShowArticlesHandler(request.BlogRequestHandler):
+ def get(self):
+ articles = Article.get_all()
+ template_vars = {'articles' : articles}
+ self.render_template('admin-main.html', template_vars)
+
+class NewArticleHandler(request.BlogRequestHandler):
+ def get(self):
+ article = Article(title='New article',
+ body='Content goes here',
+ draft=True)
+ template_vars = {'article' : article}
+ self.render_template('admin-edit.html', template_vars)
+
+class SaveArticleHandler(request.BlogRequestHandler):
+ def post(self):
+ title = cgi.escape(self.request.get('title'))
+ body = cgi.escape(self.request.get('content'))
+ id = int(cgi.escape(self.request.get('id')))
+ tags = cgi.escape(self.request.get('tags'))
+ published_when = cgi.escape(self.request.get('published_when'))
+ draft = cgi.escape(self.request.get('draft'))
+ if tags:
+ tags = [t.strip() for t in tags.split(',')]
+ else:
+ tags = []
+
+ if not draft:
+ draft = False
+ else:
+ draft = (draft.lower() == 'on')
+
+ article = Article.get(id)
+ if article:
+ # It's an edit of an existing item.
+ article.title = title
+ article.body = body
+ article.tags = tags
+ article.draft = draft
+ else:
+ # It's new.
+ article = Article(title=title,
+ body=body,
+ tags=tags,
+ id=id,
+ draft=draft)
+
+ article.save()
+
+ edit_again = cgi.escape(self.request.get('edit_again'))
+ edit_again = edit_again and (edit_again.lower() == 'true')
+ if edit_again:
+ self.redirect('/admin/article/edit/?id=%s' % id)
+ else:
+ self.redirect('/admin/')
+
+class EditArticleHandler(request.BlogRequestHandler):
+ def get(self):
+ id = int(self.request.get('id'))
+ article = Article.get(id)
+ if not article:
+ raise ValueError, 'Article with ID %d does not exist.' % id
+
+ article.tag_string = ', '.join(article.tags)
+ template_vars = {'article' : article}
+ self.render_template('admin-edit.html', template_vars)
+
+class DeleteArticleHandler(request.BlogRequestHandler):
+ def get(self):
+ id = int(self.request.get('id'))
+ article = Article.get(id)
+ if article:
+ article.delete()
+
+ self.redirect('/admin/')
+
+# -----------------------------------------------------------------------------
+# Functions
+# -----------------------------------------------------------------------------
+
+application = webapp.WSGIApplication(
+ [('/admin/?', ShowArticlesHandler),
+ ('/admin/article/new/?', NewArticleHandler),
+ ('/admin/article/delete/?', DeleteArticleHandler),
+ ('/admin/article/save/?', SaveArticleHandler),
+ ('/admin/article/edit/?', EditArticleHandler),
+ ],
+
+ debug=True)
+
+# -----------------------------------------------------------------------------
+# Main program
+# -----------------------------------------------------------------------------
+
+def main():
+ util.run_wsgi_app(application)
+
+if __name__ == "__main__":
+ main()
View
@@ -0,0 +1,24 @@
+application: example-blog
+version: 1
+runtime: python
+api_version: 1
+
+handlers:
+- url: /static
+ static_dir: static
+
+- url: /favicon.ico
+ static_files: static/favicon.ico
+ upload: static/favicon.ico
+
+- url: /admin
+ script: admin.py
+ #login: admin
+
+- url: /admin/.*
+ script: admin.py
+ #login: admin
+
+- url: /.*
+ script: blog.py
+
View
256 blog.py
@@ -0,0 +1,256 @@
+# $Id$
+
+
+# -----------------------------------------------------------------------------
+# Imports
+# -----------------------------------------------------------------------------
+
+import logging
+import os
+import sys
+import math
+import random
+import datetime
+
+# Google AppEngine imports
+from google.appengine.api import users
+from google.appengine.ext import webapp
+from google.appengine.ext.webapp import util
+
+from models import *
+from rst import rst2html
+import defs
+import request
+
+# -----------------------------------------------------------------------------
+# Classes
+# -----------------------------------------------------------------------------
+
+class DateCount(object):
+
+ def __init__(self, date, count):
+ self.date = date
+ self.count = count
+
+ def __cmp__(self, other):
+ return cmp(self.date, other.date)
+
+ def __hash__(self):
+ return self.date.__hash__()
+
+ def __str__(self):
+ return '%s(%d)' % (self.date, self.count)
+
+ def __repr__(self):
+ return '<%s: %s>' % (self.__class__.__name__, str(self))
+
+class TagCount(object):
+
+ def __init__(self, tag, count):
+ self.css_class = ""
+ self.count = count
+ self.tag = tag
+
+class AbstractPageHandler(request.BlogRequestHandler):
+
+ def get_tag_counts(self):
+ """
+ Get tag counts and calculate tag cloud frequencies.
+ """
+ tag_counts = Article.get_all_tags()
+ result = []
+ if tag_counts:
+ maximum = max(tag_counts.values())
+
+ for tag, count in tag_counts.items():
+ tc = TagCount(tag, count)
+
+ # Determine the popularity of this term as a percentage.
+
+ percent = math.floor((tc.count * 100) / maximum)
+
+ # determine the CSS class for this term based on the percentage
+
+ if percent <= 20:
+ tc.css_class = 'tag-cloud-tiny'
+ elif 20 < percent <= 40:
+ tc.css_class = 'tag-cloud-small'
+ elif 40 < percent <= 60:
+ tc.css_class = 'tag-cloud-medium'
+ elif 60 < percent <= 80:
+ tc.css_class = 'tag-cloud-large'
+ else:
+ tc.css_class = 'tag-cloud-huge'
+
+ result.append(tc)
+
+ random.shuffle(result)
+ return result
+
+ def get_month_counts(self):
+ hash = Article.get_all_datetimes()
+ datetimes = hash.keys()
+ date_count = {}
+ for dt in datetimes:
+ just_date = datetime.date(dt.year, dt.month, 1)
+ try:
+ date_count[just_date] += hash[dt]
+ except KeyError:
+ date_count[just_date] = hash[dt]
+
+ dates = date_count.keys()
+ dates.sort()
+ dates.reverse()
+ return [DateCount(date, date_count[date]) for date in dates]
+
+ def augment_articles(self, articles, url_prefix, html=True):
+ for article in articles:
+ if html:
+ try:
+ article.html = rst2html(article.body)
+ except AttributeError:
+ article.html = ''
+ article.path = '/' + defs.ARTICLE_URL_PATH + '/%s' % article.id
+ article.url = url_prefix + article.path
+
+ def render_articles(self,
+ articles,
+ request,
+ recent,
+ template_name='show-articles.html'):
+ url_prefix = 'http://' + request.environ['SERVER_NAME']
+ port = request.environ['SERVER_PORT']
+ if port:
+ url_prefix += ':%s' % port
+
+ self.augment_articles(articles, url_prefix)
+ self.augment_articles(recent, url_prefix, html=False)
+
+ last_updated = datetime.datetime.now()
+ if articles:
+ last_updated = articles[0].published_when
+
+ blog_url = url_prefix
+ tag_path = '/' + defs.TAG_URL_PATH
+ tag_url = url_prefix + tag_path
+ date_path = '/' + defs.DATE_URL_PATH
+ date_url = url_prefix + date_path
+ media_path = '/' + defs.MEDIA_URL_PATH
+ media_url = url_prefix + media_path
+
+ template_variables = {'blog_name' : defs.BLOG_NAME,
+ 'blog_owner' : defs.BLOG_OWNER,
+ 'articles' : articles,
+ 'tag_list' : self.get_tag_counts(),
+ 'date_list' : self.get_month_counts(),
+ 'version' : '0.3',
+ 'last_updated' : last_updated,
+ 'blog_path' : '/',
+ 'blog_url' : blog_url,
+ 'archive_path' : '/' + defs.ARCHIVE_URL_PATH,
+ 'tag_path' : tag_path,
+ 'tag_url' : tag_url,
+ 'date_path' : date_path,
+ 'date_url' : date_url,
+ 'rss2_path' : '/' + defs.RSS2_URL_PATH,
+ 'recent' : recent}
+
+ return self.render_template(template_name, template_variables)
+
+ def get_recent(self, articles=None):
+ if not articles:
+ articles = Article.published()
+
+ total_recent = min(len(articles), defs.TOTAL_RECENT)
+ if articles:
+ recent = articles[0:total_recent]
+ else:
+ recent = []
+
+ return recent
+
+class FrontPageHandler(AbstractPageHandler):
+ def get(self):
+ articles = Article.published()
+ if len(articles) > defs.MAX_ARTICLES_PER_PAGE:
+ articles = articles[:defs.MAX_ARTICLES_PER_PAGE]
+
+ self.response.out.write(self.render_articles(articles,
+ self.request,
+ self.get_recent()))
+
+class ArticlesByTagHandler(AbstractPageHandler):
+ def get(self, tag):
+ articles = Article.all_for_tag(tag.lower())
+ self.response.out.write(self.render_articles(articles,
+ self.request,
+ self.get_recent()))
+
+class ArticlesForMonthHandler(AbstractPageHandler):
+ def get(self, year, month):
+ articles = Article.all_for_month(int(year), int(month))
+ self.response.out.write(self.render_articles(articles,
+ self.request,
+ self.get_recent()))
+
+class SingleArticleHandler(AbstractPageHandler):
+ def get(self, id):
+ article = Article.get(int(id))
+ if article:
+ template = 'show-articles.html'
+ articles = [article]
+ more = None
+ else:
+ template = 'not-found.html'
+ articles = []
+
+ self.response.out.write(self.render_articles(articles=articles,
+ request=self.request,
+ recent=self.get_recent(),
+ template_name=template))
+
+class ArchivePageHandler(AbstractPageHandler):
+ def get(self):
+ articles = Article.published()
+ self.response.out.write(self.render_articles(articles,
+ self.request,
+ [],
+ 'archive.html'))
+
+class RSSFeedHandler(AbstractPageHandler):
+ def get(self):
+ articles = Article.published()
+ self.response.headers['Content-Type'] = 'text/xml'
+ self.response.out.write(self.render_articles(articles,
+ self.request,
+ [],
+ 'rss2.xml'))
+
+class NotFoundPageHandler(AbstractPageHandler):
+ def get(self):
+ self.response.out.write(self.render_articles([],
+ self.request,
+ [],
+ 'not-found.html'))
+
+# -----------------------------------------------------------------------------
+# Main program
+# -----------------------------------------------------------------------------
+
+application = webapp.WSGIApplication(
+ [('/', FrontPageHandler),
+ ('/tag/([^/]+)/*$', ArticlesByTagHandler),
+ ('/date/(\d\d\d\d)-(\d\d)/?$', ArticlesForMonthHandler),
+ ('/id/(\d+)/?$', SingleArticleHandler),
+ ('/archive/?$', ArchivePageHandler),
+ ('/rss2/?$', RSSFeedHandler),
+ ('/.*$', NotFoundPageHandler),
+ ],
+
+ debug=True)
+
+def main():
+ util.run_wsgi_app(application)
+
+if __name__ == '__main__':
+ main()
Oops, something went wrong.

0 comments on commit 0eebe6a

Please sign in to comment.