improve user API and add JSONP support

pull/83/head
Thibault Duplessis 2013-12-31 11:45:37 +01:00
parent 42952b6c32
commit bfc71611f2
3 changed files with 60 additions and 30 deletions

View File

@ -70,60 +70,80 @@ From here you can now run the application (`run`).
## API ## API
### GET user infos ### GET user infos: `/api/user/<username>`
> /api/user/&lt;username&gt; #### JSON
``` ```
> curl en.lichess.org/api/user/thibault > curl en.lichess.org/api/user/thibault
```
```javascript
{ {
"rating": 1503, // shortcut to perfs.global.rating
"progress": 36, // rating change over the last ten games
"online": true, // is the player currently using lichess?
"playing": "http://lichess.org/abcdefgh", // game being played, if any
"username": "thibault",
"perfs": { "perfs": {
"black": { "black": { // performances with black pieces
"deviation": 62, "rating": 1483, // Glicko2 rating
"nbGames": 465, "deviation": 62, // Glicko2 rating deviation
"rating": 1483 "nbGames": 465 // number of games played as black
}, },
"blitz": { "blitz": {
"rating": 1480,
"deviation": 63, "deviation": 63,
"nbGames": 481, "nbGames": 481
"rating": 1480
}, },
"bullet": { "bullet": {
"rating": 1640,
"deviation": 90, "deviation": 90,
"nbGames": 23, "nbGames": 23
"rating": 1640
}, },
"chess960": { "chess960": {
"rating": 1575,
"deviation": 64, "deviation": 64,
"nbGames": 323, "nbGames": 323
"rating": 1575
}, },
"global": { "global": {
"rating": 1503,
"deviation": 62, "deviation": 62,
"nbGames": 883, "nbGames": 883
"rating": 1503
}, },
"slow": { "slow": {
"rating": 1586,
"deviation": 63, "deviation": 63,
"nbGames": 379, "nbGames": 379
"rating": 1586
}, },
"standard": { "standard": {
"rating": 1504,
"deviation": 62, "deviation": 62,
"nbGames": 560, "nbGames": 560
"rating": 1504
}, },
"white": { "white": {
"rating": 1478,
"deviation": 63, "deviation": 63,
"nbGames": 418, "nbGames": 418
"rating": 1478
} }
}, }
"progress": 36,
"username": "thibault"
} }
``` ```
#### JSONP
```javascript
$.ajax({
url:'http://en.l.org/api/user/thibault',
dataType:'jsonp',
jsonp:'callback',
success: function(data) {
// data is a javascript object, do something with it!
console.debug(JSON.stringify(data));
}
});
```
### Read the move stream ### Read the move stream
Lichess streams all played moves on http://en.lichess.org/stream using chunked HTTP response and the following format: Lichess streams all played moves on http://en.lichess.org/stream using chunked HTTP response and the following format:

View File

@ -5,6 +5,8 @@ import play.api.mvc._, Results._
import lila.app._ import lila.app._
import lila.user.{ UserRepo, User UserModel, Perf, Perfs } import lila.user.{ UserRepo, User UserModel, Perf, Perfs }
import lila.game.GameRepo
import lila.app.templating.Environment.netBaseUrl
object Api extends LilaController { object Api extends LilaController {
@ -19,17 +21,26 @@ object Api extends LilaController {
case (name, perf) name -> perfWrites.writes(perf) case (name, perf) name -> perfWrites.writes(perf)
}) })
} }
private implicit val userWrites: Writes[UserModel] = Writes { u private implicit val userWrites: OWrites[UserModel] = OWrites { u
Json.obj( Json.obj(
"username" -> u.username, "username" -> u.username,
"perfs" -> u.perfs, "perfs" -> u.perfs)
"progress" -> u.progress)
} }
def user(username: String) = Action.async { req def user(username: String) = Action.async { req
UserRepo named username map { UserRepo named username flatMap {
case None NotFound case None fuccess(NotFound)
case Some(u) Ok(Json toJson u) as JSON case Some(u) GameRepo nowPlaying u.id map { gameOption
val json = userWrites.writes(u) ++ Json.obj(
"online" -> Env.user.isOnline(u.id),
"playing" -> gameOption.map(g
netBaseUrl + routes.Round.watcher(g.id, g.firstPlayer.color.name).url)
)
get("callback", req) match {
case None Ok(json) as JSON
case Some(callback) Ok(s"$callback($json)") as JAVASCRIPT
}
}
} }
} }
} }

View File

@ -11,7 +11,6 @@ import lila.game.{ Game, Player, Namer }
import lila.user.Env.{ current userEnv } import lila.user.Env.{ current userEnv }
import lila.user.{ User, Context } import lila.user.{ User, Context }
trait GameHelper { self: I18nHelper with UserHelper with AiHelper with StringHelper trait GameHelper { self: I18nHelper with UserHelper with AiHelper with StringHelper
def variantName(variant: Variant)(implicit ctx: Context) = variant match { def variantName(variant: Variant)(implicit ctx: Context) = variant match {
case Variant.Standard trans.standard.str() case Variant.Standard trans.standard.str()