diff --git a/app/controllers/Monitor.scala b/app/controllers/Monitor.scala index 6bbadf09c0..899fd6d292 100644 --- a/app/controllers/Monitor.scala +++ b/app/controllers/Monitor.scala @@ -17,6 +17,7 @@ object Monitor extends LilaController { private def reporting = env.monitor.reporting private def usernameMemo = env.user.usernameMemo private def userRepo = env.user.userRepo + private def gameRepo = env.game.gameRepo private implicit def timeout = Timeout(500 millis) def index = Action { @@ -31,10 +32,14 @@ object Monitor extends LilaController { Async { import core.Futuristic.ioToFuture (~get("key") match { - case "elo" ⇒ userRepo.idsAverageElo(usernameMemo.keys).toFuture - case "moves" ⇒ (reporting ? GetNbMoves).mapTo[Int] + case "elo" ⇒ + userRepo.idsAverageElo(usernameMemo.keys).toFuture zip + gameRepo.recentAverageElo(100000).toFuture map { + case (users, (rated, casual)) ⇒ List(users, rated, casual) mkString " " + } + case "moves" ⇒ (reporting ? GetNbMoves).mapTo[Int] case "players" ⇒ (reporting ? GetNbMembers).mapTo[Int] map { "%d %d".format(_, usernameMemo.preciseCount) } - case _ ⇒ (reporting ? GetStatus).mapTo[String] + case _ ⇒ (reporting ? GetStatus).mapTo[String] }).asPromise map { x ⇒ Ok(x.toString) } } } diff --git a/app/game/GameRepo.scala b/app/game/GameRepo.scala index f0e48e0191..fca3a46a7a 100644 --- a/app/game/GameRepo.scala +++ b/app/game/GameRepo.scala @@ -12,6 +12,7 @@ import com.novus.salat._ import com.novus.salat.dao._ import com.mongodb.casbah.{ WriteConcern, MongoCollection } import com.mongodb.casbah.query.Imports._ +import com.mongodb.casbah.map_reduce.MapReduceInlineOutput import org.joda.time.DateTime import org.scala_tools.time.Imports._ import java.util.Date @@ -56,13 +57,13 @@ final class GameRepo(collection: MongoCollection) update(idSelector(game), _grater asDBObject game.encode) } - def save(progress: Progress): IO[Unit] = + def save(progress: Progress): IO[Unit] = GameDiff(progress.origin.encode, progress.game.encode) |> { case (Nil, Nil) ⇒ io() case (sets, unsets) ⇒ { val fullSets = ("ua" -> new Date) :: sets val ops = unsets.isEmpty.fold( - $set(fullSets: _*), + $set(fullSets: _*), $set(fullSets: _*) ++ $unset(unsets: _*) ) val wc = WriteConcern.None @@ -206,6 +207,38 @@ final class GameRepo(collection: MongoCollection) count(("ca" $gte from $lt to)) }).sequence + def recentAverageElo(minutes: Int): IO[(Int, Int)] = io { + val result = collection.mapReduce( + mapFunction = """function() { + emit(!!this.ra, this.p); + }""", + reduceFunction = """function(rated, values) { + var sum = 0, nb = 0; + values.forEach(function(game) { + if(typeof game[0] != "undefined") { + game.forEach(function(player) { + if(player.elo) { + sum += player.elo; + ++nb; + } + }); + } + }); + return nb == 0 ? nb : Math.round(sum / nb); +}""", + output = MapReduceInlineOutput, + query = Some { + ("ca" $gte (DateTime.now - minutes.minutes)) ++ ("p.elo" $exists true) + } + ) + (for { + ratedRow ← result.hasNext option result.next + rated ← ratedRow.getAs[Double]("value") + casualRow ← result.hasNext option result.next + casual ← casualRow.getAs[Double]("value") + } yield rated.toInt -> casual.toInt) | (0, 0) + } + private def idSelector(game: DbGame): DBObject = idSelector(game.id) private def idSelector(id: String): DBObject = DBObject("_id" -> id) } diff --git a/todo b/todo index 6f62db1343..8d5331772d 100644 --- a/todo +++ b/todo @@ -53,3 +53,4 @@ block user creation from an IP mute IP time color toward end http://fr.lichess.org/forum/lichess-feedback/suggestion-time-color-towards-end#5 fast join game = creator not redirected properly? +resign popup on close window