U
    s@g0                     @   s@  d Z ddlmZmZ ddlZddlmZ ddlmZm	Z	m
Z
mZ ddlmZ ddlmZ ddlmZmZmZmZ dd	lmZ d
d Zdd ZG dd dejZG dd deZG dd dejZG dd dejZG dd deZG dd deZG dd deZG dd deZ G dd deZ!d d! Z"ddddddd!gZ#dS )"z0
An assortment of web server-related utilities.
    )divisionabsolute_importN)urlpath)_PY3unicodenativeStringescape)fullyQualifiedName)resource)	TagLoader	XMLStringElementrenderer)flattenStringc                 C   s   dt | f S )aK  
    Wraps <pre> tags around some text and HTML-escape it.

    This is here since once twisted.web.html was deprecated it was hard to
    migrate the html.PRE from current code to twisted.web.template.

    For new code consider using twisted.web.template.

    @return: Escaped text wrapped in <pre> tags.
    @rtype: C{str}
    z<pre>%s</pre>)r   )text r   2/usr/lib/python3/dist-packages/twisted/web/util.py_PRE   s    r   c                 C   sZ   t | trtd|dd ||  ddtt| ddi }t	rV|d}|S )a  
    Generate a redirect to the given location.

    @param URL: A L{bytes} giving the location to which to redirect.
    @type URL: L{bytes}

    @param request: The request object to use to generate the redirect.
    @type request: L{IRequest<twisted.web.iweb.IRequest>} provider

    @raise TypeError: If the type of C{URL} a L{unicode} instead of L{bytes}.

    @return: A C{bytes} containing HTML which tries to convince the client agent
        to visit the new location even if it doesn't respect the I{FOUND}
        response code.  This is intended to be returned from a render method,
        eg::

            def render_GET(self, request):
                return redirectTo(b"http://example.com/", request)
    z!Unicode object not allowed as URLs   Content-Types   text/html; charset=utf-8z
<html>
    <head>
        <meta http-equiv="refresh" content="0;URL=%(url)s">
    </head>
    <body bgcolor="#FFFFFF" text="#000000">
    <a href="%(url)s">click here</a>
    </body>
</html>
urlutf-8utf8)

isinstancer   	TypeErrorZ	setHeaderZredirectr   r   decodeencoder   )ZURLrequestZcontentr   r   r   
redirectTo(   s    

	

r   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	RedirectTc                 C   s   t j|  || _d S N)r
   Resource__init__r   selfr   r   r   r   r    R   s    zRedirect.__init__c                 C   s   t | j|S r   )r   r   r"   r   r   r   r   renderV   s    zRedirect.renderc                 C   s   | S r   r   r"   namer   r   r   r   getChildY   s    zRedirect.getChildN)__name__
__module____qualname__isLeafr    r$   r'   r   r   r   r   r   O   s   r   c                   @   s    e Zd ZdZdd Zdd ZdS )ChildRedirectorr   c                 C   s>   | ddkr.|ds.|ds.td| t| | d S )Nz://z../zvIt seems you've given me a redirect (%s) that is a child of myself! That's not good, it'll cause an infinite redirect.)find
startswith
ValueErrorr   r    r!   r   r   r   r    _   s    zChildRedirector.__init__c                 C   s(   | j }|ds|d7 }||7 }t|S )Nr.   )r   endswithr,   )r"   r&   r   ZnewUrlr   r   r   r'   g   s
    
zChildRedirector.getChildN)r(   r)   r*   r+   r    r'   r   r   r   r   r,   ]   s   r,   c                   @   s$   e Zd ZdZdZdd Zdd ZdS )ParentRedirectz'
    I redirect to URLPath.here().
       c                 C   s   t tj| |S r   )r   r   ZURLPathZfromRequestherer#   r   r   r   r$   t   s    zParentRedirect.renderc                 C   s   | S r   r   r#   r   r   r   r'   w   s    zParentRedirect.getChildN)r(   r)   r*   __doc__r+   r$   r'   r   r   r   r   r3   o   s   r3   c                   @   s<   e Zd ZdZdZdd Zdd Zdd Zd	d
 Zdd Z	dS )DeferredResourcezT
    I wrap up a Deferred that will eventually result in a Resource
    object.
    r4   c                 C   s   t j|  || _d S r   )r
   r   r    d)r"   r8   r   r   r   r       s    zDeferredResource.__init__c                 C   s   | S r   r   r%   r   r   r   r'      s    zDeferredResource.getChildc                 C   s*   | j | j|| j| ddlm} |S )Nr   )NOT_DONE_YET)r8   ZaddCallback_cbChildZ
