U
    
W[D                  y   @   s  d Z ddlmZmZ ddddddd	d
ddddddddgZddlZddlmZ ddlm	Z	 ddl
mZmZ ddlmZmZ ddlmZ ddlmZmZmZmZmZ ddlmZ ddlmZ dZdZe ZG dd deZ G d d! d!ej!ej"Z#d"d# Z$e	eG d$d deZ%e	eG d%d deZ&e	eG d&d deZ'e(d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~ddddddddddddddddddddddddddddddddgxZ)G dd deZ*e* Z+dddZ,ddl-m.Z.m/Z/ ddl0m1Z1m2Z2 ddl3Z4dS )a0  
HTML rendering for twisted.web.

@var VALID_HTML_TAG_NAMES: A list of recognized HTML tag names, used by the
    L{tag} object.

@var TEMPLATE_NAMESPACE: The XML namespace used to identify attributes and
    elements used by the templating system, which should be removed from the
    final output document.

@var tags: A convenience object which can produce L{Tag} objects on demand via
    attribute access.  For example: C{tags.div} is equivalent to C{Tag("div")}.
    Tags not specified in L{VALID_HTML_TAG_NAMES} will result in an
    L{AttributeError}.
    )divisionabsolute_importTEMPLATE_NAMESPACEVALID_HTML_TAG_NAMESElement	TagLoader	XMLStringXMLFilerendererflattenflattenStringtagsCommentCDATATagslotCharRefrenderElementN)OrderedDict)implementer)make_parserhandler)NativeStringIOitems)FilePath)r   r   r   r   r   )ITemplateLoader)Loggerz4http://twistedmatrix.com/ns/twisted.web.template/0.1   c                   @   s4   e Zd ZdZdddZdddZdd Zd	d
 ZdS )
_NSContextzL
    A mapping from XML namespaces onto their prefixes in the document.
    Nc                 C   s*   || _ |dk	rt|j| _n
ddi| _dS )ze
        Pull out the parent's namespaces, if there's no parent then default to
        XML.
        Nz$http://www.w3.org/XML/1998/namespaceZxml)parentr   nss)selfr    r"   6/usr/lib/python3/dist-packages/twisted/web/template.py__init__>   s    z_NSContext.__init__c                 C   s   | j ||S )z\
        Get a prefix for a namespace.

        @param d: The default prefix value.
        )r    get)r!   kdr"   r"   r#   r%   J   s    z_NSContext.getc                 C   s   | j || dS )zH
        Proxy through to setting the prefix for the namespace.
        N)r    __setitem__)r!   r&   vr"   r"   r#   r(   S   s    z_NSContext.__setitem__c                 C   s   | j |S )zH
        Proxy through to getting the prefix for the namespace.
        )r    __getitem__)r!   r&   r"   r"   r#   r*   Z   s    z_NSContext.__getitem__)N)N)__name__
__module____qualname____doc__r$   r%   r(   r*   r"   r"   r"   r#   r   9   s
   

	r   c                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd S )!_ToStanzd
    A SAX parser which converts an XML document to the Twisted STAN
    Document Object Model.
    c                 C   s   || _ t | _d| _dS )zM
        @param sourceFilename: the filename to load the XML out of.
        FN)sourceFilenamer   	prefixMapinCDATA)r!   r0   r"   r"   r#   r$   h   s    z_ToStan.__init__c                 C   s
   || _ dS )zY
        Set the document locator, which knows about line and character numbers.
        N)locator)r!   r3   r"   r"   r#   setDocumentLocatorq   s    z_ToStan.setDocumentLocatorc                 C   s   g | _ | j | _g | _g | _dS )z*
        Initialise the document.
        N)documentcurrentstack
xmlnsAttrsr!   r"   r"   r#   startDocumentx   s    z_ToStan.startDocumentc                 C   s   dS )z!
        Document ended.
        Nr"   r9   r"   r"   r#   endDocument   s    z_ToStan.endDocumentc                 C   s   dS )z6
        Processing instructions are ignored.
        Nr"   )r!   targetdatar"   r"   r#   processingInstruction   s    z_ToStan.processingInstructionc                 C   sT   t | j| _|| j|< |tkr"dS |dkr<| jd|f n| jd| |f dS )z
        Set up the prefix mapping, which maps fully qualified namespace URIs
        onto namespace prefixes.

        This gets called before startElementNS whenever an C{xmlns} attribute
        is seen.
        NZxmlnszxmlns:%s)r   r1   r   r8   append)r!   prefixZurir"   r"   r#   startPrefixMapping   s    	
z_ToStan.startPrefixMappingc                 C   s   | j j| _ dS )zb
        "Pops the stack" on the prefix mapping.

        Gets called after endElementNS.
        N)r1   r   )r!   r@   r"   r"   r#   endPrefixMapping   s    z_ToStan.endPrefixMappingc                 C   sB  | j }| j }| j }|\}}|tkr|dkr8d}nh|dkrz|d }	W n tk
rd   d}	Y nX t|d |	|||d}
| j|
 | j	|
 |
j
| _	dS d}t|}t|D ],\}}|\}}|tkrq|dkr|}||= qt }t|D ]<\\}}}| j|}|dkr|}nd	||f }|||< q|tkr|d
kr| jsXtdtf d|krptdtf td||||d}
|
| jd j|d < | j|
 |
j
| _	dS | jr|t| j g | _|tkr|dk	r| j| }|dk	rd	| j| |f }t|t|||||d}
| j|
 | j	|
 |
j
| _	dS )a]  
        Gets called when we encounter a new xmlns attribute.

        @param namespaceAndName: a (namespace, name) tuple, where name
            determines which type of action to take, if the namespace matches
            L{TEMPLATE_NAMESPACE}.
        @param qname: ignored.
        @param attrs: attributes on the element being started.
        transparent r   )NdefaultN)Nname)rE   filename
lineNumbercolumnNumberrenderz%s:%sattrz<{%s}attr> as top-level elementrF   z$<{%s}attr> requires a name attribute)rJ   rG   rH   rI   )
attributesrJ   rG   rH   rI   )r0   r3   ZgetLineNumberZgetColumnNumberr   KeyErrorr   r7   r?   r6   childrenr   r   r1   r%   AssertionErrorr   rM   r8   update)r!   ZnamespaceAndNameqnameZattrsrG   rH   rI   nsrF   rE   ZelrJ   r&   r)   ZattrNSZjustTheNameZnonTemplateAttrsZattrNsZattrNameZnsPrefixZattrKeyr@   r"   r"   r#   startElementNS   s    


  	


 

   z_ToStan.startElementNSc                 C   s*   | j r| jd | dS | j| dS )z
        Called when we receive some characters.  CDATA characters get passed
        through as is.

        @type ch: C{string}
        rL   N)r2   r7   r?   r6   )r!   Zchr"   r"   r#   
characters  s    z_ToStan.charactersc                 C   s,   | j   | j r | j d j| _n| j| _dS )z
        A namespace tag is closed.  Pop the stack, if there's anything left in
        it, otherwise return to the document's namespace.
        rL   N)r7   poprO   r6   r5   )r!   rF   rR   r"   r"   r#   endElementNS  s    
z_ToStan.endElementNSc                 C   s   dS z#
        DTDs are ignored.
        Nr"   )r!   rF   ZpublicIdZsystemIdr"   r"   r#   startDTD*  s    z_ToStan.startDTDc                 G   s   dS rX   r"   )r!   argsr"   r"   r#   endDTD0  s    z_ToStan.endDTDc                 C   s   d| _ | jg  dS )zO
        We're starting to be in a CDATA element, make a note of this.
        TN)r2   r7   r?   r9   r"   r"   r#   
startCDATA6  s    z_ToStan.startCDATAc                 C   s*   d| _ d| j }| jt| dS )z
        We're no longer in a CDATA element.  Collect up the characters we've
        parsed and put them in a new CDATA object.
        FrD   N)r2   joinr7   rV   r6   r?   r   )r!   commentr"   r"   r#   endCDATA>  s    z_ToStan.endCDATAc                 C   s   | j t| dS )z=
        Add an XML comment which we've encountered.
        N)r6   r?   r   )r!   Zcontentr"   r"   r#   r^   H  s    z_ToStan.commentN)r+   r,   r-   r.   r$   r4   r:   r;   r>   rA   rB   rT   rU   rW   rY   r[   r\   r_   r^   r"   r"   r"   r#   r/   b   s    	
	c
r/   c                 C   s   t  }|tjd |tjd |tjd |tjd tt| dd}|	| |
| |tj| ||  |jS )z
    Perform a SAX parse of an XML document with the _ToStan class.

    @param fl: The XML document to be parsed.
    @type fl: A file object or filename.

    @return: a C{list} of Stan objects.
    r   r   rF   N)r   Z
setFeaturer   Zfeature_validationZfeature_namespacesZfeature_external_gesZfeature_external_pesr/   getattrZsetContentHandlerZsetEntityResolverZsetPropertyZproperty_lexical_handlerparser5   )Zflparsersr"   r"   r#   _flatsaxParseP  s    	


rd   c                   @   s    e Zd ZdZdd Zdd ZdS )r   z
    An L{ITemplateLoader} that loads existing L{IRenderable} providers.

    @ivar tag: The object which will be loaded.
    @type tag: An L{IRenderable} provider.
    c                 C   s
   || _ dS )zm
        @param tag: The object which will be loaded.
        @type tag: An L{IRenderable} provider.
        Ntag)r!   rf   r"   r"   r#   r$   r  s    zTagLoader.__init__c                 C   s   | j gS Nre   r9   r"   r"   r#   loadz  s    zTagLoader.loadNr+   r,   r-   r.   r$   rh   r"   r"   r"   r#   r   i  s   c                   @   s    e Zd ZdZdd Zdd ZdS )r   z
    An L{ITemplateLoader} that loads and parses XML from a string.

    @ivar _loadedTemplate: The loaded document.
    @type _loadedTemplate: a C{list} of Stan objects.
    c                 C   s&   t |ts|d}tt|| _dS )z
        Run the parser on a L{NativeStringIO} copy of the string.

        @param s: The string from which to load the XML.
        @type s: C{str}, or a UTF-8 encoded L{bytes}.
        utf8N)
isinstancestrdecoderd   r   _loadedTemplate)r!   rc   r"   r"   r#   r$     s    

zXMLString.__init__c                 C   s   | j S )zx
        Return the document.

        @return: the loaded document.
        @rtype: a C{list} of Stan objects.
        )rn   r9   r"   r"   r#   rh     s    zXMLString.loadNri   r"   r"   r"   r#   r     s   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )r	   a3  
    An L{ITemplateLoader} that loads and parses XML from a file.

    @ivar _loadedTemplate: The loaded document, or L{None}, if not loaded.
    @type _loadedTemplate: a C{list} of Stan objects, or L{None}.

    @ivar _path: The L{FilePath}, file object, or filename that is being
        loaded from.
    c                 C   s*   t |tstjdtdd d| _|| _dS )z
        Run the parser on a file.

        @param path: The file from which to load the XML.
        @type path: L{FilePath}
        zhPassing filenames or file objects to XMLFile is deprecated since Twisted 12.1.  Pass a FilePath instead.   )category
stacklevelN)rk   r   warningswarnDeprecationWarningrn   _path)r!   pathr"   r"   r#   r$     s    
 zXMLFile.__init__c              
   C   sB   t | jtst| jS | jd}t|W  5 Q R  S Q R X dS )z{
        Read and parse the XML.

        @return: the loaded document.
        @rtype: a C{list} of Stan objects.
        rN)rk   ru   r   rd   open)r!   fr"   r"   r#   _loadDoc  s    
zXMLFile._loadDocc                 C   s   d| j f S )Nz<XMLFile of %r>)ru   r9   r"   r"   r#   __repr__  s    zXMLFile.__repr__c                 C   s   | j dkr|  | _ | j S )z
        Return the document, first loading it if necessary.

        @return: the loaded document.
        @rtype: a C{list} of Stan objects.
        N)rn   rz   r9   r"   r"   r#   rh     s    

