#!/usr/bin/ruby -w
require 'net/http'
require 'uri'
require 'rexml/document'
require 'xmlrpc/client'
require 'md5'
require 'pp'
require 'date'
require 'parseconfigfile'
privateData = ParseConfigFile::parseConfigFile('.logininfo')
RssPath=privateData['RssPath']
BlogLoginPath=privateData['BlogLoginPath']
LJUser=privateData['LJUser']
LJPass=privateData['LJPass']
BlogUser=privateData['BlogUser']
BlogPass=privateData['BlogPass']
APISleepTime = 0.2
LJAPIPrefix = "LJ.XMLRPC."
ClientName = "Ruby-gregLJBlogAdapter/0.0.1"
class String
def starts_With?(text)
return false if (length < text.length)
return (self[0,text.length] == text)
end
end
def getBlogFeed()
rssText = Net::HTTP.get URI.parse(RssPath)
return REXML::Document.new(rssText)
end
def main()
rssXML = getBlogFeed()
links = []
linkToInfo = {}
rssXML.elements.each("/rss/channel/item") do |elem|
link = nil
description = nil
title = nil
pubDate = nil
elem.elements.each("link") do |linkElem|
link = linkElem.text
end
elem.elements.each("description") do |descElem|
description = descElem.text
end
elem.elements.each("title") do |titleElem|
title = titleElem.text
end
elem.elements.each("pubDate") do |dateElem|
pubDate = dateElem.text
end
if (link)
links.push(link)
linkToInfo[link] = {}
linkToInfo[link]['description'] = description
linkToInfo[link]['title'] = title
# Hooray for a default parse!
date = DateTime.parse(pubDate)
linkToInfo[link]['year'] = date.year()
linkToInfo[link]['mon'] = date.month()
linkToInfo[link]['day'] = date.day()
linkToInfo[link]['hour'] = date.hour()
linkToInfo[link]['min'] = date.min()
end
end
@userInfo = {}
@server = XMLRPC::Client.new2("http://www.livejournal.com/interface/xmlrpc")
login()
lastLink = getLastLJPost()
#puts "Lastlink: #{ lastLink }"
linkIndex = links.index(lastLink)
if (linkIndex != nil)
links = links[0,linkIndex]
end
links.reverse!
#puts links
# We used to try to login to the blog and get the full text, but it's tricky
# and screen-scrapy so we'll just use the description in the RSS feed.
#loginResp = Net::HTTP.post_form(URI.parse(BlogLoginPath), {"name" => BlogUser, "pass" => BlogPass, "form_id" => "user_login", "op" => "Log in"})
#puts loginResp.body
links.each do |link|
sleep(APISleepTime)
info = linkToInfo[link]
pp info
doMethod("postevent", :event => "Link to post
#{ info['description'] }", :subject => info['title'], :security => 'usemask', :allowmask => 1, :year => info['year'], :mon => info['mon'], :day => info['day'], :hour => info['hour'], :min => info['min'])
#puts "Link: #{ link }, description: #{ info['description'] }"
end
end
def getLastLJPost()
result = doMethod("getevents", :selecttype => "lastn", :howmany => 5, :lineendings => "unix")
linkRE = Regexp.new(' 0)
result['events'].each do |event|
post = event['event']
if (post.starts_With?(' 0)
params.update(*args)
end
callMethod(methodName, params)
end
def callMethod(methodName, *args)
# Try to handle transient errors
firstTime = true
begin
sleep(APISleepTime)
return @server.call(LJAPIPrefix + methodName, *args)
rescue Exception
if (firstTime)
print "Got exception, retrying: #{ $! }"
sleep(2.0)
firstTime = false
retry
else
raise "Error calling LJ method '#{ methodName }'. Check that your password is correct. If it is, wait a bit and try again."
end
end
end
def getAuthHash(challenge)
response = MD5.md5(challenge + MD5.md5(LJPass).hexdigest).hexdigest
return {:username => LJUser, :auth_method => "challenge", :auth_challenge => challenge, :auth_response => response, :ver => 1}
end
def login()
result = doMethod("login")
@userInfo['fastserver'] = if (result.include?('fastserver')) then result['fastserver'] else 0 end
if (@userInfo['fastserver'] == 1)
@server.cookie = "Cookie: ljfastserver=1"
end
end
if __FILE__ == $0 then
main()
end