show puzzle menu to beta testers, migrate existing puzzles

This commit is contained in:
Thibault Duplessis 2014-02-03 20:19:08 +01:00
parent e70d54149f
commit b070b66394
7 changed files with 63 additions and 30 deletions

View file

@ -19,11 +19,18 @@ final class SiteMenu(trans: I18nKeys) {
val forum = new Elem("forum", routes.ForumCateg.index, trans.forum) val forum = new Elem("forum", routes.ForumCateg.index, trans.forum)
val tv = new Elem("tv", routes.Tv.index, I18nKey.untranslated("TV")) val tv = new Elem("tv", routes.Tv.index, I18nKey.untranslated("TV"))
val message = new Elem("message", routes.Message.inbox(page = 1), trans.inbox) val message = new Elem("message", routes.Message.inbox(page = 1), trans.inbox)
val puzzle = new Elem("puzzle", routes.Puzzle.home, I18nKey untranslated "Puzzles")
private val authenticated = List(play, game, tournament, user, team, forum, tv) private val authenticated = List(play, game, tournament, user, team, forum, tv)
private val anonymous = List(play, game, tournament, user, team, forum, tv) private val anonymous = List(play, game, tournament, user, team, forum, tv)
def all(me: Option[User]) = me.isDefined.fold(authenticated, anonymous) private val betaTesters = Set("thibault", "hellball", "clarkey", "legend", "chubakka", "iron_logician")
def all(me: Option[User]) = me match {
case Some(me) if betaTesters(me.id) authenticated :+ puzzle
case Some(me) authenticated
case _ anonymous
}
} }
object SiteMenu { object SiteMenu {

View file

@ -113,20 +113,17 @@ themepicker = true) {
data-max="@lila.analyse.AdvantageChart.max" data-max="@lila.analyse.AdvantageChart.max"
data-rows="@chart"></div> data-rows="@chart"></div>
}.getOrElse { }.getOrElse {
<div class="future_game_analysis in_progress" >
@trans.computerAnalysisInProgress()
</div>
}
}.getOrElse {
@if(game.analysable && analysis.isEmpty) {
<!-- <form class="future_game_analysis@{ctx.isAnon ?? " must_login"}" action="@routes.Analyse.computer(gameId, color.name)" method="post"> -->
<!-- <button type="submit" class="button"><span>@trans.requestAComputerAnalysis()</span></button> -->
<!-- </form> -->
<div class="future_game_analysis"> <div class="future_game_analysis">
@trans.computerAnalysisInProgress() @trans.computerAnalysisInProgress()
<div class="spinner"></div> <div class="spinner"></div>
</div> </div>
} }
}.getOrElse {
@if(game.analysable && analysis.isEmpty) {
<form class="future_game_analysis@{ctx.isAnon ?? " must_login"}" action="@routes.Analyse.computer(gameId, color.name)" method="post">
<button type="submit" class="button"><span>@trans.requestAComputerAnalysis()</span></button>
</form>
}
} }
<div class="view_game_analysis future_game_analysis"> <div class="view_game_analysis future_game_analysis">
<a class="button" href="@routes.Round.watcher(pov.gameId, pov.color.name)"> <a class="button" href="@routes.Round.watcher(pov.gameId, pov.color.name)">

View file

@ -1,19 +1,19 @@
@(title: String)(body: Html)(implicit ctx: Context) @(title: String, evenMoreCss: Option[Html] = None, evenMoreJs: Option[Html] = None)(body: Html)(implicit ctx: Context)
@moreCss = { @moreCss = {
@evenMoreCss
@cssTag("problem.css") @cssTag("problem.css")
@cssTag("chessboardjs.css")
} }
@moreJs = { @moreJs = {
@evenMoreJs
@jsTagCompiled("chessboard.js") @jsTagCompiled("chessboard.js")
@jsTag("vendor/chess.min.js")
@jsAt("compiled/problem.js")
} }
@base.layout( @base.layout(
title = title, title = title,
moreCss = moreCss, moreCss = moreCss,
moreJs = moreJs) { moreJs = moreJs,
active = siteMenu.puzzle.some) {
@body @body
} }

