tournament stats WIP: model and BSON handlers

tournamentStats
Thibault Duplessis 2015-12-11 11:55:06 +07:00
parent f4adbbf49c
commit 06e7bf0e7d
5 changed files with 73 additions and 15 deletions

View File

@ -411,6 +411,7 @@ tournament {
tournament = tournament2
player = tournament_player
pairing = tournament_pairing
leaderboard = tournament_leaderboard
}
history.message.ttl = 30 seconds
uid.timeout = 7 seconds # small to avoid missed events

View File

@ -21,7 +21,7 @@ object BSONHandlers {
implicit val tournamentHandler = new BSON[Tournament] {
def reads(r: BSON.Reader) = {
val variant = r.intO("variant").fold[chess.variant.Variant](chess.variant.Variant.default)(chess.variant.Variant.orDefault)
val variant = r.intO("variant").fold[Variant](Variant.default)(Variant.orDefault)
val position = r.strO("eco").flatMap(StartingPosition.byEco) | StartingPosition.initial
val startsAt = r date "startsAt"
Tournament(
@ -120,4 +120,28 @@ object BSONHandlers {
"b1" -> w.intO(o.berserk1),
"b2" -> w.intO(o.berserk2))
}
implicit val leaderboardEntryHandler = new BSON[LeaderboardApi.Entry] {
def reads(r: BSON.Reader) = LeaderboardApi.Entry(
id = r str "_id",
userId = r str "u",
tourId = r str "t",
score = r int "s",
rank = r int "r",
freq = Schedule.Freq.byId(r int "f") err "Invalid leaderboard freq",
speed = Schedule.Speed.byId(r int "p") err "Invalid leaderboard speed",
variant = r.intO("variant").fold[Variant](Variant.default)(Variant.orDefault),
date = r date "d")
def writes(w: BSON.Writer, o: LeaderboardApi.Entry) = BSONDocument(
"_id" -> o.id,
"u" -> o.userId,
"t" -> o.tourId,
"s" -> o.score,
"r" -> o.rank,
"f" -> o.freq.id,
"p" -> o.speed.id,
"v" -> o.variant.some.filter(_.exotic).map(_.id),
"d" -> w.date(o.date))
}
}

View File

@ -30,6 +30,7 @@ final class Env(
val CollectionTournament = config getString "collection.tournament"
val CollectionPlayer = config getString "collection.player"
val CollectionPairing = config getString "collection.pairing"
val CollectionLeaderboard = config getString "collection.leaderboard"
val HistoryMessageTtl = config duration "history.message.ttl"
val CreatedCacheTtl = config duration "created.cache.ttl"
val LeaderboardCacheTtl = config duration "leaderboard.cache.ttl"
@ -82,6 +83,8 @@ final class Env(
lazy val scheduleJsonView = new ScheduleJsonView(lightUser)
lazy val leaderboardApi = new LeaderboardApi(leaderboardColl)
private val socketHub = system.actorOf(
Props(new lila.socket.SocketHubActor.Default[Socket] {
def mkActor(tournamentId: String) = new Socket(
@ -135,6 +138,7 @@ final class Env(
private[tournament] lazy val tournamentColl = db(CollectionTournament)
private[tournament] lazy val pairingColl = db(CollectionPairing)
private[tournament] lazy val playerColl = db(CollectionPlayer)
private[tournament] lazy val leaderboardColl = db(CollectionLeaderboard)
}
object Env {

View File

@ -0,0 +1,27 @@
package lila.tournament
import org.joda.time.DateTime
import reactivemongo.bson._
import scala.concurrent.duration._
import chess.variant.Variant
import lila.db.BSON._
import lila.db.Types.Coll
final class LeaderboardApi(coll: Coll) {
}
object LeaderboardApi {
case class Entry(
id: String, // same as tournament player id
userId: String,
tourId: String,
score: Int,
rank: Int,
freq: Schedule.Freq,
speed: Schedule.Speed,
variant: Variant,
date: DateTime)
}

View File

@ -31,35 +31,37 @@ case class Schedule(
object Schedule {
sealed trait Freq {
sealed abstract class Freq(val id: Int) {
val name = toString.toLowerCase
}
object Freq {
case object Hourly extends Freq
case object Daily extends Freq
case object Eastern extends Freq
case object Weekly extends Freq
case object Monthly extends Freq
case object Marathon extends Freq
case object ExperimentalMarathon extends Freq { // for DB BC
case object Hourly extends Freq(10)
case object Daily extends Freq(20)
case object Eastern extends Freq(30)
case object Weekly extends Freq(40)
case object Monthly extends Freq(50)
case object Marathon extends Freq(60)
case object ExperimentalMarathon extends Freq(61) { // for DB BC
override val name = "Experimental Marathon"
}
val all: List[Freq] = List(Hourly, Daily, Eastern, Weekly, Monthly, Marathon, ExperimentalMarathon)
def apply(name: String) = all find (_.name == name)
def byId(id: Int) = all find (_.id == id)
}
sealed trait Speed {
sealed abstract class Speed(val id: Int) {
def name = toString.toLowerCase
}
object Speed {
case object HyperBullet extends Speed
case object Bullet extends Speed
case object SuperBlitz extends Speed
case object Blitz extends Speed
case object Classical extends Speed
case object HyperBullet extends Speed(10)
case object Bullet extends Speed(20)
case object SuperBlitz extends Speed(30)
case object Blitz extends Speed(40)
case object Classical extends Speed(50)
val all: List[Speed] = List(HyperBullet, Bullet, SuperBlitz, Blitz, Classical)
val mostPopular: List[Speed] = List(Bullet, Blitz, Classical)
def apply(name: String) = all find (_.name == name)
def byId(id: Int) = all find (_.id == id)
def similar(s1: Speed, s2: Speed) = (s1, s2) match {
case (a, b) if a == b => true
case (HyperBullet, Bullet) => true