Skip to content

Instantly share code, notes, and snippets.

@daiksy
Created May 3, 2012 08:13
Show Gist options
  • Save daiksy/2584254 to your computer and use it in GitHub Desktop.
Save daiksy/2584254 to your computer and use it in GitHub Desktop.
Play2.0でATNDのイベントサーチAPIを使うクラス
package com.github.daiksy.play2.ATND
import play.api.libs.ws.WS
import collection.mutable.ListBuffer
import play.api.libs.json.JsValue
/**
* ATNDのイベントを検索し、取得する。
*
* ・使い方
* メソッドチェーンで検索条件を指定し、executeを実行する。
*
* ex) TwitterIDに"daiksy"を指定して結果を15件取得する場合
* val atnd = new com.github.daiksy.play2.ATND.EventSearch
* val ret = atnd.twitterId("daiksy").count(15).execute
*
* 取得結果は、取得件数、対象イベントの総件数、イベント詳細[List]で取得されます。
*
* ret.resultReturned //イベント件数
* ret.resultAvailable // 対象の総イベント件数
* ret.events //イベントの詳細
*
* ex) 取得してきたイベントのタイトルを抽出する場合。
* ret.events.map(_.title)
*
* 取得されるイベントデータの項目はATND APIのリファレンスに準じています。
* http://api.atnd.org/#events-response
*
*/
class EventSearch {
private var _eventId: Option[String] = None
private var _keywordAnd: Option[String] = None
private var _keywordOr: Option[String] = None
private var _ym: Option[String] = None
private var _ymd: Option[String] = None
private var _userId: Option[String] = None
private var _nickname: Option[String] = None
private var _twitterId: Option[String] = None
private var _ownerId: Option[String] = None
private var _ownerNickname: Option[String] = None
private var _ownerTwitterId: Option[String] = None
private var _start: Option[Int] = None
private var _count: Option[Int] = None
/** 検索結果を返却するためのcase class */
case class EventSearchResult(
/** 実際に取得したイベントデータの件数 */
resultReturned: Int,
/** 指定した条件で存在するイベントデータの総件数 */
resultAvailable: Int,
/** 取得したイベントデータ */
events: List[Events]
)
/** イベントの詳細データ */
case class Events(
/** イベントID */
eventId: Int,
/** タイトル */
title: String,
/** キャッチ */
catchCopy: Option[String],
/** 概要 */
description: Option[String],
/** ATNDのURL */
eventUrl: Option[String],
/** イベント開始日時 */
startedAt: Option[String],
/** イベント終了日時 */
endedAt: Option[String],
/** 参考URL */
url: Option[String],
/** 定員 */
limit: Option[Int],
/** 開催場所 */
address: Option[String],
/** 開催会場 */
place: Option[String],
/** 開催会場の緯度 */
lat: Option[String],
/** 開催会場の軽度 */
lon: Option[String],
/** 主催者のID */
ownerId: Option[Int],
/** 主催者のニックネーム */
ownerNickname: Option[String],
/** 主催者のTwitterId */
ownerTwitterId: Option[String],
/** 参加者 */
accepted: Option[Int],
/** 補欠者 */
waiting: Option[Int],
/** 更新日時 */
updatedAt: Option[String]
)
/**
* イベント毎に割り当てられた番号で検索します。複数指定可能です(カンマ区切り)
*/
def eventId(value: String) = {
_eventId = Some(value)
this
}
/**
* イベントのタイトル、キャッチ、概要、住所をAND条件部分一致で検索します。複数指定可能です(カンマ区切り)
*/
def keywordAnd(value: String) = {
_keywordAnd = Some(value)
this
}
/**
* イベントのタイトル、キャッチ、概要、住所をOR条件部分一致で検索します。複数指定可能です(カンマ区切り)
*/
def keywordOr(value: String) = {
_keywordOr = Some(value)
this
}
/**
* 指定した年月に開催されているイベントを検索します。複数指定可能です(カンマ区切り)
* ex) 201204
*/
def ym(value: String) = {
_ym = Some(value)
this
}
/**
* 指定した年月日に開催されているイベントを検索します。複数指定可能です(カンマ区切り)
* ex) 20120501
*/
def ymd(value: String) = {
_ymd = Some(value)
this
}
/**
* 指定したユーザIDのユーザが参加しているイベントを検索します。複数指定可能です(カンマ区切り)
*/
def userId(value: String) = {
_userId = Some(value)
this
}
/**
* 指定したニックネームのユーザが参加しているイベントを検索します。複数指定可能です(カンマ区切り)
*/
def nickname(value: String) = {
_nickname = Some(value)
this
}
/**
* 指定したTwitter IDのユーザが参加しているイベントを検索します。複数指定可能です(カンマ区切り)
*/
def twitterId(value: String) = {
_twitterId = Some(value)
this
}
/**
* 指定したユーザIDのユーザが主催しているイベントを検索します。複数指定可能です(カンマ区切り)
*/
def ownerId(value: String) = {
_ownerId = Some(value)
this
}
/**
* 指定したニックネームのユーザが主催しているイベントを検索します。複数指定可能です(カンマ区切り)
*/
def ownerNickname(value: String) = {
_ownerNickname = Some(value)
this
}
/**
* 指定したtwitter IDのユーザが主催しているイベントを検索します。複数指定可能です(カンマ区切り)
*/
def ownerTwitterId(value: String) = {
_ownerTwitterId = Some(value)
this
}
/**
* 検索結果の何件目から出力するかを指定します
* ※初期値:1
*/
def start(value: Int) = {
_start = Some(value)
this
}
/**
* 検索結果の最大出力データ数を指定します
* ※初期値:10, 最小値:1, 最大値:100
*/
def count(value: Int) = {
_count = Some(value)
this
}
/** 検索実行 */
def execute = {
requestEventSearchApi
}
/** URLパラメータを組み立てて検索APIをコールし、結果をcase classにセットして返却するよ。 */
private def requestEventSearchApi = {
val apiUrl = "http://api.atnd.org/events/"
val paramBuilder = new ListBuffer[String]
_eventId.foreach(_.split(",").foreach(paramBuilder += "event_id=" + _))
_keywordAnd.foreach(_.split(",").foreach(paramBuilder += "keyword=" + _))
_keywordOr.foreach(_.split(",").foreach(paramBuilder += "keyword_or=" + _))
_ym.foreach(_.split(",").foreach(paramBuilder += "ym=" + _))
_ymd.foreach(_.split(",").foreach(paramBuilder += "ymd=" + _))
_userId.foreach(_.split(",").foreach(paramBuilder += "user_id=" + _))
_nickname.foreach(_.split(",").foreach(paramBuilder += "nickname=" + _))
_twitterId.foreach(_.split(",").foreach(paramBuilder += "twitter_id=" + _))
_ownerId.foreach(_.split(",").foreach(paramBuilder += "owner_id=" + _))
_ownerNickname.foreach(_.split(",").foreach(paramBuilder += "owner_nickname=" + _))
_ownerTwitterId.foreach(_.split(",").foreach(paramBuilder += "owner_twitter_id=" + _))
_start.foreach(paramBuilder += "start=" + _.toString)
_count.foreach(paramBuilder += "count=" + _.toString)
paramBuilder += "format=json"
val urlParam = paramBuilder.result.mkString("&")
val url = if (urlParam != "") {
apiUrl + "?" + urlParam
} else {
apiUrl
}
val ret = WS.url(url).get().value.get.json
EventSearchResult(
(ret \ "results_returned").as[Int],
(ret \ "results_available").as[Int],
(ret \ "events").asOpt[List[JsValue]].getOrElse(Nil).map { e =>
Events(
(e \ "event_id").as[Int],
(e \ "title").as[String],
(e \ "catch").asOpt[String],
(e \ "description").asOpt[String],
(e \ "event_url").asOpt[String],
(e \ "started_at").asOpt[String],
(e \ "ended_at").asOpt[String],
(e \ "url").asOpt[String],
(e \ "limit").asOpt[Int],
(e \ "address").asOpt[String],
(e \ "place").asOpt[String],
(e \ "lat").asOpt[String],
(e \ "lon").asOpt[String],
(e \ "owner_id").asOpt[Int],
(e \ "owner_nickname").asOpt[String],
(e \ "owner_twitter_id").asOpt[String],
(e \ "accepted").asOpt[Int],
(e \ "waiting").asOpt[Int],
(e \ "updated_at").asOpt[String]
)
}
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment