3
Z<                 @   sz   d Z ddlmZ ddlmZ ddlmZ ddlmZmZ dZ	ddd	Z
d
d ZeG dd deZeG dd deZdS )ae  
    werkzeug.contrib.atom
    ~~~~~~~~~~~~~~~~~~~~~

    This module provides a class called :class:`AtomFeed` which can be
    used to generate feeds in the Atom syndication format (see :rfc:`4287`).

    Example::

        def atom_feed(request):
            feed = AtomFeed("My Blog", feed_url=request.url,
                            url=request.host_url,
                            subtitle="My example blog for a feed test.")
            for post in Post.query.limit(10).all():
                feed.add(post.title, post.body, content_type='html',
                         author=post.author, url=post.url, id=post.uid,
                         updated=post.last_update, published=post.pub_date)
            return feed.get_response()

    :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details.
    :license: BSD, see LICENSE for more details.
    )datetime)escape)BaseResponse)implements_to_stringstring_typeszhttp://www.w3.org/1999/xhtmlNc             C   sB   |dkrd| t || f S |s.d| t|| f S d| |t|| f S )z?Helper function for the builder that creates an XML text block.Zxhtmlz/<%s type="xhtml"><div xmlns="%s">%s</div></%s>
z<%s>%s</%s>
z<%s type="%s">%s</%s>
)XHTML_NAMESPACEr   )namecontentcontent_type r   9/tmp/pip-build-tdvmdaws/Werkzeug/werkzeug/contrib/atom.py_make_text_block"   s    r   c             C   s   | j  }| jr|S |d S )z$Format a datetime object for iso8601Z)	isoformattzinfo)objZiso8601r   r   r   format_iso8601-   s    r   c               @   sV   e Zd ZdZdZd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 )AtomFeeda	  A helper class that creates Atom feeds.

    :param title: the title of the feed. Required.
    :param title_type: the type attribute for the title element.  One of
                       ``'html'``, ``'text'`` or ``'xhtml'``.
    :param url: the url for the feed (not the url *of* the feed)
    :param id: a globally unique id for the feed.  Must be an URI.  If
               not present the `feed_url` is used, but one of both is
               required.
    :param updated: the time the feed was modified the last time.  Must
                    be a :class:`datetime.datetime` object.  If not
                    present the latest entry's `updated` is used.
                    Treated as UTC if naive datetime.
    :param feed_url: the URL to the feed.  Should be the URL that was
                     requested.
    :param author: the author of the feed.  Must be either a string (the
                   name) or a dict with name (required) and uri or
                   email (both optional).  Can be a list of (may be
                   mixed, too) strings and dicts, too, if there are
                   multiple authors. Required if not every entry has an
                   author element.
    :param icon: an icon for the feed.
    :param logo: a logo for the feed.
    :param rights: copyright information for the feed.
    :param rights_type: the type attribute for the rights element.  One of
                        ``'html'``, ``'text'`` or ``'xhtml'``.  Default is
                        ``'text'``.
    :param subtitle: a short description of the feed.
    :param subtitle_type: the type attribute for the subtitle element.
                          One of ``'text'``, ``'html'``, ``'text'``
                          or ``'xhtml'``.  Default is ``'text'``.
    :param links: additional links.  Must be a list of dictionaries with
                  href (required) and rel, type, hreflang, title, length
                  (all optional)
    :param generator: the software that generated this feed.  This must be
                      a tuple in the form ``(name, url, version)``.  If
                      you don't want to specify one of them, set the item
                      to `None`.
    :param entries: a list with the entries for the feed. Entries can also
                    be added later with :meth:`add`.

    For more information on the elements see
    http://www.atomenabled.org/developers/syndication/

    Everywhere where a list is demanded, any iterable can be used.
    WerkzeugNc             K   s  || _ |jdd| _|jd| _|jd| j| _|jd| j| _|jd| _|jdf | _|jd| _|jd	| _	|jd
| _
|jd| _|jd| _|jdd| _|jd| _| jd kr| j| _|jdg | _|rt|pg | _t| jd st| jttf r| jg| _x2t| jD ]$\}}t|tsd|i| j|< qW | j sTtd| jsdtdx"| jD ]}d|krltdqlW d S )N
title_typetexturlfeed_urlidupdatedauthoriconlogorightsrights_typesubtitlesubtitle_type	generatorlinks__iter__r   ztitle is requiredzid is requiredz#author must contain at least a name)titlegetr   r   r   r   r   r   r   r   r   r   r    r!   r"   default_generatorr#   listentrieshasattr
isinstancer   dict	enumerate
ValueError	TypeError)selfr%   r)   kwargsir   r   r   r   __init__i   s>    


