mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	Mostly small changes.
- Fixed broken HTML in edit form that swallowed <BR> tags - Removed "another one" link in roulette, replaced with "use Reload" message - show() now has edit=1 by default; changed all calls - Display last-changed date, author, email when present and edit=1 - Added back pointers at bottom - Added a copy of the bootstrap script at the end of the file
This commit is contained in:
		
							parent
							
								
									b9f866cb7c
								
							
						
					
					
						commit
						ed531fd9df
					
				
					 1 changed files with 56 additions and 20 deletions
				
			
		|  | @ -1,7 +1,9 @@ | ||||||
| #! /depot/sundry/plat/bin/python1.4 |  | ||||||
| 
 |  | ||||||
| """Interactive FAQ project. | """Interactive FAQ project. | ||||||
| 
 | 
 | ||||||
|  | Note that this is not an executable script; it's an importable module. | ||||||
|  | The actual CGI script can be kept minimal; it's appended at the end of | ||||||
|  | this file as a string constant. | ||||||
|  | 
 | ||||||
| XXX TO DO | XXX TO DO | ||||||
| 
 | 
 | ||||||
| - generic error handler | - generic error handler | ||||||
|  | @ -22,6 +24,7 @@ | ||||||
| - Browse should display menu of 7 sections & let you pick | - Browse should display menu of 7 sections & let you pick | ||||||
|   (or frontpage should have the option to browse a section or all) |   (or frontpage should have the option to browse a section or all) | ||||||
| - support adding annotations, too | - support adding annotations, too | ||||||
|  | - make it more generic (so you can create your own FAQ) | ||||||
| 
 | 
 | ||||||
| """ | """ | ||||||
| 
 | 
 | ||||||
|  | @ -52,6 +55,11 @@ def __getattr__(self, key): | ||||||
| 	if key not in self.KEYS: | 	if key not in self.KEYS: | ||||||
| 	    raise AttributeError | 	    raise AttributeError | ||||||
| 	try: | 	try: | ||||||
|  | 	    form = self.form | ||||||
|  | 	    try: | ||||||
|  | 		item = form[key] | ||||||
|  | 	    except TypeError, msg: | ||||||
|  | 		raise KeyError, msg, sys.exc_traceback | ||||||
| 	    value = self.form[key].value | 	    value = self.form[key].value | ||||||
| 	    setattr(self, key, value) | 	    setattr(self, key, value) | ||||||
| 	    return value | 	    return value | ||||||
|  | @ -121,7 +129,7 @@ def do_show(self): | ||||||
| 	if not headers: | 	if not headers: | ||||||
| 	    print "Invalid file name", name | 	    print "Invalid file name", name | ||||||
| 	    return | 	    return | ||||||
| 	self.show(name, headers['title'], text, 1) | 	self.show(name, headers['title'], text) | ||||||
| 
 | 
 | ||||||
|     def do_all(self): |     def do_all(self): | ||||||
| 	self.prologue("The Whole Python FAQ") | 	self.prologue("The Whole Python FAQ") | ||||||
|  | @ -139,7 +147,7 @@ def do_all(self): | ||||||
| 		    section = nsec | 		    section = nsec | ||||||
| 		    print "<H1>Section %s</H1>" % section | 		    print "<H1>Section %s</H1>" % section | ||||||
| 		    print "<HR>" | 		    print "<HR>" | ||||||
| 		self.show(name, title, text, 1) | 		self.show(name, title, text) | ||||||
| 	if not section: | 	if not section: | ||||||
| 	    print "No FAQ entries?!?!" | 	    print "No FAQ entries?!?!" | ||||||
| 
 | 
 | ||||||
|  | @ -157,8 +165,8 @@ def do_roulette(self): | ||||||
| 	    name = whrandom.choice(names) | 	    name = whrandom.choice(names) | ||||||
| 	    headers, text = self.read(name) | 	    headers, text = self.read(name) | ||||||
| 	    if headers: | 	    if headers: | ||||||
| 		self.show(name, headers['title'], text, 1) | 		self.show(name, headers['title'], text) | ||||||
| 		print '<P><A HREF="faq.py?req=roulette">Show another one</A>' | 		print "<P>Use `Reload' to show another one." | ||||||
| 		break | 		break | ||||||
| 	    else: | 	    else: | ||||||
| 		names.remove(name) | 		names.remove(name) | ||||||
|  | @ -187,7 +195,7 @@ def do_recent(self): | ||||||
| 	for (mtime, name) in list: | 	for (mtime, name) in list: | ||||||
| 	    headers, text = self.read(name) | 	    headers, text = self.read(name) | ||||||
| 	    if headers: | 	    if headers: | ||||||
| 		self.show(name, headers['title'], text, 1) | 		self.show(name, headers['title'], text) | ||||||
| 		n = n+1 | 		n = n+1 | ||||||
| 	if not n: | 	if not n: | ||||||
| 	    print "No FAQ entries?!?!" | 	    print "No FAQ entries?!?!" | ||||||
|  | @ -209,7 +217,7 @@ def do_query(self): | ||||||
| 	    if headers: | 	    if headers: | ||||||
| 		title = headers['title'] | 		title = headers['title'] | ||||||
| 		if p.search(title) >= 0 or p.search(text) >= 0: | 		if p.search(title) >= 0 or p.search(text) >= 0: | ||||||
| 		    self.show(name, title, text, 1) | 		    self.show(name, title, text) | ||||||
| 		    n = n+1 | 		    n = n+1 | ||||||
| 	if not n: | 	if not n: | ||||||
| 	    print "No hits." | 	    print "No hits." | ||||||
|  | @ -274,7 +282,7 @@ def do_edit(self): | ||||||
| 	</FORM> | 	</FORM> | ||||||
| 	<HR> | 	<HR> | ||||||
| 	""" % (name, version) | 	""" % (name, version) | ||||||
| 	self.show(name, title, text) | 	self.show(name, title, text, edit=0) | ||||||
| 
 | 
 | ||||||
|     def do_review(self): |     def do_review(self): | ||||||
| 	if self.commit: | 	if self.commit: | ||||||
|  | @ -289,7 +297,7 @@ def do_review(self): | ||||||
| 	    return | 	    return | ||||||
| 	self.prologue("Python FAQ Review Form") | 	self.prologue("Python FAQ Review Form") | ||||||
| 	print "<HR>" | 	print "<HR>" | ||||||
| 	self.show(name, title, text) | 	self.show(name, title, text, edit=0) | ||||||
| 	print "<FORM METHOD=POST ACTION=faq.py>" | 	print "<FORM METHOD=POST ACTION=faq.py>" | ||||||
| 	if self.log and self.author and '@' in self.email: | 	if self.log and self.author and '@' in self.email: | ||||||
| 	    print """ | 	    print """ | ||||||
|  | @ -447,7 +455,7 @@ def checkin(self): | ||||||
| 	if not sts: | 	if not sts: | ||||||
| 	    self.prologue("Python FAQ Entry Edited") | 	    self.prologue("Python FAQ Entry Edited") | ||||||
| 	    print "<HR>" | 	    print "<HR>" | ||||||
| 	    self.show(name, title, text, 1) | 	    self.show(name, title, text) | ||||||
| 	    if output: | 	    if output: | ||||||
| 		print "<PRE>%s</PRE>" % cgi.escape(output) | 		print "<PRE>%s</PRE>" % cgi.escape(output) | ||||||
| 	else: | 	else: | ||||||
|  | @ -460,15 +468,17 @@ def checkin(self): | ||||||
| 
 | 
 | ||||||
|     def showedit(self, name, title, text): |     def showedit(self, name, title, text): | ||||||
| 	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>""" % title | 	<TEXTAREA COLS=80 ROWS=20 NAME=text>""" % title | ||||||
| 	print cgi.escape(string.strip(text)) | 	print cgi.escape(string.strip(text)) | ||||||
| 	print """</TEXTAREA> | 	print """</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=70 NAME=author VALUE="%s"<BR> | 	<CODE>Name : </CODE><INPUT TYPE=text SIZE=40 NAME=author VALUE="%s"> | ||||||
| 	<CODE>Email: </CODE><INPUT TYPE=text SIZE=70 NAME=email VALUE="%s"<BR> | 	<BR> | ||||||
|  | 	<CODE>Email: </CODE><INPUT TYPE=text SIZE=40 NAME=email VALUE="%s"> | ||||||
|  | 	<BR> | ||||||
| 	Log message (reason for the change):<BR> | 	Log message (reason for the change):<BR> | ||||||
| 	<TEXTAREA COLS=80 ROWS=5 NAME=log>\n%s\n</TEXTAREA> | 	<TEXTAREA COLS=80 ROWS=5 NAME=log>\n%s\n</TEXTAREA> | ||||||
| 	""" % (self.author, self.email, self.log) | 	""" % (self.author, self.email, self.log) | ||||||
|  | @ -482,7 +492,10 @@ def showheaders(self, headers): | ||||||
| 					 headers[key] or '') | 					 headers[key] or '') | ||||||
| 	print "</UL>" | 	print "</UL>" | ||||||
| 
 | 
 | ||||||
|  |     headers = None | ||||||
|  | 
 | ||||||
|     def read(self, name): |     def read(self, name): | ||||||
|  | 	self.headers = None | ||||||
| 	import fnmatch, rfc822 | 	import fnmatch, rfc822 | ||||||
| 	if not fnmatch.fnmatch(name, NAMEPAT): | 	if not fnmatch.fnmatch(name, NAMEPAT): | ||||||
| 	    return None, None | 	    return None, None | ||||||
|  | @ -496,14 +509,15 @@ def read(self, name): | ||||||
| 		return None, None | 		return None, None | ||||||
| 	    headers = {'title': "%s.%s. " % (self.section, self.number)} | 	    headers = {'title': "%s.%s. " % (self.section, self.number)} | ||||||
| 	    text = "" | 	    text = "" | ||||||
| 	    return headers, text | 	else: | ||||||
| 	    f = open(name) | 	    f = open(name) | ||||||
| 	    headers = rfc822.Message(f) | 	    headers = rfc822.Message(f) | ||||||
| 	    text = f.read() | 	    text = f.read() | ||||||
| 	    f.close() | 	    f.close() | ||||||
|  | 	self.headers = headers | ||||||
| 	return headers, text | 	return headers, text | ||||||
| 
 | 
 | ||||||
|     def show(self, name, title, text, edit=0): |     def show(self, name, title, text, edit=1): | ||||||
| 	# XXX Should put <A> tags around recognizable URLs | 	# XXX Should put <A> tags around recognizable URLs | ||||||
| 	# XXX Should also turn "see section N" into hyperlinks | 	# XXX Should also turn "see section N" into hyperlinks | ||||||
| 	print "<H2>%s</H2>" % cgi.escape(title) | 	print "<H2>%s</H2>" % cgi.escape(title) | ||||||
|  | @ -534,6 +548,16 @@ def show(self, name, title, text, edit=0): | ||||||
| 	    <A HREF="faq.py?req=edit&name=%s">Edit this entry</A> / | 	    <A HREF="faq.py?req=edit&name=%s">Edit this entry</A> / | ||||||
| 	    <A HREF="faq.py?req=info&name=%s" TARGET=_blank>Log info</A> | 	    <A HREF="faq.py?req=info&name=%s" TARGET=_blank>Log info</A> | ||||||
| 	    """ % (name, name) | 	    """ % (name, name) | ||||||
|  | 	    if self.headers: | ||||||
|  | 		try: | ||||||
|  | 		    date = self.headers['last-changed-date'] | ||||||
|  | 		    author = self.headers['last-changed-author'] | ||||||
|  | 		    email = self.headers['last-changed-email'] | ||||||
|  | 		except KeyError: | ||||||
|  | 		    pass | ||||||
|  | 		else: | ||||||
|  | 		    s = '(last changed on %s by <A HREF="%s">%s</A>)' | ||||||
|  | 		    print s % (date, email, author) | ||||||
| 	    print '<P>' | 	    print '<P>' | ||||||
| 	print "<HR>" | 	print "<HR>" | ||||||
| 
 | 
 | ||||||
|  | @ -568,6 +592,8 @@ def epilogue(self): | ||||||
| 	print ''' | 	print ''' | ||||||
| 	<P> | 	<P> | ||||||
| 	<HR> | 	<HR> | ||||||
|  | 	<A HREF="http://www.python.org">Python home</A> / | ||||||
|  | 	<A HREF="faq.py">FAQ home</A> / | ||||||
| 	<A HREF="mailto:guido@python.org">GvR</A> | 	<A HREF="mailto:guido@python.org">GvR</A> | ||||||
| 	</BODY> | 	</BODY> | ||||||
| 	</HTML> | 	</HTML> | ||||||
|  | @ -587,3 +613,13 @@ def epilogue(self): | ||||||
|     print "<HR>Sorry, an error occurred" |     print "<HR>Sorry, an error occurred" | ||||||
|     cgi.print_exception() |     cgi.print_exception() | ||||||
| print "<P>(running time = %s seconds)" % str(round(dt, 3)) | print "<P>(running time = %s seconds)" % str(round(dt, 3)) | ||||||
|  | 
 | ||||||
|  | # The following bootstrap script must be placed in cgi-bin/faq.py: | ||||||
|  | BOOTSTRAP = """ | ||||||
|  | #! /usr/local/bin/python | ||||||
|  | FAQDIR = "/usr/people/guido/python/FAQ" | ||||||
|  | import os, sys | ||||||
|  | os.chdir(FAQDIR) | ||||||
|  | sys.path.insert(0, os.curdir) | ||||||
|  | import faqmain | ||||||
|  | """ | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Guido van Rossum
						Guido van Rossum