Skip to content

Instantly share code, notes, and snippets.

@aquarla
Created February 13, 2013 13:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aquarla/4944461 to your computer and use it in GitHub Desktop.
Save aquarla/4944461 to your computer and use it in GitHub Desktop.
過去のはてなブックマークからランダムで1件選んでツイートするBot
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
require 'rubygems'
require 'open-uri'
require 'nokogiri'
require 'oauth'
# ActiveSupportのString#truncateを参考にする
# String#mb_charsは、Ruby1.9前提であればそのままselfを返してよい
class String
def truncate(length, options = { })
text = self.dup
options[:omission] ||= "..."
length_with_room_for_omission = length - options[:omission].mb_chars.length
chars = text.mb_chars
stop = options[:separator] ?
(chars.rindex(options[:separator].mb_chars, length_with_room_for_omission) || length_with_room_for_omission) : length_with_room_for_omission
(chars.length > length ? chars[0...stop] + options[:omission] : text).to_s
end
def mb_chars
self
end
end
# 過去のブックマークからランダムに1個を選びツイートするbotクラス
module HatenaBookmarkBot
class Base
# Twitterアクセスのための各種情報
CONSUMER_KEY = "XXXXXXXXXXXXXXXXX"
CONSUMER_SECRET = "XXXXXXXXXXXXXXXXX"
ACCESS_TOKEN = "XXXXXXXXXXXXXXXXX"
ACCESS_TOKEN_SECRET = "XXXXXXXXXXXXXXXXX"
# はてなブックマークのユーザー名
HATENA_BOOKMARK_USERNAME = "aquarla"
# はてブRSSをXMLとして取得
# offsetを指定した場合は、offset件目以降を取得
def open_hatena_bookmark_rss(username, offset=nil)
rss_url = "http://b.hatena.ne.jp/#{username}/rss"
rss_url += "?of=#{offset}" if offset
open(rss_url) do |file|
yield file.read
end
end
# XMLから現在の総ブックマーク数を取得
def bookmark_count(xml)
namespaces = {
'opensearch' => 'http://a9.com/-/spec/opensearchrss/1.0/',
}
Nokogiri::XML.parse(xml).at('.//opensearch:totalResults', namespaces).text.to_i rescue -1
end
# 文字列をツイート
def tweet(status)
consumer = OAuth::Consumer.new(CONSUMER_KEY, CONSUMER_SECRET, :site => 'https://api.twitter.com')
access_token = OAuth::AccessToken.new(consumer, ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
access_token.post('/1.1/statuses/update.json', 'status' => status)
end
# 処理本体
def run
# 1. はてブのRSSフィードから、ブックマークの全件数を取得
open_hatena_bookmark_rss(HATENA_BOOKMARK_USERNAME) do |xml|
count = bookmark_count(xml)
# 2. 全件のうち何件めをツイートするかをランダムに決定し、
index = rand(count)
open_hatena_bookmark_rss(HATENA_BOOKMARK_USERNAME, index/20*20) do |xml2|
namespaces = {"rss" => "http://purl.org/rss/1.0/"}
item = Nokogiri::XML.parse(xml2).xpath("//rss:item[#{(index%20)}]", namespaces)
title = item.xpath(".//rss:title", namespaces).text
link = item.xpath(".//rss:link", namespaces).text
description = item.xpath(".//rss:description", namespaces).text
# 3. ブックマーク情報をツイートする
# ツイートに@が含まれていると迷惑なので外すのと、
# ツイートが長すぎる場合はタイトル及びコメントを切り詰める
status = if description.nil? || description == ""
"#{title.truncate(100)} #{link}"
else
"#{description.truncate(50)} / #{title.truncate(50)} #{link}"
end
status.gsub!(/@/, "")
tweet(status)
end
end
end
end
end
if $0 == __FILE__
HatenaBookmarkBot::Base.new.run
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment