lila/app/controllers/Insight.scala

122 lines
3.7 KiB
Scala

package controllers
import play.api.libs.json.Json
import play.api.libs.json.JsValue
import play.api.mvc._
import views._
import lila.api.Context
import lila.app._
import lila.insight.{ Dimension, Metric }
final class Insight(env: Env) extends LilaController(env) {
def refresh(username: String) =
OpenOrScoped()(
open = implicit ctx =>
Accessible(username) { user =>
env.insight.api indexAll user.id inject Ok
},
scoped = req =>
me =>
AccessibleApi(username)(me.some) { user =>
env.insight.api indexAll user.id inject Ok
}
)
def index(username: String) = {
def jsonStatus(user: lila.user.User) =
env.insight.api userStatus user map { status =>
Ok(Json.obj("status" -> status.toString))
}
OpenOrScoped()(
open = implicit ctx =>
Accessible(username) { user =>
render.async {
case Accepts.Html() => doPath(user, Metric.MeanCpl.key, Dimension.Perf.key, "")
case Accepts.Json() => jsonStatus(user)
}
},
scoped = req => me => AccessibleApi(username)(me.some)(jsonStatus)
)
}
def path(username: String, metric: String, dimension: String, filters: String) =
Open { implicit ctx =>
Accessible(username) { doPath(_, metric, dimension, filters) }
}
private def doPath(user: lila.user.User, metric: String, dimension: String, filters: String)(implicit
ctx: Context
) = {
import lila.insight.InsightApi.UserStatus._
env.insight.api userStatus user flatMap {
case NoGame => Ok(html.site.message.insightNoGames(user)).fuccess
case Empty => Ok(html.insight.empty(user)).fuccess
case s =>
for {
cache <- env.insight.api insightUser user
prefId <- env.insight.share getPrefId user
} yield Ok(
html.insight.index(
u = user,
cache = cache,
prefId = prefId,
ui = env.insight.jsonView.ui(cache.ecos, asMod = isGranted(_.ViewBlurs)),
question = env.insight.jsonView.question(metric, dimension, filters),
stale = s == Stale
)
)
}
}
def json(username: String) =
OpenOrScopedBody(parse.json)(Nil)(
open = implicit ctx => {
AccessibleApi(username)(ctx.me) { user =>
processQuestion(user, ctx.body)
}
},
scoped = req =>
me =>
AccessibleApi(username)(me.some) { user =>
processQuestion(user, req)
}
)
private def processQuestion(user: lila.user.User, body: Request[JsValue]) = {
import lila.insight.JsonQuestion, JsonQuestion._
implicit val lang = reqLang(body)
body.body
.validate[JsonQuestion]
.fold(
err => BadRequest(jsonError(err.toString)).fuccess,
_.question.fold(BadRequest.fuccess) { q =>
env.insight.api.ask(q, user) map
lila.insight.Chart.fromAnswer(env.user.lightUserSync) map
env.insight.jsonView.chart.apply map { Ok(_) }
}
)
}
private def Accessible(username: String)(f: lila.user.User => Fu[Result])(implicit ctx: Context) =
env.user.repo named username flatMap {
_.fold(notFound) { u =>
env.insight.share.grant(u, ctx.me) flatMap {
case true => f(u)
case _ => fuccess(Forbidden(html.insight.forbidden(u)))
}
}
}
private def AccessibleApi(username: String)(me: Option[lila.user.User])(f: lila.user.User => Fu[Result]) =
env.user.repo named username flatMap {
_ ?? { u =>
env.insight.share.grant(u, me) flatMap {
case true => f(u)
case _ => fuccess(Forbidden)
}
}
}
}