Skip to content

Instantly share code, notes, and snippets.

@yuroyoro
Created October 30, 2009 08:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yuroyoro/222221 to your computer and use it in GitHub Desktop.
Save yuroyoro/222221 to your computer and use it in GitHub Desktop.
import java.net.{Authenticator, PasswordAuthentication}
import scala.Math._
import scala.xml._
import scala.io.Source
object TwitterListRecommender{
val url ="http://twitter.com/%s/lists/memberships.xml"
// Usage : scala TwitterListRecommender <your_id> <your_password>
def main(args:Array[String]) = {
val Array( userid, passwd ) = args
// Basic認証
Authenticator.setDefault(
new Authenticator {
override def getPasswordAuthentication =
new PasswordAuthentication( userid, passwd.toCharArray)
}
)
// 登録されているListを取得する
val source = Source.fromURL( url.format( userid) )
val xml = XML.loadString( source.getLines.mkString )
val lists = xml \\ "list"
// Listの購読者数から標準偏差を算出
val sd = {
val cnts = lists.map{ l => (l \ "subscriber_count" text ).toDouble + 1}
val total = (0.0 /: cnts ){ _ + _}
val ave = total / lists.size
cnts.map{ i => pow( i - ave , 2) }.foldLeft( 0.0 ){ _ + _ } / cnts.size
}
// followしているidを取得
val ids = {
val src = Source.fromURL( "http://twitter.com/friends/ids/%s.xml".format( userid ))
val idxml = XML.loadString( src.getLines.mkString )
(idxml \\ "id").map( _ text )
}
// Listから集計
( Map.empty[String, Double] /: lists ){ (m,l) =>
// (購読者数 + 1)/標準偏差 * 100 がweight
val weight = (( l \ "subscriber_count" text ).toDouble + 1) / sd * 100
// Listのmemberを取得する
val src = Source.fromURL( "http://twitter.com%s/members.xml".format( l \ "uri" text ))
val lxml = XML.loadString( src.getLines.mkString )
// すでにfollowしているIDはのぞく
( lxml \\ "user").filter{
user => ids.exists( _ == (user \ "id" text) ) == false
}.foldLeft( m ){
(mm , user) => {
val name = user \ "screen_name" text ;
mm + ( name -> ( mm.getOrElse( name ,0.0 ) + weight ))
}
}
}.toList.sort{ case( (_, v1), (_, v2) )=> v1 > v2 }.foreach{
case ( name, v ) => println( "%-30s : %.4f ".format( name, v))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment