home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_307 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  21.5 KB  |  905 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __version__ = '2.6'
  5. from operator import attrgetter
  6. import sys
  7. import os
  8. import urllib
  9. import UserDict
  10. import urlparse
  11. from warnings import filterwarnings, catch_warnings, warn
  12. catch_warnings().__enter__()
  13.  
  14. try:
  15.     import mimetools
  16.     if sys.py3kwarning:
  17.         filterwarnings('ignore', '.*rfc822 has been removed', DeprecationWarning)
  18.     
  19.     import rfc822
  20. finally:
  21.     pass
  22.  
  23.  
  24. try:
  25.     from cStringIO import StringIO
  26. except ImportError:
  27.     catch_warnings().__exit__
  28.     catch_warnings().__exit__
  29.     catch_warnings()
  30.     from StringIO import StringIO
  31. except:
  32.     catch_warnings().__exit__
  33.  
  34. __all__ = [
  35.     'MiniFieldStorage',
  36.     'FieldStorage',
  37.     'FormContentDict',
  38.     'SvFormContentDict',
  39.     'InterpFormContentDict',
  40.     'FormContent',
  41.     'parse',
  42.     'parse_qs',
  43.     'parse_qsl',
  44.     'parse_multipart',
  45.     'parse_header',
  46.     'print_exception',
  47.     'print_environ',
  48.     'print_form',
  49.     'print_directory',
  50.     'print_arguments',
  51.     'print_environ_usage',
  52.     'escape']
  53. logfile = ''
  54. logfp = None
  55.  
  56. def initlog(*allargs):
  57.     global logfp, log, log
  58.     if logfile and not logfp:
  59.         
  60.         try:
  61.             logfp = open(logfile, 'a')
  62.         except IOError:
  63.             pass
  64.         except:
  65.             None<EXCEPTION MATCH>IOError
  66.         
  67.  
  68.     None<EXCEPTION MATCH>IOError
  69.     if not logfp:
  70.         log = nolog
  71.     else:
  72.         log = dolog
  73.     log(*allargs)
  74.  
  75.  
  76. def dolog(fmt, *args):
  77.     logfp.write(fmt % args + '\n')
  78.  
  79.  
  80. def nolog(*allargs):
  81.     pass
  82.  
  83. log = initlog
  84. maxlen = 0
  85.  
  86. def parse(fp = None, environ = os.environ, keep_blank_values = 0, strict_parsing = 0):
  87.     if fp is None:
  88.         fp = sys.stdin
  89.     
  90.     if 'REQUEST_METHOD' not in environ:
  91.         environ['REQUEST_METHOD'] = 'GET'
  92.     
  93.     if environ['REQUEST_METHOD'] == 'POST':
  94.         (ctype, pdict) = parse_header(environ['CONTENT_TYPE'])
  95.         if ctype == 'multipart/form-data':
  96.             return parse_multipart(fp, pdict)
  97.         if ctype == 'application/x-www-form-urlencoded':
  98.             clength = int(environ['CONTENT_LENGTH'])
  99.             if maxlen and clength > maxlen:
  100.                 raise ValueError, 'Maximum content length exceeded'
  101.             clength > maxlen
  102.             qs = fp.read(clength)
  103.         else:
  104.             qs = ''
  105.         if 'QUERY_STRING' in environ:
  106.             if qs:
  107.                 qs = qs + '&'
  108.             
  109.             qs = qs + environ['QUERY_STRING']
  110.         elif sys.argv[1:]:
  111.             if qs:
  112.                 qs = qs + '&'
  113.             
  114.             qs = qs + sys.argv[1]
  115.         
  116.         environ['QUERY_STRING'] = qs
  117.     elif 'QUERY_STRING' in environ:
  118.         qs = environ['QUERY_STRING']
  119.     elif sys.argv[1:]:
  120.         qs = sys.argv[1]
  121.     else:
  122.         qs = ''
  123.     environ['QUERY_STRING'] = qs
  124.     return parse_qs(qs, keep_blank_values, strict_parsing)
  125.  
  126.  
  127. def parse_qs(qs, keep_blank_values = 0, strict_parsing = 0):
  128.     warn('cgi.parse_qs is deprecated, use urlparse.parse_qs             instead', PendingDeprecationWarning, 2)
  129.     return urlparse.parse_qs(qs, keep_blank_values, strict_parsing)
  130.  
  131.  
  132. def parse_qsl(qs, keep_blank_values = 0, strict_parsing = 0):
  133.     warn('cgi.parse_qsl is deprecated, use urlparse.parse_qsl instead', PendingDeprecationWarning, 2)
  134.     return urlparse.parse_qsl(qs, keep_blank_values, strict_parsing)
  135.  
  136.  
  137. def parse_multipart(fp, pdict):
  138.     boundary = ''
  139.     if 'boundary' in pdict:
  140.         boundary = pdict['boundary']
  141.     
  142.     if not valid_boundary(boundary):
  143.         raise ValueError, 'Invalid boundary in multipart form: %r' % (boundary,)
  144.     valid_boundary(boundary)
  145.     nextpart = '--' + boundary
  146.     lastpart = '--' + boundary + '--'
  147.     partdict = { }
  148.     terminator = ''
  149.     while terminator != lastpart:
  150.         bytes = -1
  151.         data = None
  152.         if terminator:
  153.             headers = mimetools.Message(fp)
  154.             clength = headers.getheader('content-length')
  155.             if clength:
  156.                 
  157.                 try:
  158.                     bytes = int(clength)
  159.                 except ValueError:
  160.                     pass
  161.                 except:
  162.                     None<EXCEPTION MATCH>ValueError
  163.                 
  164.  
  165.             None<EXCEPTION MATCH>ValueError
  166.             if bytes > 0:
  167.                 if maxlen and bytes > maxlen:
  168.                     raise ValueError, 'Maximum content length exceeded'
  169.                 bytes > maxlen
  170.                 data = fp.read(bytes)
  171.             else:
  172.                 data = ''
  173.         
  174.         lines = []
  175.         while None:
  176.             line = fp.readline()
  177.             if not line:
  178.                 terminator = lastpart
  179.                 break
  180.             
  181.             if line[:2] == '--':
  182.                 terminator = line.strip()
  183.                 if terminator in (nextpart, lastpart):
  184.                     break
  185.                 
  186.             
  187.             continue
  188.             if data is None:
  189.                 continue
  190.             
  191.         if bytes < 0:
  192.             if lines:
  193.                 line = lines[-1]
  194.                 if line[-2:] == '\r\n':
  195.                     line = line[:-2]
  196.                 elif line[-1:] == '\n':
  197.                     line = line[:-1]
  198.                 
  199.                 lines[-1] = line
  200.                 data = ''.join(lines)
  201.             
  202.         
  203.         line = headers['content-disposition']
  204.         if not line:
  205.             continue
  206.         
  207.         (key, params) = parse_header(line)
  208.         if key != 'form-data':
  209.             continue
  210.         
  211.         if 'name' in params:
  212.             name = params['name']
  213.         
  214.         if name in partdict:
  215.             partdict[name].append(data)
  216.             continue
  217.         'name' in params
  218.         partdict[name] = [
  219.             data]
  220.     return partdict
  221.  
  222.  
  223. def _parseparam(s):
  224.     while s[:1] == ';':
  225.         s = s[1:]
  226.         end = s.find(';')
  227.         while end > 0 and s.count('"', 0, end) % 2:
  228.             end = s.find(';', end + 1)
  229.         if end < 0:
  230.             end = len(s)
  231.         
  232.         f = s[:end]
  233.         yield f.strip()
  234.         s = s[end:]
  235.  
  236.  
  237. def parse_header(line):
  238.     parts = _parseparam(';' + line)
  239.     key = parts.next()
  240.     pdict = { }
  241.     for p in parts:
  242.         i = p.find('=')
  243.         if i >= 0:
  244.             name = p[:i].strip().lower()
  245.             value = p[i + 1:].strip()
  246.             if len(value) >= 2:
  247.                 if value[-1] == value[-1]:
  248.                     pass
  249.                 elif value[-1] == '"':
  250.                     value = value[1:-1]
  251.                     value = value.replace('\\\\', '\\').replace('\\"', '"')
  252.                 
  253.             pdict[name] = value
  254.             continue
  255.         value[0]
  256.     
  257.     return (key, pdict)
  258.  
  259.  
  260. class MiniFieldStorage:
  261.     filename = None
  262.     list = None
  263.     type = None
  264.     file = None
  265.     type_options = { }
  266.     disposition = None
  267.     disposition_options = { }
  268.     headers = { }
  269.     
  270.     def __init__(self, name, value):
  271.         self.name = name
  272.         self.value = value
  273.  
  274.     
  275.     def __repr__(self):
  276.         return 'MiniFieldStorage(%r, %r)' % (self.name, self.value)
  277.  
  278.  
  279.  
  280. class FieldStorage:
  281.     
  282.     def __init__(self, fp = None, headers = None, outerboundary = '', environ = os.environ, keep_blank_values = 0, strict_parsing = 0):
  283.         method = 'GET'
  284.         self.keep_blank_values = keep_blank_values
  285.         self.strict_parsing = strict_parsing
  286.         if 'REQUEST_METHOD' in environ:
  287.             method = environ['REQUEST_METHOD'].upper()
  288.         
  289.         self.qs_on_post = None
  290.         if method == 'GET' or method == 'HEAD':
  291.             if 'QUERY_STRING' in environ:
  292.                 qs = environ['QUERY_STRING']
  293.             elif sys.argv[1:]:
  294.                 qs = sys.argv[1]
  295.             else:
  296.                 qs = ''
  297.             fp = StringIO(qs)
  298.             if headers is None:
  299.                 headers = {
  300.                     'content-type': 'application/x-www-form-urlencoded' }
  301.             
  302.         
  303.         if headers is None:
  304.             headers = { }
  305.             if method == 'POST':
  306.                 headers['content-type'] = 'application/x-www-form-urlencoded'
  307.             
  308.             if 'CONTENT_TYPE' in environ:
  309.                 headers['content-type'] = environ['CONTENT_TYPE']
  310.             
  311.             if 'QUERY_STRING' in environ:
  312.                 self.qs_on_post = environ['QUERY_STRING']
  313.             
  314.             if 'CONTENT_LENGTH' in environ:
  315.                 headers['content-length'] = environ['CONTENT_LENGTH']
  316.             
  317.         
  318.         if not fp:
  319.             pass
  320.         self.fp = sys.stdin
  321.         self.headers = headers
  322.         self.outerboundary = outerboundary
  323.         cdisp = ''
  324.         pdict = { }
  325.         if 'content-disposition' in self.headers:
  326.             (cdisp, pdict) = parse_header(self.headers['content-disposition'])
  327.         
  328.         self.disposition = cdisp
  329.         self.disposition_options = pdict
  330.         self.name = None
  331.         if 'name' in pdict:
  332.             self.name = pdict['name']
  333.         
  334.         self.filename = None
  335.         if 'filename' in pdict:
  336.             self.filename = pdict['filename']
  337.         
  338.         if 'content-type' in self.headers:
  339.             (ctype, pdict) = parse_header(self.headers['content-type'])
  340.         elif self.outerboundary or method != 'POST':
  341.             ctype = 'text/plain'
  342.             pdict = { }
  343.         else:
  344.             ctype = 'application/x-www-form-urlencoded'
  345.             pdict = { }
  346.         self.type = ctype
  347.         self.type_options = pdict
  348.         self.innerboundary = ''
  349.         if 'boundary' in pdict:
  350.             self.innerboundary = pdict['boundary']
  351.         
  352.         clen = -1
  353.         if 'content-length' in self.headers:
  354.             
  355.             try:
  356.                 clen = int(self.headers['content-length'])
  357.             except ValueError:
  358.                 pass
  359.  
  360.             if maxlen and clen > maxlen:
  361.                 raise ValueError, 'Maximum content length exceeded'
  362.             clen > maxlen
  363.         
  364.         self.length = clen
  365.         self.list = None
  366.         self.file = None
  367.         self.done = 0
  368.         if ctype == 'application/x-www-form-urlencoded':
  369.             self.read_urlencoded()
  370.         elif ctype[:10] == 'multipart/':
  371.             self.read_multi(environ, keep_blank_values, strict_parsing)
  372.         else:
  373.             self.read_single()
  374.  
  375.     
  376.     def __repr__(self):
  377.         return 'FieldStorage(%r, %r, %r)' % (self.name, self.filename, self.value)
  378.  
  379.     
  380.     def __iter__(self):
  381.         return iter(self.keys())
  382.  
  383.     
  384.     def __getattr__(self, name):
  385.         if name != 'value':
  386.             raise AttributeError, name
  387.         name != 'value'
  388.         if self.file:
  389.             self.file.seek(0)
  390.             value = self.file.read()
  391.             self.file.seek(0)
  392.         elif self.list is not None:
  393.             value = self.list
  394.         else:
  395.             value = None
  396.         return value
  397.  
  398.     
  399.     def __getitem__(self, key):
  400.         if self.list is None:
  401.             raise TypeError, 'not indexable'
  402.         self.list is None
  403.         found = []
  404.         for item in self.list:
  405.             if item.name == key:
  406.                 found.append(item)
  407.                 continue
  408.         
  409.         if not found:
  410.             raise KeyError, key
  411.         found
  412.         if len(found) == 1:
  413.             return found[0]
  414.         return found
  415.  
  416.     
  417.     def getvalue(self, key, default = None):
  418.         if key in self:
  419.             value = self[key]
  420.             if type(value) is type([]):
  421.                 return map(attrgetter('value'), value)
  422.             return value.value
  423.         key in self
  424.         return default
  425.  
  426.     
  427.     def getfirst(self, key, default = None):
  428.         if key in self:
  429.             value = self[key]
  430.             if type(value) is type([]):
  431.                 return value[0].value
  432.             return value.value
  433.         key in self
  434.         return default
  435.  
  436.     
  437.     def getlist(self, key):
  438.         if key in self:
  439.             value = self[key]
  440.             if type(value) is type([]):
  441.                 return map(attrgetter('value'), value)
  442.             return [
  443.                 value.value]
  444.         key in self
  445.         return []
  446.  
  447.     
  448.     def keys(self):
  449.         if self.list is None:
  450.             raise TypeError, 'not indexable'
  451.         self.list is None
  452.         return list(set((lambda .0: for item in .0:
  453. item.name)(self.list)))
  454.  
  455.     
  456.     def has_key(self, key):
  457.         if self.list is None:
  458.             raise TypeError, 'not indexable'
  459.         self.list is None
  460.         return (any,)((lambda .0: for item in .0:
  461. item.name == key)(self.list))
  462.  
  463.     
  464.     def __contains__(self, key):
  465.         if self.list is None:
  466.             raise TypeError, 'not indexable'
  467.         self.list is None
  468.         return (any,)((lambda .0: for item in .0:
  469. item.name == key)(self.list))
  470.  
  471.     
  472.     def __len__(self):
  473.         return len(self.keys())
  474.  
  475.     
  476.     def __nonzero__(self):
  477.         return bool(self.list)
  478.  
  479.     
  480.     def read_urlencoded(self):
  481.         qs = self.fp.read(self.length)
  482.         if self.qs_on_post:
  483.             qs += '&' + self.qs_on_post
  484.         
  485.         self.list = list = []
  486.         for key, value in urlparse.parse_qsl(qs, self.keep_blank_values, self.strict_parsing):
  487.             list.append(MiniFieldStorage(key, value))
  488.         
  489.         self.skip_lines()
  490.  
  491.     FieldStorageClass = None
  492.     
  493.     def read_multi(self, environ, keep_blank_values, strict_parsing):
  494.         ib = self.innerboundary
  495.         if not valid_boundary(ib):
  496.             raise ValueError, 'Invalid boundary in multipart form: %r' % (ib,)
  497.         valid_boundary(ib)
  498.         self.list = []
  499.         if self.qs_on_post:
  500.             for key, value in urlparse.parse_qsl(self.qs_on_post, self.keep_blank_values, self.strict_parsing):
  501.                 self.list.append(MiniFieldStorage(key, value))
  502.             
  503.             FieldStorageClass = None
  504.         
  505.         if not self.FieldStorageClass:
  506.             pass
  507.         klass = self.__class__
  508.         part = klass(self.fp, { }, ib, environ, keep_blank_values, strict_parsing)
  509.         while not part.done:
  510.             headers = rfc822.Message(self.fp)
  511.             part = klass(self.fp, headers, ib, environ, keep_blank_values, strict_parsing)
  512.             self.list.append(part)
  513.         self.skip_lines()
  514.  
  515.     
  516.     def read_single(self):
  517.         if self.length >= 0:
  518.             self.read_binary()
  519.             self.skip_lines()
  520.         else:
  521.             self.read_lines()
  522.         self.file.seek(0)
  523.  
  524.     bufsize = 8192
  525.     
  526.     def read_binary(self):
  527.         self.file = self.make_file('b')
  528.         todo = self.length
  529.         if todo >= 0:
  530.             while todo > 0:
  531.                 data = self.fp.read(min(todo, self.bufsize))
  532.                 if not data:
  533.                     self.done = -1
  534.                     break
  535.                 
  536.                 self.file.write(data)
  537.                 todo = todo - len(data)
  538.         
  539.  
  540.     
  541.     def read_lines(self):
  542.         self.file = self._FieldStorage__file = StringIO()
  543.         if self.outerboundary:
  544.             self.read_lines_to_outerboundary()
  545.         else:
  546.             self.read_lines_to_eof()
  547.  
  548.     
  549.     def __write(self, line):
  550.         if self._FieldStorage__file is not None:
  551.             if self._FieldStorage__file.tell() + len(line) > 1000:
  552.                 self.file = self.make_file('')
  553.                 self.file.write(self._FieldStorage__file.getvalue())
  554.                 self._FieldStorage__file = None
  555.             
  556.         
  557.         self.file.write(line)
  558.  
  559.     
  560.     def read_lines_to_eof(self):
  561.         while None:
  562.             line = self.fp.readline(65536)
  563.             if not line:
  564.                 self.done = -1
  565.                 break
  566.             
  567.             continue
  568.             return None
  569.  
  570.     
  571.     def read_lines_to_outerboundary(self):
  572.         next = '--' + self.outerboundary
  573.         last = next + '--'
  574.         delim = ''
  575.         last_line_lfend = True
  576.         while None:
  577.             line = self.fp.readline(65536)
  578.             if not line:
  579.                 self.done = -1
  580.                 break
  581.             
  582.             if line[:2] == '--' and last_line_lfend:
  583.                 strippedline = line.strip()
  584.                 if strippedline == next:
  585.                     break
  586.                 
  587.                 if strippedline == last:
  588.                     self.done = 1
  589.                     break
  590.                 
  591.             
  592.             odelim = delim
  593.             if line[-2:] == '\r\n':
  594.                 delim = '\r\n'
  595.                 line = line[:-2]
  596.                 last_line_lfend = True
  597.             elif line[-1] == '\n':
  598.                 delim = '\n'
  599.                 line = line[:-1]
  600.                 last_line_lfend = True
  601.             else:
  602.                 delim = ''
  603.                 last_line_lfend = False
  604.             continue
  605.             return None
  606.  
  607.     
  608.     def skip_lines(self):
  609.         if not (self.outerboundary) or self.done:
  610.             return None
  611.         next = '--' + self.outerboundary
  612.         last = next + '--'
  613.         last_line_lfend = True
  614.         while None:
  615.             line = self.fp.readline(65536)
  616.             if not line:
  617.                 self.done = -1
  618.                 break
  619.             
  620.             if line[:2] == '--' and last_line_lfend:
  621.                 strippedline = line.strip()
  622.                 if strippedline == next:
  623.                     break
  624.                 
  625.                 if strippedline == last:
  626.                     self.done = 1
  627.                     break
  628.                 
  629.             
  630.             last_line_lfend = line.endswith('\n')
  631.             continue
  632.             return None
  633.  
  634.     
  635.     def make_file(self, binary = None):
  636.         import tempfile
  637.         return tempfile.TemporaryFile('w+b')
  638.  
  639.  
  640.  
  641. class FormContentDict(UserDict.UserDict):
  642.     
  643.     def __init__(self, environ = os.environ, keep_blank_values = 0, strict_parsing = 0):
  644.         self.dict = self.data = parse(environ = environ, keep_blank_values = keep_blank_values, strict_parsing = strict_parsing)
  645.         self.query_string = environ['QUERY_STRING']
  646.  
  647.  
  648.  
  649. class SvFormContentDict(FormContentDict):
  650.     
  651.     def __getitem__(self, key):
  652.         if len(self.dict[key]) > 1:
  653.             raise IndexError, 'expecting a single value'
  654.         len(self.dict[key]) > 1
  655.         return self.dict[key][0]
  656.  
  657.     
  658.     def getlist(self, key):
  659.         return self.dict[key]
  660.  
  661.     
  662.     def values(self):
  663.         result = []
  664.         for value in self.dict.values():
  665.             if len(value) == 1:
  666.                 result.append(value[0])
  667.                 continue
  668.             result.append(value)
  669.         
  670.         return result
  671.  
  672.     
  673.     def items(self):
  674.         result = []
  675.         for key, value in self.dict.items():
  676.             if len(value) == 1:
  677.                 result.append((key, value[0]))
  678.                 continue
  679.             result.append((key, value))
  680.         
  681.         return result
  682.  
  683.  
  684.  
  685. class InterpFormContentDict(SvFormContentDict):
  686.     
  687.     def __getitem__(self, key):
  688.         v = SvFormContentDict.__getitem__(self, key)
  689.         if v[0] in '0123456789+-.':
  690.             
  691.             try:
  692.                 return int(v)
  693.             except ValueError:
  694.                 
  695.                 try:
  696.                     return float(v)
  697.                 except ValueError:
  698.                     pass
  699.                 except:
  700.                     None<EXCEPTION MATCH>ValueError
  701.                 
  702.  
  703.                 None<EXCEPTION MATCH>ValueError
  704.             
  705.  
  706.         None<EXCEPTION MATCH>ValueError
  707.         return v.strip()
  708.  
  709.     
  710.     def values(self):
  711.         result = []
  712.         for key in self.keys():
  713.             
  714.             try:
  715.                 result.append(self[key])
  716.             continue
  717.             except IndexError:
  718.                 result.append(self.dict[key])
  719.                 continue
  720.             
  721.  
  722.         
  723.         return result
  724.  
  725.     
  726.     def items(self):
  727.         result = []
  728.         for key in self.keys():
  729.             
  730.             try:
  731.                 result.append((key, self[key]))
  732.             continue
  733.             except IndexError:
  734.                 result.append((key, self.dict[key]))
  735.                 continue
  736.             
  737.  
  738.         
  739.         return result
  740.  
  741.  
  742.  
  743. class FormContent(FormContentDict):
  744.     
  745.     def values(self, key):
  746.         if key in self.dict:
  747.             return self.dict[key]
  748.         return None
  749.  
  750.     
  751.     def indexed_value(self, key, location):
  752.         if key in self.dict:
  753.             if len(self.dict[key]) > location:
  754.                 return self.dict[key][location]
  755.             return None
  756.         key in self.dict
  757.         return None
  758.  
  759.     
  760.     def value(self, key):
  761.         if key in self.dict:
  762.             return self.dict[key][0]
  763.         return None
  764.  
  765.     
  766.     def length(self, key):
  767.         return len(self.dict[key])
  768.  
  769.     
  770.     def stripped(self, key):
  771.         if key in self.dict:
  772.             return self.dict[key][0].strip()
  773.         return None
  774.  
  775.     
  776.     def pars(self):
  777.         return self.dict
  778.  
  779.  
  780.  
  781. def test(environ = os.environ):
  782.     global maxlen
  783.     print 'Content-type: text/html'
  784.     print 
  785.     sys.stderr = sys.stdout
  786.     
  787.     try:
  788.         form = FieldStorage()
  789.         print_directory()
  790.         print_arguments()
  791.         print_form(form)
  792.         print_environ(environ)
  793.         print_environ_usage()
  794.         
  795.         def f():
  796.             exec 'testing print_exception() -- <I>italics?</I>'
  797.  
  798.         
  799.         def g(f = f):
  800.             f()
  801.  
  802.         print '<H3>What follows is a test, not an actual exception:</H3>'
  803.         g()
  804.     except:
  805.         print_exception()
  806.  
  807.     print '<H1>Second try with a small maxlen...</H1>'
  808.     maxlen = 50
  809.     
  810.     try:
  811.         form = FieldStorage()
  812.         print_directory()
  813.         print_arguments()
  814.         print_form(form)
  815.         print_environ(environ)
  816.     except:
  817.         print_exception()
  818.  
  819.  
  820.  
  821. def print_exception(type = None, value = None, tb = None, limit = None):
  822.     if type is None:
  823.         (type, value, tb) = sys.exc_info()
  824.     
  825.     import traceback
  826.     print 
  827.     print '<H3>Traceback (most recent call last):</H3>'
  828.     list = traceback.format_tb(tb, limit) + traceback.format_exception_only(type, value)
  829.     print '<PRE>%s<B>%s</B></PRE>' % (escape(''.join(list[:-1])), escape(list[-1]))
  830.     del tb
  831.  
  832.  
  833. def print_environ(environ = os.environ):
  834.     keys = environ.keys()
  835.     keys.sort()
  836.     print 
  837.     print '<H3>Shell Environment:</H3>'
  838.     print '<DL>'
  839.     for key in keys:
  840.         print '<DT>', escape(key), '<DD>', escape(environ[key])
  841.     
  842.     print '</DL>'
  843.     print 
  844.  
  845.  
  846. def print_form(form):
  847.     keys = form.keys()
  848.     keys.sort()
  849.     print 
  850.     print '<H3>Form Contents:</H3>'
  851.     if not keys:
  852.         print '<P>No form fields.'
  853.     
  854.     print '<DL>'
  855.     for key in keys:
  856.         print '<DT>' + escape(key) + ':',
  857.         value = form[key]
  858.         print '<i>' + escape(repr(type(value))) + '</i>'
  859.         print '<DD>' + escape(repr(value))
  860.     
  861.     print '</DL>'
  862.     print 
  863.  
  864.  
  865. def print_directory():
  866.     print 
  867.     print '<H3>Current Working Directory:</H3>'
  868.     
  869.     try:
  870.         pwd = os.getcwd()
  871.     except os.error:
  872.         msg = None
  873.         print 'os.error:', escape(str(msg))
  874.  
  875.     print escape(pwd)
  876.     print 
  877.  
  878.  
  879. def print_arguments():
  880.     print 
  881.     print '<H3>Command Line Arguments:</H3>'
  882.     print 
  883.     print sys.argv
  884.     print 
  885.  
  886.  
  887. def print_environ_usage():
  888.     print '\n<H3>These environment variables could have been set:</H3>\n<UL>\n<LI>AUTH_TYPE\n<LI>CONTENT_LENGTH\n<LI>CONTENT_TYPE\n<LI>DATE_GMT\n<LI>DATE_LOCAL\n<LI>DOCUMENT_NAME\n<LI>DOCUMENT_ROOT\n<LI>DOCUMENT_URI\n<LI>GATEWAY_INTERFACE\n<LI>LAST_MODIFIED\n<LI>PATH\n<LI>PATH_INFO\n<LI>PATH_TRANSLATED\n<LI>QUERY_STRING\n<LI>REMOTE_ADDR\n<LI>REMOTE_HOST\n<LI>REMOTE_IDENT\n<LI>REMOTE_USER\n<LI>REQUEST_METHOD\n<LI>SCRIPT_NAME\n<LI>SERVER_NAME\n<LI>SERVER_PORT\n<LI>SERVER_PROTOCOL\n<LI>SERVER_ROOT\n<LI>SERVER_SOFTWARE\n</UL>\nIn addition, HTTP headers sent by the server may be passed in the\nenvironment as well.  Here are some common variable names:\n<UL>\n<LI>HTTP_ACCEPT\n<LI>HTTP_CONNECTION\n<LI>HTTP_HOST\n<LI>HTTP_PRAGMA\n<LI>HTTP_REFERER\n<LI>HTTP_USER_AGENT\n</UL>\n'
  889.  
  890.  
  891. def escape(s, quote = None):
  892.     s = s.replace('&', '&')
  893.     s = s.replace('<', '<')
  894.     s = s.replace('>', '>')
  895.     if quote:
  896.         s = s.replace('"', '"')
  897.     
  898.     return s
  899.  
  900.  
  901. def valid_boundary(s, _vb_pattern = '^[ -~]{0,200}[!-~]$'):
  902.     import re
  903.     return re.match(_vb_pattern, s)
  904.  
  905.