Reading RSS feeds with Emacs

I spend most of my time at the computer in GNU Emacs. I have previously given here hints about how I find key bindings for commands, how I watch Youtube videos in Emacs, and I have even considered Emacs Lisp as a general purpose programming language.

This post is about reading blogs using Emacs, or more generally, reading RSS and Atom feeds.

Gnus

After several years using View Mail as an e-mail tool inside Emacs, I switched to Gnus 3 years ago because View Mail was a little bit slow and I had some issues in dealing with large quantities of e-mails.

Gnus is a little bit daunting at first, mostly because it was designed for newsgroups and some concepts are different from what we are used to with classical mail user agents. But once these concepts are clear to you, Gnus is very efficient in dealing with e-mail, even with huge quantities of it.

One thing I like very much about Gnus is its scoring capability. You may have heard about or even use Gmail’s priority inbox. Scoring is somewhat similar (but invented before …).

Another cool thing about reading e-mail inside Emacs is the integration with Org mode so that you can store links to and take quick notes about messages using org-capture. This is a keystone to efficiently implementing inbox zero.

But let’s get back to the main topic. Gnus also allows to read RSS feeds. I have tried 3 different approaches for reading feeds in Gnus:

  1. The Gnus RSS back-end
  2. Reading feeds via a news server
  3. Downloading feeds and convert them to e-mail

The order above is the chronological order in which I have tried things.

RSS back-end

This is the straightforward way to use Gnus for RSS. You just add a new group by giving the link to the RSS feed. Unfortunately, this does not work for Atom feeds, but they can be converted using an external tool called atom2rss. In order to automate the conversion, I use this snippet in my Gnus configuration file:

(require 'mm-url)
(defadvice mm-url-insert 
   (after DE-convert-atom-to-rss () )  
   "Converts atom to RSS by calling xsltproc."  
   (when 
      (re-search-forward
         "xmlns=\"http://www.w3.org/.*/Atom\"" 
          nil t)
      (goto-char (point-min))    
      (message "Converting Atom to RSS... ")    
      (call-process-region 
         (point-min) 
         (point-max) 
         "xsltproc" 
         t t nil 
         (expand-file-name 
            "~/.emacs.d/atom2rss.xsl") "-")    
      (goto-char (point-min))    
      (message 
         "Converting Atom to RSS... done")))
(ad-activate 'mm-url-insert)

I started looking for an alternative to the RSS back-end because it can be slow, since polling all the feeds takes time.

Gwene

Gwene is a gateway which transforms feeds to newsgroups. It is maintained by Lars Ingebrigtsen (the creator of Gnus) himself!

The way of using Gwene in Gnus is really easy. Just add this to the configuration:

(add-to-list 'gnus-secondary-select-methods '(nntp "news.gwene.org"))

It is quicker than the RSS back-end. I don’t really know why, but I guess that it is due to the fact that Gwene fetches the feeds in advance. Of course, if the feed you are looking for is not yet available in Gwene, you have to add it by using the web interface, but this only takes a couple of seconds.

The reason why I looked again for an alternative was again response time, since sometimes the Gwene server seems to be a little bit busy. This tends to block Emacs waiting for the server response.

Feed2Imap

Feed2Imap is an RSS/Atom feed aggregator. It downloads the feeds over http and then uploads them to a specified folder of an IMAP mail server or copies them to a local maildir. I only use this second way, since I read the feeds in the same computer where I download them, but the IMAP server solution could be interesting in order to synchronize the feeds between different devices, like a smart-phone and Emacs on my laptop.

The feeds to be fetched are stored into the .feed2imaprc file and look like this:

- name: GnusAnnounce
  url: http://rss.gmane.org/messages/complete/gmane.emacs.gnus.announce
  target: maildir:///home/inglada/RSSFeeds/gnus-announce
- name: BlogJI
  url: http://jordiinglada.net/wp/feed/
  target: maildir:///home/inglada/RSSFeeds/blog-ji

For Gnus to be aware of this maildir folder, I use:

(add-to-list 'gnus-secondary-select-methods
  '(nnmaildir "RSSFeeds" 
   (directory 
     "/home/inglada/RSSFeeds")              
   (directory-files 
      nnheader-directory-files-safe) 
      (get-new-mail nil)))

And then I can subscribe to the different feeds from Gnus since the nnmaildir appears in the server list as {nnmaildir:RSSFeeds}.

Feed2Imap can be run from the command line or using a cron job. I prefer to run it manually from Emacs when I am online:

(defun ji-feed2imap ()  
   (interactive)  
   (start-process 
      "feed2imap" 
       "*feed2imap*" 
       "/usr/bin/feed2imap" "-v"))

This function will run Feed2Imap in the background and generate a buffer named *feed2imap* where the log messages are stored just in case.

Actually, since I use OfflineImap1 to get my e-mail, I have this function:

(defun ji-get-feeds-email ()  
   (interactive)  
   (progn    
      (ji-feed2imap)    
      (offlineimap)))

which is bound like this:

(global-set-key (kbd "<f9> o") 
                'ji-get-feeds-email)

I am satisfied with this configuration which allows me to:

  1. Read feeds inside Gnus
  2. Fetch the feeds without blocking Emacs by pressing <f9> o
  3. Read the feeds when I am offline

Footnotes:

1

I use the Emacs package developed by J. Danjou.