Created
May 3, 2012 14:51
-
-
Save daiksy/2586213 to your computer and use it in GitHub Desktop.
Play2.0でATNDのイベントサーチAPIを使うクラス (mutableな変数を極力使わないver. case classのcopyを使ってちょっとスッキリ)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.github.daiksy.play2.ATND | |
import play.api.libs.ws.WS | |
import collection.mutable.ListBuffer | |
import play.api.libs.json.JsValue | |
/** | |
* ATNDのイベントを検索し、取得する。 | |
* | |
* https://gist.github.com/2585850 を | |
* case classのcopyメソッドを使ってちょびっとスッキリ. | |
* | |
* ・使い方 | |
* メソッドチェーンで検索条件を指定し、executeを実行する。 | |
* | |
* ex) TwitterIDに"daiksy"を指定して結果を15件取得する場合 | |
* import com.github.daiksy.play2.ATND.EventSearch.searcher | |
* val ret = searcher.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 | |
* | |
*/ | |
object EventSearch { | |
private case class Searcher( | |
_eventId: Option[String], | |
_keywordAnd: Option[String], | |
_keywordOr: Option[String], | |
_ym: Option[String], | |
_ymd: Option[String], | |
_userId: Option[String], | |
_nickname: Option[String], | |
_twitterId: Option[String], | |
_ownerId: Option[String], | |
_ownerNickname: Option[String], | |
_ownerTwitterId: Option[String], | |
_start: Option[Int], | |
_count: Option[Int] | |
) { | |
/** 検索結果を返却するための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) = this.copy(_eventId = Some(value)) | |
/** | |
* イベントのタイトル、キャッチ、概要、住所をAND条件部分一致で検索します。複数指定可能です(カンマ区切り) | |
*/ | |
def keywordAnd(value: String) = this.copy(_keywordAnd = Some(value)) | |
/** | |
* イベントのタイトル、キャッチ、概要、住所をOR条件部分一致で検索します。複数指定可能です(カンマ区切り) | |
*/ | |
def keywordOr(value: String) = this.copy(_keywordOr = Some(value)) | |
/** | |
* 指定した年月に開催されているイベントを検索します。複数指定可能です(カンマ区切り) | |
* ex) 201204 | |
*/ | |
def ym(value: String) = this.copy(_ym = Some(value)) | |
/** | |
* 指定した年月日に開催されているイベントを検索します。複数指定可能です(カンマ区切り) | |
* ex) 20120501 | |
*/ | |
def ymd(value: String) = this.copy(_ymd = Some(value)) | |
/** | |
* 指定したユーザIDのユーザが参加しているイベントを検索します。複数指定可能です(カンマ区切り) | |
*/ | |
def userId(value: String) = this.copy(_userId = Some(value)) | |
/** | |
* 指定したニックネームのユーザが参加しているイベントを検索します。複数指定可能です(カンマ区切り) | |
*/ | |
def nickname(value: String) = this.copy(_nickname = Some(value)) | |
/** | |
* 指定したTwitter IDのユーザが参加しているイベントを検索します。複数指定可能です(カンマ区切り) | |
*/ | |
def twitterId(value: String) = this.copy(_twitterId = Some(value)) | |
/** | |
* 指定したユーザIDのユーザが主催しているイベントを検索します。複数指定可能です(カンマ区切り) | |
*/ | |
def ownerId(value: String) = this.copy(_ownerId = Some(value)) | |
/** | |
* 指定したニックネームのユーザが主催しているイベントを検索します。複数指定可能です(カンマ区切り) | |
*/ | |
def ownerNickname(value: String) = this.copy(_ownerNickname = Some(value)) | |
/** | |
* 指定したtwitter IDのユーザが主催しているイベントを検索します。複数指定可能です(カンマ区切り) | |
*/ | |
def ownerTwitterId(value: String) = this.copy(_ownerTwitterId = Some(value)) | |
/** | |
* 検索結果の何件目から出力するかを指定します | |
* ※初期値:1 | |
*/ | |
def start(value: Int) = this.copy(_start = Some(value)) | |
/** | |
* 検索結果の最大出力データ数を指定します | |
* ※初期値:10, 最小値:1, 最大値:100 | |
*/ | |
def count(value: Int) = this.copy(_count = Some(value)) | |
/** 検索実行 */ | |
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] | |
) | |
} | |
) | |
} | |
} | |
val searcher = Searcher(None, None, None, None, None, None, None, None, None, None, None, None, None) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment