remove coach raw data, enforce range

pull/759/head
Thibault Duplessis 2015-07-27 12:54:08 +02:00
parent 290314c8ff
commit 1cab1b5882
5 changed files with 28 additions and 123 deletions

View File

@ -10,23 +10,6 @@ object Coach extends LilaController {
private def env = Env.coach
def raw(username: String) = Open { implicit ctx =>
Accessible(username) { user =>
env.statApi.fetchAll(user.id) map { period =>
Ok(html.coach.raw.index(user, period.map(_.data)))
}
}
}
def rawJson(username: String) = Open { implicit ctx =>
Accessible(username) { user =>
env.statApi.fetchAll(user.id) flatMap {
case None => notFoundJson(s"Data not generated yet")
case Some(period) => env.jsonView.raw(period.data) map { Ok(_) }
}
}
}
def opening(username: String, colorStr: String) = Open { implicit ctx =>
chess.Color(colorStr).fold(notFound) { color =>
Accessible(username) { user =>
@ -40,10 +23,12 @@ object Coach extends LilaController {
def openingJson(username: String, colorStr: String) = Open { implicit ctx =>
chess.Color(colorStr).fold(notFoundJson(s"No such color: $colorStr")) { color =>
AccessibleJson(username) { user =>
env.statApi.fetchRangeForOpenings(user.id, requestRange) flatMap {
_.fold(notFoundJson(s"Data not generated yet")) { period =>
env.jsonView.opening(period, color) map { data =>
Ok(data)
WithRange { range =>
env.statApi.fetchRangeForOpenings(user.id, range) flatMap {
_.fold(notFoundJson(s"Data not generated yet")) { period =>
env.jsonView.opening(period, color) map { data =>
Ok(data)
}
}
}
}
@ -61,10 +46,12 @@ object Coach extends LilaController {
def moveJson(username: String) = Open { implicit ctx =>
AccessibleJson(username) { user =>
env.statApi.fetchRangeForMoves(user.id, requestRange) flatMap {
_.fold(notFoundJson(s"Data not generated yet")) { period =>
env.jsonView.move(period) map { data =>
Ok(data)
WithRange { range =>
env.statApi.fetchRangeForMoves(user.id, range) flatMap {
_.fold(notFoundJson(s"Data not generated yet")) { period =>
env.jsonView.move(period) map { data =>
Ok(data)
}
}
}
}
@ -77,13 +64,13 @@ object Coach extends LilaController {
}
}
private def requestRange(implicit ctx: Context): Option[Range] =
get("range") flatMap {
private def WithRange(f: Range => Fu[Result])(implicit ctx: Context): Fu[Result] =
get("range").flatMap {
_.split('-') match {
case Array(a, b) => (parseIntOption(a) |@| parseIntOption(b))(Range.apply)
case _ => none
}
}
}.fold(notFound)(f)
private def Accessible(username: String)(f: lila.user.User => Fu[Result])(implicit ctx: Context) =
lila.user.UserRepo named username flatMap {

View File

@ -1,71 +0,0 @@
@(u: User, stat: Option[lila.coach.UserStat])(implicit ctx: Context)
@coach.layout(u, title = s"${u.username} raw data",
evenMoreCss = cssTag("coach.raw.css")) {
<div class="content_box no_padding">
<div class="content_box_top">
<h1>
@userLink(u, withOnline = false) raw stats
<a class="button" href="@routes.Coach.rawJson(u.username)">
Download as JSON
</a>
</h1>
</div>
@stat.map { s =>
@perfResultsTable(s.results, "Results".some)
<table class="root">
<thead>
<tr>
<th>Overall</th>
<th>As white</th>
<th>As black</th>
</tr>
</thead>
<tbody>
<tr>
<td>@resultsTable(s.results.base, none)</td>
<td>@resultsTable(s.colorResults.white, none)</td>
<td>@resultsTable(s.colorResults.black, none)</td>
</tbody>
</table>
<table class="root">
<thead>
<tr>
<th colspan=2>Favourite openings</th>
</tr>
</thead>
<tbody>
<tr>
@chess.Color.all.map { color =>
<td>
<table>
<thead>
<tr>
<th colspan=2>As @color.name</th>
</tr>
</thead>
<tbody>
@s.openings(color).best.map {
case (code, results) => {
<tr>
<th>@code</th>
<td>@resultsTable(results, none)</td>
</tr>
}
}
</tbody>
</table>
</td>
}
</tr>
</tbody>
</table>
@s.perfResults.sorted.map {
case (perfType, perfResults) => {
@perfResultsTable(perfResults, perfType.name.some)
@resultsTable(perfResults.base, none)
}
}
}
</div>
}

View File

@ -31,8 +31,6 @@ GET /@/:username/suggestions controllers.Relation.suggest(username: St
GET /rel/blocks controllers.Relation.blocks
# Coach
GET /coach/raw/:username.json controllers.Coach.rawJson(username: String)
GET /coach/raw/:username controllers.Coach.raw(username: String)
GET /coach/opening/:username/:color.json controllers.Coach.openingJson(username: String, color: String)
GET /coach/opening/:username/:color controllers.Coach.opening(username: String, color: String)
GET /coach/move/:username.json controllers.Coach.moveJson(username: String)

View File

@ -6,10 +6,6 @@ final class JsonView(jsonWriters: JSONWriters) {
import jsonWriters._
def raw(stat: UserStat): Fu[JsObject] = fuccess {
UserStatWriter writes stat
}
def opening(period: Period, color: chess.Color): Fu[JsObject] = fuccess {
val stat = period.data
val openings = stat.openings(color).trim

View File

@ -20,33 +20,28 @@ final class StatApi(coll: Coll) {
private val sortChronological = BSONDocument("from" -> 1)
private val sortAntiChronological = BSONDocument("from" -> -1)
def fetchRangeForMoves(userId: String, range: Option[Range]) =
def fetchRangeForMoves(userId: String, range: Range) =
fetchRange(userId, range, BSONDocument("data.openings" -> false))
def fetchRangeForOpenings(userId: String, range: Option[Range]) =
def fetchRangeForOpenings(userId: String, range: Range) =
fetchRange(userId, range, BSONDocument("data.perfResults" -> false))
private def fetchRange(
userId: String,
range: Option[Range],
range: Range,
projection: BSONDocument): Fu[Option[Period]] =
range.fold(fetchAll(userId)) { r =>
coll.find(selectUserId(userId), projection)
.skip(r.min)
.sort(sortChronological)
.cursor[Period]()
.enumerate(r.size) &>
Enumeratee.take(r.size) |>>>
Iteratee.fold[Period, Option[Period]](none) {
case (a, b) => a.fold(b)(_ merge b).some
}
}
def fetchAll(userId: String): Fu[Option[Period]] =
fetchRange(userId, Range(0, 1000).some, BSONDocument())
coll.find(selectUserId(userId), projection)
.skip(range.min)
.sort(sortChronological)
.cursor[Period]()
.enumerate(range.size) &>
Enumeratee.take(range.size) |>>>
Iteratee.fold[Period, Option[Period]](none) {
case (a, b) => a.fold(b)(_ merge b).some
}
def fetchFirst(userId: String): Fu[Option[Period]] =
fetchRange(userId, Range(0, 1).some, BSONDocument())
fetchRange(userId, Range(0, 1), BSONDocument())
def fetchLast(userId: String): Fu[Option[Period]] =
coll.find(selectUserId(userId)).sort(sortAntiChronological).one[Period]