diff --git a/app/ui/SiteMenu.scala b/app/ui/SiteMenu.scala
index e3f485a86e..505c53c01c 100644
--- a/app/ui/SiteMenu.scala
+++ b/app/ui/SiteMenu.scala
@@ -19,11 +19,18 @@ final class SiteMenu(trans: I18nKeys) {
val forum = new Elem("forum", routes.ForumCateg.index, trans.forum)
val tv = new Elem("tv", routes.Tv.index, I18nKey.untranslated("TV"))
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 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 {
diff --git a/app/views/analyse/replay.scala.html b/app/views/analyse/replay.scala.html
index 8e21a36268..c1d6c2e068 100644
--- a/app/views/analyse/replay.scala.html
+++ b/app/views/analyse/replay.scala.html
@@ -113,20 +113,17 @@ themepicker = true) {
data-max="@lila.analyse.AdvantageChart.max"
data-rows="@chart">
}.getOrElse {
-
- @trans.computerAnalysisInProgress()
-
- }
- }.getOrElse {
- @if(game.analysable && analysis.isEmpty) {
-
-
-
@trans.computerAnalysisInProgress()
}
+ }.getOrElse {
+ @if(game.analysable && analysis.isEmpty) {
+
+ }
}
diff --git a/app/views/puzzle/layout.scala.html b/app/views/puzzle/layout.scala.html
index ee7d4eb097..5e15e474cf 100644
--- a/app/views/puzzle/layout.scala.html
+++ b/app/views/puzzle/layout.scala.html
@@ -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 = {
+@evenMoreCss
@cssTag("problem.css")
-@cssTag("chessboardjs.css")
}
@moreJs = {
+@evenMoreJs
@jsTagCompiled("chessboard.js")
-@jsTag("vendor/chess.min.js")
-@jsAt("compiled/problem.js")
}
@base.layout(
title = title,
moreCss = moreCss,
-moreJs = moreJs) {
+moreJs = moreJs,
+active = siteMenu.puzzle.some) {
@body
}
diff --git a/app/views/puzzle/show.scala.html b/app/views/puzzle/show.scala.html
index 2fbaeab665..6957e9f726 100644
--- a/app/views/puzzle/show.scala.html
+++ b/app/views/puzzle/show.scala.html
@@ -1,6 +1,17 @@
@(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) {
diff --git a/modules/puzzle/src/main/Env.scala b/modules/puzzle/src/main/Env.scala
index 7e093c5ef9..8d98546db0 100644
--- a/modules/puzzle/src/main/Env.scala
+++ b/modules/puzzle/src/main/Env.scala
@@ -24,7 +24,7 @@ final class Env(
def cli = new lila.common.Cli {
def process = {
- case "puzzle" :: "fix" :: "fen" :: Nil ⇒ api.fixFen inject "fixed!"
+ case "puzzle" :: "fix" :: "fen" :: Nil ⇒ api.fixAll inject "fixed!"
}
}
diff --git a/modules/puzzle/src/main/PuzzleApi.scala b/modules/puzzle/src/main/PuzzleApi.scala
index 0b5f894e8d..c216bacbb7 100644
--- a/modules/puzzle/src/main/PuzzleApi.scala
+++ b/modules/puzzle/src/main/PuzzleApi.scala
@@ -6,7 +6,7 @@ import org.joda.time.DateTime
import play.api.libs.iteratee._
import play.api.libs.iteratee.Enumerator
import play.api.libs.json._
-import reactivemongo.bson.BSONDocument
+import reactivemongo.bson.{ BSONDocument, BSONInteger }
import reactivemongo.core.commands.Count
import lila.db.Types.Coll
@@ -65,17 +65,27 @@ private[puzzle] final class PuzzleApi(
BSONDocument(Attempt.BSONFields.vote -> v)
).void
- def fixFen = puzzleColl.find(BSONDocument()).cursor[Puzzle].enumerate() |>>>
- (Iteratee.foldM[Puzzle, Unit](()) {
- case (_, puzzle) ⇒ Generated fenOf puzzle.history match {
- case Success(fen) ⇒ puzzleColl.update(
- BSONDocument("_id" -> puzzle.id),
- BSONDocument("$set" -> BSONDocument(
- Puzzle.BSONFields.fen -> fen,
- Puzzle.BSONFields.rating -> Glicko.default
- ))
- ).void
- case Failure(err) ⇒ fufail(err.getMessage)
- }
+ def fixAll = puzzleColl.find(
+ BSONDocument(),
+ BSONDocument("history" -> true)
+ ).cursor[BSONDocument].enumerate() |>>>
+ (Iteratee.foldM[BSONDocument, Unit](()) {
+ case (_, doc) ⇒
+ val reader = new lila.db.BSON.Reader(doc)
+ val (id, moves) = (reader str "_id", reader str "history" split ' ')
+ Generated fenOf moves match {
+ case Success(fen) ⇒ puzzleColl.update(
+ 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)
+ }
})
}
diff --git a/todo b/todo
index 81ab449fed..fce16f2de4 100644
--- a/todo
+++ b/todo
@@ -106,6 +106,14 @@ ban only latest IP
give AI levels ratings
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
-------
lila nice + thread limit