«

Getting RSS from Apple mail to NetNewsWire

I have been using Apple Mail to monitor my RSS feeds.  I like it because it’s right there when I check email.  Unfortunately, while I can set up my mail account using IMAP and have everything in sync regardless of whether I use the Mac Pro in the study, my Macbook Air, or my iPhone, the RSS feeds do not sync up.  So, sitting here in the hospital, I am unable to keep up with all the feeds on my main machine.  I did a bit of searching and found that NetNewsWire will do the trick of keeping them all synchronized (including the iPhone).

Downloaded…Installed…now, just import my RSS feeds from Apple Mail…hmmmmm…. search Google… only hit is this blog entry bemoaning the lack of this capability.

Well now, a bored programmer, laid up in the hospital, feeling just fine, and sharing the same need can’t just let a situation like this stand.

So, here’s a ruby script that will read the RSS feeds from your Apple Mail and create an opml file named AppleMailRSS.opml on your desktop.  This file will import into NetNewsWire and, though I’ve not tested anything else, presumably any other RSS reader that imports opml files.

(Update note: (March 21, 2009) I’ve updated the script to handle any RSS feeds in folders in Apple Mail. Thanks Sebastion for pointing this out. I was not using folders in Apple Mail so I missed this detail.)

require 'rexml/document'

skeleton = <<EOSTRING
<?xml version="1.0" encoding="UTF-8"?>
<opml version="1.1">
  <head>
    <title>Subscriptions from Apple Mail</title>
    </head>
  <body>
  </body>
</opml>
EOSTRING

def getFolder(node,folders)
  return node if folders.length == 0
  folder = folders.shift
  node.each_element("outline[@title='#{folder}']") do |fNode|
    return getFolder(fNode,folders)
  end
  fNode = REXML::Element.new 'outline'
  fNode.attributes['text'] = folder
  fNode.attributes['title'] = folder
  node << fNode
  return getFolder(fNode,folders)
end

def addRSSNode(body,folders,title,url)
  ol = REXML::Element.new 'outline'
  ol.attributes['text'] = title
  ol.attributes['description'] = ''
  ol.attributes['title'] = title
  ol.attributes['type'] = 'rss'
  ol.attributes['version'] = 'RSS'
  ol.attributes['htmlUrl'] = ''
  ol.attributes['xmlUrl'] = url
  getFolder(body,folders) << ol
end

doc = REXML::Document.new(skeleton)
body = REXML::XPath.match(doc,'//body')[0]
Dir.chdir()
Dir.chdir('Library/Mail/RSS')
Dir.glob('**/*.rssmbox') do |mbox|
  m = mbox.match(/(.*\/)*(.*).rssmbox/)
  folders = m[1] ? m[1].split('/') : []
  title = m[2]
  File.open("#{mbox}/Info.plist") do |file|
    url = file.read.match(/RSSFeedURLString.*?<string>(.*?)</m)[1]
    addRSSNode(body,folders,title,url)
  end
end

Dir.chdir()
File.open('Desktop/AppleMailRSS.opml','w') do |file|
  doc.write( file, 0 )
