Skip to content

Commit

Permalink
Merge branch 'lichess-org:master' into patch-13
Browse files Browse the repository at this point in the history
  • Loading branch information
Carbrex authored Feb 18, 2024
2 parents c583ca2 + b54c306 commit 8cecde6
Showing 1,031 changed files with 2,340 additions and 1,962 deletions.
45 changes: 24 additions & 21 deletions app/controllers/RelayRound.scala
Original file line number Diff line number Diff line change
@@ -77,7 +77,7 @@ final class RelayRound(
BadRequest.page(html.relay.roundForm.edit(old, err)),
jsonFormError(err)
),
rt => negotiate(Redirect(rt.path), JsonOk(env.relay.jsonView.withUrl(rt)))
rt => negotiate(Redirect(rt.path), JsonOk(env.relay.jsonView.withUrl(rt, withTour = true)))
)
}
}
@@ -125,10 +125,10 @@ final class RelayRound(
}

def stream(id: RelayRoundId) = AnonOrScoped(): ctx ?=>
Found(env.relay.api.byIdWithStudy(id)): rt =>
studyC.CanView(rt.study) {
Found(env.relay.api.byIdWithStudy(id)): rs =>
studyC.CanView(rs.study) {
apiC.GlobalConcurrencyLimitPerIP
.events(req.ipAddress)(env.relay.pgnStream.streamRoundGames(rt)): source =>
.events(req.ipAddress)(env.relay.pgnStream.streamRoundGames(rs)): source =>
noProxyBuffer(Ok.chunked[PgnStr](source.keepAlive(60.seconds, () => PgnStr(" "))))
}(Unauthorized, Forbidden)

@@ -137,25 +137,28 @@ final class RelayRound(
env.study.api.byIdWithChapterOrFallback(rt.round.studyId, chapterId) orNotFound { doShow(rt, _) }

def push(id: RelayRoundId) = ScopedBody(parse.tolerantText)(Seq(_.Study.Write)) { ctx ?=> me ?=>
env.relay.api
.byIdWithStudy(id)
.flatMap:
case None => notFoundJson()
case Some(rt) if !rt.study.canContribute(me) => forbiddenJson()
case Some(rt) =>
given Writes[Tag] = Writes(tag => Json.obj(tag.name.name -> tag.value))
env.relay
.push(rt.withTour, PgnStr(ctx.body.body))
.map: results =>
JsonOk:
Json.obj:
"games" -> results.map:
_.fold(
fail => Json.obj("tags" -> fail.tags.value, "error" -> fail.error),
pass => Json.obj("tags" -> pass.tags.value, "moves" -> pass.moves)
)
Found(env.relay.api.byIdWithTourAndStudy(id)): rt =>
if !rt.study.canContribute(me) then forbiddenJson()
else
given Writes[Tag] = Writes(tag => Json.obj(tag.name.name -> tag.value))
env.relay
.push(rt.withTour, PgnStr(ctx.body.body))
.map: results =>
JsonOk:
Json.obj:
"games" -> results.map:
_.fold(
fail => Json.obj("tags" -> fail.tags.value, "error" -> fail.error),
pass => Json.obj("tags" -> pass.tags.value, "moves" -> pass.moves)
)
}

def teamsView(id: RelayRoundId) = Open:
Found(env.relay.api.byIdWithStudy(id)): rt =>
studyC.CanView(rt.study) {
env.relay.teamTable.tableJson(rt.relay) map JsonStrOk
}(Unauthorized, Forbidden)

private def WithRoundAndTour(@nowarn ts: String, @nowarn rs: String, id: RelayRoundId)(
f: RoundModel.WithTour => Fu[Result]
)(using ctx: Context): Fu[Result] =
5 changes: 3 additions & 2 deletions app/controllers/RelayTour.scala
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ import lila.app.{ given, * }
import lila.common.config.MaxPerSecond
import lila.common.{ config, IpAddress }
import lila.relay.{ RelayTour as TourModel }
import lila.common.config.Max

final class RelayTour(env: Env, apiC: => Api) extends LilaController(env):

@@ -177,8 +178,8 @@ final class RelayTour(env: Env, apiC: => Api) extends LilaController(env):
def apiIndex = Anon:
apiC.jsonDownload:
env.relay.api
.officialTourStream(MaxPerSecond(20), getInt("nb") | 20)
.map(env.relay.jsonView.apply(_, withUrls = true))
.officialTourStream(MaxPerSecond(20), Max(getInt("nb") | 20).atMost(100))
.map(env.relay.jsonView(_, withUrls = true))

private def WithTour(id: TourModel.Id)(f: TourModel => Fu[Result])(using Context): Fu[Result] =
Found(env.relay.api tourById id)(f)
16 changes: 10 additions & 6 deletions app/templating/AssetHelper.scala
Original file line number Diff line number Diff line change
@@ -63,20 +63,22 @@ if (window.matchMedia('(prefers-color-scheme: dark)').media === 'not all')
// load iife scripts in <head> and defer
def iifeModule(path: String): Frag = script(deferAttr, src := assetUrl(path))

private val loadEsmFunction = "site.asset.loadEsm"

// jsModule is esm, no defer needed
def jsModule(name: String): Frag =
script(tpe := "module", src := assetUrl(s"compiled/$name${minifiedAssets so ".min"}.js"))
def jsModuleInit(name: String)(using PageContext) =
frag(jsModule(name), embedJsUnsafeLoadThen(s"lichess.asset.loadEsm('$name')"))
frag(jsModule(name), embedJsUnsafeLoadThen(s"$loadEsmFunction('$name')"))
def jsModuleInit(name: String, text: String)(using PageContext) =
frag(jsModule(name), embedJsUnsafeLoadThen(s"lichess.asset.loadEsm('$name',{init:$text})"))
frag(jsModule(name), embedJsUnsafeLoadThen(s"$loadEsmFunction('$name',{init:$text})"))
def jsModuleInit(name: String, json: JsValue)(using PageContext): Frag =
jsModuleInit(name, safeJsonValue(json))
def jsModuleInit(name: String, text: String, nonce: lila.api.Nonce) =
frag(jsModule(name), embedJsUnsafeLoadThen(s"lichess.asset.loadEsm('$name',{init:$text})", nonce))
frag(jsModule(name), embedJsUnsafeLoadThen(s"$loadEsmFunction('$name',{init:$text})", nonce))
def jsModuleInit(name: String, json: JsValue, nonce: lila.api.Nonce) = frag(
jsModule(name),
embedJsUnsafeLoadThen(s"lichess.asset.loadEsm('$name',{init:${safeJsonValue(json)}})", nonce)
embedJsUnsafeLoadThen(s"$loadEsmFunction('$name',{init:${safeJsonValue(json)}})", nonce)
)
def analyseInit(mode: String, json: JsValue)(using ctx: PageContext) =
jsModuleInit("analysisBoard", Json.obj("mode" -> mode, "cfg" -> json))
@@ -121,8 +123,10 @@ if (window.matchMedia('(prefers-color-scheme: dark)').media === 'not all')
def embedJsUnsafe(js: String, nonce: lila.api.Nonce): Frag = raw:
s"""<script nonce="$nonce">$js</script>"""

private val onLoadFunction = "site.load.then"

def embedJsUnsafeLoadThen(js: String)(using PageContext): Frag =
embedJsUnsafe(s"""lichess.load.then(()=>{$js})""")
embedJsUnsafe(s"""$onLoadFunction(()=>{$js})""")

def embedJsUnsafeLoadThen(js: String, nonce: lila.api.Nonce): Frag =
embedJsUnsafe(s"""lichess.load.then(()=>{$js})""", nonce)
embedJsUnsafe(s"""$onLoadFunction(()=>{$js})""", nonce)
8 changes: 4 additions & 4 deletions app/views/base/layout.scala
Original file line number Diff line number Diff line change
@@ -178,7 +178,7 @@ object layout:
frag(
ctx.needsFp option fingerprintTag,
ctx.nonce map inlineJs.apply,
frag(cashTag, jsModule("lichess")),
frag(cashTag, jsModule("site")),
moreJs,
ctx.data.inquiry.isDefined option jsModule("mod.inquiry"),
ctx.pref.bg == lila.pref.Pref.Bg.SYSTEM option embedJsUnsafe(systemThemePolyfillJs)
@@ -214,8 +214,8 @@ object layout:
)

private val dataVapid = attr("data-vapid")
private val dataAltSocket = attr("data-alt-socket")
private val dataSocketDomains = attr("data-socket-domains") := netConfig.socketDomains.mkString(",")
private val dataSocketAlts = attr("data-socket-alts") := netConfig.socketAlts.mkString(",")
private val dataNonce = attr("data-nonce")
private val dataAnnounce = attr("data-announce")
val dataSoundSet = attr("data-sound-set")
@@ -309,8 +309,8 @@ object layout:
dataVapid := (ctx.isAuth && env.lilaCookie.isRememberMe(ctx.req)) option vapidPublicKey,
dataUser := ctx.userId,
dataSoundSet := pref.currentSoundSet.toString,
pref.isUsingAltSocket option (dataAltSocket := netConfig.altSocket.value),
dataSocketDomains,
pref.isUsingAltSocket option dataSocketAlts,
dataAssetUrl,
dataAssetVersion := assetVersion,
dataNonce := ctx.nonce.ifTrue(sameAssetDomain).map(_.value),
@@ -462,7 +462,7 @@ object layout:
_ =>
val qty = lila.i18n.JsQuantity(lang)
val i18n = safeJsonValue(i18nJsObject(i18nKeys))
s"""lichess={load:new Promise(r=>document.addEventListener("DOMContentLoaded",r)),quantity:$qty,siteI18n:$i18n}"""
s"""site={load:new Promise(r=>document.addEventListener("DOMContentLoaded",r)),quantity:$qty,siteI18n:$i18n}"""
)
def apply(nonce: Nonce)(using Lang) =
embedJsUnsafe(jsCode, nonce)
23 changes: 21 additions & 2 deletions app/views/relay/tourForm.scala
Original file line number Diff line number Diff line change
@@ -111,14 +111,33 @@ object tourForm:
form3.checkbox(
form("autoLeaderboard"),
automaticLeaderboard(),
help = automaticLeaderboardHelp().some,
half = true
help = automaticLeaderboardHelp().some
),
form3.checkbox(
form("teamTable"),
"Team tournament",
help = frag("Show a team leaderboard. Requires WhiteTeam and BlackTeam PGN tags.").some
)
),
form3.split(
form3.group(
form("players"),
replace(),
help = replaceHelp().some,
half = true
)(form3.textarea(_)(rows := 3)),
form3.group(
form("teams"),
"Optional: assign players to teams",
help = lila.common.String.html
.nl2br("""One line per player, formatted as such:
Team name; Player name
Example:
Offerspill;Magnus Carlsen
Stavanger;M. Fiskaaen
By default the PGN tags WhiteTeam and BlackTeam are used.""")
.some,
half = true
)(form3.textarea(_)(rows := 3))
),
if isGranted(_.Relay) then
6 changes: 3 additions & 3 deletions app/views/simul/home.scala
Original file line number Diff line number Diff line change
@@ -16,11 +16,11 @@ object home:
views.html.base.layout(
moreCss = cssTag("simul.list"),
moreJs = embedJsUnsafeLoadThen(s"""
lichess.StrongSocket.defaultParams.flag = 'simul';
lichess.pubsub.on('socket.in.reload', () =>
site.StrongSocket.defaultParams.flag = 'simul';
site.pubsub.on('socket.in.reload', () =>
fetch('${routes.Simul.homeReload}').then(r => r.text()).then(html => {
$$('.simul-list__content').html(html);
lichess.contentLoaded();
site.contentLoaded();
}))"""),
title = trans.simultaneousExhibitions.txt(),
openGraph = lila.app.ui
8 changes: 4 additions & 4 deletions app/views/site/page.scala
Original file line number Diff line number Diff line change
@@ -39,10 +39,10 @@ if (this.innerText == 'YES') this.style.color = 'green'; else if (this.innerText
moreCss = cssTag("source"),
contentCls = "page force-ltr",
moreJs = embedJsUnsafeLoadThen:
"""$('#asset-version-date').text(lichess.info.date);
$('#asset-version-commit').attr('href', 'https://github.com/lichess-org/lila/commits/' + lichess.info.commit).find('pre').text(lichess.info.commit.substr(0, 7));
$('#asset-version-upcoming').attr('href', 'https://github.com/lichess-org/lila/compare/' + lichess.info.commit + '...master').find('pre').text('...');
$('#asset-version-message').text(lichess.info.message);"""
"""$('#asset-version-date').text(site.info.date);
$('#asset-version-commit').attr('href', 'https://github.com/lichess-org/lila/commits/' + site.info.commit).find('pre').text(site.info.commit.substr(0, 7));
$('#asset-version-upcoming').attr('href', 'https://github.com/lichess-org/lila/compare/' + site.info.commit + '...master').find('pre').text('...');
$('#asset-version-message').text(site.info.message);"""
):
val commit = env.appVersionCommit | "???"
frag(
10 changes: 5 additions & 5 deletions conf/base.conf
Original file line number Diff line number Diff line change
@@ -13,8 +13,8 @@ mongodb {
}
net {
domain = "localhost:9663"
socket.domains = [ "localhost:9664" ]
socket.alternate = ""
socket.domains = ["localhost:9664"]
socket.alts = []
asset.domain = ${net.domain}
asset.base_url = "http://"${net.asset.domain}
asset.base_url_internal = ${net.asset.base_url}
@@ -485,9 +485,9 @@ kamon {
}
prometheus {
buckets {
default-buckets = [ 10, 100, 1000, 10000, 100000 ]
time-buckets = [ 0.01, 0.05, 0.1, 0.5, 1, 5, 10 ]
information-buckets = [ 512, 2048, 16384, 524288, ]
default-buckets = [10, 100, 1000, 10000, 100000]
time-buckets = [0.01, 0.05, 0.1, 0.5, 1, 5, 10]
information-buckets = [512, 2048, 16384, 524288]
}
}
modules {
1 change: 1 addition & 0 deletions conf/routes
Original file line number Diff line number Diff line change
@@ -267,6 +267,7 @@ POST /broadcast/round/$roundId<\w{8}>/reset controllers.RelayRound.reset(round
POST /broadcast/round/$roundId<\w{8}>/push controllers.RelayRound.push(roundId)
POST /api/broadcast/round/$roundId<\w{8}>/push controllers.RelayRound.push(roundId)
GET /broadcast/:ts/:rs/$roundId<\w{8}>.pgn controllers.RelayRound.pgn(ts, rs, roundId)
GET /broadcast/$roundId<\w{8}>/teams controllers.RelayRound.teamsView(roundId)
GET /api/broadcast/round/$roundId<\w{8}>.pgn controllers.RelayRound.apiPgn(roundId)
GET /api/stream/broadcast/round/$roundId<\w{8}>.pgn controllers.RelayRound.stream(roundId)
GET /api/broadcast controllers.RelayTour.apiIndex
2 changes: 1 addition & 1 deletion modules/common/src/main/config.scala
Original file line number Diff line number Diff line change
@@ -74,7 +74,7 @@ object config:
@ConfigName("stage.banner") stageBanner: Boolean,
@ConfigName("site.name") siteName: String,
@ConfigName("socket.domains") socketDomains: List[String],
@ConfigName("socket.alternate") altSocket: NetDomain,
@ConfigName("socket.alts") socketAlts: List[String],
crawlable: Boolean,
@ConfigName("ratelimit") rateLimit: RateLimit,
email: EmailAddress
1 change: 0 additions & 1 deletion modules/i18n/src/main/I18nKeys.scala
Original file line number Diff line number Diff line change
@@ -1840,7 +1840,6 @@ object I18nKeys:
val `longestStreak` = I18nKey("perfStat:longestStreak")
val `currentStreak` = I18nKey("perfStat:currentStreak")
val `bestRated` = I18nKey("perfStat:bestRated")
val `worstRated` = I18nKey("perfStat:worstRated")
val `gamesInARow` = I18nKey("perfStat:gamesInARow")
val `lessThanOneHour` = I18nKey("perfStat:lessThanOneHour")
val `maxTimePlaying` = I18nKey("perfStat:maxTimePlaying")
3 changes: 2 additions & 1 deletion modules/relay/src/main/BSONHandlers.scala
Original file line number Diff line number Diff line change
@@ -6,7 +6,8 @@ import lila.db.dsl.{ *, given }

object BSONHandlers:

given BSONHandler[RelayPlayers] = stringAnyValHandler(_.text, RelayPlayers.apply)
given BSONHandler[RelayPlayers] = stringAnyValHandler(_.text, RelayPlayers(_))
given BSONHandler[RelayTeams] = stringAnyValHandler(_.text, RelayTeams(_))

import RelayRound.Sync
import Sync.{ Upstream, UpstreamIds, UpstreamUrl }
9 changes: 3 additions & 6 deletions modules/relay/src/main/Env.scala
Original file line number Diff line number Diff line change
@@ -30,12 +30,7 @@ final class Env(
notifyApi: lila.notify.NotifyApi,
picfitApi: lila.memo.PicfitApi,
picfitUrl: lila.memo.PicfitUrl
)(using
ec: Executor,
system: ActorSystem,
scheduler: Scheduler,
materializer: akka.stream.Materializer
):
)(using Executor, ActorSystem, akka.stream.Materializer)(using scheduler: Scheduler):

lazy val roundForm = wire[RelayRoundForm]

@@ -65,6 +60,8 @@ final class Env(

lazy val pgnStream = wire[RelayPgnStream]

lazy val teamTable = wire[RelayTeamTable]

private lazy val sync = wire[RelaySync]

private lazy val formatApi = wire[RelayFormatApi]
20 changes: 9 additions & 11 deletions modules/relay/src/main/JsonView.scala
Original file line number Diff line number Diff line change
@@ -51,18 +51,18 @@ final class JsonView(
"tour" -> Json
.toJsObject(trs.tour)
.add("markup" -> trs.tour.markup.map(markup(trs.tour)))
.add("url" -> withUrls.option(s"$baseUrl${trs.tour.path}")),
.add("url" -> withUrls.option(s"$baseUrl${trs.tour.path}"))
.add("teamTable" -> trs.tour.teamTable),
"rounds" -> trs.rounds.map: round =>
if withUrls then withUrl(round withTour trs.tour) else apply(round)
if withUrls then withUrl(round withTour trs.tour, withTour = false) else apply(round)
)

def apply(round: RelayRound): JsObject = Json.toJsObject(round)

def withUrl(rt: RelayRound.WithTour): JsObject =
apply(rt.round) ++ Json.obj(
"tour" -> rt.tour,
"url" -> s"$baseUrl${rt.path}"
)
def withUrl(rt: RelayRound.WithTour, withTour: Boolean): JsObject =
apply(rt.round) ++ Json
.obj("url" -> s"$baseUrl${rt.path}")
.add("tour" -> withTour.option(rt.tour))

def withUrlAndGames(rt: RelayRound.WithTourAndStudy, games: List[Chapter.Metadata])(using
Option[Me]
@@ -89,7 +89,7 @@ final class JsonView(
studyData: lila.study.JsonView.JsData,
canContribute: Boolean,
isSubscribed: Option[Boolean] = none[Boolean]
) = leaderboardApi(trs.tour) map { leaderboard =>
) = leaderboardApi(trs.tour) map: leaderboard =>
JsonView.JsData(
relay = apply(trs)
.add("sync" -> (canContribute so trs.rounds.find(_.id == currentRoundId).map(_.sync)))
@@ -98,15 +98,14 @@ final class JsonView(
study = studyData.study,
analysis = studyData.analysis
)
}

object JsonView:

case class JsData(relay: JsObject, study: JsObject, analysis: JsObject)

given OWrites[SyncLog.Event] = Json.writes

private given OWrites[RelayRound.Sync] = OWrites { s =>
private given OWrites[RelayRound.Sync] = OWrites: s =>
Json
.obj(
"ongoing" -> s.ongoing,
@@ -117,4 +116,3 @@ object JsonView:
case url: RelayRound.Sync.UpstreamUrl => Json.obj("url" -> url.withRound.url)
case RelayRound.Sync.UpstreamIds(ids) => Json.obj("ids" -> ids)
}
}
Loading

0 comments on commit 8cecde6

Please sign in to comment.