Skip to content

Commit

Permalink
List tours for longer and include user tours
Browse files Browse the repository at this point in the history
  • Loading branch information
WandererXII committed Jun 27, 2024
1 parent a7ce81d commit 3fa373e
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 55 deletions.
4 changes: 2 additions & 2 deletions modules/tournament/src/main/Cached.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ final private[tournament] class Cached(

val nameCache = cacheApi.sync[(Tournament.ID, Lang), Option[String]](
name = "tournament.name",
initialCapacity = 8192,
initialCapacity = 4096,
compute = { case (id, lang) =>
tournamentRepo byId id dmap2 { _.name()(lang) }
},
Expand All @@ -29,7 +29,7 @@ final private[tournament] class Cached(
)

val onHomepage = cacheApi.unit[List[Tournament]] {
_.refreshAfterWrite(2 seconds)
_.refreshAfterWrite(10 seconds)
.buildAsyncFuture(_ => tournamentRepo.onHomepage)
}

Expand Down
51 changes: 29 additions & 22 deletions modules/tournament/src/main/Spotlight.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package lila.tournament

import lila.user.User

import org.joda.time.DateTime

case class Spotlight(
headline: String,
description: String,
Expand All @@ -15,40 +17,45 @@ object Spotlight {
import Schedule.Freq._

def select(tours: List[Tournament], user: Option[User], max: Int): List[Tournament] =
user.fold(sort(tours) take max) { select(tours, _, max) }

def select(tours: List[Tournament], user: User, max: Int): List[Tournament] =
sort(tours.filter { select(_, user) }) take max
sort(filter(tours, user)) take max

private def sort(tours: List[Tournament]) =
tours.sortBy { t =>
-(t.schedule.??(_.freq.importance))
-t.nbPlayers
}

private def select(tour: Tournament, user: User): Boolean =
!tour.isFinished &&
tour.spotlight.fold(automatically(tour, user)) { manually(tour, _) }
private def filter(tours: List[Tournament], user: Option[User]) =
tours.filter { t =>
!t.isFinished && user.fold(true)(validVariant(t, _)) && t.spotlight.fold(
automatically(t, user.isDefined)
)(
manually(t, _)
)
}

private def manually(tour: Tournament, spotlight: Spotlight): Boolean =
spotlight.homepageHours.exists { hours =>
tour.startsAt.minusHours(hours).isBeforeNow
}

private def automatically(tour: Tournament, user: User): Boolean =
tour.perfType ?? { pt =>
tour.schedule ?? { sched =>
def playedSinceWeeks(weeks: Int) =
user.perfs(pt).latest ?? { l =>
l.plusWeeks(weeks).isAfterNow
}
sched.freq match {
case Hourly => playedSinceWeeks(4)
case Daily | Eastern => true
case Weekly | Weekend => true
case Unique => true
case Monthly | Shield | Marathon | Yearly => true
case _ => false
private def automatically(tour: Tournament, isAnon: Boolean): Boolean =
tour.schedule.fold(!isAnon && tour.popular) { schedule =>
tour.startsAt isBefore DateTime.now.plusMinutes {
schedule.freq match {
case Unique | Yearly | Marathon => 3 * 24 * 60
case Monthly | Shield => 36 * 60
case Weekly | Weekend => 6 * 60
case Daily => 2 * 60
case _ => 30
}
}
}

private def validVariant(tour: Tournament, user: User): Boolean =
tour.variant.standard || tour.perfType ?? { pt =>
user.perfs(pt).latest ?? { l =>
l.plusWeeks(4).isAfterNow
}
}

}
2 changes: 2 additions & 0 deletions modules/tournament/src/main/Tournament.scala
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ case class Tournament(
case _ => false
}

def popular = nbPlayers > 3

def speed = Speed(clock)

def perfType: Option[PerfType] = PerfPicker.perfType(speed, variant, none)
Expand Down
8 changes: 4 additions & 4 deletions modules/tournament/src/main/TournamentApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -622,18 +622,18 @@ final class TournamentApi(

def notableFinished = cached.notableFinishedCache.get {}

private def scheduledCreatedAndStarted =
tournamentRepo.scheduledCreated(6 * 60) zip tournamentRepo.scheduledStarted
private def createdAndStarted =
tournamentRepo.created(8 * 60) zip tournamentRepo.started

// when loading /tournament
def fetchVisibleTournaments: Fu[VisibleTournaments] =
scheduledCreatedAndStarted zip notableFinished map { case ((created, started), finished) =>
createdAndStarted zip notableFinished map { case ((created, started), finished) =>
VisibleTournaments(created, started, finished)
}

// when updating /tournament
def fetchUpdateTournaments: Fu[VisibleTournaments] =
scheduledCreatedAndStarted dmap { case (created, started) =>
createdAndStarted dmap { case (created, started) =>
VisibleTournaments(created, started, Nil)
}

Expand Down
38 changes: 11 additions & 27 deletions modules/tournament/src/main/TournamentRepo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ final class TournamentRepo(val coll: Coll, playerCollName: CollName)(implicit

private[tournament] def notableFinished(limit: Int): Fu[List[Tournament]] =
coll.ext
.find(finishedSelect ++ scheduledSelect)
.find(finishedSelect)
.sort($sort desc "startsAt")
.cursor[Tournament]()
.list(limit)
Expand Down Expand Up @@ -193,11 +193,11 @@ final class TournamentRepo(val coll: Coll, playerCollName: CollName)(implicit
createdSelect ++
$doc("startsAt" $lt (DateTime.now plusMinutes aheadMinutes))

def scheduledCreated(aheadMinutes: Int): Fu[List[Tournament]] =
coll.list[Tournament](startingSoonSelect(aheadMinutes) ++ scheduledSelect)
def created(aheadMinutes: Int, limit: Int = Int.MaxValue): Fu[List[Tournament]] =
coll.list[Tournament](startingSoonSelect(aheadMinutes), limit)

def scheduledStarted: Fu[List[Tournament]] =
coll.list[Tournament](startedSelect ++ scheduledSelect)
def started: Fu[List[Tournament]] =
coll.list[Tournament](startedSelect)

def visibleForTeams(teamIds: Seq[TeamID], aheadMinutes: Int) =
coll.list[Tournament](
Expand All @@ -215,36 +215,20 @@ final class TournamentRepo(val coll: Coll, playerCollName: CollName)(implicit
.batchSize(1)
.cursor[Tournament]()

private def scheduledStillWorthEntering: Fu[List[Tournament]] =
coll.list[Tournament](startedSelect ++ scheduledSelect) dmap {
private def startedStillWorthEntering: Fu[List[Tournament]] =
coll.list[Tournament](startedSelect) dmap {
_.filter(_.isStillWorthEntering)
}

private def canShowOnHomepage(tour: Tournament): Boolean =
tour.schedule exists { schedule =>
tour.startsAt isBefore DateTime.now.plusMinutes {
import Schedule.Freq._
val base = schedule.freq match {
case Unique => tour.spotlight.flatMap(_.homepageHours).fold(24 * 60)(60 *)
case Unique | Yearly | Marathon => 48 * 60
case Monthly | Shield => 8 * 60
case Weekly | Weekend => 4 * 60
case Daily => 2 * 60
case _ => 30
}
if (!tour.variant.standard) base / 2 else base
}
}

private[tournament] def onHomepage: Fu[List[Tournament]] =
scheduledStillWorthEntering zip scheduledCreated(crud.CrudForm.maxHomepageHours * 60) map {
startedStillWorthEntering zip created(crud.CrudForm.maxHomepageHours * 60) map {
case (started, created) =>
(started ::: created)
.sortBy(_.startsAt.getSeconds)
.foldLeft(List.empty[Tournament]) {
case (acc, tour) if !canShowOnHomepage(tour) => acc
case (acc, tour) if acc.exists(_ similarTo tour) => acc
case (acc, tour) => tour :: acc
case (acc, tour) if tour.schedule.isEmpty && !tour.popular => acc
case (acc, tour) if acc.exists(_ similarTo tour) => acc
case (acc, tour) => tour :: acc
}
.reverse
}
Expand Down

0 comments on commit 3fa373e

Please sign in to comment.