LoginSignup
2
2

More than 5 years have passed since last update.

Microsoft TranslatorをScalaから使ってみた

Last updated at Posted at 2013-05-23

Microsoft TranslatorをScalaから使ってみた」から。
今回はソースそのまま(sbt用の設定は含まず)。

Translator.scala
import dispatch._, Defaults._
import scala.util.parsing.json.JSON
import java.util.Date
import scala.annotation.tailrec


object Translator {
  def main(args: Array[String]) {
    println("input English word")
    println("'!' to quit")

    @tailrec
    def readToTranslate(accessTokenMessage:AccessTokenMessage):Unit = {
      val line = Console.readLine("from: ")
      line match {
        case "!" => ()
        case word if word.trim.length > 0 => {
          val atm = AccessTokenMessage(Option(accessTokenMessage))
          println("to: " + translate(word.trim, atm))
          readToTranslate(atm)
        }
        case _ => {
          println(">> [empty]")
          readToTranslate(accessTokenMessage)
        }
      }
    }

    readToTranslate(AccessTokenMessage.empty)
  }

  def translate(word:String, atm:AccessTokenMessage):String = {
    MicrosoftTranslator.translate(word, atm.accessToken)
  }
}

object MicrosoftTranslator {
  def MsTransLatorPrimaryKey      = "Your Primary Key"
  def MsTransLatorClientId        = "Your Client Id"
  def MsTransLatorClientSecret    = "Your Client Secret"
  def MsTransLatorUrl             = "http://api.microsofttranslator.com/V2/Http.svc/Translate"
  def MsTransLatorScope           = "http://api.microsofttranslator.com"
  def MsTransLatorAccessTokenUrl  = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13"
  def MsTransLatorGrantType       = "client_credentials"

  // Dispatch http://dispatch.databinder.net/Dispatch.html
  // url(MsTransLatorAccessTokenUrl)は以下のようにも書ける。
  def authSecureHost = host("datamarket.accesscontrol.windows.net").secure
  def authSecureRequest = authSecureHost / "v2" / "OAuth2-13"

  // 新しいアクセストークンを取得する
  def newAccessTokenMessage: Map[String, String] = {
    val params = Map(
      "client_id"     -> MsTransLatorClientId,
      "client_secret" -> MsTransLatorClientSecret,
      "scope"         -> MsTransLatorScope,
      "grant_type"    -> MsTransLatorGrantType
      )
    val req = url(MsTransLatorAccessTokenUrl) << params
    val contents = Http(req OK as.String)
    val jsonResult = JSON.parseFull(contents())
    jsonResult.get.asInstanceOf [Map[String, String]]
  }

  def translate(word:String, accessToken:String):String = {
    val headerValue = "Bearer " + accessToken
    val headerParams = Map("Authorization" -> headerValue)
    val params = Map("text" -> word, "from" -> "en", "to" -> "ja")
    val req = url(MsTransLatorUrl) <<? params <:< headerParams
    val contents = Http(req OK as.xml.Elem)
    contents().text
  }
}

object AccessTokenMessage {
  def apply(message: Option[AccessTokenMessage]):AccessTokenMessage = message match {
    case Some(m) if !m.timeout => m
    case _ => new AccessTokenMessage(MicrosoftTranslator.newAccessTokenMessage)
  }

  def empty = null
}

class AccessTokenMessage(message:Map[String, String]) {
  val createTime = System.currentTimeMillis

  def accessToken = message("access_token").toString
  def expiresIn = message("expires_in").toLong

  def timeout =
    if (createTime + expiresIn * 1000 <= System.currentTimeMillis) true
    else false
}
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2