lila/modules/insight/src/main/InsightApi.scala

77 lines
2.2 KiB
Scala
Raw Normal View History

2015-11-26 21:05:59 -07:00
package lila.insight
2015-11-24 23:49:13 -07:00
import org.joda.time.DateTime
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._
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,
userCacheApi: UserCacheApi,
pipeline: AggregationPipeline,
notifier: Notifier,
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
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
}
}
def indexAll(user: User) = lila.common.Chronometer.result {
indexer.all(user) >> userCacheApi.remove(user.id)
} map {
case (result, millis) =>
if (millis > 1000 * 60 * 2) notifier dataIsReady user
result
}
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
}
}