Created
April 7, 2011 05:40
-
-
Save dnpp73/907105 to your computer and use it in GitHub Desktop.
指定したscreen_nameのfollowingの色んな変更をチェックする感じ。
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
=begin | |
必要なもの | |
$ gem install rubytter | |
../oauth_yaml/#{Client}-#{App}.yaml ( TwitterOAuthの情報を格納したもの ) | |
これはなに | |
指定したscreen_nameのfollowingの色んな変更をチェックする感じ。 | |
つかいかた | |
$ crontab -e | |
で、こんな感じの追記をして | |
0 0 * * * /path/to/ruby /path/to/following-check.rb | |
後は適当な画面で | |
$ tail -f /path/to/log/#{Target}-following_activity.txt | |
$ tail -f /path/to/log/#{Target}-screen_name-log.txt | |
=end | |
require 'rubygems' | |
require 'rubytter' | |
require 'yaml' | |
require 'date' | |
require 'fileutils' | |
#設定用の定数など | |
DEBUG = false | |
Client = 'DNPP' | |
App = 'Ofuton' | |
Target = 'DNPP' | |
CDIR = File.dirname(File.expand_path(__FILE__)) | |
OAuth_YAML = CDIR+'/../oauth_yaml/'+Client+'-'+App+'.yaml' | |
if DEBUG | |
Log = true | |
ELog = true | |
SleepWait = 0 | |
Log_DIR = CDIR+'/'+'log-dev' | |
Data_DIR = CDIR+'/'+'data-dev' | |
RetryWait = 0 | |
puts "---> DEBUG mode" | |
puts "---> Log = #{Log}" | |
puts "---> ELog = #{ELog}" | |
puts "---> SleepWait = #{SleepWait}" | |
puts "---> Log_DIR = #{Log_DIR}" | |
puts "---> Data_DIR = #{Data_DIR}" | |
puts "---> RetryWait = #{RetryWait}" | |
puts "" | |
else | |
Log = false | |
ELog = true | |
SleepWait = 5 | |
Log_DIR = CDIR+'/'+'log' | |
Data_DIR = CDIR+'/'+'data' | |
RetryWait = 15 | |
end | |
#YAMLへ保存しやすいように | |
def yaml_dump(contents,path) | |
open(path,'w') { |i| i << YAML.dump(contents) } | |
end | |
#ログ保存しやすいように | |
def log_dump(contents,path) | |
open(path,'a') { |i| i.puts contents } | |
end | |
#処理をまとめたclass | |
class FollowingActivityCheck | |
def initialize(screen_name) | |
#重要っぽい変数など | |
@screen_name = screen_name | |
@user = Hash.new | |
@following = Hash.new | |
@following_yaml = Data_DIR+'/'+@screen_name+'-'+'following_with_info.yaml' | |
@following_b = Hash.new | |
@following_b_yaml = Data_DIR+'/'+@screen_name+'-'+'following_with_info_before.yaml' | |
@following_bb = Hash.new | |
@screen_name_log_txt = Log_DIR+'/'+@screen_name+'-'+'screen_name-log.txt' | |
@other_log_txt = Log_DIR+'/'+@screen_name+'-'+'following_activity.txt' | |
@now = DateTime.now.strftime("%Y-%m-%d %a %H:%M") | |
@changes = false | |
#OAuth周りの認証処理 | |
begin | |
oauth = YAML.load_file(OAuth_YAML) | |
rescue | |
puts "---! Can't open #{OAuth_YAML}" | |
exit | |
end | |
consumer = OAuth::Consumer.new(oauth['consumer_key'], oauth['consumer_secret'], :site => 'https://api.twitter.com') | |
token = OAuth::AccessToken.new(consumer, oauth['oauth_token'], oauth['oauth_token_secret']) | |
@t = OAuthRubytter.new(token) | |
#screen_nameから諸情報を取得 | |
begin | |
puts "---> fetching @#{@screen_name} user info" if Log | |
@user = @t.user(@screen_name) | |
rescue | |
puts "---! Error in @t.user(\"#{@screen_name}\") retry after #{RetryWait} seconds..." if Log | |
sleep RetryWait | |
begin | |
@user = @t.user(@screen_name) | |
rescue | |
puts "---! Error in @t.user(\"#{@screen_name}\")" if ELog | |
exit | |
end | |
end | |
end | |
#followingの取得 | |
def get_following | |
puts "---> fetching @#{@screen_name}'s following" if Log | |
next_cursor = -1 ; friends_raw = Array.new | |
while next_cursor != 0 | |
begin | |
puts "---> fetching @#{@screen_name}'s following cursor #{next_cursor}" if Log | |
tmp = @t.friends(@user[:id],:cursor=>next_cursor) | |
rescue | |
puts "---! Error in @t.friends(#{@user[:id]},:cursor=>#{next_cursor}) ( #{@user[:id]} = #{@screen_name} ) retry after #{RetryWait} seconds..." if Log | |
sleep RetryWait | |
begin | |
tmp = @t.friends(@user[:id],:cursor=>next_cursor) | |
rescue | |
puts "---! Error in @t.friends(#{@user[:id]},:cursor=>#{next_cursor}) ( #{@user[:id]} = #{@screen_name} )" if ELog | |
exit | |
end | |
end | |
friends_raw.concat([tmp]) | |
next_cursor = tmp[:next_cursor] | |
sleep SleepWait | |
end | |
friends_raw.collect{|i| i[:users] }.flatten!.each {|j| @following[j[:id]] = j } | |
#前々回取得分があればロードする | |
if File.exist?(@following_b_yaml) | |
puts "---> load following_b_yaml into following_bb" if Log | |
@following_bb = YAML.load_file(@following_b_yaml) | |
end | |
#前回取得した分があればロードする | |
if File.exist?(@following_yaml) | |
puts "---> load following_yaml into following_b" if Log | |
@following_b = YAML.load_file(@following_yaml) | |
end | |
#Twitterが邪悪な結果を返してないかどうかを見る | |
def for_check(t_user) | |
id = t_user[:id] | |
screen_name = t_user[:screen_name] | |
name = t_user[:name].to_s.gsub(/\n+/,"\n").gsub(/\s+/,' '), | |
description = t_user[:description].to_s.gsub(/\n+/,"\n").gsub(/\s+/,' '), | |
location = t_user[:location].to_s.gsub(/\n+/,"\n").gsub(/\s+/,' '), | |
ary = [id,screen_name,name,description,location] | |
return ary | |
end | |
u = Array.new | |
@following.each do |id,user| | |
if ( @following_b[id] && @following_bb[id] && for_check(user) == for_check(@following_bb[id]) && for_check(user) != for_check(@following_b[id]) ) | |
puts "---> #{user[:screen_name]} の取得結果がおかしい可能性があるんで再取得するよ。" if ELog | |
begin | |
u << @t.user(id) | |
rescue | |
puts "---! Error in @t.user(#{id}) ( #{id} = #{user[:screen_name]} ) retry after #{RetryWait} seconds..." if Log | |
sleep RetryWait | |
begin | |
u << @t.user(id) | |
rescue | |
puts "---! Error in @t.user(#{id}) ( #{id} = #{user[:screen_name]} )" if ELog | |
next | |
end | |
end | |
sleep SleepWait | |
end | |
end | |
u.each {|k| @following[k[:id]] = k } | |
#今回取得した分のdumpと、前回取得分の退避 | |
if File.exist?(@following_yaml) | |
puts "---> cp following_yaml following_b_yaml" if Log | |
FileUtils.cp(@following_yaml,@following_b_yaml) | |
end | |
puts "---> dump following into following_yaml" if Log | |
yaml_dump(@following,@following_yaml) | |
end | |
#アウトプットしやすいように | |
def output(contents_raw="",path=@other_log_txt,cron_mail=false) | |
contents = contents_raw.gsub(/\n+/,' \n ') | |
puts "---> #{contents}" if Log | |
puts contents if cron_mail | |
log_dump(@now+' '+contents,path) | |
@changes = true | |
end | |
#diffを取る | |
def take_diff | |
#前回取得した分が無いなら、とりあえず今回取得した分を代入する | |
if @following_b.empty? | |
puts "---> substitute following for following_b" if Log | |
@following_b = @following | |
end | |
#まず増減の確認 | |
increase = Array.new ; decrease = Array.new | |
@following.each_key {|id| increase << id if !@following_b.has_key?(id) } | |
@following_b.each_key {|id| decrease << id if [email protected]_key?(id) } | |
increase.each do |id| | |
screen_name = @following[id][:screen_name] | |
contents = "< following + > @#{screen_name} http://twitter.com/#{screen_name}" | |
self.output(contents,@other_log_txt,false) | |
end | |
decrease.each do |id| | |
screen_name_before = @following_b[id][:screen_name] | |
begin | |
screen_name = @t.user(id)[:screen_name] | |
rescue | |
puts "---! Error in @t.user(#{id})[:screen_name] ( #{id} = #{screen_name_before} ) retry after #{RetryWait} seconds..." if Log | |
sleep RetryWait | |
begin | |
screen_name = @t.user(id)[:screen_name] | |
rescue | |
contents = "< Account deleted ? > @#{screen_name_before} is gone..." | |
self.output(contents,@screen_name_log_txt,true) | |
next | |
end | |
end | |
contents = "< following - > @#{screen_name} http://twitter.com/#{screen_name}" | |
self.output(contents,@other_log_txt,false) | |
end | |
#各種情報のdiffを取ってoutput | |
@following.each do |id,user| | |
next if !@following_b[id] | |
#screen_name | |
screen_name = user[:screen_name].to_s.gsub(/\n+/,"\n").gsub(/\s+/,' ') | |
screen_name_before = @following_b[id][:screen_name].to_s.gsub(/\n+/,"\n").gsub(/\s+/,' ') | |
if ( screen_name_before && screen_name != screen_name_before ) | |
contents = "< screen_name change > @#{screen_name_before} -> @#{screen_name} http://twitter.com/#{screen_name}" | |
self.output(contents,@screen_name_log_txt,true) | |
end | |
#name | |
name = user[:name].to_s.gsub(/\n+/,"\n").gsub(/\s+/,' ') | |
name_before = @following_b[id][:name].to_s.gsub(/\n+/,"\n").gsub(/\s+/,' ') | |
if ( name_before && name != name_before ) | |
contents = "< @#{screen_name} name > \"#{name_before}\" -> \"#{name}\" http://twitter.com/#{screen_name}" | |
self.output(contents,@other_log_txt,false) | |
end | |
#description | |
description = user[:description].to_s.gsub(/\n+/,"\n").gsub(/\s+/,' ') | |
description_before = @following_b[id][:description].to_s.gsub(/\n+/,"\n").gsub(/\s+/,' ') | |
if ( description_before && description != description_before ) | |
contents = "< @#{screen_name} bio > \"#{description_before}\" -> \"#{description}\" http://twitter.com/#{screen_name}" | |
self.output(contents,@other_log_txt,false) | |
end | |
#location | |
location = user[:location].to_s.gsub(/\n+/,"\n").gsub(/\s+/,' ') | |
location_before = @following_b[id][:location].to_s.gsub(/\n+/,"\n").gsub(/\s+/,' ') | |
if ( location_before && location != location_before ) | |
contents = "< @#{screen_name} location > \"#{location_before}\" -> \"#{location}\" http://twitter.com/#{screen_name}" | |
self.output(contents,@other_log_txt,false) | |
end | |
#url | |
url = user[:url].to_s.gsub(/\n+/,"\n").gsub(/\s+/,' ') | |
url_before = @following_b[id][:url].to_s.gsub(/\n+/,"\n").gsub(/\s+/,' ') | |
if ( url_before && url != url_before ) | |
contents = "< @#{screen_name} url > #{url_before} -> #{url} http://twitter.com/#{screen_name}" | |
self.output(contents,@other_log_txt,false) | |
end | |
#protected | |
protected = user[:protected] | |
protected_before = @following_b[id][:protected] | |
if ( protected_before && protected != protected_before ) | |
contents = "< @#{screen_name} protected > #{protected_before} -> #{protected} http://twitter.com/#{screen_name}" | |
self.output(contents,@other_log_txt,false) | |
end | |
#profile_image_url | |
profile_image_url = user[:profile_image_url] | |
profile_image_url_before = @following_b[id][:profile_image_url] | |
if ( profile_image_url_before && profile_image_url != profile_image_url_before ) | |
contents = "< @#{screen_name} icon > #{profile_image_url_before} -> #{profile_image_url} http://twitter.com/#{screen_name}" | |
self.output(contents,@other_log_txt,false) | |
end | |
#profile_background_image_url | |
# profile_background_image_url = user[:profile_background_image_url] | |
# profile_background_image_url_before = @following_b[id][:profile_background_image_url] | |
# if ( profile_background_image_url_before && profile_background_image_url != profile_background_image_url_before ) | |
# contents = "< @#{screen_name} bgimg > #{profile_background_image_url_before} -> #{profile_background_image_url} http://twitter.com/#{screen_name}" | |
# self.output(contents,@other_log_txt,false) | |
# end | |
end | |
end | |
#処理まとめ | |
def main | |
Dir.mkdir(Log_DIR) if !File.exist?(Log_DIR) | |
Dir.mkdir(Data_DIR) if !File.exist?(Data_DIR) | |
log_dump('',@screen_name_log_txt) if !File.exists?(@screen_name_log_txt) | |
log_dump('',@other_log_txt) if !File.exists?(@other_log_txt) | |
self.get_following | |
self.take_diff | |
puts "---> no changes detect on @#{@screen_name}'s following screen_names" if ( !@changes && Log ) | |
end | |
end | |
#実行 | |
puts "---> --- @#{Target} ---" if Log | |
FollowingActivityCheck.new(Target).main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment