Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions app/controllers/RelayRound.scala
Original file line number Diff line number Diff line change
Expand Up @@ -151,17 +151,19 @@ final class RelayRound(
)

private def doApiShow(id: RelayRoundId)(using Context): Fu[Result] =
Found(env.relay.api.byIdWithTour(id)): rt =>
Found(env.study.studyRepo.byId(rt.round.studyId)): study =>
studyC.CanView(study)(
for
group <- env.relay.api.withTours.get(rt.tour.id)
previews <- env.study.preview.jsonList.withoutInitialEmpty(study.id)
targetRound <- env.relay.api.officialTarget(rt.round)
yield JsonOk(
env.relay.jsonView.withUrlAndPreviews(rt.withStudy(study), previews, group, targetRound)
)
)(studyC.privateUnauthorizedJson, studyC.privateForbiddenJson)
Found(env.relay.api.byIdWithTour(id))(doApiShow)

def doApiShow(rt: RoundModel.WithTour)(using Context): Fu[Result] =
Found(env.study.studyRepo.byId(rt.round.studyId)): study =>
studyC.CanView(study)(
for
group <- env.relay.api.withTours.get(rt.tour.id)
previews <- env.study.preview.jsonList.withoutInitialEmpty(study.id)
targetRound <- env.relay.api.officialTarget(rt.round)
yield JsonOk(
env.relay.jsonView.withUrlAndPreviews(rt.withStudy(study), previews, group, targetRound)
)
)(studyC.privateUnauthorizedJson, studyC.privateForbiddenJson)

def pgn(ts: String, rs: String, id: RelayRoundId) = Open:
pgnWithFlags(ts, rs, id)
Expand Down
15 changes: 12 additions & 3 deletions app/controllers/RelayTour.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ final class RelayTour(env: Env, apiC: => Api, roundC: => RelayRound) extends Lil
Found(env.user.lightUser(owner.id)): owner =>
env.relay.pager
.byOwner(owner.id, page)
.map(_.mapResults(env.relay.jsonView(_)))
.map(_.mapResults(env.relay.jsonView.tourWithAnyRound(_)))
.map(JsonOk(_))

def subscribed(page: Int) = Auth { ctx ?=> me ?=>
Expand Down Expand Up @@ -139,9 +139,9 @@ final class RelayTour(env: Env, apiC: => Api, roundC: => RelayRound) extends Lil
case None => env.relay.api.image.delete(nav.tour, tag) >> Ok
}

def leaderboardView(id: RelayTourId) = Open:
def playersView(id: RelayTourId) = Open:
WithTour(id): tour =>
tour.autoLeaderboard.so(env.relay.leaderboard(tour)).map(_.fold(notFoundJson())(JsonStrOk))
env.relay.playerApi.jsonList(tour.id).map(JsonStrOk)

def subscribe(id: RelayTourId, isSubscribed: Boolean) = Auth { _ ?=> me ?=>
env.relay.api.subscribe(id, me.userId, isSubscribed).inject(jsonOkResult)
Expand Down Expand Up @@ -210,6 +210,15 @@ final class RelayTour(env: Env, apiC: => Api, roundC: => RelayRound) extends Lil
res <- JsonOk(env.relay.jsonView.top(active, upcoming, past))
yield res

def defaultRound(id: RelayTourId) = Anon:
Found(env.relay.api.tourById(id)): tour =>
Found(env.relay.listing.defaultRoundToShow.get(tour.id)): round =>
roundC.doApiShow(round.withTour(tour))

def player(tourId: RelayTourId, id: String) = Anon:
Found(env.relay.api.tourById(tourId)): tour =>
Found(env.relay.playerApi.player(tour.id, id))(JsonOk)

private given (using RequestHeader): JsonView.Config = JsonView.Config(html = getBool("html"))

private def WithTour(id: RelayTourId)(f: TourModel => Fu[Result])(using Context): Fu[Result] =
Expand Down
5 changes: 3 additions & 2 deletions app/controllers/Study.scala
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,9 @@ final class Study(
jsonFormError,
data =>
doImportPgn(id, data, Sri("api")): chapters =>
import lila.study.ChapterPreview.json.write
JsonOk(Json.obj("chapters" -> write(chapters.map(_.preview))(using Map.empty)))
import lila.study.ChapterPreview.json.given
val previews = chapters.map(env.study.preview.fromChapter(_)(using Map.empty))
JsonOk(Json.obj("chapters" -> previews))
)
}

