def calendar_legacy_rss(request): output = cache.get('calendar_legacy_rss') if not output: today = timezone.now() elections = Election.objects.order_by('date').all().filter( date__gt=today)[:20] current_site = Site.objects.get_current() today = rfc2822_date(today) for item in elections: if item.date_updated: item.date_updated = rfc2822_date(item.date_updated) item.country.link = 'http://%s%s' % ( current_site.domain, reverse('country', args=[item.country.id])) item.link = 'http://%s%s' % ( current_site.domain, reverse('election', args=[item.id])) output = render(request, 'pages/legacy_calendar.rss', { 'elections': elections, 'today': today }) cache.set('calendar_legacy_rss', output, None) return output
def get(self, request, **kwargs): document = self.get_object() json = {} json['id'] = "doc-%s" % (document.id,) json['title'] = document.title json['pages'] = document.page_count json['description'] = document.description json['source'] = document.source_url json['created_at'] = rfc2822_date(document.created) json['updated_at'] = rfc2822_date(document.modified) json['canonical_url'] = get_absolute_url(reverse("docviewer_viewer_view", kwargs = {'pk' : document.pk, 'slug' : document.slug})) json['contributor'] = document.contributor json['contributor_organization'] = document.contributor_organization json['resources'] = {} if document.download is True: json['resources']['pdf'] = get_absolute_url(document.doc_url) json['resources']['text'] = get_absolute_url(document.text_url) json['resources']['thumbnail'] = get_absolute_url(document.thumbnail_url) json['resources']['search'] = get_absolute_url(reverse("docviewer_search_view", kwargs = {'pk' : document.pk, 'slug' : document.slug})) + '?q={query}' json['resources']['print_annotations'] = get_absolute_url(reverse("docviewer_printannotations_view", kwargs = {'pk' : document.pk, 'slug' : document.slug})) json['resources']['page'] = {} json['resources']['page']['text'] = get_absolute_url(document.text_page_url % {'page' : '{page}'}) #json['resources']['page']['image'] = get_absolute_url(document.image_page_url % {'page' : '{page}', 'size' : '{size}'}) json['resources']['page']['image'] = "http://" + SITE.domain + "/viewer/image/%s/%s/%s/" % (document.pk, '{size}', '{page}') #json['resources']['page']['image'] = reverse('image_docviewer', kwargs = {'size' : '{size}', 'page' : '{page}'}) #FIXME : THE F**** ERROR IS HERE !!!! #json['resources']['related_article'] = get_absolute_url(document.related_url) json['resources']['published_url'] = json['canonical_url'] json['sections'] = list(document.sections_set.all().values('title', 'page')) json['annotations'] = list(document.annotations_set.all().values('location', 'title', 'id', 'page', 'content')) return HttpResponse(simplejson.dumps(json), content_type="application/json")
def test_blog_post(self): "It should contain the correct data for a blog post" user = UserFactory( first_name='Bob', last_name='Ferris', email='*****@*****.**') blog = BlogFactory( name='My Blog', slug='my-blog', show_author_email_in_feed=True) post = LivePostFactory( title="My blog post", slug="my-blog-post", excerpt='This is my <b>excerpt</b>.', intro="The post intro.", body="This is the post <b>body</b>.\n\nOK?", author=user, blog=blog, time_published=make_datetime('2017-04-25 16:00:00') ) channel = self.get_feed_channel('/terry/feeds/everything/rss/') items = channel.getElementsByTagName('item') self.assertChildNodeContent(items[0], { 'title': "My blog post", "description": "This is my excerpt.", "link": "http://example.com/terry/my-blog/2017/04/25/my-blog-post/", "guid": "http://example.com/terry/my-blog/2017/04/25/my-blog-post/", 'pubDate': rfc2822_date(post.time_published), 'author': '[email protected] (Bob Ferris)', 'content:encoded': '<p><em>From <a href="http://example.com/terry/my-blog/">My Blog</a>.</em></p><p>The post intro.</p><p>This is the post <b>body</b>.</p><p>OK?</p>' })
def add_root_elements(self, handler): """ Add additional elements to the show object""" super(ITunesElements, self).add_root_elements(handler) show = self.feed["show"] handler.addQuickElement(u"guid", str(show.uuid), attrs={"isPermaLink": "false"}) handler.addQuickElement(u"itunes:subtitle", self.feed["subtitle"]) handler.addQuickElement(u"itunes:author", fmt_people(show.authors.all())) handler.startElement(u"itunes:owner", {}) handler.addQuickElement(u"itunes:name", show.authors.all()[0].get_full_name()) handler.addQuickElement(u"itunes:email", show.authors.all()[0].email) handler.endElement(u"itunes:owner") handler.addQuickElement(u"itunes:image", attrs={"href": show.img_itunes_lg.url}) handler.startElement(u"image", {}) handler.addQuickElement(u"url", show.img_itunes_sm.url) handler.addQuickElement(u"title", self.feed["title"]) handler.addQuickElement(u"link", self.feed["link"]) handler.endElement(u"image") handler.addQuickElement(u"itunes:category", attrs={"text": self.feed["categories"][0]}) handler.addQuickElement(u"itunes:summary", show.description) handler.addQuickElement(u"itunes:explicit", show.get_explicit_display()) if show.redirect: handler.addQuickElement(u"itunes:new-feed-url", show.redirect) handler.addQuickElement(u"keywords", show.keywords) handler.addQuickElement(u"managingEditor", fmt_people(show.authors.all())) handler.addQuickElement(u"webMaster", fmt_person(show.webmaster)) try: handler.addQuickElement(u"lastBuildDate", rfc2822_date(show.episode_set.published()[1].published)) except IndexError: pass handler.addQuickElement(u"generator", "Django Web Framework") handler.addQuickElement(u"docs", "http://blogs.law.harvard.edu/tech/rss")
def test_rfc2822_date(self): """ Test rfc2822_date() correctly formats datetime objects. """ self.assertEqual( feedgenerator.rfc2822_date(datetime.datetime(2008, 11, 14, 13, 37, 0)), "Fri, 14 Nov 2008 13:37:00 -0000" )
def add_root_elements(self, handler): """ Add additional elements to the blog object""" super(ITunesElements, self).add_root_elements(handler) haqe = handler.addQuickElement blog = self.feed["blog"] self.add_artwork(blog, handler) haqe("itunes:subtitle", self.feed["subtitle"]) haqe("itunes:author", blog.user.get_full_name()) handler.startElement("itunes:owner", {}) haqe("itunes:name", blog.user.get_full_name()) haqe("itunes:email", blog.user.email) handler.endElement("itunes:owner") self.add_itunes_categories(blog, handler) haqe("itunes:summary", blog.description) haqe("itunes:explicit", blog.get_explicit_display()) try: haqe("lastBuildDate", rfc2822_date(blog.last_build_date)) except IndexError: pass generator = "Django Web Framework / django-cast" haqe("generator", generator) haqe("docs", "http://blogs.law.harvard.edu/tech/rss")
def write(self, outfile, encoding): """Write feed date into given outfile using given encoding. @param outfile: 'file' to write feed data into, e.g. Django response @type outfile: File @param encoding: feed's encoding @type encoding: string """ handler = SimplerXMLGenerator(outfile, encoding) handler.startDocument() handler.startElement(u"rss", {u"version": self._version, u"xmlns:wfw": u"http://wellformedweb.org/CommentAPI/"}) handler.startElement(u"channel", {}) handler.addQuickElement(u"title", self.feed['title']) handler.addQuickElement(u"link", self.feed['link']) handler.addQuickElement(u"description", self.feed['description']) if self.feed['language'] is not None: handler.addQuickElement(u"language", self.feed['language']) for cat in self.feed['categories']: handler.addQuickElement(u"category", cat) if self.feed['feed_copyright'] is not None: handler.addQuickElement(u"copyright", self.feed['feed_copyright']) handler.addQuickElement(u"lastBuildDate", rfc2822_date(self.latest_post_date()).decode('ascii')) self.write_items(handler) self.endChannelElement(handler) handler.endElement(u"rss")
def add_root_elements(self, handler): super(ItunesFeed, self).add_root_elements(handler) handler.addQuickElement('copyright', self.feed['copyright'], escape=False, cdata=False) handler.addQuickElement('docs', self.feed['docs']) handler.startElement('image', {}) handler.addQuickElement('url', self.feed['image']) handler.addQuickElement('title', self.feed['title']) handler.addQuickElement('link', self.feed['link']) handler.endElement('image') handler.addQuickElement('managingEditor', self.feed['managing_editor']) handler.addQuickElement('pubDate', rfc2822_date(self.latest_post_date())) handler.addQuickElement('webMaster', self.feed['webmaster']) handler.addQuickElement('itunes:type', self.feed['itunes']['type']) handler.addQuickElement('itunes:subtitle', self.feed['itunes']['subtitle']) handler.addQuickElement('itunes:summary', self.feed['itunes']['summary'], escape=False, cdata=True) handler.addQuickElement('itunes:author', self.feed['itunes']['author']['name']) handler.startElement('itunes:owner', {}) handler.addQuickElement('itunes:name', self.feed['itunes']['owner']['name']) handler.addQuickElement('itunes:email', self.feed['itunes']['owner']['email']) handler.endElement('itunes:owner') handler.addQuickElement('itunes:image', '', {'href': self.feed['image']}) for key in sorted(self.feed['itunes']['categories']): handler.startElement('itunes:category', {'text': key}) for item in self.feed['itunes']['categories'][key]: handler.addQuickElement('itunes:category', '', {'text': item}) handler.endElement('itunes:category') handler.addQuickElement('itunes:explicit', self.feed['itunes']['explicit']) handler.addQuickElement('itunes:block', self.feed['itunes']['block']) handler.addQuickElement('itunes:complete', self.feed['itunes']['complete']) if self.feed['itunes']['coming']: handler.addQuickElement('itunes:new-feed-url', self.feed['feed_url'])
def test_rfc2822_date_without_time(self): """ Test rfc2822_date() correctly formats date objects. """ self.assertEqual( feedgenerator.rfc2822_date(datetime.date(2008, 11, 14)), "Fri, 14 Nov 2008 00:00:00 -0000")
def test_rfc2822_date(self): """ Test rfc2822_date() correctly formats datetime objects. """ self.assertEqual( feedgenerator.rfc2822_date( datetime.datetime(2008, 11, 14, 13, 37, 0)), "Fri, 14 Nov 2008 13:37:00 -0000")
def test_rfc2822_date_with_timezone(self): """ Test rfc2822_date() correctly formats datetime objects with tzinfo. """ self.assertEqual( feedgenerator.rfc2822_date(datetime.datetime(2008, 11, 14, 13, 37, 0, tzinfo=tzinfo.FixedOffset(datetime.timedelta(minutes=60)))), "Fri, 14 Nov 2008 13:37:00 +0100" )
def add_root_elements(self): root_elements = { 'title': self.feed['title'], 'description': self.feed['description'], 'link': self.feed['link'], 'lastBuildDate': rfc2822_date(self.latest_post_date()) } return root_elements
def test_rfc2822_date_with_timezone(self): """ rfc2822_date() correctly formats datetime objects with tzinfo. """ self.assertEqual( feedgenerator.rfc2822_date(datetime.datetime(2008, 11, 14, 13, 37, 0, tzinfo=get_fixed_timezone(60))), "Fri, 14 Nov 2008 13:37:00 +0100" )
def test_rfc2822_date_without_time(self): """ Test rfc2822_date() correctly formats date objects. """ self.assertEqual( feedgenerator.rfc2822_date(datetime.date(2008, 11, 14)), "Fri, 14 Nov 2008 00:00:00 -0000" )
def test_rfc2822_date_with_timezone(self): """ Test rfc2822_date() correctly formats datetime objects with tzinfo. """ self.assertEqual( feedgenerator.rfc2822_date(datetime.datetime(2008, 11, 14, 13, 37, 0, tzinfo=get_fixed_timezone(60))), "Fri, 14 Nov 2008 13:37:00 +0100" )
def add_item_elements(self, handler, item): super(ExtendedRSSFeed, self).add_item_elements(handler, item) # 'content_encoded' is added to the item below, in item_extra_kwargs() # It's populated in item_your_custom_field(). Here we're creating # the <content:encoded> element and adding it to our feed xml if item['start_date'] is not None: #handler.addQuickElement(u'start_date', item['start_date']) handler.addQuickElement(u'start_date', rfc2822_date(item['start_date']))
def rss(request): from django.utils.tzinfo import LocalTimezone from datetime import datetime from django.utils.feedgenerator import rfc2822_date site = Site.objects.get_current() items = Article.objects.all()[:50] latest = Article.objects.latest('created') latest_date = latest.created if latest else datetime.now() tzinfo = default_timezone() latest_date = latest_date.replace(tzinfo = tzinfo) lastbuilddate = datetime.now().replace(tzinfo = tzinfo) feed = BlogFeed( title = 'Оптимальный веб-блог', link = 'http://%s' % site.domain, description = 'Блог о веб-разработке, Django, Python и о других интересных мне вещах', language = 'ru', feed_url = 'http://%s%s' % (site.domain, reverse('blog_rss')), categories = [unicode(category) for category in Category.objects.all()], pubdate = rfc2822_date(latest_date), lastbuilddate = rfc2822_date(lastbuilddate), image = None ) for item in items: created_date = item.created.replace(tzinfo = tzinfo) feed.add_item( title = item.title, link = item.get_full_url(), description = item.cat(), unique_id = item.get_full_url(), author_name = item.author.get_full_name(), author_email = item.author.email, author_link = 'http://%s%s' % (site.domain, reverse('about')), pubdate = created_date ) return HttpResponse(feed.writeString('UTF-8'), mimetype = 'application/rss+xml; charset=utf-8');
def get(self, request, **kwargs): document = self.get_object() json = {} json['id'] = "doc-%s" % (document.id,) json['title'] = document.title json['pages'] = document.page_count json['description'] = document.description json['source'] = document.source_url json['created_at'] = rfc2822_date(document.created) json['updated_at'] = rfc2822_date(document.modified) json['canonical_url'] = get_absolute_url(request, reverse("docviewer_viewer_view", kwargs = {'pk' : document.pk, 'slug' : document.slug})) json['contributor'] = document.contributor json['contributor_organization'] = document.contributor_organization json['resources'] = {} if document.download is True: json['resources']['pdf'] = get_absolute_url(request, document.doc_url) json['resources']['text'] = get_absolute_url(request, document.text_url) json['resources']['thumbnail'] = get_absolute_url(request, document.thumbnail_url) json['resources']['search'] = get_absolute_url(request, reverse("docviewer_search_view", kwargs = {'pk' : document.pk, 'slug' : document.slug})) + '?q={query}' json['resources']['print_annotations'] = get_absolute_url(request, reverse("docviewer_printannotations_view", kwargs = {'pk' : document.pk, 'slug' : document.slug})) json['resources']['page'] = {} json['resources']['page']['text'] = get_absolute_url(request, document.text_page_url % {'page' : '{page}'}) json['resources']['page']['image'] = get_absolute_url(request, document.image_page_url % {'page' : '{page}', 'size' : '{size}'}) json['resources']['related_article'] = get_absolute_url(request, document.related_url) json['resources']['published_url'] = json['canonical_url'] json['sections'] = list(document.sections_set.all().values('title', 'page')) json['annotations'] = list(document.annotations_set.all().values('location', 'title', 'id', 'page', 'content')) if request.GET.get('callback', None) is not None: return HttpResponse("%s(%s);" % (request.GET.get('callback'),simplejson.dumps(json)), content_type="application/javascript") else : return HttpResponse(simplejson.dumps(json), content_type="application/json")
def add_root_elements(self, handler): """ Add additional elements to the show object""" super(ITunesElements, self).add_root_elements(handler) show = self.feed["show"] if show.original_image: if imagekit: itunes_sm_url = show.img_itunes_sm.url itunes_lg_url = show.img_itunes_lg.url elif easy_thumbnails: aliases = settings.THUMBNAIL_ALIASES["podcasting.Show.original_image"] thumbnailer = easy_thumbnails.files.get_thumbnailer(show.original_image) itunes_sm_url = thumbnailer.get_thumbnail(aliases["itunes_sm"]).url itunes_lg_url = thumbnailer.get_thumbnail(aliases["itunes_lg"]).url elif sorl: itunes_sm_url = sorl.thumbnail.get_thumbnail(show.original_image, "144x144").url itunes_lg_url = sorl.thumbnail.get_thumbnail(show.original_image, "1400x1400").url else: itunes_sm_url = show.original_image.url itunes_lg_url = show.original_image.url handler.addQuickElement("itunes:image", attrs={"href": itunes_lg_url}) handler.startElement("image", {}) handler.addQuickElement("url", itunes_sm_url) handler.addQuickElement("title", self.feed["title"]) handler.addQuickElement("link", self.feed["link"]) handler.endElement("image") handler.addQuickElement("guid", str(show.uuid), attrs={"isPermaLink": "false"}) handler.addQuickElement("itunes:subtitle", self.feed["subtitle"]) handler.addQuickElement("itunes:author", show.author_text) handler.startElement("itunes:owner", {}) handler.addQuickElement("itunes:name", show.owner.get_full_name()) handler.addQuickElement("itunes:email", show.owner.email) handler.endElement("itunes:owner") handler.addQuickElement("itunes:category", attrs={"text": self.feed["categories"][0]}) handler.addQuickElement("itunes:summary", show.description) handler.addQuickElement("itunes:explicit", show.get_explicit_display()) if show.redirect: handler.addQuickElement("itunes:new-feed-url", show.redirect) handler.addQuickElement("keywords", show.keywords) if show.editor_email: handler.addQuickElement("managingEditor", show.editor_email) if show.webmaster_email: handler.addQuickElement("webMaster", show.webmaster_email) try: handler.addQuickElement("lastBuildDate", rfc2822_date(show.episode_set.published()[1].published)) except IndexError: pass handler.addQuickElement("generator", "Django Web Framework") handler.addQuickElement("docs", "http://blogs.law.harvard.edu/tech/rss")
def add_root_elements(self, handler): handler.addQuickElement(u"title", self.feed['title']) handler.addQuickElement(u"link", self.feed['link']) handler.addQuickElement(u"description", self.feed['description']) # handler.addQuickElement(u"atom:link", None, {u"rel": u"self", u"href": self.feed['feed_url']}) if self.feed['language'] is not None: handler.addQuickElement(u"language", self.feed['language']) for cat in self.feed['categories']: handler.addQuickElement(u"category", cat) if self.feed['feed_copyright'] is not None: handler.addQuickElement(u"copyright", self.feed['feed_copyright']) handler.addQuickElement(u"lastBuildDate", rfc2822_date(self.latest_post_date()).decode('utf-8')) if self.feed['ttl'] is not None: handler.addQuickElement(u"ttl", self.feed['ttl'])
def add_root_elements(self, handler): handler.addQuickElement(u"title", self.feed['title']) handler.addQuickElement(u"link", self.feed['link']) handler.addQuickElement(u"description", self.feed['description']) # handler.addQuickElement(u"atom:link", None, {u"rel": u"self", u"href": self.feed['feed_url']}) if self.feed['language'] is not None: handler.addQuickElement(u"language", self.feed['language']) for cat in self.feed['categories']: handler.addQuickElement(u"category", cat) if self.feed['feed_copyright'] is not None: handler.addQuickElement(u"copyright", self.feed['feed_copyright']) handler.addQuickElement( u"lastBuildDate", rfc2822_date(self.latest_post_date()).decode('utf-8')) if self.feed['ttl'] is not None: handler.addQuickElement(u"ttl", self.feed['ttl'])
def write_items(self, handler): for item in self.items: handler.startElement(u"item", {}) handler.addQuickElement(u"title", item['title']) handler.addQuickElement(u"link", item['link']) if item['description'] is not None: handler.addQuickElement(u"description", item['description']) # Author information. if item["author_name"] and item["author_email"]: handler.addQuickElement(u"author", "%s (%s)" % \ (item['author_email'], item['author_name'])) elif item["author_email"]: handler.addQuickElement(u"author", item["author_email"]) elif item["author_name"]: handler.addQuickElement( u"dc:creator", item["author_name"], {"xmlns:dc": u"http://purl.org/dc/elements/1.1/"}) if item['pubdate'] is not None: handler.addQuickElement( u"pubDate", rfc2822_date(item['pubdate']).decode('ascii')) if item['comments'] is not None: handler.addQuickElement(u"comments", item['comments']) if item.has_key( 'wfw_commentRss') and item['wfw_commentRss'] is not None: handler.addQuickElement(u"wfw:commentRss", item['wfw_commentRss']) if item['unique_id'] is not None: handler.addQuickElement(u"guid", item['unique_id']) # Enclosure. if item['enclosure'] is not None: handler.addQuickElement( u"enclosure", '', { u"url": item['enclosure'].url, u"length": item['enclosure'].length, u"type": item['enclosure'].mime_type }) # Categories. for cat in item['categories']: handler.addQuickElement(u"category", cat) handler.endElement(u"item")
def add_root_elements(self, handler): handler.addQuickElement('title', settings.RSS_NEWS['title']) handler.addQuickElement('link', settings.RSS_NEWS['link']) handler.addQuickElement("description", self.feed['description']) if self.feed['language'] is not None: handler.addQuickElement("language", self.feed['language']) for cat in self.feed['categories']: handler.addQuickElement("category", cat) if self.feed['feed_copyright'] is not None: handler.addQuickElement("copyright", self.feed['feed_copyright']) handler.addQuickElement("lastBuildDate", rfc2822_date(self.latest_post_date())) if self.feed['ttl'] is not None: handler.addQuickElement("ttl", self.feed['ttl']) handler.startElement('image', {}) handler.addQuickElement('url', settings.RSS_NEWS['image']) handler.endElement('image')
def write(self, outfile, encoding): handler = SimplerXMLGenerator(outfile, encoding) handler.startDocument() handler.startElement(u"rss", {u"version": self._version, u"xmlns:wfw": u"http://wellformedweb.org/CommentAPI/"}) handler.startElement(u"channel", {}) handler.addQuickElement(u"title", self.feed['title']) handler.addQuickElement(u"link", self.feed['link']) handler.addQuickElement(u"description", self.feed['description']) if self.feed['language'] is not None: handler.addQuickElement(u"language", self.feed['language']) for cat in self.feed['categories']: handler.addQuickElement(u"category", cat) if self.feed['feed_copyright'] is not None: handler.addQuickElement(u"copyright", self.feed['feed_copyright']) handler.addQuickElement(u"lastBuildDate", rfc2822_date(self.latest_post_date()).decode('ascii')) self.write_items(handler) self.endChannelElement(handler) handler.endElement(u"rss")
def format_datetime(self, data): data = self._make_aware(data) if self.datetime_formatting == 'rfc-2822': # We fix RFC 2822 serialization # See https://github.com/toastdriven/django-tastypie/pull/656 return feedgenerator.rfc2822_date(data) if self.datetime_formatting == 'iso-8601-strict': # Remove microseconds to strictly adhere to ISO-8601. data = data - datetime.timedelta(microseconds=data.microsecond) iso_datetime = data.isoformat() # Can we serialize into less bytes? if iso_datetime.endswith('+00:00'): iso_datetime = iso_datetime[:-6] + 'Z' return iso_datetime
def write(self, outfile, encoding): handler = SimplerXMLGenerator(outfile, encoding) handler.startDocument() handler.startElement(u"rss", {u"version": self._version, u"xmlns:wfw": u"http://wellformedweb.org/CommentAPI/"}) handler.startElement(u"channel", {}) handler.addQuickElement(u"title", self.feed["title"]) handler.addQuickElement(u"link", self.feed["link"]) handler.addQuickElement(u"description", self.feed["description"]) if self.feed["language"] is not None: handler.addQuickElement(u"language", self.feed["language"]) for cat in self.feed["categories"]: handler.addQuickElement(u"category", cat) if self.feed["feed_copyright"] is not None: handler.addQuickElement(u"copyright", self.feed["feed_copyright"]) handler.addQuickElement(u"lastBuildDate", rfc2822_date(self.latest_post_date()).decode("ascii")) self.write_items(handler) self.endChannelElement(handler) handler.endElement(u"rss")
def test_get_object(self): response = self.client.get("/syndication/rss2/articles/%s/" % self.e1.pk) doc = minidom.parseString(response.content) feed = doc.getElementsByTagName("rss")[0] chan = feed.getElementsByTagName("channel")[0] items = chan.getElementsByTagName("item") self.assertChildNodeContent( items[0], { "comments": "/blog/%s/article/%s/comments" % (self.e1.pk, self.a1.pk), "description": "Article description: My first article", "link": "http://example.com/blog/%s/article/%s/" % (self.e1.pk, self.a1.pk), "title": "Title: My first article", "pubDate": rfc2822_date(timezone.make_aware(self.a1.published, TZ)), }, )
def write_items(self, handler): for item in self.items: handler.startElement(u"item", {}) handler.addQuickElement(u"title", item["title"]) handler.addQuickElement(u"link", item["link"]) if item["description"] is not None: handler.addQuickElement(u"description", item["description"]) # Author information. if item["author_name"] and item["author_email"]: handler.addQuickElement(u"author", "%s (%s)" % (item["author_email"], item["author_name"])) elif item["author_email"]: handler.addQuickElement(u"author", item["author_email"]) elif item["author_name"]: handler.addQuickElement( u"dc:creator", item["author_name"], {"xmlns:dc": u"http://purl.org/dc/elements/1.1/"} ) if item["pubdate"] is not None: handler.addQuickElement(u"pubDate", rfc2822_date(item["pubdate"]).decode("ascii")) if item["comments"] is not None: handler.addQuickElement(u"comments", item["comments"]) if item.has_key("wfw_commentRss") and item["wfw_commentRss"] is not None: handler.addQuickElement(u"wfw:commentRss", item["wfw_commentRss"]) if item["unique_id"] is not None: handler.addQuickElement(u"guid", item["unique_id"]) # Enclosure. if item["enclosure"] is not None: handler.addQuickElement( u"enclosure", "", { u"url": item["enclosure"].url, u"length": item["enclosure"].length, u"type": item["enclosure"].mime_type, }, ) # Categories. for cat in item["categories"]: handler.addQuickElement(u"category", cat) handler.endElement(u"item")
def write_items(self, handler): """Write feed items into given handler. @param handler: handler to end channel in. @type handler: SimplerXMLGenerator """ for item in self.items: handler.startElement(u"item", {}) handler.addQuickElement(u"title", item['title']) handler.addQuickElement(u"link", item['link']) if item['description'] is not None: handler.addQuickElement(u"description", item['description']) # Author information. if item["author_name"] and item["author_email"]: handler.addQuickElement(u"author", "%s (%s)" % \ (item['author_email'], item['author_name'])) elif item["author_email"]: handler.addQuickElement(u"author", item["author_email"]) elif item["author_name"]: handler.addQuickElement(u"dc:creator", item["author_name"], {"xmlns:dc": u"http://purl.org/dc/elements/1.1/"}) if item['pubdate'] is not None: handler.addQuickElement(u"pubDate", rfc2822_date(item['pubdate']).decode('ascii')) if item['comments'] is not None: handler.addQuickElement(u"comments", item['comments']) if item.has_key('wfw_commentRss') and item['wfw_commentRss'] is not None: handler.addQuickElement(u"wfw:commentRss", item['wfw_commentRss']) if item['unique_id'] is not None: handler.addQuickElement(u"guid", item['unique_id']) # Enclosure. if item['enclosure'] is not None: handler.addQuickElement(u"enclosure", '', {u"url": item['enclosure'].url, u"length": item['enclosure'].length, u"type": item['enclosure'].mime_type}) # Categories. for cat in item['categories']: handler.addQuickElement(u"category", cat) handler.endElement(u"item")
def add_item_elements(self, handler, item): handler.addQuickElement("title", item['title']) handler.addQuickElement("link", item['link']) if item['description'] is not None: handler.addQuickElement("description", item['description']) # Author information. if item["author_name"] and item["author_email"]: handler.addQuickElement("author", "%s (%s)" % (item['author_email'], item['author_name'])) elif item["author_email"]: handler.addQuickElement("author", item["author_email"]) elif item["author_name"]: handler.addQuickElement( "dc:creator", item["author_name"], {"xmlns:dc": "http://purl.org/dc/elements/1.1/"}) if item['pubdate'] is not None: handler.addQuickElement("pubDate", rfc2822_date(item['pubdate'])) if item['comments'] is not None: handler.addQuickElement("comments", item['comments']) if item['unique_id'] is not None: guid_attrs = {} if isinstance(item.get('unique_id_is_permalink'), bool): guid_attrs['isPermaLink'] = str( item['unique_id_is_permalink']).lower() handler.addQuickElement("guid", item['unique_id'], guid_attrs) if item['ttl'] is not None: handler.addQuickElement("ttl", item['ttl']) # Enclosure. if item['enclosure'] is not None: handler.addQuickElement("enclosure", '', {"url": item['enclosure'].url, "length": item['enclosure'].length, "type": item['enclosure'].mime_type}) # Categories. for cat in item['categories']: handler.addQuickElement("category", cat)
def add_item_elements(self, handler, item): # Required tags handler.addQuickElement('title', item['title']) # Enclosure. if item['enclosures']: enclosures = list(item['enclosures']) if len(enclosures) > 1: raise ValueError( 'RSS feed items may only have one enclosure, see ' 'http://www.rssboard.org/rss-profile#element-channel-item-enclosure' ) enclosure = enclosures[0] handler.addQuickElement( 'enclosure', '', { 'url': enclosure.url, 'length': enclosure.length, 'type': enclosure.mime_type, }) # Recommended tags handler.addQuickElement('guid', item['unique_id']) handler.addQuickElement('pubDate', rfc2822_date(item['pubdate'])) handler.addQuickElementCDATA('description', item['description']) if item['duration']: handler.addQuickElement('itunes:duration', item['duration']) if item['website']: handler.addQuickElement('link', item['website']) if item['image']: handler.addQuickElement('itunes:image', item['image']) handler.addQuickElement('itunes:explicit', str(item['explicit']).lower()) # Situational tags handler.addQuickElement('itunes:title', item['title']) if item['episode']: handler.addQuickElement('itunes:episode', item['episode']) if item['season']: handler.addQuickElement('itunes:season', item['season']) handler.addQuickElement('itunes:episodeType', item['type']) if item['block']: handler.addQuickElement('itunes:block', 'Yes')
def add_root_elements(self, handler): """ Add additional elements to the show object""" super(ITunesElements, self).add_root_elements(handler) show = self.feed["show"] handler.addQuickElement(u"guid", str(show.uuid), attrs={"isPermaLink": "false"}) handler.addQuickElement(u"itunes:subtitle", self.feed["subtitle"]) handler.addQuickElement(u"itunes:author", show.author_text) handler.startElement(u"itunes:owner", {}) handler.addQuickElement(u"itunes:name", show.owner.get_full_name()) handler.addQuickElement(u"itunes:email", show.owner.email) handler.endElement(u"itunes:owner") handler.addQuickElement(u"itunes:image", attrs={"href": show.img_itunes_lg.url}) handler.startElement(u"image", {}) handler.addQuickElement(u"url", show.img_itunes_sm.url) handler.addQuickElement(u"title", self.feed["title"]) handler.addQuickElement(u"link", self.feed["link"]) handler.endElement(u"image") handler.addQuickElement(u"itunes:category", attrs={"text": self.feed["categories"][0]}) handler.addQuickElement(u"itunes:summary", show.description) handler.addQuickElement(u"itunes:explicit", show.get_explicit_display()) if show.redirect: handler.addQuickElement(u"itunes:new-feed-url", show.redirect) handler.addQuickElement(u"keywords", show.keywords) if show.editor_email: handler.addQuickElement(u"managingEditor", show.editor_email) if show.webmaster_email: handler.addQuickElement(u"webMaster", show.webmaster_email) try: handler.addQuickElement( u"lastBuildDate", rfc2822_date(show.episode_set.published()[1].published)) except IndexError: pass handler.addQuickElement(u"generator", "Django Web Framework") handler.addQuickElement(u"docs", "http://blogs.law.harvard.edu/tech/rss")
def test_get_object(self): response = self.client.get('/syndication/rss2/articles/%s/' % self.e1.pk) doc = minidom.parseString(response.content) feed = doc.getElementsByTagName('rss')[0] chan = feed.getElementsByTagName('channel')[0] items = chan.getElementsByTagName('item') self.assertChildNodeContent( items[0], { 'comments': '/blog/1/article/1/comments', 'description': 'Article description: My first article', 'link': 'http://example.com/blog/1/article/1/', 'title': 'Title: My first article', 'pubDate': rfc2822_date(timezone.make_aware(self.a1.published, TZ)), })
def add_item_elements(self, item): item_elements = {'title': item['title'], 'link': item['link']} if item['description'] is not None: item_elements['description'] = item['description'] if item['pubdate'] is not None: item_elements['pubDate'] = rfc2822_date(item['pubdate']) if item['unique_id'] is not None: guid_attrs = {} if isinstance(item.get('unique_id_is_permalink'), bool): guid_attrs['isPermaLink'] = str( item['unique_id_is_permalink']).lower() item_elements['guid'] = item['unique_id'] # Add image url attributes for member if item['image_url'] is not None: domain_url = self.feed['link'] head, sep, tail = domain_url.partition('/en/') item_elements['image_url'] = head + item['image_url'] # Add member_level if item['member_level'] is not None: item_elements['member_level'] = item['member_level'] # Country if item['member_country'] is not None: item_elements['member_country'] = force_unicode( item['member_country']) # Start date if item['start_date'] is not None: item_elements['start_date'] = item['start_date'] # End date if item['end_date'] is not None: item_elements['end_date'] = item['end_date'] # Member url if item['member_url'] is not None: item_elements['member_url'] = item['member_url'] return item_elements
def add_root_elements(self, handler): super().add_root_elements(handler) handler.addQuickElement("pubDate", rfc2822_date(self.latest_post_date())) handler.addQuickElement('itunes:new-feed-url', self.feed['feed_url']) handler.addQuickElement('itunes:summary', self.feed['description']) handler.addQuickElement('itunes:subtitle', truncatechars(self.feed['description'], 49)) handler.addQuickElement('itunes:author', self.feed['author_name']) handler.addQuickElement('itunes:explicit', self.feed['explicit']) handler.addQuickElement('itunes:category', attrs={'text': self.feed['itunes_category']}) handler.startElement('itunes:owner', {}) handler.addQuickElement('itunes:name', self.feed['owner_name']) handler.addQuickElement('itunes:email', self.feed['owner_email']) handler.endElement('itunes:owner') handler.addQuickElement('itunes:image', attrs={'href': self.feed['image_url']}) handler.addQuickElement('webMaster', self.feed['webMaster']) handler.startElement('image', {}) handler.addQuickElement('url', self.feed['image_url']) handler.addQuickElement('title', self.feed['title']) handler.addQuickElement('link', self.feed['link']) handler.endElement('image')
def rfc1123_date(dt): if not dt: return '' return rfc2822_date(dt)
def test_rss2_feed(self): """ Test the structure and content of feeds generated by Rss201rev2Feed. """ response = self.client.get("/syndication/rss2/") doc = minidom.parseString(response.content) # Making sure there's only 1 `rss` element and that the correct # RSS version was specified. feed_elem = doc.getElementsByTagName("rss") self.assertEqual(len(feed_elem), 1) feed = feed_elem[0] self.assertEqual(feed.getAttribute("version"), "2.0") self.assertEqual( feed.getElementsByTagName("language")[0].firstChild.nodeValue, "en" ) # Making sure there's only one `channel` element w/in the # `rss` element. chan_elem = feed.getElementsByTagName("channel") self.assertEqual(len(chan_elem), 1) chan = chan_elem[0] # Find the last build date d = Entry.objects.latest("published").published last_build_date = rfc2822_date(timezone.make_aware(d, TZ)) self.assertChildNodes( chan, [ "title", "link", "description", "language", "lastBuildDate", "item", "atom:link", "ttl", "copyright", "category", ], ) self.assertChildNodeContent( chan, { "title": "My blog", "description": "A more thorough description of my blog.", "link": "http://example.com/blog/", "language": "en", "lastBuildDate": last_build_date, "ttl": "600", "copyright": "Copyright (c) 2007, Sally Smith", }, ) self.assertCategories(chan, ["python", "django"]) # Ensure the content of the channel is correct self.assertChildNodeContent( chan, { "title": "My blog", "link": "http://example.com/blog/", }, ) # Check feed_url is passed self.assertEqual( chan.getElementsByTagName("atom:link")[0].getAttribute("href"), "http://example.com/syndication/rss2/", ) # Find the pubdate of the first feed item d = Entry.objects.get(pk=self.e1.pk).published pub_date = rfc2822_date(timezone.make_aware(d, TZ)) items = chan.getElementsByTagName("item") self.assertEqual(len(items), Entry.objects.count()) self.assertChildNodeContent( items[0], { "title": "My first entry", "description": "Overridden description: My first entry", "link": "http://example.com/blog/%s/" % self.e1.pk, "guid": "http://example.com/blog/%s/" % self.e1.pk, "pubDate": pub_date, "author": "[email protected] (Sally Smith)", "comments": "/blog/%s/comments" % self.e1.pk, }, ) self.assertCategories(items[0], ["python", "testing"]) for item in items: self.assertChildNodes( item, [ "title", "link", "description", "guid", "category", "pubDate", "author", "comments", ], ) # Assert that <guid> does not have any 'isPermaLink' attribute self.assertIsNone( item.getElementsByTagName("guid")[0].attributes.get("isPermaLink") )
def add_root_elements(self, handler): """ Add additional elements to the show object""" super(ITunesElements, self).add_root_elements(handler) show = self.feed["show"] if show.original_image: if imagekit: itunes_sm_url = show.img_itunes_sm.url itunes_lg_url = show.img_itunes_lg.url elif photologue: site = Site.objects.get_current() itunes_sm_url = "%s%s" % ( site.domain, show.original_image.get_img_itunes_sm_url()) itunes_lg_url = "%s%s" % ( site.domain, show.original_image.get_img_itunes_lg_url()) elif easy_thumbnails: aliases = settings.THUMBNAIL_ALIASES[ "podcasting.Show.original_image"] thumbnailer = easy_thumbnails.files.get_thumbnailer( show.original_image) try: itunes_sm_url = thumbnailer.get_thumbnail( aliases["itunes_sm"]).url itunes_lg_url = thumbnailer.get_thumbnail( aliases["itunes_lg"]).url except easy_thumbnails.exceptions.InvalidImageFormatError: easy_thumbnails.signal_handlers.generate_aliases_global( show.original_image) itunes_sm_url = thumbnailer.get_thumbnail( aliases["itunes_sm"]).url itunes_lg_url = thumbnailer.get_thumbnail( aliases["itunes_lg"]).url except AttributeError: itunes_sm_url = None itunes_lg_url = None elif sorl: itunes_sm_url = sorl.thumbnail.get_thumbnail( show.original_image, "144x144").url itunes_lg_url = sorl.thumbnail.get_thumbnail( show.original_image, "1400x1400").url else: itunes_sm_url = show.original_image.url itunes_lg_url = show.original_image.url if itunes_sm_url and itunes_lg_url: handler.addQuickElement("itunes:image", attrs={"href": itunes_lg_url}) handler.startElement("image", {}) handler.addQuickElement("url", itunes_sm_url) handler.addQuickElement("title", self.feed["title"]) handler.addQuickElement("link", self.feed["link"]) handler.endElement("image") handler.addQuickElement("guid", str(show.uuid), attrs={"isPermaLink": "false"}) handler.addQuickElement("itunes:subtitle", self.feed["subtitle"]) handler.addQuickElement("itunes:author", show.author_text) handler.startElement("itunes:owner", {}) handler.addQuickElement("itunes:name", show.owner.get_full_name()) handler.addQuickElement("itunes:email", show.owner.email) handler.endElement("itunes:owner") handler.addQuickElement("itunes:category", attrs={"text": self.feed["categories"][0]}) handler.addQuickElement("itunes:summary", show.description) handler.addQuickElement("itunes:explicit", show.get_explicit_display()) if show.redirect: handler.addQuickElement("itunes:new-feed-url", show.redirect) handler.addQuickElement("keywords", show.keywords) if show.editor_email: handler.addQuickElement("managingEditor", show.editor_email) if show.webmaster_email: handler.addQuickElement("webMaster", show.webmaster_email) try: handler.addQuickElement( "lastBuildDate", rfc2822_date(show.episode_set.published()[1].published)) except IndexError: pass handler.addQuickElement("generator", "Django Web Framework") handler.addQuickElement("docs", "http://blogs.law.harvard.edu/tech/rss")
def format_datetime(dt): """ RFC 2822 datetime formatter """ return rfc2822_date(dt)
def test_rss2_feed(self): """ Test the structure and content of feeds generated by Rss201rev2Feed. """ response = self.client.get('/syndication/rss2/') doc = minidom.parseString(response.content) # Making sure there's only 1 `rss` element and that the correct # RSS version was specified. feed_elem = doc.getElementsByTagName('rss') self.assertEqual(len(feed_elem), 1) feed = feed_elem[0] self.assertEqual(feed.getAttribute('version'), '2.0') # Making sure there's only one `channel` element w/in the # `rss` element. chan_elem = feed.getElementsByTagName('channel') self.assertEqual(len(chan_elem), 1) chan = chan_elem[0] # Find the last build date d = Entry.objects.latest('published').published last_build_date = rfc2822_date(timezone.make_aware(d, TZ)) self.assertChildNodes(chan, [ 'title', 'link', 'description', 'language', 'lastBuildDate', 'item', 'atom:link', 'ttl', 'copyright', 'category' ]) self.assertChildNodeContent( chan, { 'title': 'My blog', 'description': 'A more thorough description of my blog.', 'link': 'http://example.com/blog/', 'language': 'en', 'lastBuildDate': last_build_date, #'atom:link': '', 'ttl': '600', 'copyright': 'Copyright (c) 2007, Sally Smith', }) self.assertCategories(chan, ['python', 'django']) # Ensure the content of the channel is correct self.assertChildNodeContent(chan, { 'title': 'My blog', 'link': 'http://example.com/blog/', }) # Check feed_url is passed self.assertEqual( chan.getElementsByTagName('atom:link')[0].getAttribute('href'), 'http://example.com/syndication/rss2/') # Find the pubdate of the first feed item d = Entry.objects.get(pk=1).published pub_date = rfc2822_date(timezone.make_aware(d, TZ)) items = chan.getElementsByTagName('item') self.assertEqual(len(items), Entry.objects.count()) self.assertChildNodeContent( items[0], { 'title': 'My first entry', 'description': 'Overridden description: My first entry', 'link': 'http://example.com/blog/1/', 'guid': 'http://example.com/blog/1/', 'pubDate': pub_date, 'author': '[email protected] (Sally Smith)', }) self.assertCategories(items[0], ['python', 'testing']) for item in items: self.assertChildNodes(item, [ 'title', 'link', 'description', 'guid', 'category', 'pubDate', 'author' ]) # Assert that <guid> does not have any 'isPermaLink' attribute self.assertIsNone( item.getElementsByTagName('guid')[0].attributes.get( 'isPermaLink'))
def test_feed(self): """ Borrowing a lot from https://github.com/django/django/blob/master/tests/syndication_tests/tests.py """ channel = self.get_feed_channel('/terry/my-blog/feeds/posts/rss/') d = self.blog.public_posts.latest('time_modified').time_modified last_build_date = rfc2822_date(d) # TEST THE channel ELEMENT # We're not currently using 'ttl', 'copyright' or 'category': self.assertChildNodes( channel, [ 'title', 'link', 'description', 'language', 'lastBuildDate', 'item', 'image', 'atom:link', ] ) self.assertEqual(channel.attributes['xmlns:content'].value, 'http://purl.org/rss/1.0/modules/content/') self.assertChildNodeContent(channel, { 'title': 'My Feed Title', 'description': 'My feed description.', 'link': 'http://example.com/terry/my-blog/', 'language': 'en', 'lastBuildDate': last_build_date, }) # TEST THE channel image ELEMENT image_el = channel.getElementsByTagName('image')[0] self.assertChildNodes(image_el, ['url', 'title', 'link',]) self.assertChildNodeContent(image_el, { # This gets a hash on the end from WhiteNoise, so leaving it off # the test for now: # 'url': 'http://example.com/static/img/site_icon.jpg', 'title': 'Site icon', 'link': 'http://example.com' }) # TEST THE item ELEMENTS items = channel.getElementsByTagName('item') self.assertEqual(len(items), 5) # Test the content of the most recent Post: self.assertChildNodeContent(items[0], { 'title': 'Bob\'s "latest" post', 'description': 'This is my excerpt.', 'link': 'http://example.com/terry/my-blog/2017/04/25/my-latest-post/', 'guid': 'http://example.com/terry/my-blog/2017/04/25/my-latest-post/', 'pubDate': rfc2822_date(self.post2.time_published), 'author': '[email protected] (Bob Ferris)', 'content:encoded': '<p>The post intro.</p><p>This is the post <b>body</b>.</p>\n<p>OK?</p>' }) self.assertCategories(items[0], ['Fish', 'Dogs', 'Cats']) for item in items: self.assertChildNodes(item, ['title', 'link', 'description', 'guid', 'category', 'pubDate', 'author', 'content:encoded',]) # Assert that <guid> does not have any 'isPermaLink' attribute self.assertIsNone(item.getElementsByTagName( 'guid')[0].attributes.get('isPermaLink'))
def add_root_elements(self, handler): super(RssFeedWithPubDate, self).add_root_elements(handler) handler.addQuickElement("pubDate", rfc2822_date(self.latest_post_date()).decode("utf-8"))
def add_root_elements(self, handler): super(RssFeedWithPubDate, self).add_root_elements(handler) handler.addQuickElement('pubDate', rfc2822_date(self.latest_post_date()).decode('utf-8'))
def item_start_datetime(self, item): return rfc2822_date(item.start.astimezone(pytz.timezone("UTC")))
def item_end_datetime(self, item): return (rfc2822_date(item.end.astimezone(pytz.timezone("UTC"))) if item.end else "")
def test_rss2_feed(self): """ Test the structure and content of feeds generated by Rss201rev2Feed. """ response = self.client.get('/syndication/rss2/') doc = minidom.parseString(response.content) # Making sure there's only 1 `rss` element and that the correct # RSS version was specified. feed_elem = doc.getElementsByTagName('rss') self.assertEqual(len(feed_elem), 1) feed = feed_elem[0] self.assertEqual(feed.getAttribute('version'), '2.0') # Making sure there's only one `channel` element w/in the # `rss` element. chan_elem = feed.getElementsByTagName('channel') self.assertEqual(len(chan_elem), 1) chan = chan_elem[0] # Find the last build date d = Entry.objects.latest('published').published last_build_date = rfc2822_date(timezone.make_aware(d, TZ)) self.assertChildNodes(chan, ['title', 'link', 'description', 'language', 'lastBuildDate', 'item', 'atom:link', 'ttl', 'copyright', 'category']) self.assertChildNodeContent(chan, { 'title': 'My blog', 'description': 'A more thorough description of my blog.', 'link': 'http://example.com/blog/', 'language': 'en', 'lastBuildDate': last_build_date, #'atom:link': '', 'ttl': '600', 'copyright': 'Copyright (c) 2007, Sally Smith', }) self.assertCategories(chan, ['python', 'django']) # Ensure the content of the channel is correct self.assertChildNodeContent(chan, { 'title': 'My blog', 'link': 'http://example.com/blog/', }) # Check feed_url is passed self.assertEqual( chan.getElementsByTagName('atom:link')[0].getAttribute('href'), 'http://example.com/syndication/rss2/' ) # Find the pubdate of the first feed item d = Entry.objects.get(pk=1).published pub_date = rfc2822_date(timezone.make_aware(d, TZ)) items = chan.getElementsByTagName('item') self.assertEqual(len(items), Entry.objects.count()) self.assertChildNodeContent(items[0], { 'title': 'My first entry', 'description': 'Overridden description: My first entry', 'link': 'http://example.com/blog/1/', 'guid': 'http://example.com/blog/1/', 'pubDate': pub_date, 'author': '[email protected] (Sally Smith)', }) self.assertCategories(items[0], ['python', 'testing']) for item in items: self.assertChildNodes(item, ['title', 'link', 'description', 'guid', 'category', 'pubDate', 'author']) # Assert that <guid> does not have any 'isPermaLink' attribute self.assertIsNone(item.getElementsByTagName( 'guid')[0].attributes.get('isPermaLink'))
def rss_base(self): return ['<?xml version="1.0" encoding="utf-8"?>\n', '<rss ', 'xmlns:atom="http://www.w3.org/2005/Atom"', 'version="2.0"', '<lastBuildDate>%s' % rfc2822_date(datetime.now())[:-3]]
def test_rss2_feed(self): """ Test the structure and content of feeds generated by Rss201rev2Feed. """ response = self.client.get("/syndication/rss2/") doc = minidom.parseString(response.content) # Making sure there's only 1 `rss` element and that the correct # RSS version was specified. feed_elem = doc.getElementsByTagName("rss") self.assertEqual(len(feed_elem), 1) feed = feed_elem[0] self.assertEqual(feed.getAttribute("version"), "2.0") # Making sure there's only one `channel` element w/in the # `rss` element. chan_elem = feed.getElementsByTagName("channel") self.assertEqual(len(chan_elem), 1) chan = chan_elem[0] # Find the last build date d = Entry.objects.latest("published").published last_build_date = rfc2822_date(timezone.make_aware(d, TZ)) self.assertChildNodes( chan, [ "title", "link", "description", "language", "lastBuildDate", "item", "atom:link", "ttl", "copyright", "category", ], ) self.assertChildNodeContent( chan, { "title": "My blog", "description": "A more thorough description of my blog.", "link": "http://example.com/blog/", "language": "en", "lastBuildDate": last_build_date, #'atom:link': '', "ttl": "600", "copyright": "Copyright (c) 2007, Sally Smith", }, ) self.assertCategories(chan, ["python", "django"]) # Ensure the content of the channel is correct self.assertChildNodeContent(chan, {"title": "My blog", "link": "http://example.com/blog/"}) # Check feed_url is passed self.assertEqual( chan.getElementsByTagName("atom:link")[0].getAttribute("href"), "http://example.com/syndication/rss2/" ) # Find the pubdate of the first feed item d = Entry.objects.get(pk=1).published pub_date = rfc2822_date(timezone.make_aware(d, TZ)) items = chan.getElementsByTagName("item") self.assertEqual(len(items), Entry.objects.count()) self.assertChildNodeContent( items[0], { "title": "My first entry", "description": "Overridden description: My first entry", "link": "http://example.com/blog/1/", "guid": "http://example.com/blog/1/", "pubDate": pub_date, "author": "[email protected] (Sally Smith)", }, ) self.assertCategories(items[0], ["python", "testing"]) for item in items: self.assertChildNodes(item, ["title", "link", "description", "guid", "category", "pubDate", "author"]) # Assert that <guid> does not have any 'isPermaLink' attribute self.assertIsNone(item.getElementsByTagName("guid")[0].attributes.get("isPermaLink"))