zAtomFeed.__init__c             O   sR   t |dkr2| r2t|d tr2| jj|d  n| j|d< | jjt|| dS )zAdd a new entry to the feed.  This function can either be called
        with a :class:`FeedEntry` or some keyword and positional arguments
        that are forwarded to the :class:`FeedEntry` constructor.
           r   r   N)lenr+   	FeedEntryr)   appendr   )r0   argsr1   r   r   r   add   s     
zAtomFeed.addc             C   s   d| j j| jt| jf S )Nz<%s %r (%d entries)>)	__class____name__r%   r5   r)   )r0   r   r   r   __repr__   s    zAtomFeed.__repr__c       	      #   sr  | j s&tdd | jD r&ddif| _ | jsVtdd | jD }|rL|d$ pRtj | _dV  d	V  d
td| j| j	 V  dt
| j V  dt| j V  | jrdt
| j V  | jrdt
| j V  x,| jD ]" ddj fdd D  V  qW xf| j D ]\}dV  dt
|d  V  d|kr2dt
|d  V  d|krNdt
|d  V  dV   qW | jrxd
td| j| j V  | jrdt
| j V  | jrdt
| j V  | jrd
td| j| j V  | j\}}}|s|s|r8dg}|r|jdt
|  |r|jd t
|  |jd!t
|  dj|V  x.| jD ]$}x|j D ]}d
| V  qNW q@W d"V  d#S )%z-Return a generator that yields pieces of XML.c             s   s   | ]}|j  V  qd S )N)r   ).0er   r   r   	<genexpr>   s    z$AtomFeed.generate.<locals>.<genexpr>r   zUnknown authorc             S   s   g | ]
}|j qS r   )r   )r=   entryr   r   r   
<listcomp>   s    z%AtomFeed.generate.<locals>.<listcomp>r4   z'<?xml version="1.0" encoding="utf-8"?>
z+<feed xmlns="http://www.w3.org/2005/Atom">
z  r%   z  <id>%s</id>
z  <updated>%s</updated>
z  <link href="%s" />
z   <link href="%s" rel="self" />
z  <link %s/>
 c             3   s"   | ]}d |t  | f V  qdS )z%s="%s" N)r   )r=   k)linkr   r   r?      s   z  <author>
z    <name>%s</name>
uriz    <uri>%s</uri>
emailz    <email>%s</email>
z  </author>
r    z  <icon>%s</icon>
z  <logo>%s</logo>
r   z  <generatorz	 uri="%s"z version="%s"z>%s</generator>
z</feed>
N)r   anyr)   r   sortedr   utcnowr   r%   r   r   r   r   r   r   r#   joinr    r!   r   r   r   r   r"   r7   generate)	r0   datesr   Zgenerator_nameZgenerator_urlZgenerator_versiontmpr@   liner   )rD   r   rL      sd    



zAtomFeed.generatec             C   s   dj | j S )zConvert the feed into a string.rB   )rK   rL   )r0   r   r   r   	to_string   s    zAtomFeed.to_stringc             C   s   t | j ddS )z&Return a response object for the feed.zapplication/atom+xml)mimetype)r   rP   )r0   r   r   r   get_response   s    zAtomFeed.get_responsec             C   s   | j  ||S )z&Use the class as WSGI response object.)rR   )r0   environZstart_responser   r   r   __call__   s    zAtomFeed.__call__c             C   s   | j  S )N)rP   )r0   r   r   r   __str__   s    zAtomFeed.__str__)r   NN)NN)r;   
__module____qualname____doc__r'   r3   r9   r<   rL   rP   rR   rT   rU   r   r   r   r   r   5   s   0
#8r   c               @   s:   e Zd ZdZdddZdd Zdd Zd	d
 Zdd ZdS )r6   a	  Represents a single entry in a feed.

    :param title: the title of the entry. Required.
    :param title_type: the type attribute for the title element.  One of
                       ``'html'``, ``'text'`` or ``'xhtml'``.
    :param content: the content of the entry.
    :param content_type: the type attribute for the content element.  One
                         of ``'html'``, ``'text'`` or ``'xhtml'``.
    :param summary: a summary of the entry's content.
    :param summary_type: the type attribute for the summary element.  One
                         of ``'html'``, ``'text'`` or ``'xhtml'``.
    :param url: the url for the entry.
    :param id: a globally unique id for the entry.  Must be an URI.  If
               not present the URL is used, but one of both is required.
    :param updated: the time the entry was modified the last time.  Must
                    be a :class:`datetime.datetime` object.  Treated as
                    UTC if naive datetime. Required.
    :param author: the author of the entry.  Must be either a string (the
                   name) or a dict with name (required) and uri or
                   email (both optional).  Can be a list of (may be
                   mixed, too) strings and dicts, too, if there are
                   multiple authors. Required if the feed does not have an
                   author element.
    :param published: the time the entry was initially published.  Must
                      be a :class:`datetime.datetime` object.  Treated as
                      UTC if naive datetime.
    :param rights: copyright information for the entry.
    :param rights_type: the type attribute for the rights element.  One of
                        ``'html'``, ``'text'`` or ``'xhtml'``.  Default is
                        ``'text'``.
    :param links: additional links.  Must be a list of dictionaries with
                  href (required) and rel, type, hreflang, title, length
                  (all optional)
    :param categories: categories for the entry. Must be a list of dictionaries
                       with term (required), scheme and label (all optional)
    :param xml_base: The xml base (url) for this feed item.  If not provided
                     it will default to the item url.

    For more information on the elements see
    http://www.atomenabled.org/developers/syndication/

    Everywhere where a list is demanded, any iterable can be used.
    Nc             K   sH  || _ |jdd| _|| _|jdd| _|jd| _|jd| j| _|jd| _|jd| _|jd	d| _	|jd
f | _
|jd| _|jd| _|jdg | _|jdg | _|jd|| _t| j
d st| j
ttf r| j
g| _
x.t| j
D ] \}}t|tsd|i| j
|< qW | j s$td| js4td| jsDtdd S )Nr   r   r
   htmlr   r   r   summarysummary_typer   	publishedr   r#   
categoriesxml_baser$   r   ztitle is requiredzid is requiredzupdated is required)r%   r&   r   r	   r
   r   r   r   rZ   r[   r   r\   r   r#   r]   r^   r*   r+   r   r,   r-   r.   )r0   r%   r	   r   r1   r2   r   r   r   r   r3     s6    

zFeedEntry.__init__c             C   s   d| j j| jf S )Nz<%s %r>)r:   r;   r%   )r0   r   r   r   r<   4  s    zFeedEntry.__repr__c             #   s  d}| j rdt| j  }d| V  dtd| j| j V  dt| j V  dt| j V  | jrndt| j V  | j	rd	t| j	 V  x`| j
D ]V}d
V  dt|d  V  d|krdt|d  V  d|krdt|d  V  dV  qW x,| jD ]"ddjfddD  V  qW x.| jD ]$ ddj fdd D  V  qW | jrbdtd| j| j V  | jrdtd| j| j V  dV  dS )zYields pieces of ATOM XML.rB   z xml:base="%s"z
<entry%s>
z  r%   z  <id>%s</id>
z  <updated>%s</updated>
z  <published>%s</published>
z  <link href="%s" />
z  <author>
z    <name>%s</name>
r   rE   z    <uri>%s</uri>
rF   z    <email>%s</email>
z  </author>
z  <link %s/>
c             3   s"   | ]}d |t  | f V  qdS )z%s="%s" N)r   )r=   rC   )rD   r   r   r?   Q  s   z%FeedEntry.generate.<locals>.<genexpr>z  <category %s/>
c             3   s"   | ]}d |t  | f V  qdS )z%s="%s" N)r   )r=   rC   )categoryr   r   r?   T  s   rZ   r	   z	</entry>
N)r^   r   r   r%   r   r   r   r   r\   r   r   r#   rK   r]   rZ   r[   r	   r
   )r0   baser   r   )r_   rD   r   rL   :  sB    



zFeedEntry.generatec             C   s   dj | j S )z,Convert the feed item into a unicode object.rB   )rK   rL   )r0   r   r   r   rP   ^  s    zFeedEntry.to_stringc             C   s   | j  S )N)rP   )r0   r   r   r   rU   b  s    zFeedEntry.__str__)NNN)	r;   rV   rW   rX   r3   r<   rL   rP   rU   r   r   r   r   r6      s   -
$r6   )N)rX   r   Zwerkzeug.utilsr   Zwerkzeug.wrappersr   Zwerkzeug._compatr   r   r   r   r   objectr   r6   r   r   r   r   <module>   s   
 1