# Copyright (c) 2000 LOGILAB S.A. (Paris, FRANCE).
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
__revision__ = '$Id: Http.py,v 1.54 2002/02/20 12:04:31 alf Exp $'
from narval.lib import * # get_encoding
import urlparse
import copy
import re

MOD_XML='''<?xml version="1.0" encoding="ISO-8859-1"?><module xmlns:al="%s">'''%AL_NS

##
## EXTRACT URL
##

def extract_url_to_text_f(args, doc) :

#    url =args['input'].data # is this ok?
    a = args['input']
    url = select_one(a, 'url/text()').data
    t=doc.createElementNS(NO_NS,'value')
    t.appendChild(doc.createTextNode(url))
    n=doc.createElementNS(NO_NS,'text')
    n.appendChild(t)
    output = {'output': n }
    return output

MOD_XML=MOD_XML+"""
<al:action name='extract_url' func='extract_url_to_text_f'>
  <al:description lang='en'>Transform an url into a text</al:description>
  <al:description lang='fr'>Transforme une url en un texte</al:description>
  <al:input id='input'><al:match>http-request/url/text()</al:match>
  <al:description lang='en'>request element where we could find an url</al:description></al:input>
  <al:output id='output'><al:match>text/value/text()</al:match>
  <al:description lang='en'>the extracted url's text</al:description></al:output>
</al:action>"""

##
## PARSE CGI
##

def read_cgi_request_f(args, doc) :
    request= args['http_request']
    from urllib import unquote
    import cgi
    # read stuff from request
    userinput = {}
    uid = request.getAttributeNS(NO_NS,'unique-id')
    url = select_one(request,'url/text()').data
    if request.getAttributeNS(NO_NS,'type') == 'POST':
        data = select_one(request,'data/text()').data
        userinput = cgi.parse_qs(data)
    elif request.getAttributeNS(NO_NS,'type') == 'GET':
        purl = urlparse.urlparse(url)
        userinput = cgi.parse_qs(purl[4])
        
    # create output
    r=doc.createElementNS(NO_NS,'http-cgi-request')
    r.setAttributeNS(NO_NS,'unique-id', uid)
    ret = {'output_http': r}
    u=doc.createElementNS(NO_NS,'url')
    r.appendChild(u)
    u.appendChild(doc.createTextNode(re.sub('\?.*','', url)))
    if userinput:
        for k,val in userinput.items():
            n=doc.createElementNS(NO_NS,'cgi-item')
            n.setAttributeNS(NO_NS,'key',k)
            for v in val:
                n.appendChild(doc.createTextNode(
                unicode(unquote(str(v)), 'utf-8')))
            r.appendChild(n)
    return ret

MOD_XML = MOD_XML + '''
<al:action name="read_cgi_request" func="read_cgi_request_f">
<al:description lang="en">Parse a cgi request and output a CGI structure</al:description>
<al:description lang="fr">Transforme une requête CGI HTTP en une structure CGI XML
</al:description>
<al:input id='http_request' use="yes"><al:match>http-request</al:match>
         <al:description lang="en">cgi request to parse</al:description></al:input>
<al:output id='output_http'><al:match>http-cgi-request</al:match>
         <al:description lang="en">xml cgi request</al:description></al:output>
</al:action>'''

##

def html2xhtml_f(args, doc) :
    from xml.dom.ext.reader import HtmlLib
    from xml.dom import Document
    xhtml = doc.createElementNS(None,'xhtml')
    # get HTML string
    input = args['input']
    html = select_one(input,'data')
    for node in html.childNodes :
        if node.nodeName == "#text" :
            data = node.data
            htmldoc = StripXml(HtmlLib.FromHtml(data))
            htmldom2dom(htmldoc.documentElement,xhtml)
            break
    return {'output' : xhtml}

MOD_XML=MOD_XML+'''
<al:action name='html2xhtml' func='html2xhtml_f'>
  <al:description lang="en">Tidy HTML and convert to XHTML</al:description>
  <al:description lang="fr">Nettoie le HTML et le convertit en XHTML</al:description>
  <al:input id='input'><al:match>raw-file/data</al:match>
  <al:description lang="en">html file element</al:description></al:input>
  <al:output id='output'><al:match>xhtml</al:match>
  <al:description lang="en">produced xhtml element</al:description></al:output>
</al:action>'''

MOD_XML=MOD_XML+'</module>'


def htmldom2dom(node,target):
    """node is the htmldom node
    target is the node to which the new elements should be appended."""
    doc = target.ownerDocument or target
    for c in node.childNodes:
        if c.nodeType == c.ELEMENT_NODE:
            child = doc.createElementNS(None,c.tagName.lower()) # denormalize HTML tag names
            for name,attr in c.attributes.items():
                child.setAttributeNS(name[0] or None,name[1].lower(),unicode(attr.value,'UTF-8'))
            target.appendChild(child)
            htmldom2dom(c,child)
        elif c.nodeType == c.TEXT_NODE:
            target.appendChild(doc.createTextNode(unicode(c.data,'UTF-8')))
        elif c.nodeType == c.COMMENT_NODE:
            target.appendChild(doc.createComment(unicode(c.data,'UTF-8')))
        else:
            print 'htmldom2dom: unsupported node type',c.nodeType,c
        

if __name__ == "__main__" :
    print MOD_XML
    from xml.dom.ext.reader import Sax2
    doc=Sax2.FromXml(MOD_XML)
    print doc.documentElement
