Ticket #336: tracblog-rss-0.2.patch

File tracblog-rss-0.2.patch, 8.1 kB (added by mjk@aellaweil.de, 2 years ago)

Patch for RSS feed (less ugly version)

  • blog/web_ui.py

    old new  
    2424from pkg_resources import resource_filename 
    2525from trac.core import * 
    2626from trac.web import IRequestHandler 
    27 from trac.web.chrome import ITemplateProvider, add_stylesheet 
     27from trac.web.chrome import ITemplateProvider, add_stylesheet, add_link 
    2828from trac.web.chrome import INavigationContributor  
    29 from trac.util import Markup, format_date, format_datetime 
    30 from trac.wiki.formatter import Formatter, wiki_to_oneliner 
     29from trac.util import Markup, format_date, format_datetime, http_date 
     30from trac.util.text import to_unicode 
     31from trac.wiki.formatter import Formatter, wiki_to_oneliner, wiki_to_html 
    3132from trac.wiki.model import WikiPage 
    3233from trac.wiki.api import IWikiMacroProvider 
    3334from trac.perm import IPermissionRequestor 
     
    3536from tractags.api import TagEngine 
    3637from tractags.parseargs import parseargs 
    3738 
     39_title_split_match = re.compile(r'^=+\s+([^\n\r=]+?)\s+=+\s+(.+)$', 
     40                                re.DOTALL).match 
     41 
    3842BOOLS_TRUE = ['true', 'yes', 'ok', 'on', 'enabled', '1'] 
    3943 
    4044__all__ = ['TracBlogPlugin'] 
     
    105109    '''delta''' - How many days of posts should be shown.[[br]] 
    106110    '''mark_update''' - Specify whether to show "Updated on" for posts that 
    107111    have been updated.[[br]] 
     112    '''format''' - Show as RSS feed ('rss') or HTML (else).[[br]] 
    108113 
    109114    If specifying dates with {{{year}}}, {{{month}}}, and/or {{{day}}}, the 
    110115    current value is specified if missing.  For example, if {{{day}}} is  
     
    196201        add_stylesheet(req, 'blog/css/blog.css') 
    197202        add_stylesheet(req, 'common/css/wiki.css') 
    198203        tags = req.args.getlist('tag') 
     204        format = req.args.get('format') 
    199205        kwargs = {} 
    200206        for key in req.args.keys(): 
    201207            if key != 'tag': 
     
    205211            tstr = self.env.config.get('blog', 'default_tag', 'blog') 
    206212            tags = [t.strip() for t in _tag_split.split(tstr) if t.strip()] 
    207213        self._generate_blog(req, *tags, **kwargs) 
    208         return 'blog.cs', None 
     214        if format == 'rss': 
     215            return 'blog_rss.cs', 'application/rss+xml' 
     216        else: 
     217            add_link(req, 'alternate', self.env.href.blog(format='rss'), 
     218                        'RSS Feed', 'application/rss+xml', 'rss') 
     219            return 'blog.cs', None 
    209220 
    210221    def _generate_blog(self, req, *args, **kwargs): 
    211222        """Extract the blog pages and fill the HDF. 
     
    260271                time_format = self.env.config.get('blog', 'date_format') \ 
    261272                              or '%x %X' 
    262273                timeStr = format_datetime(post_time, format=time_format)  
     274                fulltext = page.text 
     275                # remove comments in blog view: 
     276                del_comments = re.compile('==== Comment.*\Z', re.DOTALL) 
     277                fulltext = del_comments.sub('', fulltext) 
     278                # remove the [[AddComment...]] tag, otherwise it would appeare 
     279                # more than one and crew up the blog view: 
     280                del_addcomment  = re.compile('\[\[AddComment.*\Z', re.DOTALL) 
     281                fulltext = del_addcomment.sub('', fulltext) 
     282                # limit length of preview: 
    263283                post_size = self._choose_value('post_size', req, kwargs, int) 
    264284                if not post_size and (not isinstance(post_size, int)): 
    265285                    post_size = int(self.env.config.get('blog', 'post_size',  
    266286                                    1024)) 
    267                 text = self._trim_page(page.text, blog_entry, post_size) 
     287                text = self._trim_page(fulltext, blog_entry, post_size) 
    268288                pagetags = [x for x in tags.get_name_tags(blog_entry) if x not in tlist] 
    269289                tagtags = [] 
    270290                for i, t in enumerate(pagetags[:3]): 
     
    274294                        } 
    275295                    tagtags.append(d) 
    276296                    continue 
     297                # extract title from text: 
     298                match = _title_split_match(fulltext) 
     299                if match: 
     300                    title = match.group(1) 
     301                    fulltext = match.group(2) 
     302                else:  
     303                    title = blog_entry 
     304                html_text = wiki_to_html(fulltext, self.env, req) 
     305                rss_text = Markup.escape(to_unicode(html_text)) 
    277306                data = { 
    278307                        'name'      : blog_entry, 
     308                        'title'     : title, 
     309                        'href'      : self.env.href.wiki(blog_entry), 
    279310                        'wiki_link' : wiki_to_oneliner(read_post %  
    280311                                                       blog_entry, 
    281312                                                       self.env), 
    282313                        'time'      : timeStr, 
     314                        'date'      : http_date(page.time), 
    283315                        'author'    : author, 
    284316                        'wiki_text' : wiki_to_nofloat_html(text, self.env, req, 
    285317                                                   macro_blacklist=macro_bl), 
     318                        'rss_text'  : rss_text, 
    286319                        'comment'   : wiki_to_oneliner(comment, self.env), 
    287320                        'tags'      : { 
    288321                                        'present' : len(pagetags), 
     
    290323                                        'more'    : len(pagetags) > 3 or 0, 
    291324                                      }, 
    292325                       } 
     326                if author: 
     327                    # For RSS, author must be an email address 
     328                    if author.find('@') != -1: 
     329                        data['author.email'] = author 
     330                    elif self._user2email(author) is not None: 
     331                        data['author.email'] = self._user2email(author) 
     332                 
    293333                if (modified != post_time) and mark_updated: 
    294334                    data['modified'] = 1 
    295335                    mod_str = format_datetime(modified, format=time_format) 
     
    312352        req.hdf['blog.hidecal'] = hidecal 
    313353        pass 
    314354 
     355    def _user2email(self, user): 
     356        for username, name, email in self.env.get_known_users(): 
     357            if email: 
     358                return email 
     359        return None 
     360 
    315361    def _generate_calendar(self, req, tallies): 
    316362        """Generate data necessary for the calendar 
    317363 
  • blog/templates/blog_rss.cs

    old new  
     1<?xml version="1.0"?> 
     2<rss version="2.0"> 
     3 <channel><?cs 
     4  if:project.name_encoded ?> 
     5   <title><?cs var:project.name_encoded ?>: <?cs var:title ?></title><?cs 
     6  else ?> 
     7   <title><?cs var:title ?></title><?cs 
     8  /if ?> 
     9  <link><?cs var:base_host ?><?cs var:trac.href.blog ?></link> 
     10  <description>Trac Blog</description> 
     11  <language>en-us</language> 
     12  <generator>Trac v<?cs var:trac.version ?></generator><?cs 
     13  if:chrome.logo.src ?> 
     14   <image> 
     15    <title><?cs var:project.name_encoded ?></title> 
     16    <url><?cs if:!chrome.logo.src_abs ?><?cs var:base_host ?><?cs /if ?><?cs 
     17     var:chrome.logo.src ?></url> 
     18    <link><?cs var:base_host ?><?cs var:trac.href.blog ?></link> 
     19   </image><?cs 
     20  /if ?><?cs 
     21  each:bentry = blog.entries ?> 
     22   <item> 
     23    <title><?cs var:bentry.title ?></title><?cs 
     24    if:bentry.author.email ?> 
     25     <author><?cs var:bentry.author.email ?></author><?cs 
     26    else ?> 
     27     <author><?cs var:bentry.author ?></author><?cs 
     28    /if ?> 
     29    <pubDate><?cs var:bentry.date ?></pubDate> 
     30    <link><?cs var:base_host ?><?cs var:bentry.href ?></link> 
     31    <guid><?cs var:base_host ?><?cs var:bentry.href ?></guid> 
     32    <description> 
     33      <?cs var:bentry.rss_text ?><?cs  
     34      if bentry.tags.present != 0 ?> 
     35        &lt;p&gt;Posted in: <?cs 
     36        each:tag=bentry.tags.tags ?> 
     37          &lt;a href="<?cs var:cgi_location ?>/tags/<?cs var:tag.link ?>"&gt; 
     38            <?cs var:tag.name ?>&lt;/a&gt;<?cs 
     39          if ! tag.last ?>,<?cs  
     40          /if ?><?cs 
     41        /each ?><?cs 
     42      /if ?> 
     43    </description> 
     44   </item><?cs 
     45  /each ?> 
     46 </channel> 
     47</rss>