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 ;) )

 
require 'rubygems'
require 'feedzirra'
require 'sqlite'
require 'atom/entry'
require 'atom/collection'
require "xmlrpc/client"
 
db = SQLite::Database.new( 'db/feeds.db', 0644 )
new_feeds=Hash.new
updated_feeds=Hash.new
 
file=File.open("feeds")
while (line=file.gets)
# fetching a single feed
if line.size>0
if 404!=(feed = Feedzirra::Feed.fetch_and_parse(line)) && feed!=0
puts "updating  "+line
puts feed
last_title = db.get_first_value("select last_title from feeds where url='"
       +feed.url.hash.to_s+"';")
if last_title
  if last_title!=feed.entries.first.title.hash.to_s
   updated_feeds[feed.url]=feed.title
   stmt = db.prepare("update feeds set last_title='"
           +feed.entries.first.title.hash.to_s+"' where  url='"+feed.url.hash.to_s+"';")
   stmt.execute
  end
else
  new_feeds[feed.url]=feed.title
  stmt = db.prepare("insert into feeds (url,last_title) values ('"
            +feed.url.hash.to_s+"','"+feed.entries.first.title.hash.to_s+"');")
  stmt.execute
end
end
end
end
file.close
 
content = ""
if updated_feeds.size>0
  content = "
 
Updated blogs:
<ul>"
  updated_feeds.each do |url, title|
  content+="
<li><a href="+url+">"+title+"</a></li>
 
"
  end
content+="</ul>
 
"
end
if new_feeds.size>0
  content+= "
 
Newly added blogs:
<ul>"
new_feeds.each do |url, title|
  content+="
<li><a href="+url+">"+title+"</a></li>
 
"
end
content+="</ul>
 
"
end
 
if content.size!=0
username = "the_user_name"
password = "a_very_secret_password"  
 
begin
server = XMLRPC::Client.new( "www.urlofyourblog.de", "/xmlrpc.php")
 
newPost = Hash.new
 
newPost['title']="Blog updates"
newPost['description'] = content
newPost['category']= "Blogs"
result = server.call("metaWeblog.newPost",1,username,password,newPost,true)
rescue XMLRPC::FaultException => e
	puts "XMLRPC Error: "
	puts e.faultCode
	puts e.faultString
rescue StandardError => e
	puts e.to_s
end
end
 
Share