zXMLFile.loadN)r+   r,   r-   r.   r$   rz   r{   rh   r"   r"   r"   r#   r	     s
   
aZabbrZacronymZaddressZappletZareaZarticleZasideZaudiobbaseZbasefontZbdiZbdoZbigZ
blockquoteZbodybrZbuttonZcanvasZcaptioncenterZcitecodecolZcolgroupZcommandZdatalistZdddelZdetailsZdfndirZdivZdlZdtZemZembedZfieldsetZ
figcaptionZfigureZfontZfooterZformframeZframesetZh1Zh2Zh3Zh4Zh5Zh6headheaderZhgroupZhrZhtmliZiframeZimginputZinsZisindexZkeygenZkbdZlabelZlegendZlilinkmapZmarkZmenumetaZmeterZnavZnoframesZnoscriptobjectZolZoptgroupZoptionoutputpZparamZpreZprogressqZrpZrtZrubyrc   ZsampZscriptZsectionZselectZsmallsourcespanZstrikeZstrongZstylesubZsummaryZsuptableZtbodyZtdZtextareaZtfootZthZtheadtimetitleZtrZttuZulvarZvideoZwbrc                   @   s   e Zd ZdZdd ZdS )_TagFactorya  
    A factory for L{Tag} objects; the implementation of the L{tags} object.

    This allows for the syntactic convenience of C{from twisted.web.html import
    tags; tags.a(href="linked-page.html")}, where 'a' can be basically any HTML
    tag.

    The class is not exposed publicly because you only ever need one of these,
    and we already made it for you.

    @see: L{tags}
    c                 C   s8   |dkrt dS |d}|tkr0td|f t |S )NrC   rD   _zunknown tag %r)r   rstripr   AttributeError)r!   ZtagNamer"   r"   r#   __getattr__   s    
z_TagFactory.__getattr__N)r+   r,   r-   r.   r   r"   r"   r"   r#   r     s   r      <!DOCTYPE html>c                    sj   |dk	r |  d  dkr.tjjj t|j } fdd}|| |fdd tS )a  
    Render an element or other C{IRenderable}.

    @param request: The C{Request} being rendered to.
    @param element: An C{IRenderable} which will be rendered.
    @param doctype: A C{bytes} which will be written as the first line of
        the request, or L{None} to disable writing of a doctype.  The C{string}
        should not include a trailing newline and will default to the HTML5
        doctype C{'<!DOCTYPE html>'}.

    @returns: NOT_DONE_YET

    @since: 12.1
    N   
c                    s<   t jd| d jjr.t | jdS d d S )Nz/An error occurred while rendering the response.failurerj   sr   <div style="font-size:800%;background-color:#FFF;color:#F00">An error occurred while rendering the response.</div>)
_moduleLogr   ZsiteZdisplayTracebacksr   writeencoder   _failElementrequestr"   r#   eb(  s    
zrenderElement.<locals>.ebc                    s      S rg   )Zfinish)r   )r   r"   r#   <lambda>8      zrenderElement.<locals>.<lambda>)	r   twistedZwebutilZFailureElementr   Z
addErrbackZaddBothNOT_DONE_YET)r   elementZdoctyper   r'   r   r"   r   r#   r     s    



)r   r
   )r   r   )r   N)5r.   Z
__future__r   r   __all__rr   collectionsr   Zzope.interfacer   Zxml.saxr   r   Ztwisted.python.compatr   r   Ztwisted.python.filepathr   Ztwisted.web._stanr   r   r   r   r   Ztwisted.web.iwebr   Ztwisted.loggerr   r   r   r   r   r   ZContentHandlerZEntityResolverr/   rd   r   r   r	   setr   r   r   r   Ztwisted.web._elementr   r
   Ztwisted.web._flattenr   r   Ztwisted.web.utilr   r"   r"   r"   r#   <module>   sT               
) o >                                                                                                            
.