diff --git a/README.md b/README.md index 51af05a0a5..c54dfd481a 100644 --- a/README.md +++ b/README.md @@ -70,60 +70,80 @@ From here you can now run the application (`run`). ## API -### GET user infos +### GET user infos: `/api/user/` -> /api/user/<username> +#### JSON ``` > 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": { - "black": { - "deviation": 62, - "nbGames": 465, - "rating": 1483 + "black": { // performances with black pieces + "rating": 1483, // Glicko2 rating + "deviation": 62, // Glicko2 rating deviation + "nbGames": 465 // number of games played as black }, "blitz": { + "rating": 1480, "deviation": 63, - "nbGames": 481, - "rating": 1480 + "nbGames": 481 }, "bullet": { + "rating": 1640, "deviation": 90, - "nbGames": 23, - "rating": 1640 + "nbGames": 23 }, "chess960": { + "rating": 1575, "deviation": 64, - "nbGames": 323, - "rating": 1575 + "nbGames": 323 }, "global": { + "rating": 1503, "deviation": 62, - "nbGames": 883, - "rating": 1503 + "nbGames": 883 }, "slow": { + "rating": 1586, "deviation": 63, - "nbGames": 379, - "rating": 1586 + "nbGames": 379 }, "standard": { + "rating": 1504, "deviation": 62, - "nbGames": 560, - "rating": 1504 + "nbGames": 560 }, "white": { + "rating": 1478, "deviation": 63, - "nbGames": 418, - "rating": 1478 + "nbGames": 418 } - }, - "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 Lichess streams all played moves on http://en.lichess.org/stream using chunked HTTP response and the following format: diff --git a/app/controllers/Api.scala b/app/controllers/Api.scala index 9353bf2a43..b75799c6c8 100644 --- a/app/controllers/Api.scala +++ b/app/controllers/Api.scala @@ -5,6 +5,8 @@ import play.api.mvc._, Results._ import lila.app._ import lila.user.{ UserRepo, User ⇒ UserModel, Perf, Perfs } +import lila.game.GameRepo +import lila.app.templating.Environment.netBaseUrl object Api extends LilaController { @@ -19,17 +21,26 @@ object Api extends LilaController { 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( "username" -> u.username, - "perfs" -> u.perfs, - "progress" -> u.progress) + "perfs" -> u.perfs) } def user(username: String) = Action.async { req ⇒ - UserRepo named username map { - case None ⇒ NotFound - case Some(u) ⇒ Ok(Json toJson u) as JSON + UserRepo named username flatMap { + case None ⇒ fuccess(NotFound) + 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 + } + } } } } diff --git a/app/templating/GameHelper.scala b/app/templating/GameHelper.scala index f5d24c2e5c..3860edf971 100644 --- a/app/templating/GameHelper.scala +++ b/app/templating/GameHelper.scala @@ -11,7 +11,6 @@ import lila.game.{ Game, Player, Namer } import lila.user.Env.{ current ⇒ userEnv } import lila.user.{ User, Context } - trait GameHelper { self: I18nHelper with UserHelper with AiHelper with StringHelper ⇒ def variantName(variant: Variant)(implicit ctx: Context) = variant match { case Variant.Standard ⇒ trans.standard.str()