<commit_before>"""EAD Sandbox WSGI Application.

The EAD Sandbox provides a Python WSGI compliant web application for playing
around with Encoded Archival Description (EAD) XML documents.

Current capabilities include validation to the DTD, cross-walk to other
metadata schemas, and extraction and display of subject and named entities.
"""

import cgi
try:
    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO

from pkg_resources import resource_string
from lxml import etree

from eadtoolbox.validate import EAD2002DTDValidator


class EADSandboxWsgiApp(object):
    """EAD Sandbox WSGI Application."""

    def __init__(self):
        self.response_headers = []
        self.txrs = {}
        
    def _fetch_ead(self, form):
        # Fetch EAD XML from the submitted form
        xml = form['eadfile'].value
        if not xml:
            xml = form.getfirst('eadxml')
        return xml
    
    def _head(self):
        # Return HTML Head
        self.response_headers.append(('Content-Type', 'text/html'))
        return [resource_string('eadtoolbox', 'data/html/head.tmpl')]
        
    def _tail(self):
        # Return HTML Tail
        return [resource_string('eadtoolbox', 'data/html/tail.tmpl')]
        
    def _apply_xslt(self, tree, xslt_path):
        # Apply XSLT from xslt_path to tree and return result as an lxml tree
        try:
            txr = self.txrs[xslt_path]
        except KeyError:
            with open(xslt_path, 'r') as fh:
                xslt = etree.parse(fh)
            self.txrs[xslt_path] = txr = etree.XSLT(xslt)
        return txr(tree)
    
    def _html_listItems_from_xpath(self, ead, xpath):
        # Return HTML list items from elements in ead that match XPath
        matches = ead.xpath(xpath)
        for xp in matches:
            xml_str = etree.tostring(xp, method="text", encoding="utf-8")
            yield '<li>{0}</li>'.format(xml_str.strip())
                
    def __call__(self, environ, start_response):
        # Method to make instances of this class callable
        self.environ = environ
        path = environ.get('PATH_INFO', '').strip('/')
        self.response_headers = []
        out = []
        if not len(path):
            # Return homepage
            out.extend(self._head())
            out.append(resource_string('eadtoolbox', 'data/html/home.html'))
            out.extend(self._tail())
            
        elif path.startswith('css/'):
            # Return static CSS
            self.response_headers.append(('Content-Type', 'text/css'))
            out.append(resource_string('eadtoolbox', 'data/{0}'.format(path)))
                
        elif path == "play":
            form = cgi.FieldStorage(fp=environ['wsgi.input'], 
                                    environ=environ)
            xml = self._fetch_ead(form)
            try:
                ead = etree.fromstring(xml)
            except etree.XMLSyntaxError:
                # Make use of browser default XML errors
                self.response_headers.append(('Content-Type', 'application/xml'))
                out.append(xml)
            else:
                func = form.getfirst('submit').lower()
                
                if func == 'show':
                    # Sacrifice potentially pretty XML display for browser compatibility
                    self.response_headers.append(('Content-Type', 'text/plain; charset=UTF-8"'))
                    xml_str = etree.tostring(ead, pretty_print=True, encoding='utf-8')
                    out.append(xml_str)
                    
                elif func == "validate":
                    out.extend(self._head())
                    validator = EAD2002DTDValidator()
                    
                    if validator.validate(ead):
                        out.append('<h2>Validation Passed!</h2>')
                    else:
                        out.append('<h2>Validation Failed!</h2>')
                        out.extend(['<p>{0}</p>'.format(e) for e in validator.errors])
                    out.extend(self._tail())
                    
                elif func == "to isad(g)":
                    out.extend(self._head())
                    out.append('<h2>ISAD(G)</h2>')
                    xslt_path = os.path.join('xml', 'ead2isadg.xsl')
                    result = self._apply_xslt(ead, xslt_path)
                    out.append(etree.tostring(result))
                    out.extend(self._tail())
                    
                elif func == "to dc":
                    xslt_path = os.path.join('xml', 'ead2oai_dc.xsl')
                    result = self._apply_xslt(ead, xslt_path)
                    # Sacrifice potentially pretty XML display for browser compatibility
                    self.response_headers.append(('Content-Type', 'text/plain; charset=UTF-8"'))
                    out.append(etree.tostring(result, pretty_print=True, encoding='utf-8'))
                    
                elif func == "to marc":
                    xslt_path = os.path.join('xml', 'ead2marcxml.xsl')
                    result = self._apply_xslt(ead, xslt_path)
                    # Sacrifice potentially pretty XML display for browser compatibility
                    self.response_headers.append(('Content-Type', 'text/plain; charset=UTF-8"'))
                    out.append(etree.tostring(result, pretty_print=True, encoding='utf-8'))
                    
                elif func == 'xsl-fo':
                    xslt_path = os.path.join('xml', 'ead2fo.xsl')
                    result = self._apply_xslt(ead, xslt_path)
                    self.response_headers.append(('Content-Type', 'application/xml'))
                    out.append(etree.tostring(result, pretty_print=True, encoding='utf-8'))
                    
                elif func == 'people':
                    out.extend(self._head())
                    out.extend(['<h2>{0}</h2>'.format(func.title()),
                                '<ul>'
                                ])
                    out.extend(self._html_listItems_from_xpath(ead, '//persname'))
                    out.extend(self._html_listItems_from_xpath(ead, '//famname'))
                    out.append('</ul>')
                    out.extend(self._tail())
                    
                elif func == 'places':
                    out.extend(self._head())
                    out.extend(['<h2>{0}</h2>'.format(func.title()),
                                '<ul>'
                                ])
                    out.extend(self._html_listItems_from_xpath(ead, '//geogname'))
                    out.append('</ul>')
                    out.extend(self._tail())
                    
                elif func == 'subjects':
                    out.extend(self._head())
                    out.extend(['<h2>{0}</h2>'.format(func.title()),
                                '<ul>'
                                ])
                    out.extend(self._html_listItems_from_xpath(ead, '//subject'))
                    out.append('</ul>')
                    out.extend(self._tail())
                    
        else:<commit_msg>made sandbox validate using a EadTransformer objects      XsltEadTransformer objects imported from eadtoolbox.transform<commit_after>"""EAD Sandbox WSGI Application.

The EAD Sandbox provides a Python WSGI compliant web application for playing
around with Encoded Archival Description (EAD) XML documents.

Current capabilities include validation to the DTD, cross-walk to other
metadata schemas, and extraction and display of subject and named entities.
"""

