File: controller.py

package info (click to toggle)
genshi 0.7.10-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,032 kB
  • sloc: python: 16,598; javascript: 3,285; ansic: 734; xml: 45; cs: 31; sh: 28; makefile: 16
file content (138 lines) | stat: -rwxr-xr-x 4,383 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/env python

import operator, os, pickle, sys

import cherrypy
from formencode import Invalid
from genshi.input import HTML
from genshi.filters import HTMLFormFiller, HTMLSanitizer

from geddit.form import LinkForm, CommentForm
from geddit.lib import ajax, template
from geddit.model import Link, Comment


class Root(object):

    def __init__(self, data):
        self.data = data

    @cherrypy.expose
    @template.output('index.html')
    def index(self):
        links = sorted(self.data.values(), key=operator.attrgetter('time'))
        return template.render(links=links)

    @cherrypy.expose
    @template.output('submit.html')
    def submit(self, cancel=False, **data):
        if cherrypy.request.method == 'POST':
            if cancel:
                raise cherrypy.HTTPRedirect('/')
            form = LinkForm()
            try:
                data = form.to_python(data)
                link = Link(**data)
                self.data[link.id] = link
                raise cherrypy.HTTPRedirect('/')
            except Invalid as e:
                errors = e.unpack_errors()
        else:
            errors = {}

        return template.render(errors=errors) | HTMLFormFiller(data=data)

    @cherrypy.expose
    @template.output('info.html')
    def info(self, id):
        link = self.data.get(id)
        if not link:
            raise cherrypy.NotFound()
        return template.render(link=link)

    @cherrypy.expose
    @template.output('comment.html')
    def comment(self, id, cancel=False, **data):
        link = self.data.get(id)
        if not link:
            raise cherrypy.NotFound()
        if cherrypy.request.method == 'POST':
            if cancel:
                raise cherrypy.HTTPRedirect('/info/%s' % link.id)
            form = CommentForm()
            try:
                data = form.to_python(data)
                markup = HTML(data['content']) | HTMLSanitizer()
                data['content'] = markup.render('xhtml')
                comment = link.add_comment(**data)
                if not ajax.is_xhr():
                    raise cherrypy.HTTPRedirect('/info/%s' % link.id)
                return template.render('_comment.html', comment=comment,
                                       num=len(link.comments))
            except Invalid as e:
                errors = e.unpack_errors()
        else:
            errors = {}

        if ajax.is_xhr():
            stream = template.render('_form.html', link=link, errors=errors)
        else:
            stream = template.render(link=link, comment=None, errors=errors)
        return stream | HTMLFormFiller(data=data)

    @cherrypy.expose
    @template.output('index.xml', method='xml')
    def feed(self, id=None):
        if id:
            link = self.data.get(id)
            if not link:
                raise cherrypy.NotFound()
            return template.render('info.xml', link=link)
        else:
            links = sorted(self.data.values(), key=operator.attrgetter('time'))
            return template.render(links=links)


def main(filename):
    # load data from the pickle file, or initialize it to an empty list
    if os.path.exists(filename):
        fileobj = open(filename, 'rb')
        try:
            data = pickle.load(fileobj)
        finally:
            fileobj.close()
    else:
        data = {}

    def _save_data():
        # save data back to the pickle file
        fileobj = open(filename, 'wb')
        try:
            pickle.dump(data, fileobj)
        finally:
            fileobj.close()
    if hasattr(cherrypy.engine, 'subscribe'): # CherryPy >= 3.1
        cherrypy.engine.subscribe('stop', _save_data)
    else:
        cherrypy.engine.on_stop_engine_list.append(_save_data)

    # Some global configuration; note that this could be moved into a
    # configuration file
    cherrypy.config.update({
        'tools.encode.on': True, 'tools.encode.encoding': 'utf-8',
        'tools.decode.on': True,
        'tools.trailing_slash.on': True,
        'tools.staticdir.root': os.path.abspath(os.path.dirname(__file__)),
    })

    cherrypy.quickstart(Root(data), '/', {
        '/media': {
            'tools.staticdir.on': True,
            'tools.staticdir.dir': 'static'
        }
    })

if __name__ == '__main__':
    import formencode
    formencode.api.set_stdtranslation(languages=['en'])
    main(sys.argv[1])