summaryrefslogtreecommitdiffstats
path: root/Tools
diff options
context:
space:
mode:
Diffstat (limited to 'Tools')
-rw-r--r--Tools/faqwiz/faqmain.py218
1 files changed, 172 insertions, 46 deletions
diff --git a/Tools/faqwiz/faqmain.py b/Tools/faqwiz/faqmain.py
index 995cd3c..d1e6a55 100644
--- a/Tools/faqwiz/faqmain.py
+++ b/Tools/faqwiz/faqmain.py
@@ -21,15 +21,17 @@ class FAQServer:
else:
method()
- KEYS = ['req', 'query', 'name', 'text', 'commit', 'title']
+ KEYS = ['req', 'query', 'name', 'text', 'commit', 'title',
+ 'author', 'email', 'log']
def __getattr__(self, key):
if key not in self.KEYS:
raise AttributeError
- if self.form.has_key(key):
+ try:
item = self.form[key]
return item.value
- return ''
+ except KeyError:
+ return ''
def do_frontpage(self):
print """
@@ -38,8 +40,8 @@ class FAQServer:
<UL>
<LI><A HREF="faq.py?req=search">Search the FAQ</A>
<LI><A HREF="faq.py?req=browse">Browse the FAQ</A>
- <LI><A HREF="faq.py?req=submit">Submit a new FAQ entry</A>
- <LI><A HREF="faq.py?req=roulette">Random FAQ entry</A>
+ <LI><A HREF="faq.py?req=submit">Submit a new FAQ entry</A> (not yet)
+ <LI><A HREF="faq.py?req=roulette">FAQ roulette</A>
</UL>
<FORM ACTION="faq.py?req=query">
@@ -62,9 +64,9 @@ class FAQServer:
names.sort()
n = 0
for name in names:
- headers, body = self.read(name)
+ headers, text = self.read(name)
if headers:
- self.show(name, headers, body, 1)
+ self.show(name, headers['title'], text, 1)
n = n+1
if not n:
print "No FAQ entries?!?!"
@@ -82,9 +84,9 @@ class FAQServer:
names = os.listdir(os.curdir)
while names:
name = whrandom.choice(names)
- headers, body = self.read(name)
+ headers, text = self.read(name)
if headers:
- self.show(name, headers, body, 1)
+ self.show(name, headers['title'], text, 1)
print '<P><A HREF="faq.py?req=roulette">Show another one</A>'
break
else:
@@ -118,18 +120,18 @@ class FAQServer:
print "<HR>"
n = 0
for name in names:
- headers, body = self.read(name)
+ headers, text = self.read(name)
if headers:
title = headers['title']
- if p.search(title) >= 0 or p.search(body) >= 0:
- self.show(name, headers, body, 1)
+ if p.search(title) >= 0 or p.search(text) >= 0:
+ self.show(name, title, text, 1)
n = n+1
if not n:
print "No hits."
def do_edit(self):
name = self.name
- headers, body = self.read(name)
+ headers, text = self.read(name)
if not headers:
print "Invalid file name", name
return
@@ -137,32 +139,26 @@ class FAQServer:
<TITLE>Python FAQ Edit Form</TITLE>
<H1>Python FAQ Edit Form</H1>
"""
- self.showheaders(headers)
title = headers['title']
+ print "<FORM METHOD=POST ACTION=faq.py>"
+ self.showedit(name, headers, text)
print """
- <FORM METHOD=POST ACTION=faq.py>
- <INPUT TYPE=text SIZE=80 NAME=title VALUE="%s"<BR>
- <TEXTAREA COLS=80 ROWS=20 NAME=text>""" % title
- print cgi.escape(string.strip(body))
- print """</TEXTAREA>
- <BR>
<INPUT TYPE=submit VALUE="Review Edit">
<INPUT TYPE=hidden NAME=req VALUE=review>
<INPUT TYPE=hidden NAME=name VALUE=%s>
</FORM>
<HR>
""" % name
- self.show(name, headers, body)
+ self.show(name, title, text)
def do_review(self):
+ if self.commit:
+ self.checkin()
+ return
name = self.name
text = self.text
- commit = self.commit
title = self.title
- if commit:
- self.precheckin(name, text, title)
- return
- headers, body = self.read(name)
+ headers, oldtext = self.read(name)
if not headers:
print "Invalid file name", name
return
@@ -170,19 +166,26 @@ class FAQServer:
<TITLE>Python FAQ Review Form</TITLE>
<H1>Python FAQ Review Form</H1>
"""
- self.show(name, {'title': title}, text)
- print """
- <FORM METHOD=POST ACTION=faq.py>
- <INPUT TYPE=submit NAME=commit VALUE="Commit">
- <P>
- <HR>
- """
- self.showheaders(headers)
+ self.show(name, title, text)
+ print "<FORM METHOD=POST ACTION=faq.py>"
+ if self.log and self.author and '@' in self.email:
+ print """
+ <INPUT TYPE=submit NAME=commit VALUE="Commit">
+ Click this button to commit the change.
+ <P>
+ <HR>
+ <P>
+ """
+ else:
+ print """
+ To commit this change, please enter your name,
+ email and a log message in the form below.
+ <P>
+ <HR>
+ <P>
+ """
+ self.showedit(name, headers, text)
print """
- <INPUT TYPE=text SIZE=80 NAME=title VALUE="%s"<BR>
- <TEXTAREA COLS=80 ROWS=20 NAME=text>""" % title
- print cgi.escape(string.strip(text))
- print """</TEXTAREA>
<BR>
<INPUT TYPE=submit VALUE="Review Edit">
<INPUT TYPE=hidden NAME=req VALUE=review>
@@ -191,8 +194,126 @@ class FAQServer:
<HR>
""" % name
- def precheckin(self, name, text, title):
- pass
+ def checkin(self):
+ import regsub, time, tempfile
+ name = self.name
+
+ headers, oldtext = self.read(name)
+ if not headers:
+ print "Invalid file name", name
+ return
+ text = self.text
+ title = self.title
+ author = self.author
+ email = self.email
+ log = self.log
+ text = regsub.gsub("\r\n", "\n", text)
+ log = regsub.gsub("\r\n", "\n", log)
+ author = string.join(string.split(author))
+ email = string.join(string.split(email))
+ title = string.join(string.split(title))
+ oldtitle = headers['title']
+ oldtitle = string.join(string.split(oldtitle))
+ text = string.strip(text)
+ oldtext = string.strip(oldtext)
+ if text == oldtext and title == oldtitle:
+ print "No changes."
+ # XXX Should exit more ceremoniously
+ return
+ # Check that the question number didn't change
+ if string.split(title)[:1] != string.split(oldtitle)[:1]:
+ print "Don't change the question number please."
+ # XXX Should exit more ceremoniously
+ return
+ remhost = os.environ["REMOTE_HOST"]
+ remaddr = os.environ["REMOTE_ADDR"]
+ try:
+ os.unlink(name + "~")
+ except os.error:
+ pass
+ try:
+ os.rename(name, name + "~")
+ except os.error:
+ pass
+ try:
+ os.unlink(name)
+ except os.error:
+ pass
+ try:
+ f = open(name, "w")
+ except IOError, msg:
+ print "Can't open", name, "for writing:", cgi.escape(str(msg))
+ # XXX Should exit more ceremoniously
+ return
+ now = time.ctime(time.time())
+ f.write("Title: %s\n" % title)
+ f.write("Last-Changed-Date: %s\n" % now)
+ f.write("Last-Changed-Author: %s\n" % author)
+ f.write("Last-Changed-Email: %s\n" % email)
+ f.write("Last-Changed-Remote-Host: %s\n" % remhost)
+ f.write("Last-Changed-Remote-Address: %s\n" % remaddr)
+ keys = headers.keys()
+ keys.sort()
+ keys.remove('title')
+ for key in keys:
+ if key[:13] != 'last-changed-':
+ f.write("%s: %s\n" % (string.capwords(key, '-'),
+ headers[key]))
+ f.write("\n")
+ f.write(text)
+ f.write("\n")
+ f.close()
+
+ tfn = tempfile.mktemp()
+ f = open(tfn, "w")
+ f.write("Last-Changed-Date: %s\n" % now)
+ f.write("Last-Changed-Author: %s\n" % author)
+ f.write("Last-Changed-Email: %s\n" % email)
+ f.write("Last-Changed-Remote-Host: %s\n" % remhost)
+ f.write("Last-Changed-Remote-Address: %s\n" % remaddr)
+ f.write("\n")
+ f.write(log)
+ f.write("\n")
+ f.close()
+
+ p = os.popen("""
+ /depot/gnu/plat/bin/rcs -l %s </dev/null 2>&1
+ /depot/gnu/plat/bin/ci -u %s <%s 2>&1
+ rm -f %s
+ """ % (name, name, tfn, tfn))
+ output = p.read()
+ sts = p.close()
+ if not sts:
+ print """
+ <H1>Python FAQ Entry Edited</H1>
+ <HR>
+ """
+ self.show(name, title, text, 1)
+ if output:
+ print "<PRE>%s</PRE>" % cgi.escape(output)
+ else:
+ print """
+ <H1>Python FAQ Entry Commit Failed</H1>
+ Exit status 0x%04x
+ """ % sts
+ if output:
+ print "<PRE>%s</PRE>" % cgi.escape(output)
+
+ def showedit(self, name, headers, text):
+ title = headers['title']
+ print """
+ Title: <INPUT TYPE=text SIZE=70 NAME=title VALUE="%s"<BR>
+ <TEXTAREA COLS=80 ROWS=20 NAME=text>""" % title
+ print cgi.escape(string.strip(text))
+ print """</TEXTAREA>
+ <BR>
+ Please provide the following information for logging purposes:
+ <BR>
+ <CODE>Name : </CODE><INPUT TYPE=text SIZE=70 NAME=author VALUE="%s"<BR>
+ <CODE>Email: </CODE><INPUT TYPE=text SIZE=70 NAME=email VALUE="%s"<BR>
+ Log message (reason for the change):<BR>
+ <TEXTAREA COLS=80 ROWS=5 NAME=log>\n%s\n</TEXTAREA>
+ """ % (self.author, self.email, self.log)
def showheaders(self, headers):
print "<UL>"
@@ -209,17 +330,16 @@ class FAQServer:
return None, None
f = open(name)
headers = rfc822.Message(f)
- body = f.read()
+ text = f.read()
f.close()
- return headers, body
+ return headers, text
- def show(self, name, headers, body, edit=0):
+ def show(self, name, title, text, edit=0):
# XXX Should put <A> tags around recognizable URLs
# XXX Should also turn "see section N" into hyperlinks
- title = headers['title']
print "<H2>%s</H2>" % title
pre = 0
- for line in string.split(body, '\n'):
+ for line in string.split(text, '\n'):
if not string.strip(line):
if pre:
print '</PRE>'
@@ -227,7 +347,7 @@ class FAQServer:
else:
print '<P>'
else:
- if line == string.lstrip(line):
+ if line == string.lstrip(line): # I.e., no leading whitespace
if pre:
print '</PRE>'
pre = 0
@@ -247,9 +367,15 @@ class FAQServer:
print "Content-type: text/html\n"
+dt = 0
try:
+ import time
+ t1 = time.time()
x = FAQServer()
x.main()
+ t2 = time.time()
+ dt = t2-t1
except:
print "<HR>Sorry, an error occurred"
cgi.print_exception()
+print "<!-- dt = %s -->" % str(round(dt, 3))