View file

@ -1,6 +1,17 @@
@(puzzle: lila.puzzle.Puzzle)(implicit ctx: Context) @(puzzle: lila.puzzle.Puzzle)(implicit ctx: Context)
@layout("Puzzle " + puzzle.id) { @moreCss = {
@cssTag("chessboardjs.css")
}
@moreJs = {
@jsTag("vendor/chess.min.js")
@jsAt("compiled/problem.js")
}
@layout("Puzzle " + puzzle.id,
evenMoreCss = moreCss.some,
evenMoreJs = moreJs.some) {
<div class="content_box" id="puzzle"> <div class="content_box" id="puzzle">

View file

@ -24,7 +24,7 @@ final class Env(
def cli = new lila.common.Cli { def cli = new lila.common.Cli {
def process = { def process = {
case "puzzle" :: "fix" :: "fen" :: Nil api.fixFen inject "fixed!" case "puzzle" :: "fix" :: "fen" :: Nil api.fixAll inject "fixed!"
} }
} }

View file

@ -6,7 +6,7 @@ import org.joda.time.DateTime
import play.api.libs.iteratee._ import play.api.libs.iteratee._
import play.api.libs.iteratee.Enumerator import play.api.libs.iteratee.Enumerator
import play.api.libs.json._ import play.api.libs.json._
import reactivemongo.bson.BSONDocument import reactivemongo.bson.{ BSONDocument, BSONInteger }
import reactivemongo.core.commands.Count import reactivemongo.core.commands.Count
import lila.db.Types.Coll import lila.db.Types.Coll
@ -65,17 +65,27 @@ private[puzzle] final class PuzzleApi(
BSONDocument(Attempt.BSONFields.vote -> v) BSONDocument(Attempt.BSONFields.vote -> v)
).void ).void
def fixFen = puzzleColl.find(BSONDocument()).cursor[Puzzle].enumerate() |>>> def fixAll = puzzleColl.find(
(Iteratee.foldM[Puzzle, Unit](()) { BSONDocument(),
case (_, puzzle) Generated fenOf puzzle.history match { BSONDocument("history" -> true)
case Success(fen) puzzleColl.update( ).cursor[BSONDocument].enumerate() |>>>
BSONDocument("_id" -> puzzle.id), (Iteratee.foldM[BSONDocument, Unit](()) {
BSONDocument("$set" -> BSONDocument( case (_, doc)
Puzzle.BSONFields.fen -> fen, val reader = new lila.db.BSON.Reader(doc)
Puzzle.BSONFields.rating -> Glicko.default val (id, moves) = (reader str "_id", reader str "history" split ' ')
)) Generated fenOf moves match {
).void case Success(fen) puzzleColl.update(
case Failure(err) fufail(err.getMessage) BSONDocument("_id" -> id),
} BSONDocument("$set" -> BSONDocument(
Puzzle.BSONFields.fen -> fen,
Puzzle.BSONFields.rating -> Glicko.default,
Puzzle.BSONFields.vote -> BSONInteger(0),
Puzzle.BSONFields.attempts -> BSONInteger(0)
))
).void
case Failure(err)
println(err)
fufail(err.getMessage)
}
}) })
} }

8
todo
View file

@ -106,6 +106,14 @@ ban only latest IP
give AI levels ratings give AI levels ratings
connect time chart to pgn viewer and say "time spent on this move: X seconds" connect time chart to pgn viewer and say "time spent on this move: X seconds"
deploy
------
db.puzzle.ensureIndex({fen:1},{unique:1})
db.puzzle.ensureIndex({date:1})
db.puzzle.ensureIndex({vote:1})
db.puzzle_attempt.ensureIndex({p:1})
db.puzzle_attempt.ensureIndex({u:1})
infra infra
------- -------
lila nice + thread limit lila nice + thread limit