More refactoring. This time post.cgi.
[bloggy.git] / common.py
blob69960f0a022658d021efbc1aeb22693e7dae488c
1 # Copyright (c) 2008, 2009, Simon Morgan <sjm@spamcop.net>
3 # Permission to use, copy, modify, and/or distribute this software for any
4 # purpose with or without fee is hereby granted, provided that the above
5 # copyright notice and this permission notice appear in all copies.
7 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 import sqlite3
16 import sys
17 import time
19 import config
21 import markdown2
23 # Database interactions.
25 def connect():
26 try:
27 conn = sqlite3.connect(config.DBPATH)
28 conn.execute("CREATE TABLE IF NOT EXISTS entries (id INTEGER \
29 PRIMARY KEY, date INTEGER, title TEXT, text TEXT)")
30 except sqlite3.OperationalError:
31 print_error("Failed to connect to database. Check file and \
32 directory permissions.")
33 sys.exit(1)
34 return conn
36 def addpost(conn, title, body):
37 curtime = int(time.time())
38 # Convert hours to seconds.
39 curtime = curtime + (config.TOFFSET * 60 * 60)
40 conn.execute("INSERT INTO entries VALUES (NULL, ?, ?, ?)",
41 (curtime, title, body))
43 def getnumposts(conn, postid=None):
44 """Enumerate the number of posts in the database.
46 If an ID is specified then enumerate the number of posts with that
47 ID. The result of the latter should be 0 or 1 as essentially this is
48 a check for whether the specified post exists.
49 """
50 if postid:
51 numposts = conn.execute("SELECT count(id) FROM entries WHERE id = ?",
52 (postid,)).fetchone()
53 else:
54 numposts = conn.execute("SELECT count(id) FROM entries").fetchone()
55 return int(numposts[0])
57 def getposts(conn, offset=0, numposts=0):
58 """Return a list of numposts posts beginning at offset.
60 SQLite doesn't seem to support the use of OFFSET without LIMIT so
61 whenever numposts is ommited, we return every post.
62 """
63 posts = []
64 if numposts == 0:
65 for row in conn.execute("SELECT * FROM entries ORDER BY date DESC"):
66 posts.append(row)
67 else:
68 for row in conn.execute("SELECT * FROM entries ORDER BY date DESC LIMIT ? OFFSET ?",
69 (numposts, offset)):
70 posts.append(row)
71 return posts
73 def getpost(conn, postid):
74 row = conn.execute("SELECT * FROM entries WHERE id = ?",
75 (postid,)).fetchone()
76 # No need to return the ID as it's one of the parameters.
77 return row[1:]
79 def updatepost(conn, postid, title, body):
80 conn.execute("UPDATE entries SET title = ?, text = ? WHERE id = ?",
81 (title, body, postid))
83 def deletepost(conn, postid):
84 conn.execute("DELETE FROM entries WHERE id = ?", (postid,))
86 # Output formatting.
88 def print_headers(title):
89 print '<head>'
90 print '<title>' + title + '</title>'
91 print '<link href="default.css" rel="stylesheet" type="text/css">'
92 print '</head>'
94 def print_class(msg, class_):
95 print '<div class="%s">%s</div>' % (class_, msg)
97 def print_id(msg, id_):
98 print '<div id="%s">%s</div>' % (id_, msg)
100 def print_error(msg):
101 print_class(msg, "error")
103 def print_msg(msg):
104 print_class(msg, "message")
106 def print_post(title, body, date=None):
107 """Formats and prints a post"""
108 print '<div class="blogpost">'
109 print '<h1>%s</h1>' % title
110 if date:
111 print '<h3>%s</h3>' % time.ctime(date)
112 print markdown2.markdown(body)
113 print '</div>'
115 def header():
116 print_id(config.HEADER, "header")
118 def footer():
119 print_id(config.FOOTER, "footer")