#!/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