O-Lab +Ossan Laboratory+

Ossanの研究所です。

twbot2でRSSを読み込んでURLはbit.lyで短縮させて、タイトル名もtwitter文字数制限にひっかからないように短縮させる。

bit.lyを使用する部分はどこかのページに書かれてたコードを引用したんだけど、
どこのコードだったか忘れてしまった。。。
本来ならば引用したページのURLを貼るべきなんだけど。すみません。


twbotに付属してた、rsspost.rbに追記した感じになります。

#!/usr/local/bin/ruby
# -*- coding: utf-8 -*-
# [en] Twitter bot of posting contents in RSS using twbot.rb
# [ja] twbot.rbを用い、RSSを取得してTwitterに投稿するbotプログラムのサンプル

$: << File.dirname(__FILE__)

require "cgi"
require "open-uri"
require "net/http"
require "twbot2"
require "json"

RSS_URL = "http://~~~~~"

def shorten_title(title,limit=90)
	strs = title.split(//u)
	if (limit < strs.length) then
		new_title=strs[0..(limit-10)].join
		return new_title.concat("...")
	end
	return title
end

def shorten_url(long_url)
    id = 'bitlyのid'
    api_key = 'bitlyのAPIKEY'
    version = '2.0.1'
	
	long_url = long_url.gsub(/#.*/, "")

    query = "version=#{version}&longUrl=#{long_url}&login=#{id}&apiKey=#{api_key}"
    result = JSON.parse(Net::HTTP.get("api.bit.ly", "/shorten?#{query}"))
    result['results'].each_pair {|long_url, value|
      return value['shortUrl']
    }
end

class RSSPost < TwBot
  def load_data
    # [en] Getting RSS
    # [ja] RSSを取得する
    buf = nil
    open(RSS_URL){ |file| buf = file.read }
    
    result = []
    @config["already_gotten"] ||= ""
    
    # [en]
    # Getting entries in RSS
    # (Using REXML library is better for strictness, but this program
    #  does not use for simpleness.)]
    # Each of RSS entry is stored in the variable "entry".
    # 
    # [ja]
    # RSSの各エントリを取得する
    # 厳密にはREXMLを使うべきだが、ここでは簡略化している
    # entryにはRSSでの各記事が格納される
    buf.scan(/<item.*?>.*?<\/item>/m).each do |entry|
      # [en] Get title and URL of the entry
      # [ja] エントリのタイトル・URLを取得
      title = nil
      entry.scan(/<title>(.*?)<\/title>/){|tmp| title = CGI.escapeHTML(tmp[0])}
      link = nil
      entry.scan(/<link>(.*?)<\/link>/){|tmp| link = CGI.escapeHTML(tmp[0])}
      
      # [ja] エントリのタイトル・URLを短縮
	  title = shorten_title(title) if title
	  link = shorten_url(link) if link
	  
      # [en]
      # If the entry is already gotten by this program, ignore this entry and
      # all following(older) entry.
      # 
      # [ja]
      # すでに取得したことのあるデータとURLが一致していたら、
      # それ以降の(それよりも古い記事の)データはすべて無視する
      break if link == @config["already_gotten"]
      
      # [en]
      # If the title and the URL of the entry is gained, add a message to
      # the list.
      # Because RSS lists entries from newer one, to post messages in the
      # original order, the message have to be added to the bottom of the
      # array("result").
      # 
      # [ja]
      # タイトル・URLが取得できていたら、投稿する発言のリストに追加する
      # RSSでは新しい記事ほど先に並ぶので、元の記事の順に発言するため、
      # 結果の配列(result)の後ろから投稿内容を追加している
      result.unshift("#{title} #{link}") if title && link
    end
    
    # [en] Keeping the URL of the newest entry in the data gotten now
    # [ja] 取得したデータのうち、最も新しい記事のURLを保持しておく
    unless result.empty?
      @config["already_gotten"] = result.last.split(/ /).last
    end
    
    # [en] Returning logged message and the result
    # [ja] ログされるメッセージと結果を返す
    @logmsg = "(#{result.size} post added)"
    result
  end
end

SELFDIR = File.dirname(__FILE__)
ARGV.each do |mode|
  RSSPost.new mode, "#{SELFDIR}/config.yml", "#{SELFDIR}/error.log"
end
# [en]
# To run this program, use commands like these:
# ruby rsspost-sample.rb load        # Load RSS and add messages to the list
# ruby rsspost-sample.rb post        # Post one message in the list
# ruby rsspost-sample.rb post post   # Post two messages in the list
# ruby rsspost-sample.rb load post   # Load RSS and add messages to the list,
#                                    # and post one message in the list
# 
# [ja]
# プログラム起動時は以下のようにする
# ruby rsspost-sample.rb load        # RSSをロードして発言リストに追加する
# ruby rsspost-sample.rb post        # ロード済みの発言を1つ発言する
# ruby rsspost-sample.rb post post   # ロード済みの発言を2つ発言する
# ruby rsspost-sample.rb load post   # RSSをロードしたのち、発言を1つ発言する