Expand Down
4 changes: 3 additions & 1 deletion conf/routes
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ GET /broadcast/:ts/$id<\w{8}> controllers.RelayTour.show(ts, id:
GET /embed/broadcast/:ts/$id<\w{8}> controllers.RelayTour.embedShow(ts, id: RelayTourId)
GET /api/broadcast/$id<\w{8}> controllers.RelayTour.apiShow(id: RelayTourId)
GET /api/broadcast/$tourId<\w{8}>.pgn controllers.RelayTour.pgn(tourId: RelayTourId)
GET /api/broadcast/$tourId<\w{8}>/default-round controllers.RelayTour.defaultRound(tourId: RelayTourId)
GET /broadcast/$tourId<\w{8}>/edit controllers.RelayTour.edit(tourId: RelayTourId)
POST /broadcast/$tourId<\w{8}>/edit controllers.RelayTour.update(tourId: RelayTourId)
POST /broadcast/$tourId<\w{8}>/delete controllers.RelayTour.delete(tourId: RelayTourId)
Expand All @@ -272,6 +273,8 @@ POST /broadcast/$tourId<\w{8}>/clone controllers.RelayTour.cloneTour(to
POST /broadcast/$tourId<\w{8}>/subscribe controllers.RelayTour.subscribe(tourId: RelayTourId, set: Boolean)
GET /broadcast/$tourId<\w{8}>/new controllers.RelayRound.form(tourId: RelayTourId)
POST /broadcast/$tourId<\w{8}>/new controllers.RelayRound.create(tourId: RelayTourId)
GET /broadcast/$tourId<\w{8}>/players controllers.RelayTour.playersView(tourId: RelayTourId)
GET /broadcast/$tourId<\w{8}>/players/:id controllers.RelayTour.player(tourId: RelayTourId, id: String)
GET /broadcast/:ts/:rs/$roundId<\w{8}> controllers.RelayRound.show(ts, rs, roundId: RelayRoundId, embed: Option[String] ?= None)
GET /api/broadcast/:ts/:rs/$roundId<\w{8}> controllers.RelayRound.apiShow(ts, rs, roundId: RelayRoundId)
GET /embed/broadcast/:ts/:rs/$roundId<\w{8}> controllers.RelayRound.embedShow(ts, rs, roundId: RelayRoundId)
Expand All @@ -285,7 +288,6 @@ GET /broadcast/round/$roundId<\w{8}>/stats controllers.RelayRound.stats(round
POST /api/broadcast/round/$roundId<\w{8}>/push controllers.RelayRound.push(roundId: RelayRoundId)
GET /broadcast/:ts/:rs/$roundId<\w{8}>.pgn controllers.RelayRound.pgn(ts, rs, roundId: RelayRoundId)
GET /broadcast/$roundId<\w{8}>/teams controllers.RelayRound.teamsView(roundId: RelayRoundId)
GET /broadcast/$tourId<\w{8}>/leaderboard controllers.RelayTour.leaderboardView(tourId: RelayTourId)
GET /api/broadcast/round/$roundId<\w{8}>.pgn controllers.RelayRound.apiPgn(roundId: RelayRoundId)
GET /api/stream/broadcast/round/$roundId<\w{8}>.pgn controllers.RelayRound.stream(roundId: RelayRoundId)
GET /api/broadcast controllers.RelayTour.apiIndex
Expand Down
6 changes: 4 additions & 2 deletions modules/core/src/main/fide.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package lila.core
package fide

import _root_.chess.{ FideId, PlayerName, PlayerTitle }
import _root_.chess.{ FideId, PlayerName, PlayerTitle, Elo }

enum FideTC:
case standard, rapid, blitz
Expand All @@ -23,10 +23,12 @@ trait Player:
def name: PlayerName
def fed: Option[Federation.Id]
def title: Option[PlayerTitle]
def ratingOf(tc: FideTC): Option[Int]
def ratingOf(tc: FideTC): Option[Elo]
def kFactorOf(tc: FideTC): Int

type PlayerToken = String
type GuessPlayer = (Option[FideId], Option[PlayerName], Option[PlayerTitle]) => Fu[Option[Player]]
type GetPlayer = FideId => Fu[Option[Player]]

type Tokenize = String => PlayerToken

Expand Down
1 change: 1 addition & 0 deletions modules/fide/src/main/Env.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ final class Env(db: lila.db.Db, cacheApi: CacheApi, ws: StandaloneWSClient)(usin
def federationNamesOf: hub.Federation.NamesOf = playerApi.federationNamesOf
def tokenize: hub.Tokenize = FidePlayer.tokenize
def guessPlayer: hub.GuessPlayer = playerApi.guessPlayer.apply
def getPlayer: hub.GetPlayer = playerApi.get

private lazy val fideSync = wire[FidePlayerSync]

Expand Down
19 changes: 14 additions & 5 deletions modules/fide/src/main/FidePlayer.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package lila.fide

import chess.{ FideId, PlayerName, PlayerTitle }
import chess.{ FideId, PlayerName, PlayerTitle, Elo }
import reactivemongo.api.bson.Macros.Annotations.Key

import java.text.Normalizer
Expand All @@ -13,22 +13,29 @@ case class FidePlayer(
token: PlayerToken,
fed: Option[lila.core.fide.Federation.Id],
title: Option[PlayerTitle],
standard: Option[Int],
standard: Option[Elo],
standardK: Option[Int],
rapid: Option[Int],
rapid: Option[Elo],
rapidK: Option[Int],
blitz: Option[Int],
blitz: Option[Elo],
blitzK: Option[Int],
year: Option[Int],
inactive: Option[Boolean],
fetchedAt: Instant
) extends lila.core.fide.Player:

def ratingOf(tc: FideTC): Option[Int] = tc match
def ratingOf(tc: FideTC): Option[Elo] = tc match
case FideTC.standard => standard
case FideTC.rapid => rapid
case FideTC.blitz => blitz

def kFactorOf(tc: FideTC): Int = tc
.match
case FideTC.standard => standardK
case FideTC.rapid => rapidK
case FideTC.blitz => blitzK
.|(FidePlayer.defaultKFactor)

def slug: String = FidePlayer.slugify(name)

def age: Option[Int] = year.map(nowInstant.date.getYear - _)
Expand All @@ -43,6 +50,8 @@ case class FidePlayer(

object FidePlayer:

private val defaultKFactor = 40

private[fide] val tokenize: Tokenize =
val nonLetterRegex = """[^a-zA-Z0-9\s]+""".r
val splitRegex = """\W""".r
Expand Down
4 changes: 3 additions & 1 deletion modules/fide/src/main/FidePlayerApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ final class FidePlayerApi(repo: FideRepo, cacheApi: lila.memo.CacheApi)(using Ex
.map: players =>
lila.fide.Federation.namesByIds(players.values.flatMap(_.flatMap(_.fed)))

private val idToPlayerCache = cacheApi[FideId, Option[FidePlayer]](1024, "player.fidePlayer.byId"):
private val idToPlayerCache = cacheApi[FideId, Option[FidePlayer]](4096, "player.fidePlayer.byId"):
_.expireAfterWrite(3.minutes).buildAsyncFuture(repo.player.fetch)

export idToPlayerCache.get

def urlToTitle(url: String): Fu[Option[PlayerTitle]] =
FideWebsite.urlToFideId(url).so(fetch).map(_.flatMap(_.title))

Expand Down
4 changes: 2 additions & 2 deletions modules/fide/src/main/FidePlayerSync.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package lila.fide

import akka.stream.contrib.ZipInputStreamSource
import akka.stream.scaladsl.*
import chess.{ FideId, PlayerName, PlayerTitle }
import chess.{ FideId, PlayerName, PlayerTitle, Elo }
import play.api.libs.ws.StandaloneWSClient
import reactivemongo.api.bson.*

Expand Down Expand Up @@ -132,7 +132,7 @@ final private class FidePlayerSync(repo: FideRepo, ws: StandaloneWSClient)(using
private def parseLine(line: String): Option[FidePlayer] =
def string(start: Int, end: Int) = line.substring(start, end).trim.some.filter(_.nonEmpty)
def number(start: Int, end: Int) = string(start, end).flatMap(_.toIntOption)
def rating(start: Int) = number(start, start + 4).filter(_ >= 1400)
def rating(start: Int) = Elo.from(number(start, start + 4).filter(_ >= 1400))
def kFactor(start: Int) = number(start, start + 2).filter(_ > 0)
for
id <- number(0, 15)
Expand Down
5 changes: 4 additions & 1 deletion modules/practice/src/main/PracticeApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ final class PracticeApi(
publishedChapters = chapters.filterNot: c =>
PracticeStructure.isChapterNameCommented(c.name)
if publishedChapters.exists(_.id == sc.chapter.id)
previews = ChapterPreview.json.write(publishedChapters)(using Map.empty)
previews =
import ChapterPreview.json.given
import play.api.libs.json.Json
Json.toJson(publishedChapters)
yield UserStudy(up, practiceStudy, previews, sc, section)

object config:
Expand Down
10 changes: 4 additions & 6 deletions modules/relay/src/main/Env.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ final class Env(
gameProxy: lila.core.game.GameProxy,
federations: lila.core.fide.Federation.FedsOf,
guessPlayer: lila.core.fide.GuessPlayer,
getPlayer: lila.core.fide.GetPlayer,
cacheApi: lila.memo.CacheApi,
settingStore: SettingStore.Builder,
irc: lila.core.irc.IrcApi,
Expand All @@ -40,7 +41,6 @@ final class Env(
)(using Executor, ActorSystem, akka.stream.Materializer, play.api.Mode, lila.core.i18n.Translator)(using
scheduler: Scheduler
):

lazy val roundForm = wire[RelayRoundForm]

lazy val tourForm = wire[RelayTourForm]
Expand All @@ -53,9 +53,7 @@ final class Env(

private lazy val groupRepo = RelayGroupRepo(colls.group)

lazy val leaderboard = wire[RelayLeaderboardApi]

private lazy val playersApi = wire[RelayPlayersApi]
private lazy val playerEnrich = wire[RelayPlayerEnrich]

private lazy val notifyAdmin = wire[RelayNotifierAdmin]

Expand All @@ -67,8 +65,6 @@ final class Env(

lazy val stats = wire[RelayStatsApi]

private lazy val playersUpdate = wire[RelayPlayersUpdate]

lazy val api: RelayApi = wire[RelayApi]

lazy val tourStream: RelayTourStream = wire[RelayTourStream]
Expand All @@ -85,6 +81,8 @@ final class Env(

lazy val playerTour = wire[RelayPlayerTour]

lazy val playerApi = wire[RelayPlayerApi]

def top(page: Int): Fu[(List[ActiveWithSomeRounds], List[WithLastRound], Paginator[WithLastRound])] = for
active <- (page == 1).so(listing.active.get({}))
upcoming <- (page == 1).so(listing.upcoming.get({}))
Expand Down
15 changes: 5 additions & 10 deletions modules/relay/src/main/JsonView.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,7 @@ import lila.memo.PicfitUrl
import lila.relay.RelayTour.{ ActiveWithSomeRounds, WithLastRound, WithRounds }
import lila.study.ChapterPreview

final class JsonView(
baseUrl: BaseUrl,
markup: RelayMarkup,
leaderboardApi: RelayLeaderboardApi,
picfitUrl: PicfitUrl
)(using Executor):
final class JsonView(baseUrl: BaseUrl, markup: RelayMarkup, picfitUrl: PicfitUrl)(using Executor):

import JsonView.{ Config, given }

Expand Down Expand Up @@ -68,7 +63,7 @@ final class JsonView(
)
.add("group" -> group)

def apply(t: RelayTour | WithLastRound | ActiveWithSomeRounds)(using Config): JsObject = t match
def tourWithAnyRound(t: RelayTour | WithLastRound | ActiveWithSomeRounds)(using Config): JsObject = t match
case tour: RelayTour => Json.obj("tour" -> fullTour(tour))
case tr: WithLastRound =>
Json
Expand Down Expand Up @@ -143,9 +138,9 @@ final class JsonView(
past: Paginator[WithLastRound]
)(using Config) =
Json.obj(
"active" -> active.sortBy(t => -(~t.tour.tier)).map(apply(_)),
"upcoming" -> upcoming.map(apply(_)),
"past" -> paginatorWriteNoNbResults.writes(past.map(apply(_)))
"active" -> active.sortBy(t => -(~t.tour.tier)).map(tourWithAnyRound(_)),
"upcoming" -> upcoming.map(tourWithAnyRound(_)),
"past" -> paginatorWriteNoNbResults.writes(past.map(tourWithAnyRound(_)))
)

object JsonView:
Expand Down
12 changes: 6 additions & 6 deletions modules/relay/src/main/RelayApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ final class RelayApi(
roundRepo: RelayRoundRepo,
tourRepo: RelayTourRepo,
groupRepo: RelayGroupRepo,
playersUpdate: RelayPlayersUpdate,
playerEnrich: RelayPlayerEnrich,
studyApi: StudyApi,
studyRepo: StudyRepo,
jsonView: JsonView,
formatApi: RelayFormatApi,
cacheApi: CacheApi,
leaderboard: RelayLeaderboardApi,
players: RelayPlayerApi,
picfitApi: PicfitApi
)(using Executor, akka.stream.Materializer, play.api.Mode):

Expand Down Expand Up @@ -230,9 +230,9 @@ final class RelayApi(
)
)
_ <- data.grouping.so(updateGrouping(tour, _))
_ <- playersUpdate(tour, prev)
_ <- playerEnrich.onPlayerTextareaUpdate(tour, prev)
yield
leaderboard.invalidate(tour.id)
players.invalidate(tour.id)
(tour.id :: data.grouping.so(_.tourIds)).foreach(withTours.invalidate)

private def updateGrouping(tour: RelayTour, data: RelayGroup.form.Data)(using me: Me): Funit =
Expand Down Expand Up @@ -352,7 +352,7 @@ final class RelayApi(
_ <- old.hasStartedEarly.so:
roundRepo.coll.unsetField($id(relay.id), "startedAt").void
_ <- roundRepo.coll.update.one($id(relay.id), $set("sync.log" -> $arr()))
yield leaderboard.invalidate(relay.tourId)
yield players.invalidate(relay.tourId)
} >> requestPlay(old.id, v = true)

def deleteRound(roundId: RelayRoundId): Fu[Option[RelayTour]] =
Expand All @@ -367,7 +367,7 @@ final class RelayApi(
.so:
for
_ <- tourRepo.delete(tour)
rounds <- roundRepo.idsByTourOrdered(tour)
rounds <- roundRepo.idsByTourOrdered(tour.id)
_ <- roundRepo.deleteByTour(tour)
_ <- rounds.map(_.into(StudyId)).sequentiallyVoid(studyApi.deleteById)
yield true
Expand Down
4 changes: 2 additions & 2 deletions modules/relay/src/main/RelayFetch.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ final private class RelayFetch(
pgnDump: PgnDump,
gameProxy: lila.core.game.GameProxy,
cacheApi: CacheApi,
playersApi: RelayPlayersApi,
playerEnrich: RelayPlayerEnrich,
notifyAdmin: RelayNotifierAdmin,
onlyIds: Option[List[RelayTourId]] = None
)(using Executor, Scheduler, lila.core.i18n.Translator)(using mode: play.api.Mode):
Expand Down Expand Up @@ -88,7 +88,7 @@ final private class RelayFetch(
_ = lila.mon.relay.games(rt.tour.official, rt.tour.id, rt.round.slug).update(allGamesInSource.size)
filtered = RelayGame.filter(rt.round.sync.onlyRound)(allGamesInSource)
sliced = RelayGame.Slices.filter(~rt.round.sync.slices)(filtered)
withPlayers <- playersApi.updateAndReportAmbiguous(rt)(sliced)
withPlayers <- playerEnrich.enrichAndReportAmbiguous(rt)(sliced)
enriched <- fidePlayers.enrichGames(rt.tour)(withPlayers)
withTeams = rt.tour.teams.fold(enriched)(_.update(enriched))
res <- sync
Expand Down
Loading