addErrback_ebChildZtwisted.web.serverr9   )r"   r   r9   r   r   r   r$      s     zDeferredResource.renderc                 C   s   | t|| d S r   )r$   r
   ZgetChildForRequest)r"   Zchildr   r   r   r   r:      s    zDeferredResource._cbChildc                 C   s   | | d S r   )ZprocessingFailed)r"   reasonr   r   r   r   r;      s    zDeferredResource._ebChildN)
r(   r)   r*   r6   r+   r    r'   r$   r:   r;   r   r   r   r   r7   {   s   r7   c                   @   s0   e Zd ZdZdd Zedd Zedd ZdS )	_SourceLineElementa  
    L{_SourceLineElement} is an L{IRenderable} which can render a single line of
    source code.

    @ivar number: A C{int} giving the line number of the source code to be
        rendered.
    @ivar source: A C{str} giving the source code to be rendered.
    c                 C   s   t | | || _|| _d S r   )r   r    numbersource)r"   loaderr>   r?   r   r   r   r       s    z_SourceLineElement.__init__c                 C   s   || j ddS )zA
        Render the line of source as a child of C{tag}.
        z  u     )r?   replacer"   r   tagr   r   r   
sourceLine   s    z_SourceLineElement.sourceLinec                 C   s   |t | jS )z>
        Render the line number as a child of C{tag}.
        )strr>   rB   r   r   r   
lineNumber   s    z_SourceLineElement.lineNumberN)r(   r)   r*   r6   r    r   rD   rF   r   r   r   r   r=      s   
r=   c                   @   s,   e Zd ZdZdd Zdd Zedd ZdS )	_SourceFragmentElementa  
    L{_SourceFragmentElement} is an L{IRenderable} which can render several lines
    of source code near the line number of a particular frame object.

    @ivar frame: A L{Failure<twisted.python.failure.Failure>}-style frame object
        for which to load a source line to render.  This is really a tuple
        holding some information from a frame object.  See
        L{Failure.frames<twisted.python.failure.Failure>} for specifics.
    c                 C   s   t | | || _d S r   r   r    framer"   r@   rI   r   r   r   r       s    z_SourceFragmentElement.__init__c                 c   sF   | j d }| j d }t|d |d D ]}|t|| fV  q&dS )a$  
        Find the source line references by C{self.frame} and yield, in source
        line order, it and the previous and following lines.

        @return: A generator which yields two-tuples.  Each tuple gives a source
            line number and the contents of that source line.
        r4      N)rI   range	linecachegetlinerstrip)r"   filenamerF   ZsnipLineNumberr   r   r   _getSourceLines   s    

z&_SourceFragmentElement._getSourceLinesc                 c   sV   |   D ]H\}}| }|| jd kr,d}nd}t|f d|i}t|||V  qdS )z
        Render the source line indicated by C{self.frame} and several
        surrounding lines.  The active line will be given a I{class} of
        C{"snippetHighlightLine"}.  Other lines will be given a I{class} of
        C{"snippetLine"}.
        rK   ZsnippetHighlightLineZsnippetLineclassN)rQ   clonerI   r   r=   )r"   r   rC   rF   rD   ZnewTagZcssClassr@   r   r   r   sourceLines   s    z"_SourceFragmentElement.sourceLinesN)r(   r)   r*   r6   r    rQ   r   rT   r   r   r   r   rG      s
   	rG   c                   @   sH   e Zd ZdZdd Zedd Zedd Zedd	 Zed
d Z	dS )_FrameElementa  
    L{_FrameElement} is an L{IRenderable} which can render details about one
    frame from a L{Failure<twisted.python.failure.Failure>}.

    @ivar frame: A L{Failure<twisted.python.failure.Failure>}-style frame object
        for which to load a source line to render.  This is really a tuple
        holding some information from a frame object.  See
        L{Failure.frames<twisted.python.failure.Failure>} for specifics.
    c                 C   s   t | | || _d S r   rH   rJ   r   r   r   r       s    z_FrameElement.__init__c                 C   s   || j d S )zY
        Render the name of the file this frame references as a child of C{tag}.
        r4   rI   rB   r   r   r   rP      s    z_FrameElement.filenamec                 C   s   |t | jd S )zc
        Render the source line number this frame references as a child of
        C{tag}.
        rK   )rE   rI   rB   r   r   r   rF      s    z_FrameElement.lineNumberc                 C   s   || j d S )zV
        Render the function name this frame references as a child of C{tag}.
        r   rV   rB   r   r   r   function  s    z_FrameElement.functionc                 C   s   t t|| jS )zn
        Render the source code surrounding the line this frame references,
        replacing C{tag}.
        )rG   r   rI   rB   r   r   r   r?     s    z_FrameElement.sourceN)
