Apr 05

RSS reader in Ruby which posts to wordpress

I wanted a possibility to automatically create a list of updated photoblogs on pacnews. A bit of search revealed that it should be fairly easy to write something in ruby for that. So I settled for the newest implementation of a RSS-Parser library for ruby: Feedzirra by Paul Dix which can be found over at github.

I created a sqlite database with the following schema (place it in db/schemal.sql):

CREATE TABLE feeds (
id INTEGER PRIMARY KEY NOT NULL,
url VARCHAR(255) DEFAULT NULL,
last_title VARCHAR(255) DEFAULT NULL
);

the database file can be created with the following command:

sqlite db/feeds.db < db/schema.sql

In this database I save a hash of the photoblog's url and a hash of the last post title. In that way I can check if a blog has been updated or added to the list with fairly decent speed (I hope).

A simple text file called feeds within the same directory contains the line separated feedurls.
The program simply checks every feed url it finds in the feeds list for a new post title. New feeds are saved to the Hash new_feeds, feeds with new posts are saved to the Hash updated_feeds.
After the updating a simple unordered list is created out of the new and updated feeds. This list is posted to my wordpress blog via the xml-rpc interface. You might have to enable that in your admin interface under settings->writing.

Now I just put the script the crontable to update regularly. The very first post created by this script can be found here.

The script:
(direct download the rendering seems to be a bit screwed ;) )

  1.  
  2. require 'rubygems'
  3. require 'feedzirra'
  4. require 'sqlite'
  5. require 'atom/entry'
  6. require 'atom/collection'
  7. require "xmlrpc/client"
  8.  
  9. db = SQLite::Database.new( 'db/feeds.db', 0644 )
  10. new_feeds=Hash.new
  11. updated_feeds=Hash.new
  12.  
  13. file=File.open("feeds")
  14. while (line=file.gets)
  15. # fetching a single feed
  16. if line.size>0
  17. if 404!=(feed = Feedzirra::Feed.fetch_and_parse(line)) && feed!=0
  18. puts "updating "+line
  19. puts feed
  20. last_title = db.get_first_value("select last_title from feeds where url='"
  21. +feed.url.hash.to_s+"';")
  22. if last_title
  23. if last_title!=feed.entries.first.title.hash.to_s
  24. updated_feeds[feed.url]=feed.title
  25. stmt = db.prepare("update feeds set last_title='"
  26. +feed.entries.first.title.hash.to_s+"' where url='"+feed.url.hash.to_s+"';")
  27. stmt.execute
  28. end
  29. else
  30. new_feeds[feed.url]=feed.title
  31. stmt = db.prepare("insert into feeds (url,last_title) values ('"
  32. +feed.url.hash.to_s+"','"+feed.entries.first.title.hash.to_s+"');")
  33. stmt.execute
  34. end
  35. end
  36. end
  37. end
  38. file.close
  39.  
  40. content = ""
  41. if updated_feeds.size>0
  42. content = "<p>Updated blogs:</p><ul>"
  43. updated_feeds.each do |url, title|
  44. content+="<li><a href="+url+">"+title+"</a></li>"
  45. end
  46. content+="</ul>"
  47. end
  48. if new_feeds.size>0
  49. content+= "<p>Newly added blogs:</p><ul>"
  50. new_feeds.each do |url, title|
  51. content+="<li><a href="+url+">"+title+"</a></li>"
  52. end
  53. content+="</ul>"
  54. end
  55.  
  56. if content.size!=0
  57. username = "the_user_name"
  58. password = "a_very_secret_password"
  59.  
  60. begin
  61. server = XMLRPC::Client.new( "www.urlofyourblog.de", "/xmlrpc.php")
  62.  
  63. newPost = Hash.new
  64.  
  65. newPost['title']="Blog updates"
  66. newPost['description'] = content
  67. newPost['category']= "Blogs"
  68. result = server.call("metaWeblog.newPost",1,username,password,newPost,true)
  69. rescue XMLRPC::FaultException => e
  70. puts "XMLRPC Error: "
  71. puts e.faultCode
  72. puts e.faultString
  73. rescue StandardError => e
  74. puts e.to_s
  75. end
  76. end
  77.  
Share