From de920db74a45ddc05fe136a394c4ac7210b0c87e Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Sat, 8 Sep 2012 14:23:12 +0200 Subject: [PATCH] more user nb games denormalization, fix filters and improve win chart --- app/user/GameFilter.scala | 12 ++++++------ app/user/User.scala | 4 ++++ app/user/UserInfo.scala | 11 +---------- app/user/WinChart.scala | 5 +++-- app/views/user/filterTitle.scala.html | 6 +++--- bin/prod/userstats.js | 10 +++++++--- todo | 2 +- 7 files changed, 25 insertions(+), 25 deletions(-) diff --git a/app/user/GameFilter.scala b/app/user/GameFilter.scala index e6b7e17461..e7b3b57b36 100644 --- a/app/user/GameFilter.scala +++ b/app/user/GameFilter.scala @@ -44,9 +44,9 @@ object GameFilterMenu extends NonEmptyLists { val all = nel(All, List( info.nbWithMe.fold(_ > 0, false) option Me, (info.nbRated > 0) option Rated, - (info.nbWin > 0) option Win, - (info.nbLoss > 0) option Loss, - (info.nbDraw > 0) option Draw, + (info.user.nbWins > 0) option Win, + (info.user.nbLosses > 0) option Loss, + (info.user.nbDraws > 0) option Draw, (info.nbPlaying > 0) option Playing, (info.nbBookmark > 0) option Bookmark ).flatten) @@ -67,9 +67,9 @@ object GameFilterMenu extends NonEmptyLists { val cachedNb: Option[Int] = current match { case All ⇒ info.user.nbGames.some case Rated ⇒ info.nbRated.some - case Win ⇒ info.nbWin.some - case Loss ⇒ info.nbLoss.some - case Draw ⇒ info.nbDraw.some + case Win ⇒ info.user.nbWins.some + case Loss ⇒ info.user.nbLosses.some + case Draw ⇒ info.user.nbDraws.some case _ ⇒ None } diff --git a/app/user/User.scala b/app/user/User.scala index 2440d5fcaa..720dc95a97 100644 --- a/app/user/User.scala +++ b/app/user/User.scala @@ -14,6 +14,10 @@ case class User( nbWins: Int, nbLosses: Int, nbDraws: Int, + nbWinsH: Int, // only against human opponents + nbLossesH: Int, // only against human opponents + nbDrawsH: Int, // only against human opponents + nbAi: Int, isChatBan: Boolean = false, enabled: Boolean, roles: List[String], diff --git a/app/user/UserInfo.scala b/app/user/UserInfo.scala index 87eefd5bbf..849fd5a35b 100644 --- a/app/user/UserInfo.scala +++ b/app/user/UserInfo.scala @@ -12,9 +12,6 @@ import scalaz.effects._ case class UserInfo( user: User, rank: Option[(Int, Int)], - nbWin: Int, - nbDraw: Int, - nbLoss: Int, nbPlaying: Int, nbWithMe: Option[Int], nbBookmark: Int, @@ -47,9 +44,6 @@ object UserInfo { Some(rank -> countUsers()) }, io(None)) - nbWin = user.nbWins - nbLoss = user.nbLosses - nbDraw = user.nbDraws nbPlaying ← (ctx is user).fold( gameRepo count (_ notFinished user) map (_.some), io(none) @@ -61,7 +55,7 @@ object UserInfo { nbBookmark = bookmarkApi countByUser user eloChart ← eloChartBuilder(user) winChart = (user.nbRatedGames > 0) option { - new WinChart(nbWin, nbDraw, nbLoss) + new WinChart(user.nbWinsH, user.nbDrawsH, user.nbLossesH, user.nbAi) } eloWithMe = ctx.me.filter(user!=) map { me ⇒ List( @@ -73,9 +67,6 @@ object UserInfo { } yield new UserInfo( user = user, rank = rank, - nbWin = nbWin, - nbDraw = nbDraw, - nbLoss = nbLoss, nbPlaying = nbPlaying | 0, nbWithMe = nbWithMe, nbBookmark = nbBookmark, diff --git a/app/user/WinChart.scala b/app/user/WinChart.scala index 4b744c5ead..fdfb5ed64b 100644 --- a/app/user/WinChart.scala +++ b/app/user/WinChart.scala @@ -8,7 +8,7 @@ import scalaz.effects._ import com.codahale.jerkson.Json import i18n.I18nKeys -final class WinChart(nbWin: Int, nbDraw: Int, nbLoss: Int) { +final class WinChart(nbWin: Int, nbDraw: Int, nbLoss: Int, nbAi: Int) { val columns = Json generate List( "string" :: "Result" :: Nil, @@ -18,6 +18,7 @@ final class WinChart(nbWin: Int, nbDraw: Int, nbLoss: Int) { List( List(trans.nbWins.str(nbWin), nbWin), List(trans.nbLosses.str(nbLoss), nbLoss), - List(trans.nbDraws.str(nbDraw), nbDraw)) + List(trans.nbDraws.str(nbDraw), nbDraw), + List("AI", nbAi)) } } diff --git a/app/views/user/filterTitle.scala.html b/app/views/user/filterTitle.scala.html index a324be2577..2d02e33797 100644 --- a/app/views/user/filterTitle.scala.html +++ b/app/views/user/filterTitle.scala.html @@ -11,13 +11,13 @@ case lila.user.GameFilter.Rated => { @info.nbRated @trans.rated() } case lila.user.GameFilter.Win => { -@trans.nbWins(info.nbWin) +@trans.nbWins(info.user.nbWins) } case lila.user.GameFilter.Loss => { -@trans.nbLosses(info.nbLoss) +@trans.nbLosses(info.user.nbLosses) } case lila.user.GameFilter.Draw => { -@trans.nbDraws(info.nbDraw) +@trans.nbDraws(info.user.nbDraws) } case lila.user.GameFilter.Playing => { @info.nbPlaying playing diff --git a/bin/prod/userstats.js b/bin/prod/userstats.js index bbe2f8a0ed..161644c415 100644 --- a/bin/prod/userstats.js +++ b/bin/prod/userstats.js @@ -1,9 +1,13 @@ db.user2.find({}).forEach(function(user) { var uid = user['_id']; var data = { - nbWins: db.game2.count({"winId": uid, "players.aiLevel":{$exists:false}}), - nbLosses: db.game2.count({"userIds": uid, "status": { "$in": [ 30, 31, 35, 33 ] }, "winId": {"$ne": uid}, "players.aiLevel":{$exists:false}}), - nbDraws: db.game2.count({"userIds": uid, "status": { "$in": [34, 32] }, "players.aiLevel":{$exists:false}}) + nbWins: db.game2.count({"winId": uid}), + nbLosses: db.game2.count({"userIds": uid, "status": { "$in": [ 30, 31, 35, 33 ] }, "winId": {"$ne": uid}}), + nbDraws: db.game2.count({"userIds": uid, "status": { "$in": [34, 32] }}), + nbWinsH: db.game2.count({"winId": uid, "players.aiLevel":{$exists:false}}), + nbLossesH: db.game2.count({"userIds": uid, "status": { "$in": [ 30, 31, 35, 33 ] }, "winId": {"$ne": uid}, "players.aiLevel":{$exists:false}}), + nbDrawsH: db.game2.count({"userIds": uid, "status": { "$in": [34, 32] }, "players.aiLevel":{$exists:false}}), + nbAi: db.game2.count({"userIds": uid, "players.aiLevel":{$exists:true}}) }; db.user2.update({"_id": uid}, {"$set":data}); }); diff --git a/todo b/todo index b812b00d11..c91b0cc8d3 100644 --- a/todo +++ b/todo @@ -43,4 +43,4 @@ count ai games in nb wins/losses http://en.lichess.org/@/ivym http://en.lichess. index game positions integrate with google+ elo stats -feedback changes to do http://en.lichess.org/forum/lichess-feedback/new-feature-landing-advanced-search#3 +player search autocomplete regex escapement