Created
February 10, 2011 19:45
-
-
Save dnpp73/821189 to your computer and use it in GitHub Desktop.
followingとかfollowersとかlistedの上下を監視する感じ。
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 | |
=begin | |
必要なもの | |
$ gem install rubytter | |
./target.yaml ( screen_nameの配列の形になってるもの ) | |
../oauth_yaml/#{Client}-#{App}.yaml ( TwitterOAuthの情報を格納したもの ) | |
これはなに | |
指定したscreen_nameの人の、following・followers・listedの上下をチェックする感じ。 | |
りむったー的に使えるかなと思って書いてたんだけど、どうせならfollowingとlistedも付けて、自分以外の人のも見られるようにしようとしたら、こんなんが出来ました。 | |
listの削除とかにも対応してるのでちゃんと見られると思います。 | |
垢削除されるとどうしようもないけど、とりあえずidだけ表示出来ると思います。 | |
つかいかた | |
$ crontab -e | |
で、こんな感じの追記をして | |
0 * * * * /path/to/ruby /path/to/activity-check.rb | |
後は適当な画面で | |
$ tail -f /path/to/log/*-log.txt | |
=end | |
require 'rubygems' | |
require 'rubytter' | |
require 'yaml' | |
require 'date' | |
require 'fileutils' | |
#設定用の定数など | |
DEBUG = false | |
Client = 'hoge' | |
App = 'fuga' | |
CDIR = File.dirname(File.expand_path(__FILE__)) | |
OAuth_YAML = CDIR+'/../oauth_yaml/'+Client+'-'+App+'.yaml' | |
if DEBUG | |
Log = true | |
ELog = true | |
Sleep = false | |
SleepWait = 3 | |
Log_DIR = CDIR+'/'+'log-dev' | |
Data_DIR = CDIR+'/'+'data-dev' | |
Target_YAML = CDIR+'/'+'target-dev.yaml' | |
RetryWait = 5 | |
ListedWait = 5 | |
UserWait = 5 | |
puts "---> DEBUG mode" | |
puts "---> Log = #{Log}" | |
puts "---> ELog = #{ELog}" | |
puts "---> Sleep = #{Sleep}" | |
puts "---> SleepWait = #{SleepWait}" | |
puts "---> Log_DIR = #{Log_DIR}" | |
puts "---> Data_DIR = #{Data_DIR}" | |
puts "---> Target_YAML = #{Target_YAML}" | |
puts "---> RetryWait = #{RetryWait}" | |
puts "---> ListedWait = #{ListedWait}" | |
else | |
Log = false | |
ELog = false | |
Sleep = true | |
SleepWait = 50 | |
Log_DIR = CDIR+'/'+'log' | |
Data_DIR = CDIR+'/'+'data' | |
Target_YAML = CDIR+'/'+'target.yaml' | |
RetryWait = 20 | |
ListedWait = 10 | |
UserWait = 10 | |
end | |
#YAMLへ保存しやすいように | |
def yaml_dump(contents,path) | |
open(path,'w') { |i| i << YAML.dump(contents) } | |
#open(path[0,path.length-5]+'-'+DateTime.now.strftime("%Y%m%d%H%M")+'.yaml','w') { |i| i << YAML.dump(contents) } | |
end | |
#ログ保存しやすいように | |
def log_dump(contents,path) | |
open(path,'a') { |i| i.puts contents } | |
end | |
#Twitterからのレスポンスの差の回収のため… | |
def isids(t) | |
begin | |
t = t[:ids] if t.has_key?(:ids) | |
rescue | |
t | |
end | |
return t | |
end | |
#処理をまとめたclass | |
class ActivityCheck | |
def initialize(screen_name) | |
#重要っぽい変数など | |
@screen_name = screen_name.to_s | |
@user = Hash.new | |
@following = Array.new | |
@followers = Array.new | |
@listed = Array.new | |
@user_yaml = Data_DIR+'/'+@screen_name+'-'+'user.yaml' | |
@following_yaml = Data_DIR+'/'+@screen_name+'-'+'following.yaml' | |
@followers_yaml = Data_DIR+'/'+@screen_name+'-'+'followers.yaml' | |
@listed_yaml = Data_DIR+'/'+@screen_name+'-'+'listed.yaml' | |
@user_before = Hash.new | |
@following_before = Array.new | |
@followers_before = Array.new | |
@listed_before = Array.new | |
@cancel = false | |
@following_cancel = false | |
@followers_cancel = false | |
@listed_cancel = false | |
@log_txt = Log_DIR+'/'+@screen_name+'-'+'log.txt' | |
@now = DateTime.now.strftime("%Y-%m-%d %a %H:%M") | |
@suffixTime = DateTime.now.strftime("%Y-%m%d-%H%M") | |
@user_yaml_bak = Data_DIR+'/'+@screen_name+'-'+'user'+'-'+@suffixTime+'.yaml' | |
@following_yaml_bak = Data_DIR+'/'+@screen_name+'-'+'following'+'-'+@suffixTime+'.yaml' | |
@followers_yaml_bak = Data_DIR+'/'+@screen_name+'-'+'followers'+'-'+@suffixTime+'.yaml' | |
@listed_yaml_bak = Data_DIR+'/'+@screen_name+'-'+'listed'+'-'+@suffixTime+'.yaml' | |
@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 | |
@cancel = true | |
puts "---! @cancel = true (\"#{@screen_name}\")" | |
end | |
puts "---> Successfully in retry @t.user(\"#{@screen_name}\")" if (!@cancel && Log) | |
end | |
if !@cancel && File.exist?(@user_yaml) | |
puts "---> backing up user yaml" if Log | |
FileUtils.cp(@user_yaml,@user_yaml_bak) | |
puts "---> load user_yaml into user_before" if Log | |
@user_before = YAML.load_file(@user_yaml) | |
puts "---> dump user in yaml" if Log | |
yaml_dump(@user,@user_yaml) | |
elsif !@cancel && !File.exist?(@user_yaml) | |
puts "---> substitute user for user_before" if Log | |
@user_before = @user | |
puts "---> dump user in yaml" if Log | |
yaml_dump(@user,@user_yaml) | |
end | |
end | |
#followingの取得と格納と、失敗した場合のフラグ | |
def get_following | |
begin | |
puts "---> fetching @#{@screen_name}'s following" if Log | |
@following = @t.friends_ids(@user[:id]) | |
rescue | |
puts "---! Error in @t.friends_ids(#{@user[:id]}) ( #{@user[:id]} = #{@screen_name} ) retry after #{RetryWait} seconds..." if Log | |
sleep RetryWait | |
begin | |
@following = @t.friends_ids(@user[:id]) | |
rescue | |
puts "---! Error in @t.friends_ids(#{@user[:id]}) ( #{@user[:id]} = #{@screen_name} )" if ELog | |
@following_cancel = true | |
end | |
puts "---> Successfully in retry @t.friends_ids(#{@user[:id]}) ( #{@user[:id]} = #{@screen_name} )" if (!@following_cancel && Log) | |
end | |
if !@following_cancel && File.exist?(@following_yaml) | |
puts "---> backing up following yaml" if Log | |
FileUtils.cp(@following_yaml,@following_yaml_bak) | |
puts "---> load following_yaml into following_before" if Log | |
@following = isids(@following) | |
@following_before = isids(YAML.load_file(@following_yaml)) | |
puts "---> dump following in yaml" if Log | |
yaml_dump(@following,@following_yaml) | |
elsif !@following_cancel && !File.exist?(@following_yaml) | |
puts "---> substitute following for following_before" if Log | |
@following = isids(@following) | |
@following_before = @following | |
puts "---> dump following in yaml" if Log | |
yaml_dump(@following,@following_yaml) | |
end | |
end | |
#followersの取得と格納と、失敗した場合のフラグ | |
def get_followers | |
begin | |
puts "---> fetching @#{@screen_name}'s followers" if Log | |
@followers = @t.followers_ids(@user[:id]) | |
rescue | |
puts "---! Error in @t.followers_ids(#{@user[:id]}) ( #{@user[:id]} = #{@screen_name} ) retry after #{RetryWait} seconds..." if Log | |
sleep RetryWait | |
begin | |
@followers = @t.followers_ids(@user[:id]) | |
rescue | |
puts "---! Error in @t.followers_ids(#{@user[:id]}) ( #{@user[:id]} = #{@screen_name} )" if ELog | |
@followers_cancel = true | |
end | |
puts "---> Successfully in retry @t.followers_ids(#{@user[:id]}) ( #{@user[:id]} = #{@screen_name} )" if (!@followers_cancel && Log) | |
end | |
if !@followers_cancel && File.exist?(@followers_yaml) | |
puts "---> backing up followers yaml" if Log | |
FileUtils.cp(@followers_yaml,@followers_yaml_bak) | |
puts "---> load followers_yaml into followers_before" if Log | |
@followers = isids(@followers) | |
@followers_before = isids(YAML.load_file(@followers_yaml)) | |
puts "---> dump followers in yaml" if Log | |
yaml_dump(@followers,@followers_yaml) | |
elsif !@followers_cancel && !File.exist?(@followers_yaml) | |
puts "---> substitute followers for followers_before" if Log | |
@followers = isids(@followers) | |
@followers_before = @followers | |
puts "---> dump followers in yaml" if Log | |
yaml_dump(@followers,@followers_yaml) | |
end | |
end | |
# listedの取得と格納と、失敗した場合のフラグ | |
def get_listed | |
ary = [];next_cursor = -1 | |
begin | |
while next_cursor != 0 | |
puts "---> fetching @#{@screen_name}'s listed cursor #{next_cursor}" if Log | |
r = @t.lists_followers(@user[:id],:cursor=>next_cursor) | |
ary.concat r[:lists] | |
next_cursor = r[:next_cursor] | |
sleep ListedWait | |
end | |
rescue | |
puts "---! Error in @t.lists_followers(#{@user[:id]},:cursor=>#{next_cursor}) ( #{@user[:id]} = #{@screen_name} )" if ELog | |
@listed_cancel = true | |
end | |
ary.each { |i| @listed << [ i[:user][:id], i[:id], i[:full_name] ] } if !@listed_cancel | |
if !@listed_cancel && File.exist?(@listed_yaml) | |
puts "---> backing up listed yaml" if Log | |
FileUtils.cp(@listed_yaml,@listed_yaml_bak) | |
puts "---> load listed_yaml into listed_before" if Log | |
@listed_before = YAML.load_file(@listed_yaml) | |
puts "---> dump listed in yaml" if Log | |
yaml_dump(@listed,@listed_yaml) | |
elsif !@listed_cancel && !File.exist?(@listed_yaml) | |
puts "---> substitute listed for listed_before" if Log | |
@listed_before = @listed | |
puts "---> dump listed in yaml" if Log | |
yaml_dump(@listed,@listed_yaml) | |
end | |
end | |
#アウトプットしやすいように | |
def output(contents,path) | |
puts "---> #{contents}" if Log | |
log_dump(@now+' '+contents,path) | |
@changes = true | |
end | |
#follow関係のdiffを取る | |
def diff_follow(b,n,c) | |
def ch_screen_name(t,v,c) | |
t.each do |m| | |
begin | |
screen_name = @t.user(m)[:screen_name] | |
sleep UserWait | |
rescue | |
begin | |
puts "---! Error in @t.user(#{m}) ( @#{@screen_name}/#{c} ) retry after #{RetryWait} seconds..." if Log | |
sleep RetryWait | |
screen_name = @t.user(m)[:screen_name] | |
rescue | |
puts "---! Error in @t.user(#{m}) ( @#{@screen_name}/#{c} )" if ELog | |
screen_name = '_(id: '+m.to_s+' )_' | |
end | |
end | |
contents = "< #{c} #{v} > @#{screen_name} http://twitter.com/#{screen_name}" | |
self.output(contents,@log_txt) | |
end | |
end | |
begin | |
mns = b - n | |
rescue | |
puts "---! Error in diff_follow line:294" if Log | |
begin | |
mns = b[:ids] - n[:ids] | |
rescue | |
puts "---! Error in diff_follow line:298" if Log | |
begin | |
mns = b - n[:ids] | |
rescue | |
puts "---! Error in diff_follow line:302" if Log | |
mns = b[:ids] -n | |
end | |
end | |
end | |
ch_screen_name(mns,'-',c) if mns | |
begin | |
pls = n - b | |
rescue | |
puts "---! Error in diff_follow line:312" if Log | |
begin | |
pls = n[:ids] - b[:ids] | |
rescue | |
puts "---! Error in diff_follow line:316" if Log | |
begin | |
pls = n - b[:ids] | |
rescue | |
puts "---! Error in diff_follow line:320" if Log | |
pls = n[:ids] -b | |
end | |
end | |
end | |
ch_screen_name(pls,'+',c) if pls | |
end | |
#listed関係のdiffを取る | |
def diff_listed | |
def ch_listed(t,v) | |
t.each do |m| | |
begin | |
list_full_name = @t.list(m[0],m[1])[:full_name] | |
rescue | |
begin | |
puts "---! Error in @t.list(#{m[0]},#{m[1]})[:full_name] ( @#{@screen_name}/lists/memberships ) retry after #{RetryWait} seconds..." if Log | |
sleep RetryWait | |
list_full_name = @t.list(m[0],m[1])[:full_name] | |
rescue | |
puts "---! Error in @t.list(#{m[0]},#{m[1]})[:full_name] ( @#{@screen_name}/lists/memberships )" if ELog | |
list_full_name = m[2] | |
end | |
end | |
contents = "< listed #{v} > #{list_full_name} http://twitter.com/#{list_full_name[1,list_full_name.length]}" | |
self.output(contents,@log_txt) | |
end | |
end | |
mns = @listed_before - @listed | |
ch_listed(mns,'-') if mns | |
pls = @listed - @listed_before | |
ch_listed(pls,'+') if pls | |
end | |
#処理まとめ。デバッグの時は先頭に#とか付けてコメントアウト出来て便利 | |
def run | |
log_dump('',@log_txt) if !File.exists?(@log_txt) | |
self.get_following | |
self.get_followers | |
self.get_listed | |
self.diff_follow(@following_before,@following,'following') if !@following_cancel | |
self.diff_follow(@followers_before,@followers,'followers') if !@followers_cancel | |
self.diff_listed if !@listed_cancel | |
puts "---> no changes detect on @#{@screen_name}" if ( !@changes && Log ) | |
end | |
#initializeで調べた感じ、無効なscreen_nameでないっぽいなら run | |
def main | |
self.run if !@cancel | |
end | |
end | |
#ターゲット情報の格納と、出力先ディレクトリの確認して無いなら作成 | |
begin | |
target = YAML.load_file(Target_YAML) | |
rescue | |
puts "---! Can't open #{Target_YAML}" | |
exit | |
end | |
Dir.mkdir(Log_DIR) if !File.exist?(Log_DIR) | |
Dir.mkdir(Data_DIR) if !File.exist?(Data_DIR) | |
#実行 | |
target.each do |t| | |
puts "\n---> --- @#{t} ---" if Log | |
ActivityCheck.new(t).main | |
puts "---> sleep #{SleepWait} secsonds..." if ( Log && Sleep ) | |
sleep SleepWait if Sleep | |
end |
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
consumer_key: hoge | |
consumer_secret: fuga | |
oauth_token: nyaa | |
oauth_token_secret: uguu |
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
--- | |
- DNPP | |
- target_screen_name_1 | |
- target_screen_name_2 | |
- target_screen_name_3 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment