ó
ù¢TQc           @  si  d  Z  d d l m Z d d l Z y d d l m Z Wn! e k
 rY d d l m Z n Xd d l m Z d d l	 m
 Z
 m Z d d l m Z d d l m Z d d	 l m Z d d
 l m Z d „  Z d „  Z d „  Z d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ e Z d S(   uí  
Syndication feed generation library -- used for generating RSS, etc.

Sample usage:

>>> from django.utils import feedgenerator
>>> feed = feedgenerator.Rss201rev2Feed(
...     title="Poynter E-Media Tidbits",
...     link="http://www.poynter.org/column.asp?id=31",
...     description="A group Weblog by the sharpest minds in online media/journalism/publishing.",
...     language="en",
... )
>>> feed.add_item(
...     title="Hello",
...     link="http://www.holovaty.com/test/",
...     description="Testing."
... )
>>> with open('test.rss', 'w') as fp:
...     feed.write(fp, 'utf-8')

For definitions of the different versions of RSS, see:
http://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004/02/04/incompatible-rss
iÿÿÿÿ(   t   unicode_literalsN(   t   urlparse(   t   SimplerXMLGenerator(   t
   force_textt
   iri_to_uri(   t   datetime_safe(   t   six(   t   StringIO(   t   is_awarec   
      C  sÝ   d } d } t  j |  ƒ }  | |  j ƒ  } | |  j d } |  j d | | f ƒ } t j sp | j d ƒ } n  t |  ƒ rÑ |  j	 j
 |  ƒ } | j d d | j d } t | d ƒ \ } }	 | d | |	 f S| d Sd  S(   Nu   Janu   Febu   Maru   Apru   Mayu   Junu   Julu   Augu   Sepu   Octu   Novu   Decu   Monu   Tueu   Wedu   Thuu   Friu   Satu   Suni   u   %s, %%d %s %%Y %%H:%%M:%%S u   utf-8i   i<   u	   %+03d%02du   -0000(   u   Janu   Febu   Maru   Apru   Mayu   Junu   Julu   Augu   Sepu   Octu   Novu   Dec(   u   Monu   Tueu   Wedu   Thuu   Friu   Satu   Sun(   R   t   new_datetimet   weekdayt   montht   strftimeR   t   PY3t   decodeR   t   tzinfot	   utcoffsett   dayst   secondst   divmod(
   t   datet   monthsR   t   dowR   t   time_strt   offsett   timezonet   hourt   minute(    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyt   rfc2822_date&   s    	c         C  s¦   t  j |  ƒ }  |  j d ƒ } t j s9 | j d ƒ } n  t |  ƒ rš |  j j |  ƒ } | j	 d d | j
 d } t | d ƒ \ } } | d | | f S| d Sd  S(   Nu   %Y-%m-%dT%H:%M:%Su   utf-8i   i<   u
   %+03d:%02du   Z(   R   R	   R   R   R   R   R   R   R   R   R   R   (   R   R   R   R   R   R   (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyt   rfc3339_date;   s    	c         C  sZ   t  |  ƒ } d } | d k	 r= d t j | ƒ j d ƒ } n  d | j | | j | j f S(   uˆ   
    Creates a TagURI.

    See http://web.archive.org/web/20110514113830/http://diveintomark.org/archives/2004/05/28/howto-atom-id
    u    u   ,%su   %Y-%m-%du   tag:%s%s:%s/%sN(   R   t   NoneR   R	   R   t   hostnamet   patht   fragment(   t   urlR   t   bitst   d(    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyt   get_tag_uriI   s
    t   SyndicationFeedc           B  s¤   e  Z d  Z d d d d d d d d d d d „
 Z d d d d d d d d d d d „
 Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d „  Z d	 „  Z d
 „  Z RS(   uG   Base class for all syndication feeds. Subclasses should provide write()c         K  s  d „  } |	 r1 g  |	 D] } t  | ƒ ^ q }	 n  | d  k	 rL t  | ƒ } n  i | | ƒ d 6t | ƒ d 6| | ƒ d 6| | ƒ d 6| | ƒ d 6| | ƒ d 6t | ƒ d 6| | ƒ d	 6|	 pÀ d d
 6t |
 ƒ d 6| | ƒ d 6| pç | d 6| d 6|  _ |  j j | ƒ g  |  _ d  S(   Nc         S  s   t  |  d t ƒS(   Nt   strings_only(   R   t   True(   t   s(    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyt   <lambda>Z   s    u   titleu   linku   descriptionu   languageu   author_emailu   author_nameu   author_linku   subtitleu
   categoriesu   feed_urlu   feed_copyrightu   idu   ttl(    (   R   R   R   t   feedt   updatet   items(   t   selft   titlet   linkt   descriptiont   languaget   author_emailt   author_namet   author_linkt   subtitlet
   categoriest   feed_urlt   feed_copyrightt	   feed_guidt   ttlt   kwargst
   to_unicodet   c(    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyt   __init__W   s*    	"c         K  s
  d „  } | r1 g  | D] } | | ƒ ^ q } n  | d k	 rL t | ƒ } n  i | | ƒ d 6t | ƒ d 6| | ƒ d 6| | ƒ d 6| | ƒ d 6t | ƒ d 6| d 6| | ƒ d	 6| |	 ƒ d
 6|
 d 6| pÎ d d 6| | ƒ d 6| d 6} | j | ƒ |  j j | ƒ d S(   uß   
        Adds an item to the feed. All args are expected to be Python Unicode
        objects except pubdate, which is a datetime.datetime object, and
        enclosure, which is an instance of the Enclosure class.
        c         S  s   t  |  d t ƒS(   NR'   (   R   R(   (   R)   (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyR*   {   s    u   titleu   linku   descriptionu   author_emailu   author_nameu   author_linku   pubdateu   commentsu	   unique_idu	   enclosureu
   categoriesu   item_copyrightu   ttlN(    (   R   R   R   R,   R-   t   append(   R.   R/   R0   R1   R3   R4   R5   t   pubdatet   commentst	   unique_idt	   enclosureR7   t   item_copyrightR;   R<   R=   R>   t   item(    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyt   add_itemr   s*    		"
c         C  s   t  |  j ƒ S(   N(   t   lenR-   (   R.   (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyt	   num_items“   s    c         C  s   i  S(   ux   
        Return extra attributes to place on the root (i.e. feed/channel) element.
        Called from write().
        (    (   R.   (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyt   root_attributes–   s    c         C  s   d S(   ud   
        Add elements in the root (i.e. feed/channel) element. Called
        from write().
        N(    (   R.   t   handler(    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyt   add_root_elements   s    c         C  s   i  S(   uZ   
        Return extra attributes to place on each item (i.e. item/entry) element.
        (    (   R.   RF   (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyt   item_attributes¤   s    c         C  s   d S(   uF   
        Add elements on each item (i.e. item/entry) element.
        N(    (   R.   RK   RF   (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyt   add_item_elementsª   s    c         C  s
   t  ‚ d S(   uŠ   
        Outputs the feed in the given encoding to outfile, which is a file-like
        object. Subclasses should override this.
        N(   t   NotImplementedError(   R.   t   outfilet   encoding(    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyt   write°   s    c         C  s#   t  ƒ  } |  j | | ƒ | j ƒ  S(   uE   
        Returns the feed in the given encoding as a string.
        (   R   RR   t   getvalue(   R.   RQ   R)   (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyt   writeString·   s    	c         C  se   g  |  j  D]  } | d d k	 r
 | d ^ q
 } t | ƒ d k rT | j ƒ  | d St j j ƒ  Sd S(   u€   
        Returns the latest item's pubdate. If none of them have a pubdate,
        this returns the current date/time.
        u   pubdatei    iÿÿÿÿN(   R-   R   RH   t   sortt   datetimet   now(   R.   t   it   updates(    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyt   latest_post_date¿   s
    0
N(    (   t   __name__t
   __module__t   __doc__R   R?   RG   RI   RJ   RL   RM   RN   RR   RT   RZ   (    (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyR&   U   s    							t	   Enclosurec           B  s   e  Z d  Z d „  Z RS(   u   Represents an RSS enclosurec         C  s&   | | |  _  |  _ t | ƒ |  _ d S(   u2   All args are expected to be Python Unicode objectsN(   t   lengtht	   mime_typeR   R"   (   R.   R"   R_   R`   (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyR?   Í   s    (   R[   R\   R]   R?   (    (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyR^   Ë   s   t   RssFeedc           B  s;   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z RS(   u"   application/rss+xml; charset=utf-8c         C  s}   t  | | ƒ } | j ƒ  | j d |  j ƒ  ƒ | j d |  j ƒ  ƒ |  j | ƒ |  j | ƒ |  j | ƒ | j d ƒ d  S(   Nu   rssu   channel(	   R   t   startDocumentt   startElementt   rss_attributesRJ   RL   t   write_itemst   endChannelElementt
   endElement(   R.   RP   RQ   RK   (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyRR   Ô   s    
c         C  s   i |  j  d 6d d 6S(   Nu   versionu   http://www.w3.org/2005/Atomu
   xmlns:atom(   t   _version(   R.   (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyRd   Þ   s    c         C  sN   xG |  j  D]< } | j d |  j | ƒ ƒ |  j | | ƒ | j d ƒ q
 Wd  S(   Nu   item(   R-   Rc   RM   RN   Rg   (   R.   RK   RF   (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyRe   â   s    c         C  sR  | j  d |  j d ƒ | j  d |  j d ƒ | j  d |  j d ƒ |  j d d  k	 rƒ | j  d d  i d d 6|  j d d 6ƒ n  |  j d	 d  k	 r° | j  d	 |  j d	 ƒ n  x% |  j d
 D] } | j  d | ƒ q¾ W|  j d d  k	 r| j  d |  j d ƒ n  | j  d t |  j ƒ  ƒ ƒ |  j d d  k	 rN| j  d |  j d ƒ n  d  S(   Nu   titleu   linku   descriptionu   feed_urlu	   atom:linku   selfu   relu   hrefu   languageu
   categoriesu   categoryu   feed_copyrightu	   copyrightu   lastBuildDateu   ttl(   t   addQuickElementR+   R   R   RZ   (   R.   RK   t   cat(    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyRL   è   s    c         C  s   | j  d ƒ d  S(   Nu   channel(   Rg   (   R.   RK   (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyRf   ù   s    (   R[   R\   R`   RR   Rd   Re   RL   Rf   (    (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyRa   Ò   s   	
			t   RssUserland091Feedc           B  s   e  Z d  Z d „  Z RS(   u   0.91c         C  sS   | j  d | d ƒ | j  d | d ƒ | d d  k	 rO | j  d | d ƒ n  d  S(   Nu   titleu   linku   description(   Ri   R   (   R.   RK   RF   (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyRN   þ   s    (   R[   R\   Rh   RN   (    (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyRk   ü   s   t   Rss201rev2Feedc           B  s   e  Z d  Z d „  Z RS(   u   2.0c         C  sï  | j  d | d ƒ | j  d | d ƒ | d d  k	 rO | j  d | d ƒ n  | d rˆ | d rˆ | j  d d | d | d f ƒ nL | d r© | j  d | d ƒ n+ | d rÔ | j  d | d i d	 d
 6ƒ n  | d d  k	 r| j  d t | d ƒ ƒ n  | d d  k	 r(| j  d | d ƒ n  | d d  k	 rO| j  d | d ƒ n  | d d  k	 rv| j  d | d ƒ n  | d d  k	 rÆ| j  d d i | d j d 6| d j d 6| d j d 6ƒ n  x" | d D] } | j  d | ƒ qÑWd  S(   Nu   titleu   linku   descriptionu   author_nameu   author_emailu   authoru   %s (%s)u
   dc:creatoru    http://purl.org/dc/elements/1.1/u   xmlns:dcu   pubdateu   pubDateu   commentsu	   unique_idu   guidu   ttlu	   enclosureu    u   urlu   lengthu   typeu
   categoriesu   category(   Ri   R   R   R"   R_   R`   (   R.   RK   RF   Rj   (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyRN     s2    

!(   R[   R\   Rh   RN   (    (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyRl     s   t	   Atom1Feedc           B  sA   e  Z d  Z d Z d „  Z d „  Z d „  Z d „  Z d „  Z RS(   u#   application/atom+xml; charset=utf-8u   http://www.w3.org/2005/Atomc         C  sZ   t  | | ƒ } | j ƒ  | j d |  j ƒ  ƒ |  j | ƒ |  j | ƒ | j d ƒ d  S(   Nu   feed(   R   Rb   Rc   RJ   RL   Re   Rg   (   R.   RP   RQ   RK   (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyRR   .  s    
c         C  sA   |  j  d d  k	 r/ i |  j d 6|  j  d d 6Si |  j d 6Sd  S(   Nu   languageu   xmlnsu   xml:lang(   R+   R   t   ns(   R.   (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyRJ   6  s    c         C  sä  | j  d |  j d ƒ | j  d d i d d 6|  j d d 6ƒ |  j d d  k	 r} | j  d d i d d 6|  j d d 6ƒ n  | j  d	 |  j d	 ƒ | j  d
 t |  j ƒ  ƒ ƒ |  j d d  k	 rT| j d i  ƒ | j  d |  j d ƒ |  j d d  k	 r| j  d |  j d ƒ n  |  j d d  k	 rD| j  d |  j d ƒ n  | j d ƒ n  |  j d d  k	 r| j  d |  j d ƒ n  x/ |  j d D]  } | j  d d i | d 6ƒ qW|  j d d  k	 rà| j  d |  j d ƒ n  d  S(   Nu   titleu   linku    u	   alternateu   relu   hrefu   feed_urlu   selfu   idu   updatedu   author_nameu   authoru   nameu   author_emailu   emailu   author_linku   uriu   subtitleu
   categoriesu   categoryu   termu   feed_copyrightu   rights(   Ri   R+   R   R   RZ   Rc   Rg   (   R.   RK   Rj   (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyRL   <  s(    (+c         C  sN   xG |  j  D]< } | j d |  j | ƒ ƒ |  j | | ƒ | j d ƒ q
 Wd  S(   Nu   entry(   R-   Rc   RM   RN   Rg   (   R.   RK   RF   (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyRe   R  s    c         C  s  | j  d | d ƒ | j  d d i | d d 6d d 6ƒ | d d  k	 rf | j  d t | d ƒ ƒ n  | d	 d  k	 rø | j d
 i  ƒ | j  d | d	 ƒ | d d  k	 rÁ | j  d | d ƒ n  | d d  k	 rè | j  d | d ƒ n  | j d
 ƒ n  | d d  k	 r| d } n t | d | d ƒ } | j  d | ƒ | d d  k	 rm| j  d | d i d d 6ƒ n  | d d  k	 rÄ| j  d d i d d 6| d j d 6| d j d 6| d j d 6ƒ n  x, | d D]  } | j  d d i | d 6ƒ qÏW| d d  k	 r| j  d | d ƒ n  d  S(   Nu   titleu   linku    u   hrefu	   alternateu   relu   pubdateu   updatedu   author_nameu   authoru   nameu   author_emailu   emailu   author_linku   uriu	   unique_idu   idu   descriptionu   summaryu   htmlu   typeu	   enclosureu   lengthu
   categoriesu   categoryu   termu   item_copyrightu   rights(	   Ri   R   R   Rc   Rg   R%   R"   R_   R`   (   R.   RK   RF   RC   Rj   (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyRN   X  s8    %!
(	   R[   R\   R`   Rn   RR   RJ   RL   Re   RN   (    (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyRm   )  s   				(   R]   t
   __future__R    RV   t   urllib.parseR   t   ImportErrort   django.utils.xmlutilsR   t   django.utils.encodingR   R   t   django.utilsR   R   t   django.utils.sixR   t   django.utils.timezoneR   R   R   R%   t   objectR&   R^   Ra   Rk   Rl   Rm   t   DefaultFeed(    (    (    s3   ../Django//lib/python/django/utils/feedgenerator.pyt   <module>   s,   			v*%\