blob: 6b971132b9ae9c77f10829f11a9ecc60223ef5b6 [file] [log] [blame]
Guido van Rossumf66cccf2002-10-17 15:53:02 +00001"""Wiki main program. Imported and run by cgi3.py."""
2
Guido van Rossumc9776bd2002-10-17 16:26:45 +00003import os, re, cgi, sys, tempfile
Guido van Rossumf66cccf2002-10-17 15:53:02 +00004escape = cgi.escape
5
6def main():
7 form = cgi.FieldStorage()
Collin Winter6f2df4d2007-07-17 20:59:35 +00008 print("Content-type: text/html")
9 print()
Guido van Rossumf66cccf2002-10-17 15:53:02 +000010 cmd = form.getvalue("cmd", "view")
11 page = form.getvalue("page", "FrontPage")
12 wiki = WikiPage(page)
Guido van Rossumf66cccf2002-10-17 15:53:02 +000013 method = getattr(wiki, 'cmd_' + cmd, None) or wiki.cmd_view
14 method(form)
15
16class WikiPage:
17
Guido van Rossumc9776bd2002-10-17 16:26:45 +000018 homedir = tempfile.gettempdir()
Guido van Rossumf66cccf2002-10-17 15:53:02 +000019 scripturl = os.path.basename(sys.argv[0])
20
21 def __init__(self, name):
22 if not self.iswikiword(name):
Collin Winter6f2df4d2007-07-17 20:59:35 +000023 raise ValueError("page name is not a wiki word")
Guido van Rossumf66cccf2002-10-17 15:53:02 +000024 self.name = name
25 self.load()
26
27 def cmd_view(self, form):
Collin Winter6f2df4d2007-07-17 20:59:35 +000028 print("<h1>", escape(self.splitwikiword(self.name)), "</h1>")
29 print("<p>")
Guido van Rossumf66cccf2002-10-17 15:53:02 +000030 for line in self.data.splitlines():
31 line = line.rstrip()
32 if not line:
Collin Winter6f2df4d2007-07-17 20:59:35 +000033 print("<p>")
Guido van Rossum154c0882002-10-17 21:43:47 +000034 else:
Collin Winter6f2df4d2007-07-17 20:59:35 +000035 print(self.formatline(line))
36 print("<hr>")
37 print("<p>", self.mklink("edit", self.name, "Edit this page") + ";")
38 print(self.mklink("view", "FrontPage", "go to front page") + ".")
Guido van Rossumf66cccf2002-10-17 15:53:02 +000039
Guido van Rossum154c0882002-10-17 21:43:47 +000040 def formatline(self, line):
41 words = []
42 for word in re.split('(\W+)', line):
43 if self.iswikiword(word):
44 if os.path.isfile(self.mkfile(word)):
45 word = self.mklink("view", word, word)
46 else:
47 word = self.mklink("new", word, word + "*")
48 else:
49 word = escape(word)
50 words.append(word)
51 return "".join(words)
52
Guido van Rossumf66cccf2002-10-17 15:53:02 +000053 def cmd_edit(self, form, label="Change"):
Collin Winter6f2df4d2007-07-17 20:59:35 +000054 print("<h1>", label, self.name, "</h1>")
55 print('<form method="POST" action="%s">' % self.scripturl)
Guido van Rossumf66cccf2002-10-17 15:53:02 +000056 s = '<textarea cols="70" rows="20" name="text">%s</textarea>'
Collin Winter6f2df4d2007-07-17 20:59:35 +000057 print(s % self.data)
58 print('<input type="hidden" name="cmd" value="create">')
59 print('<input type="hidden" name="page" value="%s">' % self.name)
60 print('<br>')
61 print('<input type="submit" value="%s Page">' % label)
62 print("</form>")
Guido van Rossumf66cccf2002-10-17 15:53:02 +000063
64 def cmd_create(self, form):
65 self.data = form.getvalue("text", "").strip()
66 error = self.store()
67 if error:
Collin Winter6f2df4d2007-07-17 20:59:35 +000068 print("<h1>I'm sorry. That didn't work</h1>")
69 print("<p>An error occurred while attempting to write the file:")
70 print("<p>", escape(error))
Guido van Rossumf66cccf2002-10-17 15:53:02 +000071 else:
Guido van Rossum9c3848b2002-10-17 21:41:42 +000072 # Use a redirect directive, to avoid "reload page" problems
Collin Winter6f2df4d2007-07-17 20:59:35 +000073 print("<head>")
Guido van Rossum9c3848b2002-10-17 21:41:42 +000074 s = '<meta http-equiv="refresh" content="1; URL=%s">'
Collin Winter6f2df4d2007-07-17 20:59:35 +000075 print(s % (self.scripturl + "?cmd=view&page=" + self.name))
76 print("<head>")
77 print("<h1>OK</h1>")
78 print("<p>If nothing happens, please click here:", end=' ')
79 print(self.mklink("view", self.name, self.name))
Guido van Rossumf66cccf2002-10-17 15:53:02 +000080
81 def cmd_new(self, form):
Guido van Rossum9c3848b2002-10-17 21:41:42 +000082 self.cmd_edit(form, label="Create")
Guido van Rossumf66cccf2002-10-17 15:53:02 +000083
84 def iswikiword(self, word):
85 return re.match("[A-Z][a-z]+([A-Z][a-z]*)+", word)
86
87 def splitwikiword(self, word):
88 chars = []
89 for c in word:
90 if chars and c.isupper():
91 chars.append(' ')
92 chars.append(c)
93 return "".join(chars)
94
95 def mkfile(self, name=None):
96 if name is None:
97 name = self.name
98 return os.path.join(self.homedir, name + ".txt")
99
100 def mklink(self, cmd, page, text):
101 link = self.scripturl + "?cmd=" + cmd + "&page=" + page
102 return '<a href="%s">%s</a>' % (link, text)
103
104 def load(self):
105 try:
106 f = open(self.mkfile())
107 data = f.read().strip()
108 f.close()
109 except IOError:
110 data = ""
111 self.data = data
112
113 def store(self):
114 data = self.data
115 try:
116 f = open(self.mkfile(), "w")
117 f.write(data)
118 if data and not data.endswith('\n'):
119 f.write('\n')
120 f.close()
121 return ""
Guido van Rossumb940e112007-01-10 16:19:56 +0000122 except IOError as err:
Guido van Rossumf66cccf2002-10-17 15:53:02 +0000123 return "IOError: %s" % str(err)