remove coach raw data, enforce range
parent
290314c8ff
commit
1cab1b5882
|
@ -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,7 +23,8 @@ 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 {
|
||||
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)
|
||||
|
@ -50,6 +34,7 @@ object Coach extends LilaController {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def move(username: String) = Open { implicit ctx =>
|
||||
Accessible(username) { user =>
|
||||
|
@ -61,7 +46,8 @@ object Coach extends LilaController {
|
|||
|
||||
def moveJson(username: String) = Open { implicit ctx =>
|
||||
AccessibleJson(username) { user =>
|
||||
env.statApi.fetchRangeForMoves(user.id, requestRange) flatMap {
|
||||
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)
|
||||
|
@ -70,6 +56,7 @@ object Coach extends LilaController {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def refresh(username: String) = Open { implicit ctx =>
|
||||
Accessible(username) { user =>
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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>
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
.skip(range.min)
|
||||
.sort(sortChronological)
|
||||
.cursor[Period]()
|
||||
.enumerate(r.size) &>
|
||||
Enumeratee.take(r.size) |>>>
|
||||
.enumerate(range.size) &>
|
||||
Enumeratee.take(range.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())
|
||||
|
||||
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]
|
||||
|
|
Loading…
Reference in New Issue