2015-11-26 21:05:59 -07:00
|
|
|
package lila.insight
|
2015-11-24 23:49:13 -07:00
|
|
|
|
2015-11-28 21:50:54 -07:00
|
|
|
import org.joda.time.DateTime
|
2015-11-26 10:03:34 -07:00
|
|
|
import reactivemongo.api.collections.bson.BSONBatchCommands.AggregationFramework._
|
2015-11-25 03:27:01 -07:00
|
|
|
import reactivemongo.bson._
|
2015-11-24 23:49:13 -07:00
|
|
|
|
2015-11-25 03:27:01 -07:00
|
|
|
import lila.db.Implicits._
|
2015-11-28 03:48:27 -07:00
|
|
|
import lila.game.{ Game, GameRepo, Pov }
|
2015-11-25 03:27:01 -07:00
|
|
|
import lila.user.User
|
|
|
|
|
2015-11-26 21:05:59 -07:00
|
|
|
final class InsightApi(
|
2015-11-26 12:12:34 -07:00
|
|
|
storage: Storage,
|
2015-11-28 21:50:54 -07:00
|
|
|
userCacheApi: UserCacheApi,
|
2015-11-28 03:48:27 -07:00
|
|
|
pipeline: AggregationPipeline,
|
2015-11-29 22:27:28 -07:00
|
|
|
notifier: Notifier,
|
2015-11-28 03:48:27 -07:00
|
|
|
indexer: Indexer) {
|
2015-11-25 03:27:01 -07:00
|
|
|
|
2015-11-26 21:05:59 -07:00
|
|
|
import lila.insight.{ Dimension => D, Metric => M }
|
|
|
|
import InsightApi._
|
2015-11-25 03:27:01 -07:00
|
|
|
|
2015-11-28 21:50:54 -07:00
|
|
|
def userCache(user: User): Fu[UserCache] = userCacheApi find user.id flatMap {
|
|
|
|
case Some(c) => fuccess(c)
|
|
|
|
case None => for {
|
|
|
|
count <- storage count user.id
|
|
|
|
ecos <- storage ecos user.id
|
|
|
|
c = UserCache(user.id, count, ecos, DateTime.now)
|
|
|
|
_ <- userCacheApi save c
|
|
|
|
} yield c
|
|
|
|
}
|
2015-11-28 07:23:47 -07:00
|
|
|
|
2015-11-26 12:12:34 -07:00
|
|
|
def ask[X](question: Question[X], user: User): Fu[Answer[X]] =
|
2015-11-29 05:59:11 -07:00
|
|
|
storage.aggregate(pipeline(question, user.id)).flatMap { res =>
|
|
|
|
val clusters = AggregationClusters(question, res)
|
|
|
|
val gameIds = scala.util.Random.shuffle(clusters.flatMap(_.gameIds)) take 4
|
|
|
|
GameRepo.userPovsByGameIds(gameIds, user) map { povs =>
|
|
|
|
Answer(question, clusters, povs)
|
|
|
|
}
|
2015-11-26 12:12:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
def userStatus(user: User): Fu[UserStatus] =
|
2015-11-28 21:57:59 -07:00
|
|
|
GameRepo lastFinishedRatedNotFromPosition user flatMap {
|
2015-11-26 12:12:34 -07:00
|
|
|
case None => fuccess(UserStatus.NoGame)
|
|
|
|
case Some(game) => storage fetchLast user map {
|
|
|
|
case None => UserStatus.Empty
|
|
|
|
case Some(entry) if entry.date isBefore game.createdAt => UserStatus.Stale
|
|
|
|
case _ => UserStatus.Fresh
|
|
|
|
}
|
2015-11-26 10:03:34 -07:00
|
|
|
}
|
2015-11-28 03:48:27 -07:00
|
|
|
|
2015-11-29 22:27:28 -07:00
|
|
|
def indexAll(user: User) = lila.common.Chronometer.result {
|
2015-11-28 21:50:54 -07:00
|
|
|
indexer.all(user) >> userCacheApi.remove(user.id)
|
2015-11-29 22:27:28 -07:00
|
|
|
} map {
|
|
|
|
case (result, millis) =>
|
|
|
|
if (millis > 1000 * 60 * 2) notifier dataIsReady user
|
|
|
|
result
|
|
|
|
}
|
2015-11-28 03:48:27 -07:00
|
|
|
|
|
|
|
def updateGame(g: Game) = Pov(g).map { pov =>
|
|
|
|
pov.player.userId ?? { userId =>
|
|
|
|
storage exists Entry.povToId(pov) flatMap {
|
|
|
|
_ ?? indexer.one(g, userId)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}.sequenceFu.void
|
2015-11-24 23:49:13 -07:00
|
|
|
}
|
2015-11-26 12:12:34 -07:00
|
|
|
|
2015-11-26 21:05:59 -07:00
|
|
|
object InsightApi {
|
2015-11-26 12:12:34 -07:00
|
|
|
|
|
|
|
sealed trait UserStatus
|
|
|
|
object UserStatus {
|
|
|
|
case object NoGame extends UserStatus
|
|
|
|
case object Empty extends UserStatus
|
|
|
|
case object Stale extends UserStatus
|
|
|
|
case object Fresh extends UserStatus
|
|
|
|
}
|
|
|
|
}
|