package dispatch.meetup
import dispatch._
import dispatch.oauth._
import dispatch.oauth.OAuth._
import dispatch.liftjson.Js._
import net.liftweb.json._
import net.liftweb.json.JsonAST._
import dispatch.mime.Mime._
import java.util.Date
import java.io.File
abstract class Client extends ((Request => Request) => Request) {
import Http.builder2product
val host = :/("api.meetup.com")
def call[T](method: Method[T])(implicit http: Http): T =
http(method.default_handler(apply(method)))
}
trait Method[T] extends Builder[Request => Request] {
def default_handler: Request => Handler[T]
}
trait ReadMethod extends Method[(List[JValue],List[JValue])] {
def default_handler = _ ># (Response.results ~ Response.meta)
}
trait WriteMethod extends Method[(List[String],List[String])] {
def default_handler = _ ># (WriteResponse.description ~ WriteResponse.details)
}
case class OAuthClient(consumer: Consumer, access: Token) extends Client {
def apply(block: Request => Request): Request =
block(host) <@ (consumer, access)
}
case class APIKeyClient(apikey: String) extends Client {
def apply(block: Request => Request): Request =
block(host) <<? Map("key" -> apikey)
}
object Auth {
val host = :/("www.meetup.com")
val svc = host / "oauth"
def request_token(consumer: Consumer): Handler[Token] = request_token(consumer, OAuth.oob)
def request_token(consumer: Consumer, callback_url: String) =
svc / "request/" << OAuth.callback(callback_url) <@ consumer as_token
def authorize_url(token: Token) = host / "authorize/" <<? token
def m_authorize_url(token: Token) = authorize_url(token) <<? Map("set_mobile" -> "on")
def access_token(consumer: Consumer, token: Token, verifier: String) =
svc.POST / "access/" <@ (consumer, token, verifier) as_token
}
object Response {
val results = 'results ? ary
val meta = 'meta ? obj
}
object WriteResponse {
val description = 'description ? str
val details = 'details ? str
}
object Meta {
val count = 'count ? int
val next = 'next ? str
val total_count = 'total_count ? int
val title = 'title ? str
val updated = 'updated ? date
val description = 'description ? str
val method = 'method ? str
val link = 'link ? str
val url = 'url ? str
}
object Groups extends GroupsBuilder(Map())
private[meetup] class GroupsBuilder(params: Map[String, Any]) extends ReadMethod {
private def param(key: String)(value: Any) = new GroupsBuilder(params + (key -> value))
val member_id = param("member_id")_
val urlname = param("group_urlname")_
val topic = param("topic")_
def topic(topic: Any, groupnum: Any) = param("topic")(topic).param("groupnum")(groupnum)
val id = param("id")_
val zip = param("zip")_
def geo(lat: Any, lon: Any) = param("lat")(lat).param("lon")(lon)
def city(city: Any, country: Any) = param("city")(city).param("country")(country)
def cityUS(city: Any, state: Any) = param("city")(city).param("state")(state).param("country")("us")
val radius = param("radius")_
private def order(value: String) = param("order")(value)
def order_ctime = order("ctime")
def order_name = order("name")
def order_location = order("location")
def order_members = order("members")
def product = (_: Request) / "groups" <<? params
}
trait Location {
val lat = 'lat ? str
val lon = 'lon ? str
val city = 'city ? str
val state = 'state ? str
val country = 'country ? str
val zip = 'zip ? str
}
object Group extends Location {
val name = 'name ? str
val urlname = 'group_urlname ? str
val group_photo_count = 'group_photo_count ? str
val photo_url = 'photo_url ? str
val link = 'link ? str
val organizer_name = 'organizer_name ? str
val who = 'who ? str
val id = 'id ? str
val topics = 'topics ? ary
val organizerProfileURL = 'organizerProfileURL ? str
val updated = 'updated ? date
val created = 'created ? date
val description = 'description ? str
val rating = 'rating ? str
val members = 'members ? str
val daysleft = 'daysleft ? str
object Topic {
val id = 'id ? str
val urlkey = 'urlkey ? str
val name = 'name ? str
}
}
object Events extends EventsBuilder(Map())
private[meetup] class EventsBuilder(params: Map[String, Any]) extends ReadMethod {
private def param(key: String)(value: Any) = new EventsBuilder(params + (key -> value))
private val df = new java.text.SimpleDateFormat("MMddyyyy")
private def date_param(key: String)(value: Date) = param(key)(df.format(value))
val member_id = param("member_id")_
val group_urlname = param("group_urlname")_
val topic = param("topic")_
def topic(topic: Any, groupnum: Any) = param("topic")(topic).param("groupnum")(groupnum)
val group_id = param("group_id")_
val zip = param("zip")_
def geo(lat: Any, lon: Any) = param("lat")(lat).param("lon")(lon)
def city(city: Any, country: Any) = param("city")(city).param("country")(country)
def cityUS(city: Any, state: Any) = param("city")(city).param("state")(state).param("country")("us")
val radius = param("radius")_
val after = date_param("after")_
val before = date_param("before")_
def status(s: Event.Status*) = param("status")(s map { _.values } mkString ",")
private def order(value: String) = param("order")(value)
def order_time = order("time")
def order_group = order("group")
def order_location = order("location")
def order_topic = order("topic")
def product = (_: Request) / "events" <<? params
}
object Event extends Location {
val name = 'name ? str
val id = 'id ? str
val time = 'time ? date
sealed abstract trait Status extends JString
object Upcoming extends JString("upcoming") with Status
object Past extends JString("past") with Status
val status = 'status ? in(Upcoming, Past)
val description = 'description ? str
val event_url = 'event_url ? str
val photo_url = 'photo_url ? str
val group_name = 'group_name ? str
val group_photo_url = 'group_photo_url ? str
val group_id = 'group_id ? str
val attendee_count = 'attendee_count ? str
val rsvpcount = 'rsvpcount ? str
val no_rsvpcount = 'no_rsvpcount ? str
val maybe_rsvpcount = 'maybe_rsvpcount ? str
val rsvp_cutoff = 'rsvp_cutoff ? str
val rsvp_closed = 'rsvp_closed ? str
val rsvp_limit = 'rsvp_limit ? str
val venue_name = 'venue_name ? str
val venue_id = 'venue_id ? str
val venue_address1 = 'venue_address1 ? str
val venue_address2 = 'venue_address2 ? str
val venue_address3 = 'venue_address3 ? str
val venue_city = 'venue_city ? str
val venue_state = 'venue_state ? str
val venue_zip = 'venue_zip ? str
val venue_phone = 'venue_phone ? str
val venue_lat = 'venue_lat ? str
val venue_lon = 'venue_lon ? str
val venue_map = 'venue_map ? str
val organizer_id = 'organizer_id ? str
val organizer_name = 'organizer_name ? str
val allow_maybe_rsvp = 'allow_maybe_rsvp ? str
val myrsvp = 'myrsvp ? str
val fee = 'fee ? str
val feecurrency = 'feecurrency ? str
val feedesc = 'feedesc ? str
val ismeetup = 'ismeetup ? str
val updated = 'updated ? date
val questions = 'questions ? ary >>~> str
}
object Members extends MembersBuilder(Map())
private[meetup] class MembersBuilder(params: Map[String, Any]) extends ReadMethod {
private def param(key: String)(value: Any) = new MembersBuilder(params + (key -> value))
val member_id = param("member_id")_
def self = param("relation")("self")
val group_id = param("group_id")_
def topic(topic: Any, groupnum: Any) = param("topic")(topic).param("groupnum")(groupnum)
val group_urlname = param("group_urlname")_
def product = (_: Request) / "members" <<? params
}
object Member extends Location {
val name = 'name ? str
val id = 'id ? str
val photo_url = 'photo_url ? str
val link = 'link ? str
val visited = 'visited ? date
val joined = 'joined ? date
val bio = 'bio ? str
}
object Rsvps extends RsvpsBuilder(Map())
private[meetup] class RsvpsBuilder(params: Map[String, Any]) extends ReadMethod {
private def param(key: String)(value: Any) = new RsvpsBuilder(params + (key -> value))
val event_id = param("event_id")_
def product = (_: Request) / "rsvps" <<? params
}
object Rsvp extends Location {
val name = 'name ? str
val id = 'id ? str
val photo_url = 'photo_url ? str
val link = 'link ? str
val comment = 'comment ? str
val response = 'response ? str
val created = 'created ? date
val update = 'updated ? date
}
object PhotoUpload extends PhotoUploadBuilder(None, Map())
private[meetup] class PhotoUploadBuilder(photo: Option[File], params: Map[String, Any]) extends WriteMethod {
private def param(key: String)(value: Any) = new PhotoUploadBuilder(photo, params + (key -> value))
val event_id = param("event_id")_
def photo(photo: File) = new PhotoUploadBuilder(Some(photo), params)
val caption = param("caption")_
def product = (_: Request) / "photo" <<? params <<* ("photo", photo.getOrElse { error("photo not specified for PhotoUpload") } )
}