Edgewall Software

source: trunk/svntrac/Wiki.py@ 1

Last change on this file since 1 was 1, checked in by Jonas Borgström, 20 years ago

Initial import

File size: 9.4 KB
Line 
1# svntrac
2#
3# Copyright (C) 2003 Xyche Software
4#
5# svntrac is free software; you can redistribute it and/or
6# modify it under the terms of the GNU General Public License as
7# published by the Free Software Foundation; either version 2 of the
8# License, or (at your option) any later version.
9#
10# svntrac is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18#
19# Author: Jonas Borgström <jonas@xyche.com>
20
21import re
22import time
23import os
24import StringIO
25import auth
26import perm
27from Module import Module
28from db import get_connection
29from util import *
30from xml.sax.saxutils import quoteattr, escape
31
32
33h1_re = re.compile ('!!!(.*)!!!')
34h2_re = re.compile ('!!(.*)!!')
35h3_re = re.compile ('!(.*)!')
36url_re = re.compile ('((((new|(ht|f)tp)s?://))([a-z0-9_-]+:[a-z0-9_-]+\@)?([a-z0-9]+(\-*[a-z0-9]+)*\.)+[a-z]{2,7}(/~?[a-z0-9_\.%\-]+)?(/[a-z0-9_\.%\-]+)*(/?[a-z0-9_\%\-]+(\.[a-z0-9]+)?(\#[a-zA-Z0-9_\.]+)?)(\?([a-z0-9_\.\%\-]+)\=[a-z0-9_\.\%\/\-]*)?(&([a-z0-9_\.\%\-]+)\=[a-z0-9_\.\%\/\-]*)?(#[a-z0-9]+)?)')
37oldstylelink_re = re.compile ('([[A-Z][a-z]*(?:[A-Z][a-z]+)+)')
38newstylelink_re = re.compile ('\[([^]*])\]')
39list_re = re.compile ('^(([\*#])\\2*) (.*)$')
40newline_re = re.compile ('(%%%)')
41strong_re = re.compile ('\__([^ ]+)\__')
42emph_re = re.compile ("''([^ ]+)''")
43empty_line_re = re.compile ("^[ ]*$")
44indented_re = re.compile ("^[ ]")
45
46def format_wiki (text, out):
47 """
48 some basic wiki style text formatting
49 """
50 def set_list_depth (stack, type, depth):
51 listdepth = len(stack)
52 diff = depth - listdepth
53 if diff > 0:
54 for i in range (diff):
55 out.write ('<%s>' % type)
56 stack.append('</%s>' % type)
57 elif diff < 0:
58 for i in range (-diff):
59 out.write (stack.pop())
60 if depth > 0 and stack[0][2:4] != type:
61 out.write (stack.pop())
62 out.write ('<%s>' % type)
63 stack.append('</%s>' % type)
64
65 def handle_links (line):
66 line = oldstylelink_re.sub('<a href="?mode=wiki&page=\\1">\\1</a>', line)
67 line = url_re.sub('<a href="\\1">\\1</a>', line)
68 return line
69
70 newp = 1
71 inverb = 0
72 liststack = []
73
74 for line in text.splitlines():
75 line = escape(line)
76 if empty_line_re.match(line):
77 if not newp:
78 newp = 1
79 set_list_depth (liststack, None, 0)
80 if inverb:
81 inverb = 0
82 out.write ('</pre>\n')
83 out.write ('<p>\n')
84 continue
85 if newp and indented_re.match(line):
86 out.write('<pre>\n')
87 inverb = 1
88 newp = 0
89
90 match = list_re.match(line)
91 if match:
92 depth = len(match.group(1))
93 if match.group(2) == '#':
94 type = 'ol'
95 else:
96 type = 'ul'
97 set_list_depth(liststack, type, depth)
98 line = list_re.sub('<li>\\3', line)
99
100 line = newline_re.sub('<br>', line)
101 line = handle_links(line)
102 line = h1_re.sub('<h1>\\1</h1>', line)
103 line = h2_re.sub('<h2>\\1</h2>', line)
104 line = h3_re.sub('<h3>\\1</h3>', line)
105 line = strong_re.sub('<strong>\\1</strong>', line)
106 line = emph_re.sub('<em>\\1</em>', line)
107 out.write(line + '\n')
108 if inverb:
109 out.write ('</pre>\n')
110
111
112class Page:
113 def __init__(self, name, version):
114
115 self.name = name
116 cnx = get_connection ()
117 cursor = cnx.cursor ()
118 if version:
119 cursor.execute ('SELECT version, text FROM wiki '
120 'WHERE name=%s AND version=%s',
121 name, version)
122 else:
123 cursor.execute ('SELECT version, text FROM wiki '
124 'WHERE name=%s ORDER BY version DESC LIMIT 1', name)
125 row = cursor.fetchone()
126 if row:
127 self.new = 0
128 self.version = int(row[0])
129 self.text = row[1]
130 else:
131 self.version = 0
132 self.text = 'describe %s here' % name
133 self.new = 1
134
135 def set_content (self, text):
136 self.text = text
137 self.version = self.version + 1
138
139 def commit (self):
140 if self.new:
141 perm.assert_permission (perm.WIKI_CREATE)
142 else:
143 perm.assert_permission (perm.WIKI_MODIFY)
144 cnx = get_connection ()
145 cursor = cnx.cursor ()
146 cursor.execute ('SELECT MAX(version)+1 FROM '
147 '(SELECT version FROM wiki WHERE name=%s '
148 'UNION ALL SELECT 0 as version)', self.name)
149 row = cursor.fetchone()
150 new_version = int(row[0])
151
152 cursor.execute ('INSERT INTO WIKI '
153 '(name, version, time, author, ipnr, locked, text) '
154 'VALUES (%s, %s, %s, %s, %s, %s, %s)',
155 self.name, new_version, int(time.time()),
156 auth.get_authname(), os.getenv('REMOTE_ADDR'),
157 0, self.text)
158 cnx.commit ()
159
160 def render_edit(self, out):
161 perm.assert_permission (perm.WIKI_MODIFY)
162 out.write ('<h3>source</h3>')
163 out.write ('<form action="svntrac.cgi" method="POST">')
164 out.write ('<input type="hidden" name="page" value="%s">' % self.name)
165 out.write ('<input type="hidden" name="mode" value="wiki">')
166 out.write ('<textarea name="text" rows="15" cols="80">')
167 out.write(escape(self.text))
168 out.write ('</textarea><p>')
169 out.write ('<input type="submit" name="action" value="preview">&nbsp;')
170 out.write ('<input type="submit" name="action" value="commit">')
171 out.write ('</form>')
172
173 def render_view(self, out, edit_button=1):
174 self.render_history(out)
175 perm.assert_permission (perm.WIKI_VIEW)
176 out.write ('<div class="wikipage">')
177 format_wiki(self.text, out)
178 out.write ('</div>')
179 if edit_button and perm.has_permission (perm.WIKI_MODIFY):
180 out.write ('<form action="svntrac.cgi" method="POST">')
181 out.write ('<input type="hidden" name="mode" value="wiki">')
182 out.write ('<input type="hidden" name="page" value="%s">' % self.name)
183 out.write ('<input type="submit" name="action" value=" edit ">')
184 out.write ('</form>')
185
186 def render_preview (self, out):
187 perm.assert_permission (perm.WIKI_MODIFY)
188
189 out.write ('<h3>preview</h3>')
190 self.render_view (out, edit_button=0)
191 self.render_edit (out)
192
193 def render_history (self, out):
194 cnx = get_connection ()
195 cursor = cnx.cursor ()
196
197 cursor.execute ('SELECT version, time, author, ipnr FROM wiki '
198 'WHERE name=%s ORDER BY version DESC', self.name)
199
200 out.write ('<div align="right">'
201 '<a href=\"javascript:view_history()\">show/hide history</a>'
202 '</div>')
203 out.write ('<table class="wiki-history" id="history">')
204 out.write ('<tr class="wiki-history-header"><th>version</th>'
205 '<th>time</th><th>author</th><th>ipnr</th></tr>')
206 while 1:
207 row = cursor.fetchone()
208 if row == None:
209 break
210 # for row in cursor:
211 t = int(row[1])
212 if t:
213 time_str = time.strftime('%F', time.localtime(t))
214 else:
215 time_str = ''
216 out.write ('<tr><td><a href="%s">%s</a></td><td>%s</td>'
217 '<td>%s</td><td>%s</td></tr>'
218 % (wiki_href(self.name, row[0]), row[0], time_str,
219 row[2], row[3]))
220 out.write ('</table>')
221
222class Wiki (Module):
223 template_key = 'wiki_template'
224
225 def render(self):
226 if self.args.has_key('page'):
227 name = self.args['page']
228 else:
229 name = 'WikiStart'
230 if self.args.has_key('version'):
231 version = self.args['version']
232 else:
233 version = 0
234
235 if self.args.has_key('action'):
236 action = self.args['action']
237 else:
238 action = 'view'
239
240 page = Page(name, version)
241
242 if self.args.has_key('text'):
243 page.set_content (self.args['text'])
244
245 out = StringIO.StringIO()
246 if action == 'commit':
247 page.commit ()
248 redirect (wiki_href (page.name))
249 elif action == ' edit ':
250 out.write ('<h2>edit <a href="%s">%s</a></h2>' %
251 (wiki_href(page.name), page.name))
252 page.render_edit (out)
253 self.namespace['title'] = 'wiki - edit'
254 elif action == 'preview':
255 out.write ('<h2>edit <a href="%s">%s</a></h2>' %
256 (wiki_href(page.name), page.name))
257 page.render_preview (out)
258 self.namespace['title'] = 'wiki - preview'
259 else:
260 out.write ('<h2><a href="%s">%s</a></h2>' %
261 (wiki_href(page.name), page.name))
262 page.render_view (out)
263 self.namespace['title'] = 'wiki - view'
264 self.namespace['content'] = out.getvalue()
265
Note: See TracBrowser for help on using the repository browser.