|
1 | | -# |
2 | | -# DB Forum - a buggy web forum server backed by a good database |
3 | | -# |
| 1 | +#!/usr/bin/env python3 |
| 2 | +# |
| 3 | +# A buggy web service in need of a database. |
4 | 4 |
|
5 | | -# The forumdb module is where the database interface code goes. |
6 | | -import forumdb |
| 5 | +import datetime |
| 6 | +from flask import Flask, request, redirect, url_for |
7 | 7 |
|
8 | | -# Other modules used to run a web server. |
9 | | -import cgi |
10 | | -from wsgiref.simple_server import make_server |
11 | | -from wsgiref import util |
| 8 | +from forumdb import get_posts, add_post |
| 9 | + |
| 10 | +app = Flask(__name__) |
12 | 11 |
|
13 | 12 | # HTML template for the forum page |
14 | 13 | HTML_WRAP = '''\ |
|
21 | 20 | textarea { width: 400px; height: 100px; } |
22 | 21 | div.post { border: 1px solid #999; |
23 | 22 | padding: 10px 10px; |
24 | | - margin: 10px 20%%; } |
| 23 | + margin: 10px 20%%; } |
25 | 24 | hr.postbound { width: 50%%; } |
26 | 25 | em.date { color: #999 } |
27 | 26 | </style> |
28 | 27 | </head> |
29 | 28 | <body> |
30 | 29 | <h1>DB Forum</h1> |
31 | | - <form method=post action="/post"> |
| 30 | + <form method=post> |
32 | 31 | <div><textarea id="content" name="content"></textarea></div> |
33 | 32 | <div><button id="go" type="submit">Post message</button></div> |
34 | 33 | </form> |
|
40 | 39 |
|
41 | 40 | # HTML template for an individual comment |
42 | 41 | POST = '''\ |
43 | | - <div class=post><em class=date>%(time)s</em><br>%(content)s</div> |
| 42 | + <div class=post><em class=date>%s</em><br>%s</div> |
44 | 43 | ''' |
45 | 44 |
|
46 | | -## Request handler for main page |
47 | | -def View(env, resp): |
48 | | - '''View is the 'main page' of the forum. |
49 | | -
|
50 | | - It displays the submission form and the previously posted messages. |
51 | | - ''' |
52 | | - # get posts from database |
53 | | - posts = forumdb.GetAllPosts() |
54 | | - # send results |
55 | | - headers = [('Content-type', 'text/html')] |
56 | | - resp('200 OK', headers) |
57 | | - return [HTML_WRAP % ''.join(POST % p for p in posts)] |
58 | 45 |
|
59 | | -## Request handler for posting - inserts to database |
60 | | -def Post(env, resp): |
61 | | - '''Post handles a submission of the forum's form. |
62 | | - |
63 | | - The message the user posted is saved in the database, then it sends a 302 |
64 | | - Redirect back to the main page so the user can see their new post. |
65 | | - ''' |
66 | | - # Get post content |
67 | | - input = env['wsgi.input'] |
68 | | - length = int(env.get('CONTENT_LENGTH', 0)) |
69 | | - # If length is zero, post is empty - don't save it. |
70 | | - if length > 0: |
71 | | - postdata = input.read(length) |
72 | | - fields = cgi.parse_qs(postdata) |
73 | | - content = fields['content'][0] |
74 | | - # If the post is just whitespace, don't save it. |
75 | | - content = content.strip() |
76 | | - if content: |
77 | | - # Save it in the database |
78 | | - forumdb.AddPost(content) |
79 | | - # 302 redirect back to the main page |
80 | | - headers = [('Location', '/'), |
81 | | - ('Content-type', 'text/plain')] |
82 | | - resp('302 REDIRECT', headers) |
83 | | - return ['Redirecting'] |
| 46 | +@app.route('/', methods=['GET']) |
| 47 | +def main(): |
| 48 | + '''Main page of the forum.''' |
| 49 | + posts = "".join(POST % (date, text) for text, date in get_posts()) |
| 50 | + html = HTML_WRAP % posts |
| 51 | + return html |
84 | 52 |
|
85 | | -## Dispatch table - maps URL prefixes to request handlers |
86 | | -DISPATCH = {'': View, |
87 | | - 'post': Post, |
88 | | - } |
89 | 53 |
|
90 | | -## Dispatcher forwards requests according to the DISPATCH table. |
91 | | -def Dispatcher(env, resp): |
92 | | - '''Send requests to handlers based on the first path component.''' |
93 | | - page = util.shift_path_info(env) |
94 | | - if page in DISPATCH: |
95 | | - return DISPATCH[page](env, resp) |
96 | | - else: |
97 | | - status = '404 Not Found' |
98 | | - headers = [('Content-type', 'text/plain')] |
99 | | - resp(status, headers) |
100 | | - return ['Not Found: ' + page] |
| 54 | +@app.route('/', methods=['POST']) |
| 55 | +def post(): |
| 56 | + '''New post submission.''' |
| 57 | + message = request.form['content'] |
| 58 | + add_post(message) |
| 59 | + return redirect(url_for('main')) |
101 | 60 |
|
102 | 61 |
|
103 | | -# Run this bad server only on localhost! |
104 | | -httpd = make_server('', 8000, Dispatcher) |
105 | | -print "Serving HTTP on port 8000..." |
106 | | -httpd.serve_forever() |
| 62 | +if __name__ == '__main__': |
| 63 | + app.run(host='0.0.0.0', port=8000) |
| 64 | + app.run(debug=True) |
107 | 65 |
|
0 commit comments