読者です 読者をやめる 読者になる 読者になる

日々常々

ふつうのプログラマがあたりまえにしたいこと。

フォロー出来てないフォロワーのリストを作ってみる

欲しくなったんです。でもTwitterのリスト編集はお世辞にも使いやすいとは言えない。すみません、言い直します。Twitterのリスト編集は使い難い。
で、リスト管理するサービスってやっぱりあって、いくつか見てみたんですけど、なんか使うのめんどくさい。すみません、説明書読まずに使えるものでないとめんどくさいんです。後何してるかわかり辛いのも困ります。

めんどくさいなら書けば良いんですよね。

かいてみた

@Grab('org.twitter4j:twitter4j-core:2.2.3')
import twitter4j.*
import twitter4j.conf.*

def conf = new ConfigurationBuilder()
  .setOAuthConsumerKey('consumer key')
  .setOAuthConsumerSecret('consumer secret')
  .setOAuthAccessToken('access token')
  .setOAuthAccessTokenSecret('access token secret')

new TwitterFactory(conf.build()).instance.with{
    def listId = it.createUserList('test', true, 'byGroovy').id
    (it.getFollowersIDs(it.id, -1).IDs.toList() - it.getFriendsIDs(it.id, -1).IDs.toList()).each { id ->
        it.addUserListMember(listId, id)
    }
}

困ったのは IDs#getIDs() が long[] を返してくるところ*1。Groovyでリスト同士は引き算できるんですが、配列は引けないっぽくてちょっと悩みました。リストにして引き算してますけど、多分別のもっと良いスマートな方法がありますよね。

引き算せずにやってみる

new TwitterFactory(conf.build()).instance.with{
    def listId = it.createUserList('test', true, 'byGroovy').id
    def friends = it.getFriendsIDs(it.id, -1).IDs.toSet()
    it.getFollowersIDs(it.id, -1).IDs.findAll{
        !friends.contains(it)
    }.each{id ->
        it.addUserListMember(listId, id)
    }
}

……うーん。なんかわかり辛い気も?なんか回りくどいし。多分私のGroovy力が足りない。


gistに上げてるんで、誰か何とかしてくれると嬉しいかも。 https://gist.github.com/1046394

あ、リスト登録数(500人)超えたり、Twitterがエラー吐いたりすると例外なってアレです。例外処理とか考えてません。最初は入れてたんですけど面倒になって……やるにしても例外でたらdestroyListするくらいですかねー。

ちなみに同じ名前でもリスト作れます。作るとなんか枝番が付きます。test-10とかそんな感じで。

Collection#removeAll

Groovy1.7.2から導入されたらしい removeAll を使ってみた。なんかマイナスに戻った…というかマイナスより劣化したような。
あ、twitter4j.properties使ってるのでConfigurationBuilderは無しです。

@Grab('org.twitter4j:twitter4j-core:2.2.3')
import twitter4j.*

new TwitterFactory().instance.with{
    def listId = it.createUserList('test', true, 'byGroovy').id
    def IDs = (it.getFollowersIDs(it.id, -1).IDs as Collection)
    IDs.removeAll(it.getFriendsIDs(it.id, -1).IDs)
    IDs.each{id ->
        it.addUserListMember(listId, id)
    }
}