#!/export/home/ht/bin/python1.6
""" $Id: xmlschema-check,v 1.33 2001/10/28 18:13:31 ht Exp $
"""

import sys
import cgi
import os
import string
import traceback
import time
import tempfile
import urlparse
import urllib


import applyschema
from PyLTXML import error

Page = """<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
<head><title>XML Schema (REC (20010502) version) Checking Service (BETA TEST) </title>
<link href="http://www.w3.org/StyleSheets/base.css" rel="stylesheet" type="text/css" />
</head>
<body>
<p><a href="http://www.w3.org/"><img src="http://www.w3.org/Icons/WWW/w3c_home" alt="W3C" /></a> <a href="http://www.w3.org/XML/">XML</a> <a href="http://www.ltg.ed.ac.uk/">LTG</a></p>

<h1>Validator for XML Schema <span style="color:red">REC (20010502) version</span></h1>
<h4>XSV version: %s</h4>
<p><strong>NOTICE:</strong> This is an Beta
Test of a service for a <strong><a
href="http://www.w3.org/TR/xmlschema-1/">approved recommendation</a></strong>.  This version is for schema documents with the namespace URI <code>http://www.w3.org/2001/XMLSchema</code> and is being actively developed:  see <a href="http://www.w3.org/2000/09/webdata/xsv">XSV for XML Schema 20000922 version</a> for the no longer maintained previous version, for schema documents with the namespace URI <code>http://www.w3.org/2000/10/XMLSchema</code>, and <a href="http://www.w3.org/2000/06/webdata/xsv">XSV for XML Schema 200004007 version</a> for the no longer maintained even earlier version, for schema documents with the namespace URI <code>http://www.w3.org/1999/XMLSchema</code>.</p>
<hr />
<p>Use this form for checking a schema which is accessible via the Web, and/or schema-validating an instance with a schema of your own.</p>
<form method="GET">
<p><label><a href="#hlp-addr">Address(es)</a>: <input name="docAddrs" size="80"/></label> <br />
<label><input type="checkbox" name="warnings"/> <a href="#hlp-warn">Show warnings</a></label>
<label><input type="checkbox" name="keepGoing"/> <a href="#hlp-keep">Keep Going</a></label>

<label><input type="checkbox" name="logOK"/> <a href="#hlp-contribute">Contribute</a></label></p>
<p>Default output is now text/xml with an XSLT stylesheet.  Select fallbacks for browsers which don't support http://www.w3.org/1999/XSL/Transform stylesheets:
<table>
<tbody>
<tr><td>
<input type="radio" name="style" value="xsl" checked="checked">text/xml + official XSLT (suits IE5(.5) + MSXML3)</input></td></tr>
<tr><td>
<input type="radio" name="style" value="msxsl">text/xml + early MS XSL support (suits vanilla IE5)</input></td></tr>
<tr><td><input type="radio" name="style" value="offline">text/html (styled server-side: suits Netscape, older IE)</input></td></tr>
<tr><td>
<input type="radio" name="style" value="text">xml, but labelled text/plain (works for any browser, but hard to read)</input></td></tr>
</tbody>
</table>
</p>


<p><input type="submit" value="Get Results"/></p>
</form>
<hr />
<p>Use this form only if you are behind a firewall or have a schema to check which is not accessible via the Web.</p>
<form method="POST" enctype="multipart/form-data">
<p><label>File to upload: <input name="docFile" type="file" /></label> <br />
<label><input type="checkbox" name="warnings"/> <a href="#hlp-warn">Show warnings</a></label>
<label><input type="checkbox" name="keepGoing"/> <a href="#hlp-keep">Keep Going</a></label>

<label><input type="checkbox" name="logOK"/> <a href="#hlp-contribute">Contribute</a></label></p>

<p>Default output is now text/xml with an XSLT stylesheet.  Select fallbacks for browsers which don't support http://www.w3.org/1999/XSL/Transform stylesheets:
<table>

<tbody>
<tr><td>
<input type="radio" name="style" value="xsl" checked="checked">text/xml + official XSLT (suits IE5(.5) + MSXML3)</input></td></tr>
<tr><td>
<input type="radio" name="style" value="msxsl">text/xml + early MS XSL support (suits vanilla IE5)</input></td></tr>
<tr><td>
<input type="radio" name="style" value="offline">text/html (styled server-side: suits Netscape, older IE)</input></td></tr>
<tr><td>
<input type="radio" name="style" value="text">xml, but labelled text/plain (works for any browser, but hard to read)</input></td></tr>
</tbody>
</table>
</p>

<p><input type="submit" value="Upload and Get Results"/></p>
</form>
<hr />
<dl>
<dt><a name="hlp-addr">Address(es)</a></dt>
<dd> of document to schema-validate.
If you enter more than one URL, the 2nd etc. will be used to schema-validate
the first</dd>
<dt><a name="hlp-warn">Show Warnings</a></dt>
<dd>display warning messages, e.g. about use of wildcards</dd>
<dt><a name="hlp-keep">Keep Going</a></dt>
<dd>continue schema-validation after finding errors</dd>

<dt><a name="hlp-contribute">Contribute</a></dt>

<dd>We need schemas to provide a regression testing pool: if you're
willing for a copy of your input to be logged and copied offline,
please give us permission to do so. </dd>

</dl>

<hr />
<h2>Stuff</h2>
<ul>
<li><a href="http://lists.w3.org/Archives/Public/xmlschema-dev/">xmlschema-dev archive</a></li>
<li><a href="http://www.w3.org/XML/Activity#schema-wg">W3C XML Schema WG</a></li>
<li><a href="http://www.ltg.ed.ac.uk/">HCRC Language Technology Group </a></li>

<li><a href="http://www.ltg.ed.ac.uk/~ht/xsv-status.html">Coverage report for XSV</a></li>
<li><a href="http://dev.w3.org/cvsweb/xmlschema/">source code for XSV schema checker</a></li>
<li><a href="http://www.python.org/">python</a>, apache, etc.</li>
</ul>
<address>
report problems (and sucesses!) to <a href="mailto:xmlschema-dev@w3.org">xmlschema-dev</a> (<a href="http://lists.w3.org/Archives/Public/xmlschema-dev/">archive</a>)<br />
Schema validator by <a href="http://www.ltg.ed.ac.uk/~ht/">Henry S. Thompson</a> and <a href="http://www.ltg.ed.ac.uk/~richard/">Richard Tobin</a>.<br />
Web interface by <a href="http://www.w3.org/People/Connolly/">Dan Connolly</a> and <a href="http://www.ltg.ed.ac.uk/~ht/">Henry S. Thompson</a><br />
<small>script $Revision: 1.33 $ of $Date: 2001/10/28 18:13:31 $</small>
</address>
</body>
</html>
"""%applyschema.vs                             # '

def serveRequest():
    tempfile.tempdir="/usr/local/XSV/xsvlog"
    logFile=None
    fields = cgi.FieldStorage()

    if not (fields.has_key('docAddrs') or fields.has_key('docFile')):
        print "Content-Type: text/html"
	print
        print Page
    else:
        timeString=time.asctime(time.gmtime(time.time()))
        ss=None
        stemplate='../style/%s'
        style = fields['style'].value
        if style=='text':
          mime='text/plain'
        elif style=='offline':
          mime='text/html'
        else:
          mime='text/xml'
          if style=='msxsl':
            ss=stemplate%'xsv.msxsl'
          else:
            ss=stemplate%'xsv.xsl'

	if fields.has_key('docFile'):
            upFile=fields['docFile']
            info=upFile.headers
            fileInfo={'realName':upFile.filename}
	    data = upFile.file.read()
#	    print "writing %d bytes of uploaded data ..." \
#		  %(len(data), )
	    uploadTmp = tempfile.mktemp("uploaded") #@@hmm... when to delete these?
#	    print "... to %s" % (uploadTmp,)
	    fp = open(uploadTmp, "w")
	    fp.write(data)
	    fp.close()
	    target = 'file:' + uploadTmp
	    args = [target,]
	    schemas = [] #@@hmm... allow both upload and schemas?
	else:
	    addrs = fields['docAddrs'].value
	    if "'" in addrs:
		print """Content-Type: text/plain

                sorry, I can't handle addresses with ' in them"""
		return
            
	    args=string.split(addrs)
            for fn in args:
              if not urlparse.urlparse(fn)[0]:
		print """Content-Type: text/plain

                sorry, I can't handle relative addresses: %s"""%fn
		return
	    target=args[0]
	    schemas=args[1:]
            uhandle=urllib.urlopen(target)
            info=uhandle.info()
            fileInfo={'realName':uhandle.geturl()}
            
        for n,k in (('modDate','Last-Modified'),
                  ('size','Content-Length'),
                  ('server','Server')):
          if info.has_key(k):
            fileInfo[n]=info[k]

        if fields.has_key('warnings'):
          dontWarn=0
        else:
          dontWarn=1

        if fields.has_key('keepGoing'):
            keep='on'
        else:
            keep='off'

        if fields.has_key('logOK'):
            logFile=tempfile.mktemp()
            log = open(logFile,"a+")
            log.write("<noteRun time='%s' input=\"%s\" keep='%s' version='%s'/>\n"%
                      (timeString,
                       args,keep,applyschema.vs))
            log.close()
	print "Content-Type: %s"%mime
	print
        sys.stdout.flush()
        outFile=tempfile.mktemp("xsvout")
        try:
          ers=applyschema.runitAndShow(target,
                                       schemas,
                                       keep=='on',
                                       ss,
                                       fileInfo,
                                       outFile,
                                       dontWarn)
        except:
          # IO Error in PyXML
          ers=string.join(traceback.format_exception(sys.exc_type,
                                                     sys.exc_value,
                                                     sys.exc_traceback),
                          '')
        if ers:
          if not logFile:
              logFile=tempfile.mktemp()
          log = open(logFile,"a+")
          log.write("<fault time='%s' input=\"%s\" keep='%s' version='%s'>"%
                    (time.asctime(time.gmtime(time.time())),
                     args,keep,applyschema.vs))
          log.write("<![CDATA[")
          log.write(ers)
          log.write("]]>\n")
          log.write("</fault>\n")
          log.close()
        if style=='offline':
          os.system("/export/home/ht/bin/doxt %s /usr/local/Jigsaw/Jigsaw/WWW/style/xsv.xsl"%outFile)
        else:
          os.system("cat %s"%outFile)

if __name__ == '__main__':
    #sys.stderr = open("/tmp/cgi-write/xmlschema-log", "w+")
    #sys.stderr.write(str(os.environ))
    if os.environ.has_key('SCRIPT_NAME'):
        try:
            serveRequest()
        except:
	    print "Content-Type: text/plain"
            print
            traceback.print_exc(file=sys.stdout)