import cgi
try:
    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO

from pkg_resources import resource_stream, resource_string
from lxml import etree

from eadtoolbox.validate import EAD2002DTDValidator
from eadtoolbox.transform import XsltEadTransformer


class EADSandboxWsgiApp(object):
    """EAD Sandbox WSGI Application."""

    def __init__(self):
        self.response_headers = []
        self.txrs = {}
        
    def _fetch_ead(self, form):
        # Fetch EAD XML from the submitted form
        xml = form['eadfile'].value
        if not xml:
            xml = form.getfirst('eadxml')
        return xml
    
    def _head(self):
        # Return HTML Head
        self.response_headers.append(('Content-Type', 'text/html'))
        return [resource_string('eadtoolbox', 'data/html/head.tmpl')]
        
    def _tail(self):
        # Return HTML Tail
        return [resource_string('eadtoolbox', 'data/html/tail.tmpl')]
        
    def _apply_xslt(self, tree, xslt_path):
        # Apply XSLT from xslt_path to tree and return result as an lxml tree
        try:
            transformer = self.txrs[xslt_path]
        except KeyError:
            fh = resource_stream('eadtoolbox', 'data/xml/{0}'.format(xslt_path))
            self.txrs[xslt_path] = transformer = XsltEadTransformer(fh)
            
        return transformer.transform(tree)
    
    def _html_listItems_from_xpath(self, ead, xpath):
        # Return HTML list items from elements in ead that match XPath
        matches = ead.xpath(xpath)
        for xp in matches:
            xml_str = etree.tostring(xp, method="text", encoding="utf-8")
            yield '<li>{0}</li>'.format(xml_str.strip())
                
    def __call__(self, environ, start_response):
        # Method to make instances of this class callable
        self.environ = environ
        path = environ.get('PATH_INFO', '').strip('/')
        self.response_headers = []
        out = []
        if not len(path):
            # Return homepage
            out.extend(self._head())
            out.append(resource_string('eadtoolbox', 'data/html/home.html'))
            out.extend(self._tail())
            
        elif path.startswith('css/'):
            # Return static CSS
            self.response_headers.append(('Content-Type', 'text/css'))
            out.append(resource_string('eadtoolbox', 'data/{0}'.format(path)))
                
        elif path == "play":
            form = cgi.FieldStorage(fp=environ['wsgi.input'], 
                                    environ=environ)
            xml = self._fetch_ead(form)
            try:
                ead = etree.fromstring(xml)
            except etree.XMLSyntaxError:
                # Make use of browser default XML errors
                self.response_headers.append(('Content-Type', 'application/xml'))
                out.append(xml)
            else:
                func = form.getfirst('submit').lower()
                
                if func == 'show':
                    # Sacrifice potentially pretty XML display for browser compatibility
                    self.response_headers.append(('Content-Type', 'text/plain; charset=UTF-8"'))
                    xml_str = etree.tostring(ead, pretty_print=True, encoding='utf-8')
                    out.append(xml_str)
                    
                elif func == "validate":
                    out.extend(self._head())
                    validator = EAD2002DTDValidator()
                    
                    if validator.validate(ead):
                        out.append('<h2>Validation Passed!</h2>')
                    else:
                        out.append('<h2>Validation Failed!</h2>')
                        out.extend(['<p>{0}</p>'.format(e) for e in validator.errors])
                    out.extend(self._tail())
                    
                elif func == "to isad(g)":
                    out.extend(self._head())
                    out.append('<h2>ISAD(G)</h2>')
                    xslt_path = 'ead2isadg.xsl'
                    result = self._apply_xslt(ead, xslt_path)
                    out.append(etree.tostring(result, encoding='utf-8'))
                    out.extend(self._tail())
                    
                elif func == "to dc":
                    xslt_path = 'ead2oai_dc.xsl'
                    result = self._apply_xslt(ead, xslt_path)
                    # Sacrifice potentially pretty XML display for browser compatibility
                    self.response_headers.append(('Content-Type',
                                                  'text/plain; charset=UTF-8"'))
                    out.append(etree.tostring(result,
                                              pretty_print=True,
                                              encoding='utf-8')
                    )
                elif func == "to marc":
                    xslt_path = 'ead2marcxml.xsl'
                    result = self._apply_xslt(ead, xslt_path)
                    # Sacrifice potentially pretty XML display for browser compatibility
                    self.response_headers.append(('Content-Type',
                                                  'text/plain; charset=UTF-8"'))
                    out.append(etree.tostring(result,
                                              pretty_print=True,
                                              encoding='utf-8')
                    )
                    
                elif func == 'people':
                    out.extend(self._head())
                    out.extend(['<h2>{0}</h2>'.format(func.title()),
                                '<ul>'
                                ])
                    out.extend(self._html_listItems_from_xpath(ead, '//persname'))
                    out.extend(self._html_listItems_from_xpath(ead, '//famname'))
                    out.append('</ul>')
                    out.extend(self._tail())
                    
                elif func == 'places':
                    out.extend(self._head())
                    out.extend(['<h2>{0}</h2>'.format(func.title()),
                                '<ul>'
                                ])
                    out.extend(self._html_listItems_from_xpath(ead, '//geogname'))
                    out.append('</ul>')
                    out.extend(self._tail())
                    
                elif func == 'subjects':
                    out.extend(self._head())
                    out.extend(['<h2>{0}</h2>'.format(func.title()),
                                '<ul>'
                                ])
                    out.extend(self._html_listItems_from_xpath(ead, '//subject'))
                    out.append('</ul>')
                    out.extend(self._tail())
                    
        else:
{'fraction_non_alphanumeric': 0.11087242741320767, 'fraction_numerical': 0.005266440302127365, 'mean_word_length': 1.4531701512833588, 'pattern_counts': {'":': 10, '<': 47, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 38}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3909598', 'n_tokens_mistral': 3945, 'n_tokens_neox': 3725, 'n_words': 771}