Kaydet (Commit) f8f0fb70 authored tarafından Guido van Rossum's avatar Guido van Rossum

Added last mtime on whole faq.

Added more elaborate explanation of version conflict.
Set fake header on commit so show() shows the new mtime.
Reorder name/email fields to be after the log message.
üst 1d579810
...@@ -8,32 +8,42 @@ XXX TO DO ...@@ -8,32 +8,42 @@ XXX TO DO
XXX User Features TO DO XXX User Features TO DO
- next/prev/index links in do_show? - next/prev/index links in do_show???
- explanation of editing somewhere - explanation of editing somewhere
- embellishments, GIFs, crosslinks, hints, etc. - embellishments, GIFs, hints, etc.
- make references to other Q's and whole sections into links
- support adding annotations, too - support adding annotations, too
- restrict recent changes to last week (or make it an option)
- extended search capabilities
XXX Management Features TO DO XXX Management Features TO DO
- username/password for authors
- create new sections - create new sections
- rearrange entries - rearrange entries
- delete entries - delete entries
- freeze entries
- send email on changes? - send email on changes?
- send email on ERRORS! - send email on ERRORS!
- optional staging of entries until reviewed? - optional staging of entries until reviewed?
- freeze entries (could be done using rcs branches!)
- username/password for authors - prevent race conditions on nearly simultaneous commits
- read section titles from a file (could be a Python file: import faqcustom)
XXX Performance
- could cache generated HTML
- could speed up searches with a separate index file
XXX Code organization TO DO XXX Code organization TO DO
- read section titles from a file (could be a Python file: import faqcustom)
- customize rcs command pathnames (and everything else) - customize rcs command pathnames (and everything else)
- make it more generic (so you can create your own FAQ) - make it more generic (so you can create your own FAQ)
- more OO structure, e.g. add a class representing one FAQ entry - more OO structure, e.g. add a class representing one FAQ entry
""" """
# NB for timing purposes, the imports are at the end of this file
NAMEPAT = "faq??.???.htp" NAMEPAT = "faq??.???.htp"
NAMEREG = "^faq\([0-9][0-9]\)\.\([0-9][0-9][0-9]\)\.htp$" NAMEREG = "^faq\([0-9][0-9]\)\.\([0-9][0-9][0-9]\)\.htp$"
...@@ -160,11 +170,24 @@ class FAQServer: ...@@ -160,11 +170,24 @@ class FAQServer:
self.show(name, headers['title'], text) self.show(name, headers['title'], text)
def do_all(self): def do_all(self):
import fnmatch, stat
self.prologue("The Whole Python FAQ") self.prologue("The Whole Python FAQ")
print "<HR>"
names = os.listdir(os.curdir) names = os.listdir(os.curdir)
lastmtime = 0
for name in names:
if not fnmatch.fnmatch(name, NAMEPAT):
continue
try:
st = os.stat(name)
except os.error:
continue
lastmtime = max(lastmtime, st[stat.ST_MTIME])
if lastmtime:
print time.strftime("Last changed on %c %Z",
time.localtime(lastmtime))
names.sort() names.sort()
section = None section = None
print "<HR>"
for name in names: for name in names:
headers, text = self.read(name) headers, text = self.read(name)
if headers: if headers:
...@@ -419,10 +442,23 @@ class FAQServer: ...@@ -419,10 +442,23 @@ class FAQServer:
version = self.version version = self.version
curversion = self.getversion(name) curversion = self.getversion(name)
if version != curversion: if version != curversion:
self.error("Version conflict.", self.error(
"You edited version %s but current version is %s." % ( "Version conflict.",
version, curversion), "You edited version %s but current version is %s." % (
'<A HREF="faq.py?req=show&name=%s">Reload.</A>' % name) version, curversion),
"""
<P>
The two most common causes of this problem are:
<UL>
<LI>After committing a change, you went back in your browser,
edited the entry some more, and clicked Commit again.
<LI>Someone else started editing the same entry and committed
before you did.
</UL>
<P>
""",
'<A HREF="faq.py?req=show&name=%s"' % name,
'>Click here to reload the entry and try again.</A>')
return return
text = self.text text = self.text
title = self.title title = self.title
...@@ -494,6 +530,16 @@ class FAQServer: ...@@ -494,6 +530,16 @@ class FAQServer:
f.write(log) f.write(log)
f.write("\n") f.write("\n")
f.close() f.close()
# Do this for show() below
self.headers = {
'title': title,
'last-changed-date': now,
'last-changed-author': author,
'last-changed-email': email,
'last-changed-remote-host': remhost,
'last-changed-remote-address': remaddr,
}
p = os.popen(""" p = os.popen("""
/depot/gnu/plat/bin/rcs -l %s </dev/null 2>&1 /depot/gnu/plat/bin/rcs -l %s </dev/null 2>&1
...@@ -514,8 +560,6 @@ class FAQServer: ...@@ -514,8 +560,6 @@ class FAQServer:
"Exit status 0x%04x" % sts) "Exit status 0x%04x" % sts)
if output: if output:
print "<PRE>%s</PRE>" % cgi.escape(output) print "<PRE>%s</PRE>" % cgi.escape(output)
print '<HR>'
print '<A HREF="faq.py?req=show&name=%s">Reload this entry.</A>' % name
def set_cookie(self, author, email): def set_cookie(self, author, email):
name = "Python-FAQ-ID" name = "Python-FAQ-ID"
...@@ -558,19 +602,19 @@ class FAQServer: ...@@ -558,19 +602,19 @@ class FAQServer:
email = email or e email = email or e
print """ print """
Title: <INPUT TYPE=text SIZE=70 NAME=title VALUE="%s"><BR> Title: <INPUT TYPE=text SIZE=70 NAME=title VALUE="%s"><BR>
<TEXTAREA COLS=80 ROWS=20 NAME=text>""" % self.escape(title) <TEXTAREA COLS=80 ROWS=20 NAME=text>%s</TEXTAREA>
print cgi.escape(string.strip(text)) """ % (self.escape(title), cgi.escape(string.strip(text)))
print """</TEXTAREA> print """
<BR>
Log message (reason for the change):<BR>
<TEXTAREA COLS=80 ROWS=5 NAME=log>%s\n</TEXTAREA>
<BR> <BR>
Please provide the following information for logging purposes: Please provide the following information for logging purposes:
<BR> <BR>
<CODE>Name : </CODE><INPUT TYPE=text SIZE=40 NAME=author VALUE="%s"> <CODE>Name : </CODE><INPUT TYPE=text SIZE=40 NAME=author VALUE="%s">
<BR> <BR>
<CODE>Email: </CODE><INPUT TYPE=text SIZE=40 NAME=email VALUE="%s"> <CODE>Email: </CODE><INPUT TYPE=text SIZE=40 NAME=email VALUE="%s">
<BR> """ % (self.escape(self.log), self.escape(author), self.escape(email))
Log message (reason for the change):<BR>
<TEXTAREA COLS=80 ROWS=5 NAME=log>%s\n</TEXTAREA>
""" % (self.escape(author), self.escape(email), self.escape(self.log))
def escape(self, s): def escape(self, s):
import regsub import regsub
...@@ -619,8 +663,6 @@ class FAQServer: ...@@ -619,8 +663,6 @@ class FAQServer:
return headers, text return headers, text
def show(self, name, title, text, edit=1): def show(self, name, title, text, edit=1):
# XXX Should put <A> tags around recognizable URLs
# XXX Should also turn "see section N" into hyperlinks
print "<H2>%s</H2>" % cgi.escape(title) print "<H2>%s</H2>" % cgi.escape(title)
pre = 0 pre = 0
for line in string.split(text, '\n'): for line in string.split(text, '\n'):
...@@ -765,7 +807,7 @@ class FAQServer: ...@@ -765,7 +807,7 @@ class FAQServer:
print "Content-type: text/html" print "Content-type: text/html"
dt = 0 dt = 0
wanttime = 1 wanttime = 0
try: try:
import time import time
t1 = time.time() t1 = time.time()
...@@ -774,6 +816,7 @@ try: ...@@ -774,6 +816,7 @@ try:
x.main() x.main()
t2 = time.time() t2 = time.time()
dt = t2-t1 dt = t2-t1
wanttime = 1
except: except:
print "\n<HR>Sorry, an error occurred" print "\n<HR>Sorry, an error occurred"
cgi.print_exception() cgi.print_exception()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment