o 3a;@sdZddlZddlZddlmZddlmZddlmZddl m Z ddl m Z dd Z d d Zd d ZGdddZGdddZGdddeZGdddeZGdddeZGdddeZeZdS)a 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: https://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004/02/04/incompatible-rss N)StringIO)urlparse) iri_to_uri)utc)SimplerXMLGeneratorcCs*t|tjstj|t}tj|SN) isinstancedatetimecombinetimeemailutilsformat_datetimedater.to_strcSsg|]}t|qSrr#.0crrr Bz,SyndicationFeed.__init__..r) titlelink descriptionlanguage author_email author_name author_linksubtitle categoriesfeed_urlfeed_copyrightidttl)rfeeditems)selfr.r/r0r1r2r3r4r5r6r7r8 feed_guidr:kwargsr'rrr__init__=s& zSyndicationFeed.__init__rc sdd| ofdd| D} |j|t||||t||||| | |p0d| p3d| | d|dS)z Add an item to the feed. All args are expected to be strings except pubdate and updateddate, which are datetime.datetime objects, and enclosures, which is an iterable of instances of the Enclosure class. cSr"rr#r%rrrr'^r(z(SyndicationFeed.add_item..to_strcsg|]}|qSrrr)r'rrr,`r-z,SyndicationFeed.add_item..r)r.r/r0r2r3r4pubdate updateddatecomments unique_idunique_id_is_permalink enclosuresr6item_copyrightr:N)r<appendr)r=r.r/r0r2r3r4rBrDrErFr6rHr:rCrGr?rrAradd_itemUs*  zSyndicationFeed.add_itemcCs t|jSr)lenr<r=rrr num_itemsts zSyndicationFeed.num_itemscCiS)zx Return extra attributes to place on the root (i.e. feed/channel) element. Called from write(). rrLrrrroot_attributeswzSyndicationFeed.root_attributescCdS)zd Add elements in the root (i.e. feed/channel) element. Called from write(). Nrr=handlerrrradd_root_elements~rPz!SyndicationFeed.add_root_elementscCrN)zZ Return extra attributes to place on each item (i.e. item/entry) element. r)r=itemrrritem_attributeszSyndicationFeed.item_attributescCrQ)zF Add elements on each item (i.e. item/entry) element. Nrr=rSrUrrradd_item_elementsrWz!SyndicationFeed.add_item_elementscCstd)z Output the feed in the given encoding to outfile, which is a file-like object. Subclasses should override this. z;subclasses of SyndicationFeed must provide a write() method)NotImplementedError)r=outfileencodingrrrwriteszSyndicationFeed.writecCst}||||S)zD Return the feed in the given encoding as a string. )rr]getvalue)r=r\r&rrr writeStrings zSyndicationFeed.writeStringcCsVd}d}|jD]}|D]}||}|r|dus||kr|}q q|p*tjjtdS)z Return the latest item's pubdate or updateddate. If no items have either of these attributes this return the current UTC date/time. N)rCrB)tzinfo)r<getr utcnowreplacer)r= latest_date date_keysrUdate_key item_daterrrlatest_post_dates  z SyndicationFeed.latest_post_date) NNNNNNNNNN) NNNNNNNrNNNN)__name__ __module__ __qualname____doc__r@rJrMrOrTrVrYr]r_rhrrrrr!;s&   r!c@eZdZdZddZdS) EnclosurezAn RSS enclosurecCs|||_|_t||_dS)z#All args are expected to be stringsN)length mime_typerr)r=rrorprrrr@szEnclosure.__init__N)rirjrkrlr@rrrrrns rnc@s8eZdZdZddZddZddZdd Zd d Zd S) RssFeedz"application/rss+xml; charset=utf-8cCs^t||}||d||d||||||||ddS)Nrsschannel) r startDocument startElementrss_attributesrOrT write_itemsendChannelElement endElementr=r[r\rSrrrr]s    z RssFeed.writecCs |jddS)Nhttp://www.w3.org/2005/Atom)versionz xmlns:atom)_versionrLrrrrvszRssFeed.rss_attributescC8|jD]}|d||||||dqdS)NrUr<rurVrYryrXrrrrw   zRssFeed.write_itemscCs|d|jd|d|jd|d|jd|jddur/|ddd|jdd|jddur?|d|jd|jd D]}|d |qD|jd dur]|d |jd |d t||jddury|d|jddSdS)Nr.r/r0r7z atom:linkr=relhrefr1r6categoryr8 copyright lastBuildDater:)addQuickElementr;rrhr=rScatrrrrTszRssFeed.add_root_elementscCs|ddS)Nrs)ryrRrrrrxszRssFeed.endChannelElementN) rirjrk content_typer]rvrwrTrxrrrrrqs  rqc@rm)RssUserland091Feedz0.91cCsD|d|d|d|d|ddur |d|ddSdS)Nr.r/r0)rrXrrrrYs  z$RssUserland091Feed.add_item_elementsNrirjrkr}rYrrrrrs rc@rm)Rss201rev2Feedz2.0cCs|d|d|d|d|ddur|d|d|dr5|dr5|dd|d|dfn|drB|d|dn|drQ|d|dd d i|d dura|d t|d |d duro|d |d |dduri}t|dtrt|d|d<|d|d||ddur|d|d|drt|d}t|dkrt d|d}|dd|j |j |j d|dD]}|d|qdS)Nr.r/r0r3r2authorz%s (%s)z dc:creatorzxmlns:dcz http://purl.org/dc/elements/1.1/rBpubDaterDrErF isPermaLinkguidr:rGzrRSS feed items may only have one enclosure, see http://www.rssboard.org/rss-profile#element-channel-item-enclosurer enclosurer)rrotyper6r) rrrraboolr$lowerlistrK ValueErrorrrorp)r=rSrU guid_attrsrGrrrrrrYsL        z Rss201rev2Feed.add_item_elementsNrrrrrrs rc@s<eZdZdZdZddZddZddZd d Zd d Z d S) Atom1Feedz#application/atom+xml; charset=utf-8r{cCsDt||}||d||||||ddS)Nr;)rrtrurOrTrwryrzrrrr]+s   zAtom1Feed.writecCs*|jddur|j|jddSd|jiS)Nr1)xmlnszxml:langr)r;nsrLrrrrO3s zAtom1Feed.root_attributescCsZ|d|jd|ddd|jdd|jddur*|ddd|jdd|d|jd|d t||jd durx|d i|d |jd |jd durc|d|jd |jddurs|d|jd|d |jddur|d|jd|jdD] }|ddd|iq|jddur|d|jddSdS)Nr.r/r alternaterr7r=r9updatedr3rnamer2r r4urir5r6rtermr8rights)rr;rrhruryrrrrrT9s*  zAtom1Feed.add_root_elementscCr~)NentryrrXrrrrwOrzAtom1Feed.write_itemsc Cs|d|d|dd|ddd|ddur$|dt|d|ddur4|d t|d|d duri|d i|d |d |d durV|d|d |ddurd|d|d|d |ddurt|d}n t|d|d}|d||ddur|d|dddi|dD]}|ddd|j|j|jdq|dD] }|ddd|iq|ddur|d|ddSdS)Nr.r/rr)rrrB publishedrCrr3rrr2r r4rrEr9r0summaryrhtmlrGr)rrrorr6rrrHr)rrruryr rrorp)r=rSrUrErrrrrrYUs@              zAtom1Feed.add_item_elementsN) rirjrkrrr]rOrTrwrYrrrrr&s r)rlr r ior urllib.parserdjango.utils.encodingrdjango.utils.timezonerdjango.utils.xmlutilsrrrr r!rnrqrrr DefaultFeedrrrrs$      x- 4b