59 lines
1.7 KiB
Scala
59 lines
1.7 KiB
Scala
package lila.puzzle
|
|
|
|
import scala.concurrent.ExecutionContext
|
|
|
|
import lila.db.dsl._
|
|
import lila.user.User
|
|
|
|
// mobile app BC
|
|
final class PuzzleBatch(colls: PuzzleColls, anonApi: PuzzleAnon, pathApi: PuzzlePathApi)(implicit
|
|
ec: ExecutionContext
|
|
) {
|
|
|
|
import BsonHandlers._
|
|
|
|
def nextFor(user: Option[User], nb: Int): Fu[Vector[Puzzle]] = (nb > 0) ?? {
|
|
user match {
|
|
case None => anonApi.getBatchFor(nb)
|
|
case Some(user) =>
|
|
{
|
|
val tier =
|
|
if (user.perfs.puzzle.nb > 5000) PuzzleTier.Good
|
|
else PuzzleTier.Top
|
|
pathApi.nextFor(
|
|
user,
|
|
PuzzleTheme.mix.key,
|
|
tier,
|
|
PuzzleDifficulty.Normal,
|
|
Set.empty
|
|
) orFail
|
|
s"No puzzle path for ${user.id} $tier" flatMap { pathId =>
|
|
colls.path {
|
|
_.aggregateList(nb) { framework =>
|
|
import framework._
|
|
Match($id(pathId)) -> List(
|
|
Project($doc("puzzleId" -> "$ids", "_id" -> false)),
|
|
Unwind("puzzleId"),
|
|
Sample(nb),
|
|
PipelineOperator(
|
|
$lookup.simple(
|
|
from = colls.puzzle,
|
|
local = "puzzleId",
|
|
foreign = "_id",
|
|
as = "puzzle"
|
|
)
|
|
),
|
|
PipelineOperator(
|
|
$doc("$replaceWith" -> $doc("$arrayElemAt" -> $arr("$puzzle", 0)))
|
|
)
|
|
)
|
|
}.map {
|
|
_.view.flatMap(PuzzleBSONReader.readOpt).toVector
|
|
}
|
|
}
|
|
}
|
|
}.mon(_.puzzle.selector.user.batch(nb = nb))
|
|
}
|
|
}
|
|
}
|