cmlenz@611: #!/usr/bin/env python cmlenz@611: cmlenz@611: import os cmlenz@611: import pickle cmlenz@611: import sys cmlenz@611: cmlenz@611: import cherrypy cmlenz@611: from formencode import Invalid cmlenz@611: from genshi.filters import HTMLFormFiller cmlenz@611: from paste.evalexception.middleware import EvalException cmlenz@611: cmlenz@611: from geddit.form import SubmissionForm, CommentForm cmlenz@611: from geddit.lib import template cmlenz@611: from geddit.model import Submission, Comment cmlenz@611: cmlenz@611: cmlenz@611: class Root(object): cmlenz@611: cmlenz@611: def __init__(self, data): cmlenz@611: self.data = data cmlenz@611: self.submission_lookup = {} cmlenz@611: self.comment_lookup = {} cmlenz@611: for submission in self.data: cmlenz@611: self.submission_lookup[submission.code] = submission cmlenz@611: for comment in submission.comments: cmlenz@611: self.comment_lookup[comment.code] = comment cmlenz@611: def _add_replies(comment): cmlenz@611: for reply in comment.replies: cmlenz@611: self.comment_lookup[reply.code] = reply cmlenz@611: _add_replies(comment) cmlenz@611: cmlenz@611: @cherrypy.expose cmlenz@611: @template.output('index.html', method='html', doctype='html') cmlenz@611: def index(self): cmlenz@611: return template.render(submissions=self.data) cmlenz@611: cmlenz@611: @cherrypy.expose cmlenz@611: @template.output('info.html', method='html', doctype='html') cmlenz@611: def info(self, code): cmlenz@611: submission = self.submission_lookup.get(code) cmlenz@611: if not submission: cmlenz@611: raise cherrypy.NotFound() cmlenz@611: return template.render(submission=submission) cmlenz@611: cmlenz@611: @cherrypy.expose cmlenz@611: @template.output('submit.html', method='html', doctype='html') cmlenz@611: def submit(self, cancel=False, **data): cmlenz@611: if cherrypy.request.method == 'POST': cmlenz@611: if cancel: cmlenz@611: raise cherrypy.HTTPRedirect('/') cmlenz@611: form = SubmissionForm() cmlenz@611: try: cmlenz@611: data = form.to_python(data) cmlenz@611: submission = Submission(**data) cmlenz@611: self.data.append(submission) cmlenz@611: raise cherrypy.HTTPRedirect('/') cmlenz@611: except Invalid, e: cmlenz@611: errors = e.unpack_errors() cmlenz@611: else: cmlenz@611: errors = {} cmlenz@611: cmlenz@611: return template.render(errors=errors) | HTMLFormFiller(data=data) cmlenz@611: cmlenz@611: @cherrypy.expose cmlenz@611: @template.output('comment.html', method='html', doctype='html') cmlenz@611: def comment(self, code, cancel=False, **data): cmlenz@611: submission = self.submission_lookup.get(code) cmlenz@611: if not submission: cmlenz@611: raise cherrypy.NotFound() cmlenz@611: if cherrypy.request.method == 'POST': cmlenz@611: if cancel: cmlenz@611: raise cherrypy.HTTPRedirect('/info/%s' % submission.code) cmlenz@611: form = CommentForm() cmlenz@611: try: cmlenz@611: data = form.to_python(data) cmlenz@611: comment = submission.add_comment(**data) cmlenz@611: self.comment_lookup[comment.code] = comment cmlenz@611: raise cherrypy.HTTPRedirect('/') cmlenz@611: except Invalid, e: cmlenz@611: errors = e.unpack_errors() cmlenz@611: else: cmlenz@611: errors = {} cmlenz@611: cmlenz@611: return template.render(submission=submission, comment=None, cmlenz@611: errors=errors) cmlenz@611: cmlenz@611: @cherrypy.expose cmlenz@611: @template.output('comment.html', method='html', doctype='html') cmlenz@611: def reply(self, code, cancel=False, **data): cmlenz@611: comment = self.comment_lookup.get(code) cmlenz@611: submission = comment.submission cmlenz@611: if not comment: cmlenz@611: raise cherrypy.NotFound() cmlenz@611: if cherrypy.request.method == 'POST': cmlenz@611: if cancel: cmlenz@611: raise cherrypy.HTTPRedirect('/info/%s' % submission.code) cmlenz@611: form = CommentForm() cmlenz@611: try: cmlenz@611: data = form.to_python(data) cmlenz@611: comment = comment.add_reply(**data) cmlenz@611: self.comment_lookup[comment.code] = comment cmlenz@611: raise cherrypy.HTTPRedirect('/') cmlenz@611: except Invalid, e: cmlenz@611: errors = e.unpack_errors() cmlenz@611: else: cmlenz@611: errors = {} cmlenz@611: cmlenz@611: return template.render(submission=submission, comment=comment, cmlenz@611: errors=errors) cmlenz@611: cmlenz@611: cmlenz@611: def main(filename): cmlenz@611: # load data from the pickle file, or initialize it to an empty list cmlenz@611: if os.path.exists(filename): cmlenz@611: fileobj = open(filename, 'rb') cmlenz@611: try: cmlenz@611: data = pickle.load(fileobj) cmlenz@611: finally: cmlenz@611: fileobj.close() cmlenz@611: else: cmlenz@611: data = [] cmlenz@611: cmlenz@611: def _save_data(): cmlenz@611: # save data back to the pickle file cmlenz@611: fileobj = open(filename, 'wb') cmlenz@611: try: cmlenz@611: pickle.dump(data, fileobj) cmlenz@611: finally: cmlenz@611: fileobj.close() cmlenz@611: cherrypy.engine.on_stop_engine_list.append(_save_data) cmlenz@611: cmlenz@611: # Some global configuration; note that this could be moved into a configuration file cmlenz@611: cherrypy.config.update({ cmlenz@611: 'request.throw_errors': True, cmlenz@611: 'tools.encode.on': True, 'tools.encode.encoding': 'utf-8', cmlenz@611: 'tools.decode.on': True, cmlenz@611: 'tools.trailing_slash.on': True, cmlenz@611: 'tools.staticdir.root': os.path.abspath(os.path.dirname(__file__)), cmlenz@611: }) cmlenz@611: cmlenz@611: # Initialize the application, and add EvalException for more helpful error messages cmlenz@611: app = cherrypy.Application(Root(data)) cmlenz@611: app.wsgiapp.pipeline.append(('paste_exc', EvalException)) cmlenz@611: cherrypy.quickstart(app, '/', { cmlenz@611: '/media': { cmlenz@611: 'tools.staticdir.on': True, cmlenz@611: 'tools.staticdir.dir': 'static' cmlenz@611: } cmlenz@611: }) cmlenz@611: cmlenz@611: if __name__ == '__main__': cmlenz@611: import formencode cmlenz@611: formencode.api.set_stdtranslation(languages=['en']) cmlenz@611: main(sys.argv[1])