#!/usr/bin/env ruby require "pathname" require "yaml" require "rubygems" require "oauth" require "json" # -> [access_token, access_secret] def authorize(consumer) request_token = consumer.get_request_token puts "Access following URL: %s" % request_token.authorize_url print 'and input OAuth verifier: ' oauth_verifier = STDIN.gets.chomp.strip access_token = request_token.get_access_token(:oauth_verifier => oauth_verifier) [access_token.token, access_token.secret] end def save_access_token!(token, secret) atoken = Pathname.new('~/.friendship_cleaner/atoken').expand_path atoken.parent.mkdir(0700) unless atoken.parent.exist? YAML.dump({ :token => token, :secret => secret }, atoken.open('w+', 0600)) end # -> [access_token, access_secret] def get_access_token atoken_file = Pathname.new('~/.friendship_cleaner/atoken').expand_path access_token = YAML.load(atoken_file.open) [access_token[:token], access_token[:secret]] end def main(args) abort "Usage: #{$0} [user_id]" unless args.size > 0 config = YAML.load(DATA) consumer = OAuth::Consumer.new( config[:ckey], config[:csecret], :site => 'https://api.twitter.com' ) token, secret = *get_access_token access_token = OAuth::AccessToken.new(consumer, token, secret) ers = followers(access_token, :self => self_id) ing = following(access_token, :self => self_id) ers.reject {|i| !i.has_key?('users') || i['next_cursor'].zero? }.map {|i| i['users']['screen_name'] } ing.reject {|i| !i.has_key?('users') || i['next_cursor'].zero? }.map {|i| i['users']['screen_name'] } ers.each do |user| block(access_token, user) unblock(access_token, user) end (ing - ers).each do |user| remove(access_token, user) end rescue Errno::ENOENT _atoken = authorize(consumer) save_access_token!(*_atoken) retry end def block(access_token, user) access_token.post("/blocks/create.json", :screen_name => user) end def unblock(access_token, user) access_token.post("/blocks/destroy.json", :screen_name => user) end def remove(access_token, user) access_token.post("/friendships/destroy.json", :screen_name => user) end def following(access_token, opts={}) cursor = opts.fetch(:cursor, -1) response = access_token.get("/statuses/friends/#{opts[:self]}.json?lite=true&cursor=#{cursor}") body = JSON.parse(response.body) ret = [body] ret << following(access_token, :cursor => body['next_cursor']) if body.has_key?('next_cursor') ret.flatten end def followers(access_token, opts={}) cursor = opts.fetch(:cursor, -1) response = access_token.get("/statuses/followers/#{opts[:self]}.json?lite=true&cursor=#{cursor}") body = JSON.parse(response.body) ret = [body] ret << followers(access_token, :cursor => body['next_cursor']) if body.has_key?('next_cursor') ret.flatten end main(ARGV.dup) if $0 == __FILE__ __END__ --- :ckey: hoge :csecret: fuga
定期的にやってくる人間関係を精算したくなる病気が発症したので対処療法としてfollowingとfollowersを0にする。そのためのスクリプトを書いた。
consumer keyとconsumer secretは各々で取得しましょう。
OAuthの実装をほとんど oauth に任せてしまっているので、実際に OAuth 認証でなにをすればいいのかよくわかっていない。その内、しらべてみる。かもしれない。
あと、あまり深く考えずに書いたので、膨大な数のfollowingやfollowersだとメモリをばくばく食うとおもいます。ご利用は計画的に。