まめ畑

ゆるゆると書いていきます

見てるNow!とFuetterスクリプトを更新しました

Twitterのレイアウト変更でFuetterが動かなくなったので修正しました。
ついでに、見てるNow!も更新しました。


見てるNow!の詳しいエントリは見ているページをTwitterにPOSTするJetpack Feature作ってみた - まめ畑です。
既にインストールされている方で自動更新にチェックを入れている場合は自動で更新されます。それ以外の方はmame-lab.com: The Leading Mame Lab Site on the Netからインストールして下さい。

今まではIDやPASSの保存に「jetpack.sessionStorage」を使用していましたが、「simpleStorage」などのstorageAPIのサポートがあり「jetpack.sessionStorage」を使用すると警告されるようになったので、「jetpack.storage.live」を使用するようにしました。
以前、「jetpack.storage.simple」を使用したのですが、こちらは各Jetpack Feature毎にストレージの名前空間が分かれており他のFeatureと保存時に使用するKeyの衝突を気にしなくて大丈夫なAPIであり、Persistence Storageとして使用可能です。「jetpack.storage.live」は共通領域に保存するので名前は気をつける必要があります。
Featureをまたいで使用したいデータは「jetpack.storage.live」で保存するといいです。
Jetpackのストレージ関係のAPIはこちらででJEPとしてまとめられています。:Labs/Jetpack/JEP/11 - MozillaWiki


コード

/*
	@author: con_mame
	@url: http://d.hatena.ne.jp/con_mame/
	@title: Miteru Now!
	@description: POST Watching Site's Title, URL and Short Comment to Twitter
	@version: 0.5
*/
(function(){

	const TWITTER_ICON = "http://assets1.twitter.com/images/favicon.ico";

	function getPageInfo(){
		var url = jetpack.tabs.focused.url;
		var title = jetpack.tabs.focused.contentWindow.document.title;
		var status = title + " " + url;
		return status;
	}

	function postToTwitter(){
		var cWindow =  jetpack.tabs.focused.contentWindow;
		var sStorage = jetpack.storage.live;
		if(!sStorage.twitterId && !sStorage.twitterPass){
			sStorage.twitterId = cWindow.prompt("Input Your Twitter ID");
			sStorage.twitterPass = cWindow.prompt("Input Your Twitter PASS");
		}
		var tId = sStorage.twitterId;
		var tPass = sStorage.twitterPass;

		var status = "\u898B\u3066\u308B\u004E\u006F\u0077\u0021\u0020";
		var comment = cWindow.prompt("Input Short Comment");
		comment = (comment != null) ? comment : "";
		status = status + encodeURIComponent(comment+ " " + getPageInfo());
		var status = "status=" + status;

		$.ajax({
			type: "POST",
			url: "http://twitter.com/statuses/update.xml",
			username: tId,
			password: tPass,
			processData: false,
			data: status,
			success: function(msg){
				jetpack.notifications.show({
							title: "Update!",
							body: "Update Success",
							icon: TWITTER_ICON
				});
			},
			error: function(xtr, status, thrown){
				if(xtr.readyState == 4 && xtr.status == 401){
					sStorage.twitterId = "";
					sStorage.twitterPass = "";
				}
				jetpack.notifications.show({
							title: "Error!",
							body: status,
							icon: TWITTER_ICON
				});
			}
		});
	}

	jetpack.statusBar.append({
		html: <>
			<img src="http://assets1.twitter.com/images/favicon.ico" />
			<span id="message">Miteru Now!!</span>
		</>,
		onReady: function(doc){
			$(doc).click(function(e){
				if(e.button == 2) return;
				postToTwitter();
			});
			$("#message", doc).css({
				position: "absolute",
				fontSize: "10pt",
				fontWeight: "bold",
				paddingLeft: "3px",
				cursor: "pointer"
			});
		},
		width: 110
	});
})();

