def output_rss(self, filename): self.log("Rss2","Generating RSS2 feed for site at {}".format(self.rssfile), self.data.level) import PyRSS2Gen as rss2 import htmltruncate import datetime items = [] posts = sorted(self.data.content['blog'], key=lambda c: c.published, reverse=True)[0:self.NUM_POSTS] for c in posts: try: description = htmltruncate.truncate(c.render(),self.PREVIEW_CHARS,"...") except htmltruncate.UnbalancedError: self.log("Rss2", "Error truncating {}, ensure proper document structure".format(post.name), self.data.level) raise link = self.siteroot + c.metadata['link'] items.append(rss2.RSSItem( title = c.metadata['title'], description = description, link = link, guid = rss2.Guid(link), pubDate = c.metadata['published'] )) rss = rss2.RSS2( title = self.rsstitle, link = "http://masenf.com/", description = "Latests posts about the life of Masen Furer", lastBuildDate = datetime.datetime.utcnow(), items = items ) with open(filename,'w') as f: f.write(rss.to_xml())
def teaser(self): """ Get the markup preceding first <hr /> tag """ index = self.content.find('<hr') if index > 10: return str(BeautifulSoup(self.content[:index])) else: return htmltruncate.truncate(self.content, 250, '...')
def render(self, *args, **kwds): self.log("Posts", "rendering posts listing for {}".format(self.__class__), self.data.level) if not hasattr(self,"rendered"): self.rendered = "" # copy all blogposts loc_content = self.get_content() for post in loc_content: fields = post.metadata try: fields['body'] = htmltruncate.truncate(post.render(),self.PREVIEW_CHARS,"...") except htmltruncate.UnbalancedError: self.log("Posts", "Error truncating {}, ensure proper document structure".format(post.name), self.data.level) raise self.rendered += self.data.render_template(self.TEMPLATE, fields) return self.rendered
def testEllipsis(self): self.assertEqual( htmltruncate.truncate('this <b>word</b> is bolded', 10, '...' ), "this <b>word</b> ...")
def testSelfClosing(self): self.assertEqual( htmltruncate.truncate( "I need<br /> a break", 11 ), "I need<br /> a br" )
def testEntity(self): self.assertEqual( htmltruncate.truncate( "I'm one", 3 ), "I'm" )
def testTruncation(self): for input, count, output in self.cases: self.assertEqual( htmltruncate.truncate(input, count), output )
def testUnbalanced(self): self.assertEqual( htmltruncate.truncate( 'I am a <b>bad</strong> little string with unbalanced tags', 20 ), htmltruncate.ERR_UNBALANCED )
def testFullWord(self): self.assertEqual( htmltruncate.truncate( "I need<br /> a break", 11, full_word=True ), "I need<br /> a break" )
def testSurrounding(self): self.assertEqual( htmltruncate.truncate('<p>this paragraph should be cut in half</p>', 11, '...' ), "<p>this paragr...</p>")
def testVoidElements(self): self.assertEqual( htmltruncate.truncate( "<a href='http://www.example.com'>I need<br> a break</a> one more time.", 17), "<a href='http://www.example.com'>I need<br> a break</a> on")