Skip to content

Commit

Permalink
Merge branch 'master' into password-show-hide-14321
Browse files Browse the repository at this point in the history
  • Loading branch information
ornicar committed Jun 26, 2024
2 parents 8ed4e83 + 223488a commit 7770169
Show file tree
Hide file tree
Showing 92 changed files with 318 additions and 257 deletions.
1 change: 1 addition & 0 deletions app/controllers/Account.scala
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ final class Account(
me.value,
withFollows = apiC.userWithFollows,
withTrophies = false,
withCanChallenge = false,
forWiki = wikiGranted
)
.dmap { JsonOk(_) }
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/Api.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ final class Api(
.extended(
name,
withFollows = userWithFollows,
withTrophies = getBool("trophies")
withTrophies = getBool("trophies"),
withCanChallenge = getBool("challenge")
)
.map(toApiResult)
.map(toHttp)
Expand Down
6 changes: 3 additions & 3 deletions app/controllers/Challenge.scala
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ final class Challenge(
case None => redir
case Some(dest) if ctx.is(dest) => redir
case Some(dest) =>
env.challenge.granter.isDenied(dest, c.perfType).flatMap {
env.challenge.granter.isDenied(dest, c.perfType.key.some).flatMap {
case Some(denied) =>
showChallenge(c, lila.challenge.ChallengeDenied.translated(denied).some)
case None => api.setDestUser(c, dest).inject(redir)
Expand Down Expand Up @@ -303,7 +303,7 @@ final class Challenge(
limit.challengeUser(me, rateLimited, cost = cost):
for
challenge <- makeOauthChallenge(config, me, destUser)
grant <- env.challenge.granter.isDenied(destUser, config.perfType)
grant <- env.challenge.granter.isDenied(destUser, config.perfKey.some)
res <- grant match
case Some(denied) =>
fuccess:
Expand Down Expand Up @@ -376,7 +376,7 @@ final class Challenge(
NoBot:
Found(env.game.gameRepo.game(gameId)): g =>
g.opponentOf(me).flatMap(_.userId).so(env.user.repo.byId).orNotFound { opponent =>
env.challenge.granter.isDenied(opponent, g.perfKey).flatMap {
env.challenge.granter.isDenied(opponent, g.perfKey.some).flatMap {
case Some(d) => BadRequest(jsonError(lila.challenge.ChallengeDenied.translated(d)))
case _ =>
api.offerRematchForGame(g, me).map {
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/RelayRound.scala
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ final class RelayRound(
studyC.CanView(study)(
for
group <- env.relay.api.withTours.get(rt.tour.id)
previews <- env.study.preview.jsonList(study.id)
previews <- env.study.preview.jsonList.withoutInitialEmpty(study.id)
yield JsonOk(env.relay.jsonView.withUrlAndPreviews(rt.withStudy(study), previews, group))
)(studyC.privateUnauthorizedJson, studyC.privateForbiddenJson)

Expand Down
2 changes: 1 addition & 1 deletion app/controllers/Setup.scala
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ final class Setup(
for
origUser <- ctx.user.soFu(env.user.perfsRepo.withPerf(_, config.perfType))
destUser <- userId.so(env.user.api.enabledWithPerf(_, config.perfType))
denied <- destUser.so(u => env.challenge.granter.isDenied(u.user, config.perfType))
denied <- destUser.so(u => env.challenge.granter.isDenied(u.user, config.perfKey.some))
result <- denied match
case Some(denied) =>
val message = lila.challenge.ChallengeDenied.translated(denied)
Expand Down
10 changes: 8 additions & 2 deletions modules/api/src/main/UserApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ final class UserApi(
trophyApi: lila.user.TrophyApi,
shieldApi: lila.tournament.TournamentShieldApi,
revolutionApi: lila.tournament.RevolutionApi,
challengeGranter: lila.challenge.ChallengeGranter,
net: NetConfig
)(using Executor, lila.core.i18n.Translator):

Expand All @@ -38,16 +39,18 @@ final class UserApi(
def extended(
username: UserStr,
withFollows: Boolean,
withTrophies: Boolean
withTrophies: Boolean,
withCanChallenge: Boolean
)(using Option[Me], Lang): Fu[Option[JsObject]] =
userApi.withPerfs(username).flatMapz {
extended(_, withFollows, withTrophies).dmap(some)
extended(_, withFollows, withTrophies, withCanChallenge).dmap(some)
}

def extended(
u: User | UserWithPerfs,
withFollows: Boolean,
withTrophies: Boolean,
withCanChallenge: Boolean,
forWiki: Boolean = false
)(using as: Option[Me], lang: Lang): Fu[JsObject] =
u.match
Expand All @@ -69,6 +72,7 @@ final class UserApi(
gameCache.nbImportedBy(u.id),
(withTrophies && !u.lame).soFu(getTrophiesAndAwards(u.user)),
streamerApi.listed(u.user),
withCanChallenge.so(challengeGranter.mayChallenge(u.user).dmap(some)),
forWiki.soFu(userRepo.email(u.id))
).mapN:
(
Expand All @@ -83,6 +87,7 @@ final class UserApi(
nbImported,
trophiesAndAwards,
streamer,
canChallenge,
email
) =>
jsonView.full(u.user, u.perfs.some, withProfile = true) ++ {
Expand Down Expand Up @@ -112,6 +117,7 @@ final class UserApi(
.add("nbFollowing", following)
.add("nbFollowers", withFollows.option(0))
.add("trophies", trophiesAndAwards.map(trophiesJson))
.add("canChallenge", canChallenge)
.add(
"streamer",
streamer.map: s =>
Expand Down
64 changes: 34 additions & 30 deletions modules/challenge/src/main/ChallengeGranter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,38 +42,42 @@ final class ChallengeGranter(

val ratingThreshold = 300

def isDenied(dest: User, perfKey: PerfKey)(using
def mayChallenge(dest: User)(using Executor)(using me: Option[Me]): Fu[Boolean] =
isDenied(dest, None).map(_.isEmpty)

// perfkey is None when we're not yet trying to challenge
def isDenied(dest: User, perfKey: Option[PerfKey])(using
Executor
)(using me: Option[Me]): Fu[Option[ChallengeDenied]] = me
.fold[Fu[Option[ChallengeDenied.Reason]]] {
prefApi.getChallenge(dest.id).map {
case lila.core.pref.Challenge.ALWAYS => none
case _ => YouAreAnon.some
}
} { from =>
type Res = Option[ChallengeDenied.Reason]
given Conversion[Res, Fu[Res]] = fuccess
relationApi.fetchRelation(dest.id, from.userId).zip(prefApi.getChallenge(dest.id)).flatMap {
case (Some(Block), _) => YouAreBlocked.some
case (_, lila.core.pref.Challenge.NEVER) => TheyDontAcceptChallenges.some
case (Some(Follow), _) => none // always accept from followed
case (_, _) if from.marks.engine && !dest.marks.engine => YouAreBlocked.some
case (_, lila.core.pref.Challenge.FRIEND) => FriendsOnly.some
case (_, lila.core.pref.Challenge.RATING) =>
userApi
.perfsOf(from.value -> dest, primary = false)
.map: (fromPerfs, destPerfs) =>
if fromPerfs(perfKey).provisional || destPerfs(perfKey).provisional
then RatingIsProvisional(perfKey).some
else
val diff =
math.abs(fromPerfs(perfKey).intRating.value - destPerfs(perfKey).intRating.value)
(diff > ratingThreshold).option(RatingOutsideRange(perfKey))
case (_, lila.core.pref.Challenge.REGISTERED) => none
case _ if from == dest => SelfChallenge.some
case _ => none
}
}
.match
case None =>
prefApi.getChallenge(dest.id).map {
case lila.core.pref.Challenge.ALWAYS => none
case _ => YouAreAnon.some
}
case Some(from) =>
type Res = Option[ChallengeDenied.Reason]
given Conversion[Res, Fu[Res]] = fuccess
relationApi.fetchRelation(dest.id, from.userId).zip(prefApi.getChallenge(dest.id)).flatMap {
case (Some(Block), _) => YouAreBlocked.some
case (_, lila.core.pref.Challenge.NEVER) => TheyDontAcceptChallenges.some
case (Some(Follow), _) => none // always accept from followed
case (_, _) if from.marks.engine && !dest.marks.engine => YouAreBlocked.some
case (_, lila.core.pref.Challenge.FRIEND) => FriendsOnly.some
case (_, lila.core.pref.Challenge.RATING) =>
perfKey.so: pk =>
userApi
.perfsOf(from.value -> dest, primary = false)
.map: (fromPerfs, destPerfs) =>
if fromPerfs(pk).provisional || destPerfs(pk).provisional
then RatingIsProvisional(pk).some
else
val diff = math.abs(fromPerfs(pk).intRating.value - destPerfs(pk).intRating.value)
(diff > ratingThreshold).option(RatingOutsideRange(pk))
case (_, lila.core.pref.Challenge.REGISTERED) => none
case _ if from == dest => SelfChallenge.some
case _ => none
}
.map:
case None if dest.isBot && perfKey == PerfKey.ultraBullet => BotUltraBullet.some
case res => res
Expand Down
9 changes: 6 additions & 3 deletions modules/relay/src/main/RelayFetch.scala
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ final private class RelayFetch(
lila.mon.relay.moves(tour.official, round.slug).increment(result.nbMoves)
if !round.hasStarted && !tour.official then
irc.broadcastStart(round.id, round.withTour(tour).fullName)
continueRelay(tour, updating(_.ensureStarted.resume(tour.official)))
continueRelay(tour, updating(_.ensureStarted.resume(tour.official)))
else continueRelay(tour, updating)
case _ => continueRelay(tour, updating)

private def continueRelay(tour: RelayTour, updating: Updating[RelayRound]): Updating[RelayRound] =
Expand Down Expand Up @@ -157,11 +158,13 @@ final private class RelayFetch(
val base =
if upstream.isLcc then 6
else if upstream.isRound then 10 // uses push so no need to pull often
else 3
else 2
base * {
if tour.official then 1 else 2
} * {
if round.crowd.exists(_ > 4) then 1 else 2
} * {
if round.hasStarted then 1 else 2
}

private val gameIdsUpstreamPgnFlags = PgnDump.WithFlags(
Expand Down Expand Up @@ -210,7 +213,7 @@ final private class RelayFetch(
type LccGameKey = String
private val finishedGames =
cacheApi.notLoadingSync[LccGameKey, GameJson](512, "relay.fetch.finishedLccGames"):
_.expireAfterWrite(3 minutes).build()
_.expireAfterWrite(5 minutes).build()
def apply(lcc: RelayRound.Sync.Lcc, index: Int, roundTags: Tags)(
fetch: () => Fu[GameJson]
): Fu[GameJson] =
Expand Down
22 changes: 13 additions & 9 deletions modules/relay/src/main/RelayRoundForm.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,20 @@ final class RelayRoundForm(using mode: Mode):
)

private def lccIsComplete(url: Upstream.Url) =
url.isLcc || !url.url.host.toString.contains("livechesscloud.com")
url.isLcc || !url.url.host.toString.endsWith("livechesscloud.com")

val roundMapping =
def roundMapping(using Me) =
mapping(
"name" -> cleanText(minLength = 3, maxLength = 80).into[RelayRound.Name],
"caption" -> optional(cleanText(minLength = 3, maxLength = 80).into[RelayRound.Caption]),
"syncSource" -> optional(stringIn(sourceTypes.map(_._1).toSet)),
"syncUrl" -> optional(
of[Upstream.Url]
.verifying("LCC URLs must end with /{round-number}, e.g. /5 for round 5", lccIsComplete)
.verifying(
"Invalid source URL",
u => !u.url.host.toString.endsWith("lichess.org") || Granter(_.Relay)
)
),
"syncUrls" -> optional(of[Upstream.Urls]),
"syncIds" -> optional(of[Upstream.Ids]),
Expand All @@ -67,19 +71,20 @@ final class RelayRoundForm(using mode: Mode):
.transform[List[RelayGame.Slice]](RelayGame.Slices.parse, RelayGame.Slices.show)
)(Data.apply)(unapply)

def create(trs: RelayTour.WithRounds) = Form(
def create(trs: RelayTour.WithRounds)(using Me) = Form(
roundMapping
.verifying(
s"Maximum rounds per tournament: ${RelayTour.maxRelays}",
_ => trs.rounds.sizeIs < RelayTour.maxRelays
)
).fill(fillFromPrevRounds(trs.rounds))

def edit(r: RelayRound) = Form(
roundMapping.verifying(
"The round source cannot be itself",
d => d.syncSource.pp.forall(_ != "url") || d.syncUrl.forall(_.roundId.forall(_ != r.id))
)
def edit(r: RelayRound)(using Me) = Form(
roundMapping
.verifying(
"The round source cannot be itself",
d => d.syncSource.forall(_ != "url") || d.syncUrl.forall(_.roundId.forall(_ != r.id))
)
).fill(Data.make(r))

object RelayRoundForm:
Expand Down Expand Up @@ -176,7 +181,6 @@ object RelayRoundForm:
"twitch.com",
"youtube.com",
"youtu.be",
"lichess.org",
"google.com",
"vk.com",
"chess-results.com",
Expand Down
1 change: 1 addition & 0 deletions modules/setup/src/main/ApiConfig.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ final case class ApiConfig(
):

def perfType: PerfType = lila.rating.PerfType(variant, chess.Speed(days.isEmpty.so(clock)))
def perfKey = perfType.key

def validFen = Variant.isValidInitialFen(variant, position)

Expand Down
1 change: 1 addition & 0 deletions modules/setup/src/main/Config.scala
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ private[setup] trait Config:
def makeSpeed: Speed = chess.Speed(makeClock)

def perfType: PerfType = lila.rating.PerfType(variant, makeSpeed)
def perfKey = perfType.key

trait Positional:
self: Config =>
Expand Down
12 changes: 12 additions & 0 deletions modules/study/src/main/StudyChapterPreview.scala
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ final class ChapterPreviewApi(

def apply(studyId: StudyId): Fu[AsJsons] = cache.get(studyId)

def withoutInitialEmpty(studyId: StudyId): Fu[AsJsons] =
apply(studyId).map: json =>
val singleInitial = json
.asOpt[JsArray]
.map(_.value)
.filter(_.sizeIs == 1)
.flatMap(_.headOption)
.exists:
case single: JsObject => single.str("name").contains("Chapter 1")
case _ => false
if singleInitial then JsArray.empty else json

object dataList:
private[ChapterPreviewApi] val cache =
cacheApi[StudyId, List[ChapterPreview]](512, "study.chapterPreview.data"):
Expand Down
2 changes: 1 addition & 1 deletion translation/dest/appeal/tr-TR.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<string name="closedByModerators">Hesabınız moderatörler tarafından kapatılmıştır.</string>
<string name="hiddenBlog">Bloglarınız moderatörler tarafından görünmeze alınmıştır.</string>
<string name="hiddenBlogInfo">%s bölümümüzü tekrar okuduğunuzdan emin olun.</string>
<string name="playTimeout" comment="play timeout = Lichess prevents you temporarily from playing any games">Oyun zaman aşımınız var.</string>
<string name="playTimeout" comment="play timeout = Lichess prevents you temporarily from playing any games">Uzaklaştırma cezanız var.</string>
<string name="communicationGuidelines" comment="Part of a longer sentence:&#10;&#10;Read our communication guidelines. Failure to follow the communication guidelines can result in accounts being muted.">iletişim kuralları</string>
<string name="blogRules">blog kuralları</string>
<string name="fairPlay">Fair Play</string>
Expand Down
4 changes: 1 addition & 3 deletions translation/dest/broadcast/af-ZA.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@
<string name="tournamentDescription">Kort beskrywing van die toernooi</string>
<string name="fullDescription">Volle geleentheid beskrywing</string>
<string name="fullDescriptionHelp">Opsionele lang beskrywing van die uitsending. %1$s is beskikbaar. Lengte moet minder as %2$s karakters.</string>
<string name="sourceSingleUrl" comment="An input box. The user can add the external URL the PGN playback of the game is coming from, to set up their event broadcast.">PGN-Bronskakel</string>
<string name="sourceSingleUrl">PGN-Bronskakel</string>
<string name="sourceUrlHelp">URL wat Lichess sal nagaan vir PGN opdaterings. Dit moet openbaar beskikbaar wees vanaf die Internet.</string>
<string name="startDate">Begin datum in jou eie tydsone</string>
<string name="startDateHelp">Optioneel, indien jy weet wanner die geleentheid begin</string>
<string name="credits">Gee krediet aan die bron</string>
<string name="broadcastUrl">Uitsaai bronadres</string>
<string name="currentRoundUrl">Huidige ronde se bronadres</string>
<string name="currentGameUrl">Huidige spel se bronadres</string>
<string name="downloadAllRounds">Laai al die rondes af</string>
<string name="resetRound">Herstel die ronde</string>
Expand Down
2 changes: 0 additions & 2 deletions translation/dest/broadcast/an-ES.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,5 @@
<string name="startDate">Data d\'inicio en a tuya zona horaria</string>
<string name="startDateHelp">Opcional, si sabes quan prencipia l\'evento</string>
<string name="credits">Cita la fuent</string>
<string name="broadcastUrl">URL d\'a emisión</string>
<string name="currentRoundUrl">Vinclo d\'a ronda actual</string>
<string name="currentGameUrl">Vinclo d\'a partida actual</string>
</resources>
4 changes: 1 addition & 3 deletions translation/dest/broadcast/ar-SA.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,12 @@
<string name="tournamentDescription">وصف موجز للبطولة</string>
<string name="fullDescription">الوصف الكامل</string>
<string name="fullDescriptionHelp">الوصف الاختياري الطويل للبث. %1$s متوفر. يجب أن لا يتجاوز طول النص %2$s حرفاً.</string>
<string name="sourceSingleUrl" comment="An input box. The user can add the external URL the PGN playback of the game is coming from, to set up their event broadcast.">رابط مصدر PGN</string>
<string name="sourceSingleUrl">رابط مصدر PGN</string>
<string name="sourceUrlHelp">URL الذي سيتحقق منه Lichess للحصول على تحديثات PGN. يجب أن يكون متاحًا للجميع على الإنترنت.</string>
<string name="sourceGameIds">حتى 64 معرف لُعْبَة ليتشيس، مفصولة بمسافات.</string>
<string name="startDate">تاريخ البدء في المنطقة الزمنية الخاصة بك</string>
<string name="startDateHelp">اختياري، إذا كنت تعرف متى يبدأ الحدث</string>
<string name="credits">ائتمن المصدر</string>
<string name="broadcastUrl">رابط البث</string>
<string name="currentRoundUrl">رابط الجولة الحالية</string>
<string name="currentGameUrl">رابط المباراة الحالية</string>
<string name="downloadAllRounds">تحميل جميع المباريات</string>
<string name="resetRound">إعادة ضبط هذه الجولة</string>
Expand Down
2 changes: 0 additions & 2 deletions translation/dest/broadcast/az-AZ.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
<string name="startDate">Öz saat qurşağınızdakı başlama tarixi</string>
<string name="startDateHelp">İstəyə bağlı, tədbirin başlama vaxtını bilirsinizsə</string>
<string name="credits">Mənbəyə bax</string>
<string name="broadcastUrl">Yayım URL-i</string>
<string name="currentRoundUrl">Hazırkı tur URL-i</string>
<string name="currentGameUrl">Hazırkı oyun URL-i</string>
<string name="resetRound">Bu turu sıfırla</string>
<string name="deleteRound">Bu turu sil</string>
Expand Down
2 changes: 0 additions & 2 deletions translation/dest/broadcast/be-BY.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
<string name="startDate">Дата пачатаку ў вашым часавым поясе</string>
<string name="startDateHelp">Па жаданні, калі вы ведаеце пачатак падзеі</string>
<string name="credits">Падзякаваць крыніцы</string>
<string name="broadcastUrl">Спасылка на трансляцыю</string>
<string name="currentRoundUrl">Спасылка на бягучы тур</string>
<string name="currentGameUrl">Спасылка на бягучую гульню</string>
<string name="downloadAllRounds">Спампаваць усе туры</string>
<string name="resetRound">Скасаваць гэты тур</string>
Expand Down
2 changes: 0 additions & 2 deletions translation/dest/broadcast/bg-BG.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
<string name="startDate">Дата на започване във вашата часова зона</string>
<string name="startDateHelp">По избор, ако знаете, кога започва събитието</string>
<string name="credits">Признателност на източника</string>
<string name="broadcastUrl">URL на предаването</string>
<string name="currentRoundUrl">URL на настоящия гунд</string>
<string name="currentGameUrl">URL на настоящата партия</string>
<string name="downloadAllRounds">Изтегли всички рундове</string>
<string name="resetRound">Нулирай този рунд</string>
Expand Down
Loading

0 comments on commit 7770169

Please sign in to comment.