r(   r)   r*   r6   r    r   rP   rF   rW   r?   r   r   r   r   rU      s   	


rU   c                   @   s$   e Zd ZdZdd Zedd ZdS )_StackElementzW
    L{_StackElement} renders an L{IRenderable} which can render a list of frames.
    c                 C   s   t | | || _d S r   )r   r    stackFrames)r"   r@   rY   r   r   r   r      s    z_StackElement.__init__c                    s    fdd| j D S )zW
        Render the list of frames in this L{_StackElement}, replacing C{tag}.
        c                    s   g | ]}t t  |qS r   )rU   r   rS   ).0rI   rC   r   r   
<listcomp>(  s   z(_StackElement.frames.<locals>.<listcomp>)rY   rB   r   r[   r   frames#  s    
z_StackElement.framesN)r(   r)   r*   r6   r    r   r]   r   r   r   r   rX     s   rX   c                   @   sF   e Zd ZdZedZdddZedd Zedd	 Z	ed
d Z
dS )FailureElementa  
    L{FailureElement} is an L{IRenderable} which can render detailed information
    about a L{Failure<twisted.python.failure.Failure>}.

    @ivar failure: The L{Failure<twisted.python.failure.Failure>} instance which
        will be rendered.

    @since: 12.1
    ao  
<div xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1">
  <style type="text/css">
    div.error {
      color: red;
      font-family: Verdana, Arial, helvetica, sans-serif;
      font-weight: bold;
    }

    div {
      font-family: Verdana, Arial, helvetica, sans-serif;
    }

    div.stackTrace {
    }

    div.frame {
      padding: 1em;
      background: white;
      border-bottom: thin black dashed;
    }

    div.frame:first-child {
      padding: 1em;
      background: white;
      border-top: thin black dashed;
      border-bottom: thin black dashed;
    }

    div.location {
    }

    span.function {
      font-weight: bold;
      font-family: "Courier New", courier, monospace;
    }

    div.snippet {
      margin-bottom: 0.5em;
      margin-left: 1em;
      background: #FFFFDD;
    }

    div.snippetHighlightLine {
      color: red;
    }

    span.code {
      font-family: "Courier New", courier, monospace;
    }
  </style>

  <div class="error">
    <span t:render="type" />: <span t:render="value" />
  </div>
  <div class="stackTrace" t:render="traceback">
    <div class="frame" t:render="frames">
      <div class="location">
        <span t:render="filename" />:<span t:render="lineNumber" /> in
        <span class="function" t:render="function" />
      </div>
      <div class="snippet" t:render="source">
        <div t:render="sourceLines">
          <span class="lineno" t:render="lineNumber" />
          <code class="code" t:render="sourceLine" />
        </div>
      </div>
    </div>
  </div>
  <div class="error">
    <span t:render="type" />: <span t:render="value" />
  </div>
</div>
Nc                 C   s   t | | || _d S r   )r   r    failure)r"   r_   r@   r   r   r   r      s    zFailureElement.__init__c                 C   s   |t | jjS )zA
        Render the exception type as a child of C{tag}.
        )r	   r_   typerB   r   r   r   r`     s    zFailureElement.typec                 C   s   |t | jjdS )zB
        Render the exception value as a child of C{tag}.
        r   )r   r_   valuer   rB   r   r   r   ra     s    zFailureElement.valuec                 C   s   t t|| jjS )z
        Render all the frames in the wrapped
        L{Failure<twisted.python.failure.Failure>}'s traceback stack, replacing
        C{tag}.
        )rX   r   r_   r]   rB   r   r   r   	traceback  s    zFailureElement.traceback)N)r(   r)   r*   r6   r   r@   r    r   r`   ra   rb   r   r   r   r   r^   /  s   	K


r^   c                 C   sN   g }t dt| |j t|d tr>|d dddS |d   dS )a  
    Construct an HTML representation of the given failure.

    Consider using L{FailureElement} instead.

    @type myFailure: L{Failure<twisted.python.failure.Failure>}

    @rtype: C{bytes}
    @return: A string containing the HTML representation of the given failure.
    Nr   r   asciixmlcharrefreplace)	r   r^   ZaddBothappendr   bytesr   r   ZraiseException)Z	myFailureresultr   r   r   formatFailure  s
    rh   )$r6   Z
__future__r   r   rM   Ztwisted.pythonr   Ztwisted.python.compatr   r   r   r   Ztwisted.python.reflectr	   Ztwisted.webr
   Ztwisted.web.templater   r   r   r   r   r   r   r   r   r,   r3   r7   r=   rG   rU   rX   r^   rh   __all__r   r   r   r   <module>   s8   ' 12u     