end
Share

  1. Sebastian says:

    Hi!

    Looks like a great script, but unfortunately I get an error trying to run it on my MacBook. I ran it by copying the text from here into a file I named mailrssopml.rb and ran it from the Terminal using ‘ruby mailrssopml.rb’.

    mailrssopml.rb:31: undefined method `[]‘ for nil:NilClass (NoMethodError)
    from mailrssopml.rb:30:in `glob’
    from mailrssopml.rb:30

    I have no experience in Ruby so I have no idea how to correct it.

  2. Mike Cargal says:

    That would seem to imply that the script did not find any *.rssmbox files.

    Can you open a terminal session and try the follwing command?

    ls ~/Library/Mail/RSS

    if you see a list of files ending with .rssmbox, then I need to work on the script since I’m obviously not finding them. If you don’t have any files in that directory, I’m not sure what to say. For my version of Apple Mail, this is where those files are located.

  3. Sebastian says:

    I have my RSS feeds organized in folders, so running that command displays my folders, and the lone *.rssmbox that does not reside in a folder. Does your script check in sub folders? Even if it doesn’t, I think it should pick up the one RSS feed that is in the root folder.

  4. Mike Cargal says:

    Ah, that makes sense. I wasn’t using folders. Let me play around and I’ll try to post an updated version in the next few days (maybe this weekend)

  5. Mike Cargal says:

    I’ve just updated the script to handle RSS feeds in folders. Give it a try and let me know if you have any problems.

  6. Sebastian says:

    Hey!

    Great update to the script.

    Sebastian

  7. Pirsey says:

    The style of writing is quite familiar to me. Did you write guest posts for other blogs?

  8. Mike Cargal says:

    Nope, guess I’ve just been influenced by others. I’ve been told that I write pretty conversationally. Folks that know me have told me that I write exactly the way I talk and that they can pretty much hear me talking as they read what I write. It’s always a bit funny that they find this surprising. “Hey the words come out the same whether you speak or type!!”.

  9. cico says:

    A backslash is missing on line 44, before the yellow forward slash..
    Fixed line:
    m = mbox.match(/(.*\/)*(.*).rssmbox/)

    And so I learned Ruby to avoid writing an email :)

    Thanks Mike!

  10. Mike Cargal says:

    hmmm… that’s interesting. I just pulled up my local copy and it has the missing backslash. I wondered how it worked for me if I had it wrong. Looks like something funky happened when I used TextMate to create the syntax highlighted html for the script.

    I’ve updated it. Thanks for pointing that out.

  11. ewok says:

    great, it did exactly the job!
    thank you very much for turning out this solution.

    maybe, you wanna add some little tips for newbies –
    how to use this code.
    (saving the code to a “***.rb” file,
    executing in terminal with “ruby *file*”

    bye,
    ewok

  12. Mike Cargal says:

    sure, share all you want

  13. You wouldn¡¯t believe it but I¡¯ve wasted all day digging for some articles about this. You¡¯re a lifesaver, it was an excellent read and has helped me out to no end. Cheers,

  14. [...] welches die RSS-Feeds aus Mail ausliest und als OPML Datei zusammenfasst. Den Script Content vom Blog des Entwicklers – Danke an dieser Stelle an Mike Cargal – in eine neue “ImportRSS.rb” [...]

  15. Tee Hamburg says:

    Nice post, thanks!

  16. Great blog, I will add this blog to my favorites.

  17. Ashley says:

    hey, nice blog…really like it and added to bookmarks. keep up with good work

  18. Brian says:

    I pasted the code above into a text file and saved as mailrssopml.rb. I placed this file in my /user folder. I then issued this command in terminal: ruby mailrssopml.rb.

    However, I got this error message in terminal “mailrssopml.rb:39: uninitialized constant REXML (NameError)”

    Any ideas why this would occur? Thanks so much for putting this code together!

  19. Mike Cargal says:

    Your error message would imply that REXML may not be installed. That’s odd for two reasons. 1 – I would expect to see some error on the require statement at the top of the script. Apparently, that executed fine (unless there were more messages than just the one you left in your comment). 2 – REXML is a standard Ruby library, and definitely should be installed on your machine.

    Can you tell me what version of OS X you are on? maybe what version of Ruby as well (you can get this by executing “ruby -v” in a terminal window. I get “ruby 1.8.6 (2007-03-13 patchlevel 0) [universal-darwin8.0]“. That’s on Snow Leopard.

    You might take a look at the REXML page as well (http://www.germane-software.com/software/rexml/).

  20. Carri Corell says:

    Would you please translate your blog into Germany because I’m not selfsame comfortable reading it in English? I’m getting tired of employing Google Translate totally the time, there is a small WP plugin predicted like global translator which will translate entirely your pages automatically- that will construct reading posts on your corking blog evening more cosy. Cheers dude, Thanks!

  21. rrgrfrfrf says:

    thanks for posting this, I was looking for this info

  22. lowsmagco says:

    Excellent post once again. I am looking forward for your next post:)

  23. davide says:

    I liked your post. Cheers

  24. luciano rahal says:

    This is chinese to me but i need to do it can you please put step by step.

    I understand that i need to copy paste the code into terminal ? is that it?

  25. Mike Cargal says:

    No, sorry that’s not clear. You’ll need to open an editor and copy and paste the code into the editor. Then save the file. You can call it whatever you want but the convention would be to have the file end in “.rb”. I’d suggest something like ConvertRSS.rb. Once you’ve saved it, open terminal, go to the directory where you’ve saved the file and, at the command prompt, type “Ruby ConvertRSS.rb” (or whatever you decided to name your file.

    Hope that helps.

Leave a Reply

Spam Protection by WP-SpamFree

Edit translation
Machine translation (Google):
Loading...
Copy to editor
or Cancel