reorganize core

This commit is contained in:
Thibault Duplessis
2024-04-10 09:27:02 +02:00
parent ca8844ba0c
commit e2e40024ef
117 changed files with 223 additions and 134 deletions
+1 -1
View File
@@ -184,6 +184,6 @@ given ConfigLoader[NetConfig] = ConfigLoader(config =>
socketAlts = get[List[String]]("socket.alts"),
crawlable = get[Boolean]("crawlable"),
rateLimit = get[RateLimit]("ratelimit"),
email = get[lila.core.EmailAddress]("email")
email = get[EmailAddress]("email")
)
)
+1
View File
@@ -12,6 +12,7 @@ import lila.app.{ *, given }
import lila.common.HTTPRequest
import lila.core.LightUser
import lila.core.net.IpAddress
import lila.core.chess.MultiPv
import lila.gathering.Condition.GetMyTeamIds
import lila.security.Mobile
+2 -1
View File
@@ -12,6 +12,7 @@ import lila.security.{ FingerPrint, Signup }
import lila.user.User.ClearPassword
import lila.user.{ PasswordHasher, User as UserModel }
import lila.core.net.IpAddress
import lila.core.email.{ UserStrOrEmail, UserIdOrEmail }
final class Auth(
env: Env,
@@ -83,7 +84,7 @@ final class Auth(
referrer.ifTrue(ctx.isAuth).ifTrue(switch.isEmpty) match
case Some(url) => Redirect(url) // redirect immediately if already logged in
case None =>
val prefillUsername = lila.core.UserStrOrEmail(~switch.filter(_ != "1"))
val prefillUsername = UserStrOrEmail(~switch.filter(_ != "1"))
val form = api.loginFormFilled(prefillUsername)
Ok.page(html.auth.login(form, referrer)).map(_.withCanonical(routes.Auth.login))
+1
View File
@@ -13,6 +13,7 @@ import lila.app.*
import lila.core.net.IpAddress
import lila.game.Pov
import lila.pref.{ PieceSet, Theme }
import lila.core.id.PuzzleId
final class Export(env: Env) extends LilaController(env):
+1
View File
@@ -4,6 +4,7 @@ import views.*
import lila.app.{ *, given }
import lila.core.config
import lila.core.id.{ ForumCategId, ForumTopicId }
import lila.forum.ForumCateg.{ diagnosticId, ublogId }
import lila.team.Team
+1
View File
@@ -4,6 +4,7 @@ import play.api.mvc.*
import lila.app.{ *, given }
import lila.forum.ForumTopic
import lila.core.id.{ ForumCategId, ForumTopicId }
private[controllers] trait ForumController:
self: LilaController =>
+1
View File
@@ -5,6 +5,7 @@ import views.*
import lila.app.{ *, given }
import lila.core.net.IpAddress
import lila.core.i18n.I18nKey as trans
import lila.core.id.{ ForumCategId, ForumTopicId }
import lila.msg.MsgPreset
final class ForumPost(env: Env) extends LilaController(env) with ForumController:
+1
View File
@@ -6,6 +6,7 @@ import views.*
import lila.app.{ *, given }
import lila.core.net.IpAddress
import lila.forum.ForumCateg.diagnosticId
import lila.core.id.{ ForumCategId, ForumTopicId }
final class ForumTopic(env: Env) extends LilaController(env) with ForumController:
+1
View File
@@ -10,6 +10,7 @@ import lila.app.{ *, given }
import lila.common.HTTPRequest
import lila.core.perf.{ PerfKey, PerfType }
import lila.core.id.GameAnyId
final class Game(env: Env, apiC: => Api) extends LilaController(env):
+1
View File
@@ -8,6 +8,7 @@ import views.*
import lila.app.{ *, given }
import lila.common.HTTPRequest
import lila.core.id.GameFullId
import Forms.*
+1
View File
@@ -18,6 +18,7 @@ import lila.report.{ Mod as AsMod, Suspect }
import lila.security.FingerHash
import lila.user.User as UserModel
import lila.core.net.IpAddress
import lila.core.userId.ModId
final class Mod(
env: Env,
+1
View File
@@ -7,6 +7,7 @@ import scala.util.chaining.*
import lila.app.*
import lila.game.Pov
import lila.core.id.GameAnyId
// both bot & board APIs
final class PlayApi(env: Env, apiC: => Api)(using akka.stream.Materializer) extends LilaController(env):
+1
View File
@@ -13,6 +13,7 @@ import lila.app.{ *, given }
import lila.common.Json.given
import lila.core.net.ApiVersion
import lila.core.app.LangPath
import lila.core.id.PuzzleId
import lila.puzzle.{
Puzzle as Puz,
PuzzleAngle,
+1
View File
@@ -11,6 +11,7 @@ import scala.annotation.nowarn
import lila.app.{ *, given }
import lila.common.HTTPRequest
import lila.relay.{ RelayRound as RoundModel, RelayTour as TourModel }
import lila.core.id.RelayRoundId
final class RelayRound(
env: Env,
+1
View File
@@ -12,6 +12,7 @@ import lila.game.{ Game as GameModel, PgnDump, Pov }
import lila.tournament.Tournament as Tour
import lila.user.{ User as UserModel }
import lila.core.data.Preload
import lila.core.id.{ GameFullId, GameAnyId }
final class Round(
env: Env,
+1
View File
@@ -18,6 +18,7 @@ import lila.study.{ Chapter, Order, Settings, Study as StudyModel, StudyForm }
import lila.tree.Node.partitionTreeJsonWriter
import lila.core.actorApi.lpv.LpvEmbed
import lila.core.net.IpAddress
import lila.core.id.RelayRoundId
final class Study(
env: Env,
+1
View File
@@ -4,6 +4,7 @@ import play.api.mvc.*
import lila.app.{ *, given }
import lila.game.{ AnonCookie, Game as GameModel, Pov }
import lila.core.id.GamePlayerId
private[controllers] trait TheftPrevention:
self: LilaController =>
+4 -1
View File
@@ -22,6 +22,7 @@ import lila.user.User as UserModel
import lila.core.perf.{ PerfKey, PerfType }
import lila.core.net.IpAddress
import lila.core.user.LightPerf
import lila.core.userId.UserSearch
final class User(
override val env: Env,
@@ -202,7 +203,9 @@ final class User(
EnabledUser(username): u =>
env.history
.ratingChartApi(u)
.dmap(_ | SafeJsonStr("[]")) // send an empty JSON array if no history JSON is available
.dmap(
_ | lila.core.data.SafeJsonStr("[]")
) // send an empty JSON array if no history JSON is available
.dmap(jsonStr => Ok(jsonStr).as(JSON))
private def currentlyPlaying(user: UserModel): Fu[Option[Pov]] =
+1
View File
@@ -11,6 +11,7 @@ import lila.app.{ *, given }
import lila.common.HTTPRequest
import lila.game.Pov
import lila.tree.ExportOptions
import lila.core.id.GameFullId
final class UserAnalysis(
env: Env,
+1
View File
@@ -10,6 +10,7 @@ import lila.relation.RelationApi
import lila.core.perm.Granter
import lila.ublog.{ UblogApi, UblogPost }
import lila.user.{ Me, User, given_MyId }
import lila.core.data.SafeJsonStr
case class UserInfo(
nbs: UserInfo.NbGames,
+1
View File
@@ -11,6 +11,7 @@ import lila.rating.Perf
import lila.report.Report
import lila.core.socket.Sri
import lila.core.perf.PerfKey
import lila.core.id.*
// These are only meant for the play router,
// so that controllers can take richer types than routes allow
+1
View File
@@ -4,6 +4,7 @@ import play.api.libs.json.{ JsValue, Json, Writes }
import lila.app.ui.ScalatagsTemplate.*
import lila.core.net.AssetVersion
import lila.core.data.SafeJsonStr
import lila.common.String.html.safeJsonValue
trait AssetHelper extends HasEnv:
+1
View File
@@ -10,6 +10,7 @@ import lila.core.forum.ForumTopicMini
import lila.core.forum.ForumPostMini
import lila.core.rating.Score
import lila.core.rating.RatingProg
import lila.core.chess.Rank
object activity:
+1
View File
@@ -6,6 +6,7 @@ import controllers.routes
import lila.app.templating.Environment.{ *, given }
import lila.app.ui.ScalatagsTemplate.{ *, given }
import lila.common.String.html.richText
import lila.core.data.RichText
object show:
+2 -2
View File
@@ -7,8 +7,8 @@ import lila.app.ui.ScalatagsTemplate.{ *, given }
object emailConfirm:
def apply(query: String, user: Option[lila.user.User.WithPerfs], email: Option[lila.core.EmailAddress])(
using ctx: PageContext
def apply(query: String, user: Option[lila.user.User.WithPerfs], email: Option[EmailAddress])(using
ctx: PageContext
) =
views.html.base.layout(
title = "Email confirmation",
+1
View File
@@ -11,6 +11,7 @@ import lila.app.ui.ScalatagsTemplate.{ *, given }
import lila.evaluation.PlayerAssessment
import lila.game.Pov
import lila.core.perf.PerfType
import lila.core.chess.Rank
import lila.tournament.LeaderboardApi.TourEntry
import lila.user.User
+1 -1
View File
@@ -18,7 +18,7 @@ object index:
private val namespaceAttr = attr("data-namespace")
def apply(
email: Option[lila.core.EmailAddress],
email: Option[EmailAddress],
stripePublicKey: String,
payPalPublicKey: String,
patron: Option[lila.plan.Patron],
+1 -1
View File
@@ -64,7 +64,7 @@ object header:
),
(s.streamer.youTube.isDefined && s.stream.isEmpty && (isMe || isMod)).option(
form(
action := routes.Streamer.checkOnline(s.streamer._id.value).url,
action := routes.Streamer.checkOnline(s.streamer.id.value).url,
method := "post"
)(input(cls := "button online-check", tpe := "submit", value := "force online check"))
)
+1
View File
@@ -8,6 +8,7 @@ import lila.app.ui.ScalatagsTemplate.{ *, given }
import lila.perfStat.{ PerfStat, PerfStatData }
import lila.rating.Perf
import lila.core.perf.PerfType
import lila.core.data.SafeJsonStr
import lila.user.User
object perfStat:
+1
View File
@@ -8,6 +8,7 @@ import lila.app.templating.Environment.{ *, given }
import lila.app.ui.ScalatagsTemplate.{ *, given }
import lila.game.Game
import lila.user.User
import lila.core.data.SafeJsonStr
object page:
@@ -8,6 +8,7 @@ import lila.db.dsl.*
import lila.game.LightPov
import lila.user.User
import lila.core.swiss.{ IdName as SwissIdName }
import lila.core.chess.Rank
final class ActivityReadApi(
coll: AsyncCollFailingSilently,
@@ -8,6 +8,7 @@ import lila.activity.activities.*
import lila.core.forum.ForumPostMini
import lila.core.forum.ForumTopicMini
import lila.core.rating.Score
import lila.core.chess.Rank
case class ActivityView(
interval: TimeInterval,
@@ -10,6 +10,7 @@ import lila.rating.Perf
import lila.core.perf.{ PerfKey, PerfType }
import lila.core.rating.RatingProg
import lila.core.rating.Score
import lila.core.chess.Rank
private object BSONHandlers:
@@ -5,6 +5,7 @@ import alleycats.Zero
import lila.core.perf.PerfType
import lila.core.rating.Score
import lila.activity.Score.plus
import lila.core.chess.Rank
object activities:
+1
View File
@@ -5,6 +5,7 @@ import lila.core.perm.Granter
import lila.team.Team
import lila.user.Me
import lila.core.team.Access
import lila.core.id.ForumCategId
final class ForumAccess(
teamApi: lila.team.TeamApi,
+1 -1
View File
@@ -57,7 +57,7 @@ case class Appeal(
object Appeal:
opaque type Id = String
object Id extends OpaqueUserId[Id]
object Id extends lila.core.userId.OpaqueUserId[Id]
given UserIdOf[Appeal] = _.id.userId
+4 -6
View File
@@ -1,9 +1,10 @@
package lila.coach
import reactivemongo.api.bson.Macros.Annotations.Key
import lila.memo.PicfitImage
case class Coach(
_id: Coach.Id, // user ID
@Key("_id") id: Coach.Id, // user ID
listed: Coach.Listed,
available: Coach.Available,
profile: CoachProfile,
@@ -14,9 +15,6 @@ case class Coach(
createdAt: Instant,
updatedAt: Instant
):
inline def id = _id
def hasPicture = picture.isDefined
def daysOld = daysBetween(createdAt, nowInstant)
@@ -26,7 +24,7 @@ case class Coach(
object Coach:
opaque type Id = String
object Id extends OpaqueUserId[Id]
object Id extends lila.core.userId.OpaqueUserId[Id]
given UserIdOf[Coach] = _.id.userId
@@ -34,7 +32,7 @@ object Coach:
def make(user: lila.user.User.WithPerfs) =
Coach(
_id = user.id.into(Id),
id = user.id.into(Id),
listed = Listed(false),
available = Available(true),
profile = CoachProfile(),
@@ -1,5 +1,7 @@
package lila.coach
import lila.core.data.RichText
case class CoachProfile(
headline: Option[String] = None,
hourlyRate: Option[String] = None,
@@ -6,6 +6,7 @@ import play.api.i18n.Lang
import play.api.libs.json.{ JsSuccess, Json, Reads }
import lila.common.Form.given
import lila.core.data.RichText
object CoachProfileForm:
+2 -1
View File
@@ -6,6 +6,7 @@ import _root_.chess.{ Color, Mode }
import lila.core.data.Days
import lila.core.userId.UserId
import lila.core.rating.data.*
trait Challenge:
import Challenge.*
@@ -37,7 +38,7 @@ object Challenge:
// All durations are expressed in seconds
export config.{ limit, increment, show }
case class Rating(int: rating.IntRating, provisional: rating.RatingProvisional):
case class Rating(int: IntRating, provisional: RatingProvisional):
def show = s"$int${if provisional.yes then "?" else ""}"
enum Challenger:
+3 -1
View File
@@ -1,7 +1,6 @@
package lila.core
import lila.core.net.Domain
import lila.core.userId.UserIdOrEmail
import scalalib.newtypes.OpaqueString
object email:
@@ -68,3 +67,6 @@ object email:
def normalize = UserIdOrEmail(
EmailAddress.from(e).fold(e.toLowerCase)(e => EmailAddress.normalize(e).value)
)
opaque type UserIdOrEmail = String
object UserIdOrEmail extends OpaqueString[UserIdOrEmail]
+1 -1
View File
@@ -7,7 +7,7 @@ import lila.core.userId.*
import reactivemongo.api.bson.Macros.Annotations.Key
case class CreatePost(post: ForumPostMini)
case class RemovePost(id: ForumPostId, by: Option[UserId], text: String, asAdmin: Boolean)(using MyId)
case class RemovePost(id: ForumPostId, by: Option[UserId], text: String, asAdmin: Boolean)(using val me: MyId)
case class RemovePosts(ids: List[ForumPostId])
// case class PostCloseToggle(categ: ForumCategId, topicSlug: String, closed: Boolean)(using val me: user.MyId)
// erasing = blankng, still in db but with empty text
+2 -1
View File
@@ -1,7 +1,8 @@
package lila.core
package history
import lila.core.rating.{ Perf, IntRating }
import lila.core.rating.Perf
import lila.core.rating.data.IntRating
import lila.core.perf.PerfKey
import lila.core.user.User
import lila.core.user.WithPerf
+3 -9
View File
@@ -35,6 +35,9 @@ object id:
object GamePlayerId extends OpaqueString[GamePlayerId]:
val size = 4
opaque type TourId = String
object TourId extends OpaqueString[TourId]
opaque type TourPlayerId = String
object TourPlayerId extends OpaqueString[TourPlayerId]
@@ -59,24 +62,15 @@ object id:
opaque type StudyChapterId = String
object StudyChapterId extends OpaqueString[StudyChapterId]
opaque type StudyChapterName = String
object StudyChapterName extends OpaqueString[StudyChapterName]
opaque type RelayRoundId = String
object RelayRoundId extends OpaqueString[RelayRoundId]
opaque type RelayRoundName = String
object RelayRoundName extends OpaqueString[RelayRoundName]
opaque type PuzzleId = String
object PuzzleId extends OpaqueString[PuzzleId]
opaque type Flair = String
object Flair extends OpaqueString[Flair]
opaque type TourId = String
object TourId extends OpaqueString[TourId]
opaque type TeamId = String
object TeamId extends OpaqueString[TeamId]
+4 -3
View File
@@ -13,11 +13,12 @@ object Lilaism extends LilaLibraryExtensions:
SimulId,
SwissId,
ForumPostId,
UblogPostId
UblogPostId,
RoomId
}
export lila.core.userId.{ UserId, UserName, UserStr, MyId, UserIdOf }
export lila.core.data.{ Markdown, Html }
export lila.core.rating.{ IntRating, IntRatingDiff, RatingProvisional }
export lila.core.data.{ Markdown, Html, JsonStr }
export lila.core.rating.data.{ IntRating, IntRatingDiff, RatingProvisional }
export lila.core.email.EmailAddress
def some[A](a: A): Option[A] = Some(a)
+1 -1
View File
@@ -4,7 +4,7 @@ package notify
import alleycats.Zero
import lila.core.id.*
import lila.core.study.StudyName
import lila.core.study.data.StudyName
import lila.core.chess.Win
import lila.core.userId.*
+1 -1
View File
@@ -2,7 +2,7 @@ package lila.core
package perfStat
import lila.core.perf.PerfType
import lila.core.rating.IntRating
import lila.core.rating.data.IntRating
import lila.core.userId.UserId
trait PerfStatApi:
+2 -1
View File
@@ -4,7 +4,8 @@ package pool
import alleycats.Zero
import _root_.chess.{ Clock, ByColor }
import lila.core.rating.{ RatingRange, IntRating }
import lila.core.rating.RatingRange
import lila.core.rating.data.IntRating
import lila.core.socket.Sri
import lila.core.perf.PerfKey
import lila.core.id.GameFullId
+2 -2
View File
@@ -2,14 +2,14 @@ package lila.core
package practice
import lila.core.id.{ StudyId, StudyChapterId }
import lila.core.study.StudyName
import lila.core.study.data.StudyName
import lila.core.userId.UserId
case class OnComplete(userId: UserId, studyId: StudyId, chapterId: StudyChapterId)
trait Study:
val id: StudyId
val name: lila.core.study.StudyName
val name: StudyName
def slug: String
type Studies = StudyId => Option[Study]
+46 -43
View File
@@ -1,8 +1,9 @@
package lila.core
package rating
import alleycats.Zero
object rating:
object data:
opaque type IntRating = Int
object IntRating extends OpaqueInt[IntRating]:
@@ -18,55 +19,57 @@ object rating:
opaque type RatingProvisional = Boolean
object RatingProvisional extends YesNo[RatingProvisional]
trait Perf:
val glicko: Glicko
val nb: Int
export glicko.{ intRating, intDeviation, provisional }
def progress: IntRatingDiff
import data.*
trait Glicko:
val rating: Double
val deviation: Double
val volatility: Double
def provisional: RatingProvisional
def intRating = IntRating(rating.toInt)
def intDeviation = deviation.toInt
trait Perf:
val glicko: Glicko
val nb: Int
export glicko.{ intRating, intDeviation, provisional }
def progress: IntRatingDiff
case class RatingProg(before: IntRating, after: IntRating):
def diff = IntRatingDiff(after - before)
def isEmpty = diff == IntRatingDiff(0)
case class Score(win: Int, loss: Int, draw: Int, rp: Option[RatingProg]):
def size = win + loss + draw
trait Glicko:
val rating: Double
val deviation: Double
val volatility: Double
def provisional: RatingProvisional
def intRating: IntRating = IntRating(rating.toInt)
def intDeviation = deviation.toInt
case class RatingRange(min: IntRating, max: IntRating):
def contains(rating: IntRating) =
(min <= RatingRange.min || rating >= min) &&
(max >= RatingRange.max || rating <= max)
override def toString = s"$min-$max"
case class RatingProg(before: IntRating, after: IntRating):
def diff = IntRatingDiff(after.value - before.value)
def isEmpty = diff == IntRatingDiff(0)
case class Score(win: Int, loss: Int, draw: Int, rp: Option[RatingProg]):
def size = win + loss + draw
object RatingRange:
case class RatingRange(min: IntRating, max: IntRating):
def contains(rating: IntRating) =
(min <= RatingRange.min || rating >= min) &&
(max >= RatingRange.max || rating <= max)
override def toString = s"$min-$max"
val min = IntRating(400)
val max = IntRating(2900)
object RatingRange:
val broad = RatingRange(min, max)
val default = broad
val min = IntRating(400)
val max = IntRating(2900)
def noneIfDefault(from: String): Option[RatingRange] =
if from == default.toString then none
else parse(from).filter(_ != default)
val broad = RatingRange(min, max)
val default = broad
private def readRating(str: String) = IntRating.from(str.toIntOption)
def noneIfDefault(from: String): Option[RatingRange] =
if from == default.toString then none
else parse(from).filter(_ != default)
// ^\d{3,4}\-\d{3,4}$
def parse(from: String): Option[RatingRange] = for
min <- readRating(from.takeWhile('-' !=))
if acceptable(min)
max <- readRating(from.dropWhile('-' !=).tail)
if acceptable(max)
if min < max
yield RatingRange(min, max)
private def readRating(str: String) = IntRating.from(str.toIntOption)
def isValid(from: String): Boolean = parse(from).isDefined
def orDefault(from: String) = parse(from) | default
def acceptable(rating: IntRating) = broad.contains(rating)
// ^\d{3,4}\-\d{3,4}$
def parse(from: String): Option[RatingRange] = for
min <- readRating(from.takeWhile('-' !=))
if acceptable(min)
max <- readRating(from.dropWhile('-' !=).tail)
if acceptable(max)
if min < max
yield RatingRange(min, max)
def isValid(from: String): Boolean = parse(from).isDefined
def orDefault(from: String) = parse(from) | default
def acceptable(rating: IntRating) = broad.contains(rating)
+9 -3
View File
@@ -5,10 +5,16 @@ import reactivemongo.api.bson.Macros.Annotations.Key
import lila.core.id.StudyId
import lila.core.userId.UserId
import lila.core.study.StudyName
opaque type StudyName = String
object StudyName extends OpaqueString[StudyName]
object data:
opaque type StudyName = String
object StudyName extends OpaqueString[StudyName]
opaque type StudyChapterName = String
object StudyChapterName extends OpaqueString[StudyChapterName]
import data.*
case class IdName(@Key("_id") id: StudyId, name: StudyName)
+1 -1
View File
@@ -59,6 +59,6 @@ case class JoinTeam(id: TeamId, userId: UserId)
case class IsLeader(id: TeamId, userId: UserId, promise: Promise[Boolean])
case class IsLeaderOf(leaderId: UserId, memberId: UserId, promise: Promise[Boolean])
case class IsLeaderWithCommPerm(id: TeamId, userId: UserId, promise: Promise[Boolean])
case class KickFromTeam(teamId: TeamId, teamName: String, userId: UserId)(using MyId)
case class KickFromTeam(teamId: TeamId, teamName: String, userId: UserId)(using val me: MyId)
case class LeaveTeam(teamId: TeamId, userId: UserId)
case class TeamIdsJoinedBy(userId: UserId, promise: Promise[List[TeamId]])
+1 -1
View File
@@ -3,7 +3,7 @@ package timeline
import lila.core.perf.PerfKey
import lila.core.id.*
import lila.core.study.StudyName
import lila.core.study.data.StudyName
import lila.core.userId.UserId
case class ReloadTimelines(userIds: List[UserId])
+2 -1
View File
@@ -4,7 +4,8 @@ package user
import play.api.i18n.Lang
import _root_.chess.PlayerTitle
import lila.core.rating.{ Perf, IntRating, IntRatingDiff }
import lila.core.rating.Perf
import lila.core.rating.data.{ IntRating, IntRatingDiff }
import lila.core.perf.PerfKey
import lila.core.userId.*
import lila.core.email.*
-3
View File
@@ -66,8 +66,5 @@ object userId:
val clean = str.trim.takeWhile(' ' !=)
if regex.matches(clean) then Some(clean.toLowerCase) else None
opaque type UserIdOrEmail = String
object UserIdOrEmail extends OpaqueString[UserIdOrEmail]
opaque type ModId = String
object ModId extends OpaqueUserId[ModId]
@@ -7,6 +7,7 @@ import play.api.libs.json.JsObject
import lila.db.AsyncCollFailingSilently
import lila.db.dsl.{ *, given }
import lila.tree.CloudEval
import lila.core.chess.MultiPv
final class EvalCacheApi(coll: AsyncCollFailingSilently, cacheApi: lila.memo.CacheApi)(using Executor):
@@ -3,6 +3,7 @@ package lila.evalCache
import chess.variant.Variant
import lila.tree.CloudEval
import lila.core.chess.MultiPv
case class EvalCacheEntry(
nbMoves: Int, // multipv cannot be greater than number of legal moves
+1
View File
@@ -6,6 +6,7 @@ import chess.variant.Variant
export lila.core.lilaism.Lilaism.{ *, given }
export lila.common.extensions.*
import lila.tree.CloudEval
import lila.core.chess.MultiPv
extension (e: CloudEval)
def multiPv = MultiPv(e.pvs.size)
+1
View File
@@ -6,6 +6,7 @@ import play.api.libs.json.*
import lila.common.Json.{ *, given }
import lila.core.net.IpAddress
import lila.core.chess.Depth
import lila.fishnet.Work as W
import lila.tree.Eval.{ Cp, Mate }
+2
View File
@@ -2,6 +2,8 @@ package lila.fishnet
import scalalib.ThreadLocalRandom
import lila.core.chess.Depth
final private class Monitor(
repo: FishnetRepo,
cacheApi: lila.memo.CacheApi
+1
View File
@@ -2,5 +2,6 @@ package lila.forum
export lila.core.lilaism.Lilaism.{ *, given }
export lila.common.extensions.*
export lila.core.id.{ ForumCategId, ForumTopicId }
private val logger = lila.log("forum")
+1
View File
@@ -5,6 +5,7 @@ import chess.ByColor
export lila.core.lilaism.Lilaism.{ *, given }
export lila.common.extensions.*
export lila.core.id.{ GameFullId, GamePlayerId, GameAnyId }
type RatingDiffs = ByColor[IntRatingDiff]
@@ -6,6 +6,7 @@ import lila.common.Json.given
import play.api.i18n.Lang
import lila.core.user.{ User, UserApi }
import lila.core.perf.{ PerfKey, PerfType }
import lila.core.data.SafeJsonStr
final class RatingChartApi(
historyApi: HistoryApi,
+2 -1
View File
@@ -6,9 +6,10 @@ import lila.analyse.{ Analysis, AnalysisRepo }
import lila.common.Bus
import lila.db.dsl.{ *, given }
import lila.game.{ Game, GameRepo, Pov, Query }
import lila.report.{ Mod, ModId, Report, Reporter, Suspect }
import lila.report.{ Mod, Report, Reporter, Suspect }
import lila.core.report.SuspectId
import lila.user.{ Me, User, UserRepo, modId, given }
import lila.core.userId.ModId
final class IrwinApi(
reportColl: Coll,
+2 -1
View File
@@ -8,9 +8,10 @@ import lila.db.AsyncColl
import lila.db.dsl.{ *, given }
import lila.game.{ BinaryFormat, GameRepo }
import lila.memo.CacheApi
import lila.report.{ Mod, ModId, Report, Reporter, Suspect }
import lila.report.{ Mod, Report, Reporter, Suspect }
import lila.user.{ Me, User, UserPerfsRepo, UserRepo }
import lila.core.report.SuspectId
import lila.core.userId.ModId
final class KaladinApi(
coll: AsyncColl,
+2 -2
View File
@@ -157,8 +157,8 @@ final private class LobbySyncActor(
def registerAbortedGame(g: Game) = recentlyAbortedUserIdPairs.register(g)
private object recentlyAbortedUserIdPairs:
private val cache = scalalib.cache.ExpireSetMemo[CacheKey](1 hour)
private def makeKey(u1: UserId, u2: UserId) = CacheKey:
private val cache = scalalib.cache.ExpireSetMemo[String](1 hour)
private def makeKey(u1: UserId, u2: UserId) = String:
if u1.value < u2.value then s"$u1/$u2" else s"$u2/$u1"
def register(g: Game) =
+1 -1
View File
@@ -3,7 +3,7 @@ package lila.mod
import chess.PlayerTitle
import lila.common.Bus
import lila.report.{ ModId, Room, Suspect }
import lila.report.{ Room, Suspect }
import lila.core.perm.{ Granter, Permission }
import lila.user.{ LightUserApi, Me, User, UserRepo, modId, given }
import lila.core.report.SuspectId
+1 -2
View File
@@ -1,6 +1,6 @@
package lila.mod
import lila.report.{ ModId, Suspect }
import lila.report.Suspect
import lila.user.{ Me, modId }
case class Modlog(
@@ -11,7 +11,6 @@ case class Modlog(
date: Instant = nowInstant,
index: Option[String] = None
):
def isLichess = mod.is(UserId.lichess)
def notable = action != Modlog.terminateTournament
+2 -1
View File
@@ -6,9 +6,10 @@ import reactivemongo.api.bson.*
import lila.db.dsl.{ *, given }
import lila.core.irc.IrcApi
import lila.core.msg.MsgPreset
import lila.report.{ Mod, ModId, Report, Suspect }
import lila.report.{ Mod, Report, Suspect }
import lila.core.perm.Permission
import lila.user.{ Me, User, UserRepo, given }
import lila.core.id.ForumCategId
final class ModlogApi(repo: ModlogRepo, userRepo: UserRepo, ircApi: IrcApi, presetsApi: ModPresetsApi)(using
Executor
+1
View File
@@ -4,6 +4,7 @@ import lila.user.User
export lila.core.lilaism.Lilaism.{ *, given }
export lila.common.extensions.*
export lila.core.userId.ModId
private val logger = lila.log("mod")
+1
View File
@@ -8,6 +8,7 @@ import lila.db.dsl.{ *, given }
import lila.core.actorApi.clas.ClasMatesAndTeachers
import lila.user.Me
import lila.core.user.KidMode
import lila.core.userId.UserSearch
final class MsgSearch(
colls: MsgColls,
@@ -3,6 +3,7 @@ package lila.practice
import play.api.ConfigLoader
import lila.common.autoconfig.{ *, given }
import lila.core.study.data.StudyName
final class PracticeConfig(val sections: List[PracticeConfigSection]):
@@ -1,6 +1,7 @@
package lila.practice
import lila.study.Chapter
import lila.core.study.data.{ StudyName, StudyChapterName }
case class PracticeStructure(sections: List[PracticeSection]):
+1
View File
@@ -12,6 +12,7 @@ import lila.core.actorApi.map.Tell
import lila.core.actorApi.push.TourSoon
import lila.core.round.{ IsOnGame, MoveEvent }
import lila.core.data.LazyFu
import lila.core.study.data.StudyName
import lila.core.notify.*
final private class PushApi(
+2 -2
View File
@@ -148,9 +148,9 @@ final class PuzzleApi(
object casual:
private val store = scalalib.cache.ExpireSetMemo[CacheKey](30 minutes)
private val store = scalalib.cache.ExpireSetMemo[String](30 minutes)
private def key(user: User, id: PuzzleId) = CacheKey(s"${user.id}:${id}")
private def key(user: User, id: PuzzleId) = s"${user.id}:${id}"
def setCasualIfNotYetPlayed(user: User, puzzle: Puzzle): Funit =
round.exists(user, puzzle.id).not.mapz(store.put(key(user, puzzle.id)))
+1
View File
@@ -2,6 +2,7 @@ package lila.puzzle
export lila.core.lilaism.Lilaism.{ *, given }
export lila.common.extensions.*
export lila.core.id.PuzzleId
private val logger = lila.log("puzzle")
@@ -5,6 +5,7 @@ import reactivemongo.api.bson.*
import lila.db.dsl.{ *, given }
import lila.storm.StormPuzzle
import lila.core.id.PuzzleId
private object RacerBsonHandlers:
+1
View File
@@ -11,6 +11,7 @@ import lila.db.dsl.{ *, given }
import lila.memo.{ CacheApi, PicfitApi }
import lila.relay.RelayRound.WithTour
import lila.core.perm.Granter
import lila.core.study.data.StudyName
import lila.study.{ Settings, Study, StudyApi, StudyId, StudyMaker, StudyRepo, StudyTopic }
import lila.user.{ Me, User, given }
+4 -1
View File
@@ -10,7 +10,7 @@ case class RelayRound(
/* Same as the Study id it refers to */
@Key("_id") id: RelayRoundId,
tourId: RelayTour.Id,
name: RelayRoundName,
name: RelayRound.Name,
caption: Option[RelayRound.Caption],
sync: RelayRound.Sync,
/* When it's planned to start */
@@ -61,6 +61,9 @@ object RelayRound:
def makeId = RelayRoundId(ThreadLocalRandom.nextString(8))
opaque type Name = String
object Name extends OpaqueString[Name]
opaque type Caption = String
object Caption extends OpaqueString[Caption]
+3 -3
View File
@@ -20,7 +20,7 @@ final class RelayRoundForm(using mode: play.api.Mode):
val roundMapping =
mapping(
"name" -> cleanText(minLength = 3, maxLength = 80).into[RelayRoundName],
"name" -> cleanText(minLength = 3, maxLength = 80).into[RelayRound.Name],
"caption" -> optional(cleanText(minLength = 3, maxLength = 80).into[RelayRound.Caption]),
"syncUrl" -> optional {
cleanText(minLength = 8, maxLength = 600)
@@ -45,7 +45,7 @@ final class RelayRoundForm(using mode: play.api.Mode):
)
}.fill(
Data(
name = RelayRoundName(s"Round ${trs.rounds.size + 1}"),
name = RelayRound.Name(s"Round ${trs.rounds.size + 1}"),
caption = none,
syncUrlRound = Some(trs.rounds.size + 1)
)
@@ -102,7 +102,7 @@ object RelayRoundForm:
)
case class Data(
name: RelayRoundName,
name: RelayRound.Name,
caption: Option[RelayRound.Caption],
syncUrl: Option[String] = None,
syncUrlRound: Option[Int] = None,
+1
View File
@@ -2,6 +2,7 @@ package lila.relay
export lila.core.lilaism.Lilaism.{ *, given }
export lila.common.extensions.*
export lila.core.id.RelayRoundId
private val logger = lila.log("relay")
private type RelayGames = Vector[RelayGame]
+1
View File
@@ -5,6 +5,7 @@ import reactivemongo.api.bson.Macros.Annotations.Key
import lila.user.User
import lila.core.report.SuspectId
import lila.core.userId.ModId
case class Report(
@Key("_id") id: Report.Id, // also the url slug
+1
View File
@@ -8,6 +8,7 @@ import lila.game.GameRepo
import lila.memo.CacheApi.*
import lila.user.{ Me, User, UserApi, UserRepo, modId, given }
import lila.core.report.SuspectId
import lila.core.userId.ModId
final class ReportApi(
val coll: Coll,
+1
View File
@@ -2,6 +2,7 @@ package lila.report
import lila.user.{ Me, User }
import lila.core.report.SuspectId
import lila.core.userId.{ ModId, OpaqueUserId }
case class Mod(user: User) extends AnyVal:
def id = user.id.into(ModId)
-1
View File
@@ -2,4 +2,3 @@ package lila.room
export lila.core.lilaism.Lilaism.{ *, given }
export lila.common.extensions.*
export lila.core.id.RoomId
@@ -3,6 +3,7 @@ package lila.round
import lila.game.Game
import lila.core.timeline.{ GameEnd as TLGameEnd, Propagate }
import lila.core.notify.{ GameEnd, NotifyApi }
import lila.core.chess.Win
final private class RoundNotifier(
isUserPresent: (Game, UserId) => Fu[Boolean],
+1
View File
@@ -4,6 +4,7 @@ import lila.game.Event
export lila.core.lilaism.Lilaism.{ *, given }
export lila.common.extensions.*
export lila.core.id.{ GameFullId, GamePlayerId, GameAnyId }
private val logger = lila.log("round")
+1 -1
View File
@@ -16,7 +16,7 @@ import lila.oauth.{ AccessToken, OAuthScope, OAuthServer }
import lila.user.User.LoginCandidate.Result
import lila.user.User.{ ClearPassword, LoginCandidate }
import lila.user.{ Me, User, UserRepo }
import lila.core.{ EmailAddress, UserStrOrEmail }
import lila.core.email.UserStrOrEmail
import lila.core.security.{ IsProxy, Ip2ProxyApi }
final class SecurityApi(
+1
View File
@@ -11,6 +11,7 @@ import lila.common.{ HTTPRequest }
import lila.core.net.{ ApiVersion, IpAddress }
import lila.memo.RateLimit
import lila.user.{ PasswordHasher, User }
import lila.core.email.UserIdOrEmail
final class Signup(
store: Store,
@@ -7,6 +7,7 @@ import scala.util.Success
import lila.common.LichessDay
import lila.db.dsl.{ *, given }
import lila.core.id.PuzzleId
object StormBsonHandlers:
+1
View File
@@ -1,6 +1,7 @@
package lila.storm
import chess.format.{ Fen, Uci }
import lila.core.id.PuzzleId
case class StormPuzzle(
id: PuzzleId,
+14 -17
View File
@@ -1,5 +1,6 @@
package lila.streamer
import reactivemongo.api.bson.Macros.Annotations.Key
import cats.derived.*
import lila.core.i18n.Language
@@ -7,7 +8,7 @@ import lila.memo.PicfitImage
import lila.user.User
case class Streamer(
_id: Streamer.Id,
@Key("_id") id: Streamer.Id,
listed: Streamer.Listed,
approval: Streamer.Approval,
picture: Option[PicfitImage.Id],
@@ -22,9 +23,6 @@ case class Streamer(
updatedAt: Instant,
lastStreamLang: Option[Language]
):
inline def id = _id
def userId = id.userId
def hasPicture = picture.isDefined
@@ -37,13 +35,24 @@ case class Streamer(
object Streamer:
opaque type Id = String
object Id extends lila.core.userId.OpaqueUserId[Id]
opaque type Listed = Boolean
object Listed extends YesNo[Listed]
opaque type Name = String
object Name extends OpaqueString[Name]
opaque type Headline = String
object Headline extends OpaqueString[Headline]
opaque type Description = String
object Description extends OpaqueString[Description]
given UserIdOf[Streamer] = _.id.userId
val imageSize = 350
def make(user: User) =
Streamer(
_id = user.id.into(Id),
id = user.id.into(Id),
listed = Listed(true),
approval = Approval(
requested = false,
@@ -66,12 +75,6 @@ object Streamer:
lastStreamLang = none
)
opaque type Id = String
object Id extends OpaqueUserId[Id]
opaque type Listed = Boolean
object Listed extends YesNo[Listed]
case class Approval(
requested: Boolean, // user requests a mod to approve
granted: Boolean, // a mod approved
@@ -80,12 +83,6 @@ object Streamer:
chatEnabled: Boolean, // embed chat inside lichess
lastGrantedAt: Option[Instant]
)
opaque type Name = String
object Name extends OpaqueString[Name]
opaque type Headline = String
object Headline extends OpaqueString[Headline]
opaque type Description = String
object Description extends OpaqueString[Description]
case class Twitch(userId: String) derives Eq:
def fullUrl = s"https://www.twitch.tv/$userId"
@@ -9,6 +9,7 @@ import lila.chat.ChatApi
import lila.game.{ Game, Namer }
import lila.tree.{ Branches, Root }
import lila.core.i18n.Translator
import lila.core.id.GameFullId
final private class ChapterMaker(
net: lila.core.config.NetConfig,
+1
View File
@@ -2,6 +2,7 @@ package lila.study
export lila.core.lilaism.Lilaism.{ *, given }
export lila.common.extensions.*
export lila.core.study.data.{ StudyName, StudyChapterName }
private val logger = lila.log("study")
+1
View File
@@ -20,6 +20,7 @@ import lila.rating.Perf
import lila.core.round.QuietFlag
import lila.user.{ Me, User, UserApi, UserPerfsRepo, UserRepo, given }
import lila.core.swiss.{ IdName, SwissFinish }
import lila.core.userId.UserSearch
final class SwissApi(
mongo: SwissMongo,
+1
View File
@@ -2,6 +2,7 @@ package lila.swiss
import lila.core.LightUser
import lila.game.Game
import lila.core.chess.Rank
private case class SwissBoard(
gameId: GameId,
@@ -5,6 +5,7 @@ import reactivemongo.api.bson.*
import lila.db.dsl.{ *, given }
import lila.memo.CacheApi
import lila.core.swiss.Ranking
import lila.core.chess.Rank
final private class SwissRankingApi(
mongo: SwissMongo,
+1
View File
@@ -1,6 +1,7 @@
package lila.swiss
import lila.user.User
import lila.core.chess.Rank
opaque type SwissRoundNumber = Int
object SwissRoundNumber extends OpaqueInt[SwissRoundNumber]
+1
View File
@@ -15,6 +15,7 @@ import lila.memo.CacheApi.*
import lila.core.perm.Granter
import lila.user.{ Me, User, UserApi, UserRepo, given }
import lila.core.team.*
import lila.core.userId.UserSearch
final class TeamApi(
teamRepo: TeamRepo,
@@ -11,6 +11,7 @@ import lila.core.perf.PerfType
import UserId.lichess
import lila.core.tournament.leaderboard.Ratio
import lila.core.tournament.Status
import lila.core.id.TourPlayerId
object BSONHandlers:

Some files were not shown because too many files have changed in this diff Show More