Fuetterの詳しい事はTwitterのfollowerの増減をお知らせするよ改 - まめ畑のエントリを参照してください。
先日Twitterのレイアウト変更で動かなくなっていたので更新しました。
少しだけコードも書き換えています。
サーバでCronで定期実行するなどしてお使いください。


コード

require 'open-uri'
require 'rubygems'
require 'mechanize'
require 'tmail'
require 'net/smtp'
require 'date'
require 'time'
require 'yaml'


def read_yaml
	settings = YAML::load(File.open('fuetter.yaml'))
	$id = settings['user']['id']
	$pass = settings['user']['pass']
	$smtp_server = settings['mail']['server']
	$mail_to = settings['mail']['to']
	$mail_from = settings['mail']['from']
end

def login
	$agent = WWW::Mechanize.new
	$agent.max_history = 1
	$agent.user_agent_alias = 'Windows IE 7'
	login_page = $agent.get('http://twitter.com/')
	login_form = login_page.forms[1]
	login_form['session[username_or_email]'] = $id
	login_form['session[password]'] = $pass
	my_home = $agent.submit(login_form)
end

def get_followers_data(last_page_index = 20)
	followers = []
	(1..last_page_index).each do |n|
		my_follower_page = $agent.get("http://twitter.com/followers?page=#{n}")
		follower = (my_follower_page/"//span[@class=\"label screenname\"]/a")
		follower.each { |f| followers << f.inner_text }
	end
	followers
end

def get_my_followers(isFileExists = false)
	begin
		my_follower_page = $agent.get('http://twitter.com/followers')
		followers_count = (my_follower_page/"/html/body/div[2]/table/tbody/tr/td/div/div/h2/span").inner_text
		followers = followers_count.match(/\d+/)[0].to_i
		last_page_index =  (followers%20 != 0) ? (followers/20 + 1) : (followers/20)


		before_followers = []
		now_followers = []

		now_followers = get_followers_data(last_page_index)

		if isFileExists
			open("followers.txt","r") do |f|
				while line = f.gets
					before_followers << line.chomp
				end
			end

			new_follower = now_followers - before_followers
			remove = before_followers - now_followers
			make_body(new_follower, remove)
		end

		open("followers.txt","w") do |f|
			now_followers.each { |fr| f.puts(fr) }
		end
	rescue =>ex
		#get_my_followers(isFileExists)
	end
end

def make_body(add_follower, bye_follower)
	mail_body = "*Your Followers Report*\n\n"
	mail_body << "*** New Follower(s) ***\n"
	if(add_follower.length.zero?)
		mail_body << "No New Follower\n"
	else
		mail_body << add_follower.join("\n")
	end

	mail_body << "\n"
	mail_body << "*** Remove Follower(s) ***\n"
	if(bye_follower.length.zero?)
		mail_body << "No Bye Follower\n\n"
	else
		bye_follower = check_user(bye_follower)
		mail_body << bye_follower.join("\n")
	end

	send_mail(mail_body)
end

def check_user(bye_follower)
	tmp = []
	bye_follower.each do |id|
		begin
			open("http://twitter.com/#{id}")
			tmp << id.to_s + " [Exist]"
		rescue OpenURI::HTTPError
			tmp << id.to_s + " [Del]"
		end
	end
	tmp
end

def send_mail(body)
	today = Date.today
	mail = TMail::Mail.new
	mail.to = $mail_to
	mail.from = $mail_from
	mail.reply_to = $mail_from
	mail.subject = "Fuetter Report "+ today.strftime("%Y/%m/%d")
	mail.body = body

	mail.date = Time.now
	mail.mime_version = "1.0"
	mail.set_content_type 'text', 'plain', {'charset'=>'iso-2022-jp'}

	mail.write_back

	Net::SMTP.start($smtp_server) do |smtp|
	  smtp.sendmail(mail.encoded, mail.from, mail.to)
	end
end

read_yaml
login
get_my_followers(File.exists?("followers.txt"))