Created
February 13, 2013 13:04
-
-
Save aquarla/4944461 to your computer and use it in GitHub Desktop.
過去のはてなブックマークからランダムで1件選んでツイートするBot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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