Skip to content

Commit 5af9d19

Browse files
author
Mike Wales
committed
Initial commit.
0 parents  commit 5af9d19

File tree

14 files changed

+398
-0
lines changed

14 files changed

+398
-0
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
rdb-fullstack
2+
=============
3+
4+
Common code for the Relational Databases and Full Stack Fundamentals courses
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1.5:a5703ba0-4f2b-48a2-a9cd-df7f9f6351bc
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1417389922
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
a5703ba0-4f2b-48a2-a9cd-df7f9f6351bc
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0ec7f8cc1f8c4b4288739a3eba765013
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"virtualbox":{"/vagrant":{"guestpath":"/vagrant","hostpath":"/Users/karl/rdb-fullstack/vagrant","disabled":false}}}

vagrant/Vagrantfile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# -*- mode: ruby -*-
2+
# vi: set ft=ruby :
3+
4+
VAGRANTFILE_API_VERSION = "2"
5+
6+
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
7+
config.vm.provision "shell", path: "pg_config.sh"
8+
# config.vm.box = "hashicorp/precise32"
9+
config.vm.box = "ubuntu/trusty32"
10+
config.vm.network "forwarded_port", guest: 8000, host: 8000
11+
end

vagrant/forum/forum.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#
2+
# DB Forum - a buggy web forum server backed by a good database
3+
#
4+
5+
# The forumdb module is where the database interface code goes.
6+
import forumdb
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
12+
13+
# HTML template for the forum page
14+
HTML_WRAP = '''\
15+
<!DOCTYPE html>
16+
<html>
17+
<head>
18+
<title>DB Forum</title>
19+
<style>
20+
h1, form { text-align: center; }
21+
textarea { width: 400px; height: 100px; }
22+
div.post { border: 1px solid #999;
23+
padding: 10px 10px;
24+
margin: 10px 20%%; }
25+
hr.postbound { width: 50%%; }
26+
em.date { color: #999 }
27+
</style>
28+
</head>
29+
<body>
30+
<h1>DB Forum</h1>
31+
<form method=post action="/post">
32+
<div><textarea id="content" name="content"></textarea></div>
33+
<div><button id="go" type="submit">Post message</button></div>
34+
</form>
35+
<!-- post content will go here -->
36+
%s
37+
</body>
38+
</html>
39+
'''
40+
41+
# HTML template for an individual comment
42+
POST = '''\
43+
<div class=post><em class=date>%(time)s</em><br>%(content)s</div>
44+
'''
45+
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+
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']
84+
85+
## Dispatch table - maps URL prefixes to request handlers
86+
DISPATCH = {'': View,
87+
'post': Post,
88+
}
89+
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]
101+
102+
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()
107+

vagrant/forum/forum.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
CREATE TABLE posts ( content TEXT,
3+
time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
4+
id SERIAL );
5+

vagrant/forum/forumdb.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#
2+
# Database access functions for the web forum.
3+
#
4+
5+
import time
6+
7+
## Database connection
8+
DB = []
9+
10+
## Get posts from database.
11+
def GetAllPosts():
12+
'''Get all the posts from the database, sorted with the newest first.
13+
14+
Returns:
15+
A list of dictionaries, where each dictionary has a 'content' key
16+
pointing to the post content, and 'time' key pointing to the time
17+
it was posted.
18+
'''
19+
posts = [{'content': str(row[1]), 'time': str(row[0])} for row in DB]
20+
posts.sort(key=lambda row: row['time'], reverse=True)
21+
return posts
22+
23+
## Add a post to the database.
24+
def AddPost(content):
25+
'''Add a new post to the database.
26+
27+
Args:
28+
content: The text content of the new post.
29+
'''
30+
t = time.strftime('%c', time.localtime())
31+
DB.append((t, content))

0 commit comments

Comments
 (0)