remove Boolean.fold - what's wrong with if-else?

noBooleanFold
Thibault Duplessis 2018-07-20 11:41:46 +02:00
parent 123d3a3c37
commit 40497b41e9
60 changed files with 268 additions and 261 deletions

View File

@ -42,20 +42,18 @@ object Auth extends LilaController {
def authenticateUser(u: UserModel, result: Option[String => Result] = None)(implicit ctx: Context): Fu[Result] = {
implicit val req = ctx.req
u.ipBan.fold(
fuccess(Redirect(routes.Lobby.home)),
api.saveAuthentication(u.id, ctx.mobileApiVersion) flatMap { sessionId =>
negotiate(
html = fuccess {
val redirectTo = get("referrer").filter(goodReferrer) orElse
req.session.get(api.AccessUri) getOrElse
routes.Lobby.home.url
result.fold(Redirect(redirectTo))(_(redirectTo))
},
api = _ => mobileUserOk(u, sessionId)
) map authenticateCookie(sessionId)
} recoverWith authRecovery
)
if (u.ipBan) fuccess(Redirect(routes.Lobby.home))
else api.saveAuthentication(u.id, ctx.mobileApiVersion) flatMap { sessionId =>
negotiate(
html = fuccess {
val redirectTo = get("referrer").filter(goodReferrer) orElse
req.session.get(api.AccessUri) getOrElse
routes.Lobby.home.url
result.fold(Redirect(redirectTo))(_(redirectTo))
},
api = _ => mobileUserOk(u, sessionId)
) map authenticateCookie(sessionId)
} recoverWith authRecovery
}
private def authenticateCookie(sessionId: String)(result: Result)(implicit req: RequestHeader) =
@ -161,7 +159,10 @@ object Auth extends LilaController {
else print.fold[Fu[MustConfirmEmail]](fuccess(YesBecausePrintMissing)) { fp =>
api.recentByPrintExists(fp) flatMap { printFound =>
if (printFound) fuccess(YesBecausePrintExists)
else Env.security.ipTrust.isSuspicious(ip).map { _.fold(YesBecauseIpSusp, Nope) }
else Env.security.ipTrust.isSuspicious(ip).map {
case true => YesBecauseIpSusp
case _ => Nope
}
}
}
}

View File

@ -79,7 +79,8 @@ object Challenge extends LilaController {
} flatMap { res =>
if (res.isDefined) jsonOkResult.fuccess
else Env.bot.player.rematchAccept(id, me) flatMap {
_.fold(jsonOkResult.fuccess, notFoundJson())
case true => jsonOkResult.fuccess
case _ => notFoundJson()
}
}
}
@ -91,7 +92,7 @@ object Challenge extends LilaController {
implicit val req = ctx.req
LilaCookie.cookie(
AnonCookie.name,
game.player(owner.fold(c.finalColor, !c.finalColor)).id,
game.player(if (owner) c.finalColor else !c.finalColor).id,
maxAge = AnonCookie.maxAge.some,
httpOnly = false.some
)
@ -110,7 +111,8 @@ object Challenge extends LilaController {
def apiDecline(id: String) = Scoped() { _ => me =>
env.api.activeByIdFor(id, me) flatMap {
case None => Env.bot.player.rematchDecline(id, me) flatMap {
_.fold(jsonOkResult.fuccess, notFoundJson())
case true => jsonOkResult.fuccess
case _ => notFoundJson()
}
case Some(c) => env.api.decline(c) inject jsonOkResult
}
@ -153,7 +155,8 @@ object Challenge extends LilaController {
lila.challenge.ChallengeDenied translated d
}).fuccess
case _ => env.api.sendRematchOf(g, me) map {
_.fold(Ok, BadRequest(jsonError("Sorry, couldn't create the rematch.")))
case true => Ok
case _ => BadRequest(jsonError("Sorry, couldn't create the rematch."))
}
}
}

View File

@ -10,32 +10,32 @@ import lila.i18n.{ I18nKeys, I18nLangPicker, enLang }
object Dasher extends LilaController {
private def translations(implicit ctx: Context) = lila.i18n.JsDump.keysToObject(
ctx.isAnon.fold(
(if (ctx.isAnon)
List(
I18nKeys.signIn,
I18nKeys.signUp
),
I18nKeys.signIn,
I18nKeys.signUp
)
else
List(
I18nKeys.profile,
I18nKeys.inbox,
I18nKeys.preferences,
I18nKeys.logOut
)
) ::: List(
I18nKeys.networkLagBetweenYouAndLichess,
I18nKeys.timeToProcessAMoveOnLichessServer,
I18nKeys.sound,
I18nKeys.background,
I18nKeys.light,
I18nKeys.dark,
I18nKeys.transparent,
I18nKeys.backgroundImageUrl,
I18nKeys.boardGeometry,
I18nKeys.boardTheme,
I18nKeys.boardSize,
I18nKeys.pieceSet,
I18nKeys.zenMode
), lila.i18n.I18nDb.Site, ctx.lang
)) ::: List(
I18nKeys.networkLagBetweenYouAndLichess,
I18nKeys.timeToProcessAMoveOnLichessServer,
I18nKeys.sound,
I18nKeys.background,
I18nKeys.light,
I18nKeys.dark,
I18nKeys.transparent,
I18nKeys.backgroundImageUrl,
I18nKeys.boardGeometry,
I18nKeys.boardTheme,
I18nKeys.boardSize,
I18nKeys.pieceSet,
I18nKeys.zenMode
), lila.i18n.I18nDb.Site, ctx.lang
) ++ lila.i18n.JsDump.keysToObject(
// the language settings should never be in a totally foreign language
List(I18nKeys.language),

View File

@ -22,10 +22,8 @@ private[controllers] trait ForumController extends forum.Granter { self: LilaCon
Env.team.api.owns(teamId, userId)
protected def CategGrantRead[A <: Result](categSlug: String)(a: => Fu[A])(implicit ctx: Context): Fu[Result] =
isGrantedRead(categSlug).fold(
a,
fuccess(Forbidden("You cannot access to this category"))
)
if (isGrantedRead(categSlug)) a
else fuccess(Forbidden("You cannot access to this category"))
protected def CategGrantWrite[A <: Result](categSlug: String)(a: => Fu[A])(implicit ctx: Context): Fu[Result] =
isGrantedWrite(categSlug) flatMap { granted =>
@ -35,9 +33,7 @@ private[controllers] trait ForumController extends forum.Granter { self: LilaCon
protected def CategGrantMod[A <: Result](categSlug: String)(a: => Fu[A])(implicit ctx: Context): Fu[Result] =
isGrantedMod(categSlug) flatMap { granted =>
(granted | isGranted(_.ModerateForum)) fold (
a,
fuccess(Forbidden("You cannot post to this category"))
)
if (granted | isGranted(_.ModerateForum)) a
else fuccess(Forbidden("You cannot post to this category"))
}
}

View File

@ -13,12 +13,10 @@ object ForumPost extends LilaController with ForumController {
def search(text: String, page: Int) = OpenBody { implicit ctx =>
NotForKids {
text.trim.isEmpty.fold(
Redirect(routes.ForumCateg.index).fuccess,
Env.forumSearch(text, page, isGranted(_.StaffForum), ctx.troll) map { paginator =>
html.forum.search(text, paginator)
}
)
if (text.trim.isEmpty) Redirect(routes.ForumCateg.index).fuccess
else Env.forumSearch(text, page, isGranted(_.StaffForum), ctx.troll) map { paginator =>
html.forum.search(text, paginator)
}
}
}

View File

@ -62,7 +62,8 @@ object Insight extends LilaController {
lila.user.UserRepo named username flatMap {
_.fold(notFound) { u =>
env.share.grant(u, ctx.me) flatMap {
_.fold(f(u), fuccess(Forbidden(html.insight.forbidden(u))))
case true => f(u)
case _ => fuccess(Forbidden(html.insight.forbidden(u)))
}
}
}

View File

@ -121,17 +121,17 @@ private[controllers] trait LilaController
protected def Secure[A](parser: BodyParser[A])(perm: Permission)(f: Context => UserModel => Fu[Result]): Action[A] =
Auth(parser) { implicit ctx => me =>
isGranted(perm).fold(f(ctx)(me), authorizationFailed)
if (isGranted(perm)) f(ctx)(me) else authorizationFailed
}
protected def SecureF(s: UserModel => Boolean)(f: Context => UserModel => Fu[Result]): Action[AnyContent] =
Auth(BodyParsers.parse.anyContent) { implicit ctx => me =>
s(me).fold(f(ctx)(me), authorizationFailed)
if (s(me)) f(ctx)(me) else authorizationFailed
}
protected def SecureBody[A](parser: BodyParser[A])(perm: Permission)(f: BodyContext[A] => UserModel => Fu[Result]): Action[A] =
AuthBody(parser) { implicit ctx => me =>
isGranted(perm).fold(f(ctx)(me), authorizationFailed)
if (isGranted(perm)) f(ctx)(me) else authorizationFailed
}
protected def SecureBody(perm: Permission.type => Permission)(f: BodyContext[_] => UserModel => Fu[Result]): Action[AnyContent] =

View File

@ -26,25 +26,22 @@ object Accuracy {
startedAtTurn = pov.game.chess.startedAtTurn
)
def diffsList(pov: PovLike, analysis: Analysis): List[Int] =
(pov.color == pov.startColor).fold(
Info.start(pov.startedAtTurn) :: analysis.infos,
analysis.infos
).grouped(2).foldLeft(List[Int]()) {
case (list, List(i1, i2)) =>
makeDiff.lift(i1.cp, i1.mate, i2.cp, i2.mate).fold(list) { diff =>
(if (pov.color.white) -diff else diff).max(0) :: list
}
case (list, _) => list
}.reverse
def diffsList(pov: PovLike, analysis: Analysis): List[Int] = {
if (pov.color == pov.startColor) Info.start(pov.startedAtTurn) :: analysis.infos
else analysis.infos
}.grouped(2).foldLeft(List[Int]()) {
case (list, List(i1, i2)) =>
makeDiff.lift(i1.cp, i1.mate, i2.cp, i2.mate).fold(list) { diff =>
(if (pov.color.white) -diff else diff).max(0) :: list
}
case (list, _) => list
}.reverse
def prevColorInfos(pov: PovLike, analysis: Analysis): List[Info] = {
(pov.color == pov.startColor).fold(
Info.start(pov.startedAtTurn) :: analysis.infos,
analysis.infos
).zipWithIndex.collect {
case (e, i) if (i % 2) == 0 => e
}
if (pov.color == pov.startColor) Info.start(pov.startedAtTurn) :: analysis.infos
else analysis.infos
}.zipWithIndex.collect {
case (e, i) if (i % 2) == 0 => e
}
def mean(pov: PovLike, analysis: Analysis): Option[Int] = {

View File

@ -45,10 +45,16 @@ private[api] final class GameApi(
else $doc(
G.playerUids -> user.id,
G.status $gte chess.Status.Mate.id,
G.analysed -> analysed.map(_.fold[BSONValue](BSONBoolean(true), $doc("$exists" -> false)))
G.analysed -> analysed.map[BSONValue] {
case true => BSONBoolean(true)
case _ => $doc("$exists" -> false)
}
)
} ++ $doc(
G.rated -> rated.map(_.fold[BSONValue](BSONBoolean(true), $doc("$exists" -> false)))
G.rated -> rated.map[BSONValue] {
case true => BSONBoolean(true)
case _ => $doc("$exists" -> false)
}
),
projection = $empty,
sort = $doc(G.createdAt -> -1),
@ -57,7 +63,10 @@ private[api] final class GameApi(
nbResults =
if (~playing) gameCache.nbPlaying(user.id)
else fuccess {
rated.fold(user.count.game)(_.fold(user.count.rated, user.count.casual))
rated.fold(user.count.game) {
case true => user.count.rated
case _ => user.count.casual
}
}
),
currentPage = page,
@ -91,10 +100,16 @@ private[api] final class GameApi(
if (~playing) lila.game.Query.nowPlayingVs(users._1.id, users._2.id)
else lila.game.Query.opponents(users._1, users._2) ++ $doc(
G.status $gte chess.Status.Mate.id,
G.analysed -> analysed.map(_.fold[BSONValue](BSONBoolean(true), $doc("$exists" -> false)))
G.analysed -> analysed.map[BSONValue] {
case true => BSONBoolean(true)
case _ => $doc("$exists" -> false)
}
)
} ++ $doc(
G.rated -> rated.map(_.fold[BSONValue](BSONBoolean(true), $doc("$exists" -> false)))
G.rated -> rated.map[BSONValue] {
case true => BSONBoolean(true)
case _ => $doc("$exists" -> false)
}
),
projection = $empty,
sort = $doc(G.createdAt -> -1),
@ -128,10 +143,16 @@ private[api] final class GameApi(
if (~playing) lila.game.Query.nowPlayingVs(userIds)
else lila.game.Query.opponents(userIds) ++ $doc(
G.status $gte chess.Status.Mate.id,
G.analysed -> analysed.map(_.fold[BSONValue](BSONBoolean(true), $doc("$exists" -> false)))
G.analysed -> analysed.map[BSONValue] {
case true => BSONBoolean(true)
case _ => $doc("$exists" -> false)
}
)
} ++ $doc(
G.rated -> rated.map(_.fold[BSONValue](BSONBoolean(true), $doc("$exists" -> false))),
G.rated -> rated.map[BSONValue] {
case true => BSONBoolean(true)
case _ => $doc("$exists" -> false)
},
G.createdAt $gte since
),
projection = $empty,

View File

@ -48,9 +48,9 @@ final class BotPlayer(
GameRepo game id map {
_.flatMap(Pov(_, me)).filter(_.opponent.isOfferingRematch) ?? { pov =>
// delay so it feels more natural
lila.common.Future.delay(accept.fold(100, 2000) millis) {
lila.common.Future.delay(if (accept) 100.millis else 2.seconds) {
fuccess {
roundMap ! Tell(pov.gameId, accept.fold(RematchYes, RematchNo)(pov.playerId))
roundMap ! Tell(pov.gameId, (if (accept) RematchYes else RematchNo)(pov.playerId))
}
}(system)
true

View File

@ -57,7 +57,7 @@ final class BotJsonView(
def chatLine(username: String, text: String, player: Boolean) = Json.obj(
"type" -> "chatLine",
"room" -> player.fold("player", "spectator"),
"room" -> (if (player) "player" else "spectator"),
"username" -> username,
"text" -> text
)

View File

@ -83,7 +83,7 @@ object Challenge {
}
case class Rating(int: Int, provisional: Boolean) {
def show = s"$int${provisional.fold("?", "")}"
def show = s"$int${if (provisional) "?" else ""}"
}
object Rating {
def apply(p: lila.rating.Perf): Rating = Rating(p.intRating, p.provisional)
@ -154,10 +154,9 @@ object Challenge {
_id = randomId,
status = Status.Created,
variant = variant,
initialFen = (variant == FromPosition).fold(
initialFen,
!variant.standardInitialPosition option FEN(variant.initialFen)
),
initialFen =
if (variant == FromPosition) initialFen
else !variant.standardInitialPosition option FEN(variant.initialFen),
timeControl = timeControl,
mode = finalMode,
colorChoice = colorChoice,

View File

@ -36,8 +36,8 @@ private[challenge] final class Joiner(onStart: String => Unit) {
chess = chessGame,
whitePlayer = Player.make(chess.White, c.finalColor.fold(challengerUser, destUser), perfPicker),
blackPlayer = Player.make(chess.Black, c.finalColor.fold(destUser, challengerUser), perfPicker),
mode = chessGame.board.variant.fromPosition.fold(Mode.Casual, c.mode),
source = chessGame.board.variant.fromPosition.fold(Source.Position, Source.Friend),
mode = if (chessGame.board.variant.fromPosition) Mode.Casual else c.mode,
source = if (chessGame.board.variant.fromPosition) Source.Position else Source.Friend,
daysPerTurn = c.daysPerTurn,
pgnImport = None
).copy(id = c.id).|> { g =>

View File

@ -29,10 +29,9 @@ case class UserChat(
val loginRequired = true
def forUser(u: Option[User]) = u.??(_.troll).fold(
this,
copy(lines = lines filterNot (_.troll))
)
def forUser(u: Option[User]): UserChat =
if (u.??(_.troll)) this
else copy(lines = lines filterNot (_.troll))
def markDeleted(u: User) = copy(
lines = lines.map { l =>
@ -64,13 +63,12 @@ case class MixedChat(
val loginRequired = false
def forUser(u: Option[User]) = u.??(_.troll).fold(
this,
copy(lines = lines filter {
def forUser(u: Option[User]): MixedChat =
if (u.??(_.troll)) this
else copy(lines = lines filter {
case l: UserLine => !l.troll
case l: PlayerLine => true
})
)
def mapLines(f: Line => Line) = copy(lines = lines map f)

View File

@ -42,7 +42,7 @@ object Form {
def trueish(v: Any) = v == 1 || v == "1" || v == "true" || v == "on" || v == "yes"
private def pluralize(pattern: String, nb: Int) =
pattern.replace("{s}", (nb != 1).fold("s", ""))
pattern.replace("{s}", if (nb == 1) "" else "s")
object formatter {
def stringFormatter[A](from: A => String, to: String => A): Formatter[A] = new Formatter[A] {

View File

@ -15,8 +15,6 @@ final class PimpedBoolean(private val self: Boolean) extends AnyVal {
def !(f: => Unit) = if (self) f
def fold[A](t: => A, f: => A): A = if (self) t else f
def ?[X](t: => X) = new { def |(f: => X) = if (self) t else f }
def option[A](a: => A): Option[A] = if (self) Some(a) else None
@ -64,4 +62,4 @@ final class PimpedDouble(private val self: Double) extends AnyVal {
def atMost(topValue: Double): Double = min(self, topValue)
def squeeze(bottom: Double, top: Double): Double = max(min(self, top), bottom)
}
}

View File

@ -47,7 +47,7 @@ case class PlayerAggregateAssessment(
(percentCheatingGames(10) || percentLikelyCheatingGames(20))
val reportable: Boolean = isWorthLookingAt &&
(cheatingSum >= 2 || cheatingSum + likelyCheatingSum >= (isNewRatedUser.fold(2, 4))) &&
(cheatingSum >= 2 || cheatingSum + likelyCheatingSum >= (if (isNewRatedUser) 2 else 4)) &&
(percentCheatingGames(5) || percentLikelyCheatingGames(10))
val bannable: Boolean = (relatedCheatersCount == relatedUsersCount) && relatedUsersCount >= 1

View File

@ -17,18 +17,18 @@ case class Categ(
def id = _id
def nbTopics(troll: Boolean): Int = troll.fold(nbTopicsTroll, nbTopics)
def nbPosts(troll: Boolean): Int = troll.fold(nbPostsTroll, nbPosts)
def lastPostId(troll: Boolean): String = troll.fold(lastPostIdTroll, lastPostId)
def nbTopics(troll: Boolean): Int = if (troll) nbTopicsTroll else nbTopics
def nbPosts(troll: Boolean): Int = if (troll) nbPostsTroll else nbPosts
def lastPostId(troll: Boolean): String = if (troll) lastPostIdTroll else lastPostId
def isStaff = slug == Categ.staffId
def isTeam = team.nonEmpty
def withTopic(post: Post): Categ = copy(
nbTopics = post.troll.fold(nbTopics, nbTopics + 1),
nbPosts = post.troll.fold(nbPosts, nbPosts + 1),
lastPostId = post.troll.fold(lastPostId, post.id),
nbTopics = if (post.troll) nbTopics else nbTopics + 1,
nbPosts = if (post.troll) nbPosts else nbPosts + 1,
lastPostId = if (post.troll) lastPostId else post.id,
nbTopicsTroll = nbTopicsTroll + 1,
nbPostsTroll = nbPostsTroll + 1,
lastPostIdTroll = post.id

View File

@ -11,10 +11,7 @@ trait Granter {
protected def userOwnsTeam(teamId: String, userId: String): Fu[Boolean]
def isGrantedRead(categSlug: String)(implicit ctx: UserContext): Boolean =
(categSlug == Categ.staffId).fold(
ctx.me exists Master(Permission.StaffForum),
true
)
categSlug != Categ.staffId || ctx.me.exists(Master(Permission.StaffForum))
def isGrantedWrite(categSlug: String)(implicit ctx: UserContext): Fu[Boolean] =
ctx.me.filter(isOldEnoughToForum) ?? { me =>

View File

@ -56,17 +56,16 @@ final class PostApi(
(!categ.quiet ?? (indexer ! InsertPost(post))) >>-
(!categ.quiet ?? env.recent.invalidate) >>-
ctx.userId.?? { userId =>
shutup ! post.isTeam.fold(
lila.hub.actorApi.shutup.RecordTeamForumMessage(userId, post.text),
lila.hub.actorApi.shutup.RecordPublicForumMessage(userId, post.text)
)
shutup ! {
if (post.isTeam) lila.hub.actorApi.shutup.RecordTeamForumMessage(userId, post.text)
else lila.hub.actorApi.shutup.RecordPublicForumMessage(userId, post.text)
}
} >>- {
(ctx.userId ifFalse post.troll ifFalse categ.quiet) ?? { userId =>
timeline ! Propagate(ForumPost(userId, topic.id.some, topic.name, post.id)).|>(prop =>
post.isStaff.fold(
prop toStaffFriendsOf userId,
prop toFollowersOf userId toUsers topicUserIds exceptUser userId
))
timeline ! Propagate(ForumPost(userId, topic.id.some, topic.name, post.id)).|> { prop =>
if (post.isStaff) prop toStaffFriendsOf userId
else prop toFollowersOf userId toUsers topicUserIds exceptUser userId
}
}
lila.mon.forum.post.create()
mentionNotifier.notifyMentionedUsers(post, topic)
@ -187,14 +186,12 @@ final class PostApi(
view optionT(view(post))
_ optionT(for {
first PostRepo.isFirstPost(view.topic.id, view.post.id)
_ first.fold(
env.topicApi.delete(view.categ, view.topic),
env.postColl.remove(view.post) >>
(env.topicApi denormalize view.topic) >>
(env.categApi denormalize view.categ) >>-
env.recent.invalidate >>-
(indexer ! RemovePost(post.id))
)
_ if (first) env.topicApi.delete(view.categ, view.topic)
else env.postColl.remove(view.post) >>
(env.topicApi denormalize view.topic) >>
(env.categApi denormalize view.categ) >>-
env.recent.invalidate >>-
(indexer ! RemovePost(post.id))
_ MasterGranter(_.ModerateForum)(mod) ?? modLog.deletePost(mod.id, post.userId, post.author, post.ip,
text = "%s / %s / %s".format(view.categ.name, view.topic.name, post.text))
} yield true.some)

View File

@ -6,7 +6,7 @@ import reactivemongo.api.{ CursorProducer, ReadPreference }
object PostRepo extends PostRepo(false) {
def apply(troll: Boolean): PostRepo = troll.fold(PostRepoTroll, PostRepo)
def apply(troll: Boolean): PostRepo = if (troll) PostRepoTroll else PostRepo
}
object PostRepoTroll extends PostRepo(true)
@ -18,7 +18,7 @@ sealed abstract class PostRepo(troll: Boolean) {
// dirty
private val coll = Env.current.postColl
private val trollFilter = troll.fold($empty, $doc("troll" -> false))
private val trollFilter = !troll ?? $doc("troll" -> false)
def byIds(ids: List[Post.ID]) = coll.byIds[Post](ids)

View File

@ -30,7 +30,7 @@ private[forum] final class Recent(
(user.map(_.id) ?? getTeams).map { teamIds =>
user.fold("en")(_.langs.mkString(",")) :: {
(user.??(_.troll) ?? List("[troll]")) :::
(user ?? MasterGranter(Permission.StaffForum)).fold(staffCategIds, publicCategIds) :::
(if (user ?? MasterGranter(Permission.StaffForum)) staffCategIds else publicCategIds) :::
(teamIds.map(teamSlug)(scala.collection.breakOut): List[String])
} mkString ";"
}

View File

@ -24,10 +24,10 @@ case class Topic(
def id = _id
def updatedAt(troll: Boolean): DateTime = troll.fold(updatedAtTroll, updatedAt)
def nbPosts(troll: Boolean): Int = troll.fold(nbPostsTroll, nbPosts)
def updatedAt(troll: Boolean): DateTime = if (troll) updatedAtTroll else updatedAt
def nbPosts(troll: Boolean): Int = if (troll) nbPostsTroll else nbPosts
def nbReplies(troll: Boolean): Int = nbPosts(troll) - 1
def lastPostId(troll: Boolean): String = troll.fold(lastPostIdTroll, lastPostId)
def lastPostId(troll: Boolean): String = if (troll) lastPostIdTroll else lastPostId
def open = !closed
def visibleOnHome = !hidden
@ -37,9 +37,9 @@ case class Topic(
def isStaff = categId == Categ.staffId
def withPost(post: Post): Topic = copy(
nbPosts = post.troll.fold(nbPosts, nbPosts + 1),
lastPostId = post.troll.fold(lastPostId, post.id),
updatedAt = post.troll.fold(updatedAt, post.createdAt),
nbPosts = if (post.troll) nbPosts else nbPosts + 1,
lastPostId = if (post.troll) lastPostId else post.id,
updatedAt = if (post.troll) updatedAt else post.createdAt,
nbPostsTroll = nbPostsTroll + 1,
lastPostIdTroll = post.id,
updatedAtTroll = post.createdAt
@ -54,7 +54,7 @@ object Topic {
def nameToId(name: String) = (lila.common.String slugify name) |> { slug =>
// if most chars are not latin, go for random slug
(slug.size > (name.size / 2)).fold(slug, Random nextString 8)
if (slug.size > (name.size / 2)) slug else Random nextString 8
}
val idSize = 8

View File

@ -70,15 +70,17 @@ private[forum] final class TopicApi(
(!categ.quiet ?? (indexer ! InsertPost(post))) >>-
(!categ.quiet ?? env.recent.invalidate) >>-
ctx.userId.?? { userId =>
val text = topic.name + " " + post.text
shutup ! post.isTeam.fold(
lila.hub.actorApi.shutup.RecordTeamForumMessage(userId, text),
lila.hub.actorApi.shutup.RecordPublicForumMessage(userId, text)
)
val text = s"${topic.name} ${post.text}"
shutup ! {
if (post.isTeam) lila.hub.actorApi.shutup.RecordTeamForumMessage(userId, text)
else lila.hub.actorApi.shutup.RecordPublicForumMessage(userId, text)
}
} >>- {
(ctx.userId ifFalse post.troll ifFalse categ.quiet) ?? { userId =>
timeline ! Propagate(ForumPost(userId, topic.id.some, topic.name, post.id)).|>(prop =>
post.isStaff.fold(prop toStaffFriendsOf userId, prop toFollowersOf userId))
timeline ! Propagate(ForumPost(userId, topic.id.some, topic.name, post.id)).|> { prop =>
if (post.isStaff) prop toStaffFriendsOf userId
else prop toFollowersOf userId
}
}
lila.mon.forum.post.create()
} >>- {

View File

@ -4,7 +4,7 @@ import lila.db.dsl._
object TopicRepo extends TopicRepo(false) {
def apply(troll: Boolean): TopicRepo = troll.fold(TopicRepoTroll, TopicRepo)
def apply(troll: Boolean): TopicRepo = if (troll) TopicRepoTroll else TopicRepo
}
object TopicRepoTroll extends TopicRepo(true)
@ -16,7 +16,7 @@ sealed abstract class TopicRepo(troll: Boolean) {
// dirty
private val coll = Env.current.topicColl
private val trollFilter = troll.fold($empty, $doc("troll" -> false))
private val trollFilter = !troll ?? $doc("troll" -> false)
private val notStickyQuery = $doc("sticky" $ne true)
private val stickyQuery = $doc("sticky" -> true)
@ -47,11 +47,9 @@ sealed abstract class TopicRepo(troll: Boolean) {
def nextSlug(categ: Categ, name: String, it: Int = 1): Fu[String] = {
val slug = Topic.nameToId(name) + ~(it != 1).option("-" + it)
// also take troll topic into accounts
TopicRepoTroll.byTree(categ.slug, slug) flatMap {
_.isDefined.fold(
nextSlug(categ, name, it + 1),
fuccess(slug)
)
TopicRepoTroll.byTree(categ.slug, slug) flatMap { found =>
if (found.isDefined) nextSlug(categ, name, it + 1)
else fuccess(slug)
}
}

View File

@ -232,10 +232,10 @@ case class Game(
blackPlayer = f(blackPlayer)
)
def start = started.fold(this, copy(
def start = if (started) this else copy(
status = Status.Started,
mode = Mode(mode.rated && userIds.distinct.size == 2)
))
)
def correspondenceClock: Option[CorrespondenceClock] = daysPerTurn map { days =>
val increment = days * 24 * 60 * 60

View File

@ -24,7 +24,7 @@ final class PgnDump(
tagsFuture map { ts =>
val turns = flags.moves ?? {
val fenSituation = ts.fen.map(_.value) flatMap Forsyth.<<<
val moves2 = fenSituation.??(_.situation.color.black).fold(".." +: game.pgnMoves, game.pgnMoves)
val moves2 = if (fenSituation.exists(_.situation.color.black)) ".." +: game.pgnMoves else game.pgnMoves
makeTurns(
moves2,
fenSituation.map(_.fullMoveNumber) | 1,

View File

@ -101,7 +101,7 @@ object Query {
def checkableOld = F.checkAt $lt DateTime.now.minusHours(1)
def variant(v: chess.variant.Variant) =
$doc(F.variant -> v.standard.fold[BSONValue]($exists(false), $int(v.id)))
$doc(F.variant -> (if (v.standard) $exists(false) else $int(v.id)))
lazy val variantStandard = variant(chess.variant.Standard)

View File

@ -29,7 +29,7 @@ private final class AggregationPipeline {
MaterialRange.reversedButEqualAndLast.foldLeft[BSONValue](BSONInteger(MaterialRange.Up4.id)) {
case (acc, mat) => $doc(
"$cond" -> $arr(
$doc(mat.negative.fold("$lt", "$lte") -> $arr("$" + F.moves("i"), mat.imbalance)),
$doc((if (mat.negative) "$lt" else "$lte") -> $arr("$" + F.moves("i"), mat.imbalance)),
mat.id,
acc
)

View File

@ -29,7 +29,7 @@ object Color {
object Random extends Color("random") {
def resolve = nextBoolean.fold(White, Black).resolve
def resolve = chess.Color(nextBoolean)
def unary_! = this
}

View File

@ -107,7 +107,7 @@ object Seek {
import lila.db.BSON.BSONJodaDateTimeHandler
implicit val lobbyPerfBSONHandler = new BSONHandler[BSONInteger, LobbyPerf] {
def read(b: BSONInteger) = LobbyPerf(b.value.abs, b.value < 0)
def write(x: LobbyPerf) = BSONInteger(x.rating * x.provisional.fold(-1, 1))
def write(x: LobbyPerf) = BSONInteger(x.rating * (if (x.provisional) -1 else 1))
}
private[lobby] implicit val lobbyUserBSONHandler = Macros.handler[LobbyUser]
private[lobby] implicit val seekBSONHandler = Macros.handler[Seek]

View File

@ -57,18 +57,20 @@ case class Thread(
def hasUser(user: User) = userIds contains user.id
def otherUserId(user: User) = isCreator(user).fold(invitedId, creatorId)
def otherUserId(user: User) = if (isCreator(user)) invitedId else creatorId
def visibleOtherUserId(user: User) =
isCreator(user).fold(invitedId, asMod.fold(Thread.lichess, creatorId))
if (isCreator(user)) invitedId
else if (asMod) Thread.lichess
else creatorId
def senderOf(post: Post) = post.isByCreator.fold(creatorId, invitedId)
def senderOf(post: Post) = if (post.isByCreator) creatorId else invitedId
def visibleSenderOf(post: Post) =
if (post.isByCreator && asMod) Thread.lichess
else senderOf(post)
def receiverOf(post: Post) = post.isByCreator.fold(invitedId, creatorId)
def receiverOf(post: Post) = if (post.isByCreator) invitedId else creatorId
def visibleReceiverOf(post: Post) =
if (!post.isByCreator && asMod) Thread.lichess

View File

@ -42,8 +42,8 @@ final class Gamify(
private def buildHistoryAfter(afterYear: Int, afterMonth: Int, until: DateTime): Funit =
(afterYear to until.getYear).flatMap { year =>
((year == afterYear).fold(afterMonth + 1, 1) to
(year == until.getYear).fold(until.getMonthOfYear, 12)).map { month =>
((if (year == afterYear) afterMonth + 1 else 1) to
(if (year == until.getYear) until.getMonthOfYear else 12)).map { month =>
mixedLeaderboard(
after = new DateTime(year, month, 1, 0, 0).pp("compute mod history"),
before = new DateTime(year, month, 1, 0, 0).plusMonths(1).some

View File

@ -24,9 +24,9 @@ case class PerfStat(
val thisYear = pov.game.createdAt isAfter DateTime.now.minusYears(1)
copy(
highest = RatingAt.agg(highest, pov, 1),
lowest = thisYear.fold(RatingAt.agg(lowest, pov, -1), lowest),
bestWins = (~pov.win).fold(bestWins.agg(pov, -1), bestWins),
worstLosses = (thisYear && ~pov.loss).fold(worstLosses.agg(pov, 1), worstLosses),
lowest = if (thisYear) RatingAt.agg(lowest, pov, -1) else lowest,
bestWins = if (~pov.win) bestWins.agg(pov, -1) else bestWins,
worstLosses = if (thisYear && ~pov.loss) worstLosses.agg(pov, 1) else worstLosses,
count = count(pov),
resultStreak = resultStreak agg pov,
playStreak = playStreak agg pov
@ -94,7 +94,7 @@ object Streaks {
val init = Streaks(Streak.init, Streak.init)
}
case class Streak(v: Int, from: Option[RatingAt], to: Option[RatingAt]) {
def apply(cont: Boolean, pov: Pov)(v: Int) = cont.fold(inc(pov, v), Streak.init)
def apply(cont: Boolean, pov: Pov)(v: Int) = if (cont) inc(pov, v) else Streak.init
private def inc(pov: Pov, by: Int) = copy(
v = v + by,
from = from orElse pov.player.rating.map { RatingAt(_, pov.game.createdAt, pov.gameId) },
@ -121,20 +121,20 @@ case class Count(
) {
def apply(pov: Pov) = copy(
all = all + 1,
rated = rated + pov.game.rated.fold(1, 0),
win = win + pov.win.contains(true).fold(1, 0),
loss = loss + pov.win.contains(false).fold(1, 0),
draw = draw + pov.win.isEmpty.fold(1, 0),
tour = tour + pov.game.isTournament.fold(1, 0),
berserk = berserk + pov.player.berserk.fold(1, 0),
rated = rated + (if (pov.game.rated) 1 else 0),
win = win + (if (pov.win.contains(true)) 1 else 0),
loss = loss + (if (pov.win.contains(false)) 1 else 0),
draw = draw + (if (pov.win.isEmpty) 1 else 0),
tour = tour + (if (pov.game.isTournament) 1 else 0),
berserk = berserk + (if (pov.player.berserk) 1 else 0),
opAvg = pov.opponent.stableRating.fold(opAvg)(opAvg.agg),
seconds = seconds + (pov.game.durationSeconds match {
case Some(s) if s <= 3 * 60 * 60 => s
case _ => 0
}),
disconnects = disconnects + {
~pov.loss && pov.game.status == chess.Status.Timeout
}.fold(1, 0)
if (~pov.loss && pov.game.status == chess.Status.Timeout) 1 else 0
}
)
}
object Count {

View File

@ -33,8 +33,8 @@ private final class GameStarter(
(perfs.get(p1.userId) |@| perfs.get(p2.userId)).tupled ?? {
case (perf1, perf2) => for {
p1White <- UserRepo.firstGetsWhite(p1.userId, p2.userId)
(whitePerf, blackPerf) = p1White.fold(perf1 -> perf2, perf2 -> perf1)
(whiteMember, blackMember) = p1White.fold(p1 -> p2, p2 -> p1)
(whitePerf, blackPerf) = if (p1White) perf1 -> perf2 else perf2 -> perf1
(whiteMember, blackMember) = if (p1White) p1 -> p2 else p2 -> p1
game = makeGame(
pool,
whiteMember.userId -> whitePerf,

View File

@ -108,19 +108,19 @@ object DataForm {
object PrefData {
def apply(pref: Pref): PrefData = PrefData(
display = DisplayData(
highlight = pref.highlight.fold(1, 0),
destination = pref.destination.fold(1, 0),
highlight = if (pref.highlight) 1 else 0,
destination = if (pref.destination) 1 else 0,
animation = pref.animation,
coords = pref.coords,
replay = pref.replay,
captured = pref.captured.fold(1, 0),
captured = if (pref.captured) 1 else 0,
blindfold = pref.blindfold,
zen = pref.zen.some,
pieceNotation = pref.pieceNotation.some
),
behavior = BehaviorData(
moveEvent = pref.moveEvent.some,
premove = pref.premove.fold(1, 0),
premove = if (pref.premove) 1 else 0,
takeback = pref.takeback,
autoQueen = pref.autoQueen,
autoThreefold = pref.autoThreefold,
@ -130,9 +130,9 @@ object DataForm {
rookCastle = pref.rookCastle.some
),
clockTenths = pref.clockTenths,
clockBar = pref.clockBar.fold(1, 0),
clockSound = pref.clockSound.fold(1, 0),
follow = pref.follow.fold(1, 0),
clockBar = if (pref.clockBar) 1 else 0,
clockSound = if (pref.clockSound) 1 else 0,
follow = if (pref.follow) 1 else 0,
challenge = pref.challenge,
message = pref.message,
studyInvite = pref.studyInvite.some,

View File

@ -3,13 +3,13 @@ package lila.puzzle
case class AggregateVote(up: Int, down: Int, nb: Int, ratio: Int) {
def add(v: Boolean) = copy(
up = up + v.fold(1, 0),
down = down + v.fold(0, 1)
up = up + (if (v) 1 else 0),
down = down + (if (v) 0 else 1)
).computeNbAndRatio
def change(from: Boolean, to: Boolean) = if (from == to) this else copy(
up = up + to.fold(1, -1),
down = down + to.fold(-1, 1)
up = up + (if (to) 1 else -1),
down = down + (if (to) -1 else 1)
).computeNbAndRatio
def count = up + down

View File

@ -51,10 +51,10 @@ private final class GameJson(
"color" -> p.color.name
)
}),
"treeParts" -> onlyLast.fold(
tree.mainlineNodeList.lastOption.map(minimalNodeJsonWriter.writes),
partitionTreeJsonWriter.writes(tree).some
)
"treeParts" -> {
if (onlyLast) tree.mainlineNodeList.lastOption.map(minimalNodeJsonWriter.writes)
else partitionTreeJsonWriter.writes(tree).some
}
).add("clock", game.clock.map(_.config.show))
}
}

View File

@ -122,7 +122,7 @@ private object RelayFetch {
}
def maxChapters(relay: Relay) =
lila.study.Study.maxChapters * relay.official.fold(2, 1)
lila.study.Study.maxChapters * (if (relay.official) 2 else 1)
import com.github.blemale.scaffeine.{ Cache, Scaffeine }
private val cache: Cache[Upstream, GamesSeenBy] = Scaffeine()

View File

@ -83,7 +83,7 @@ final class JsonView(
"animationDuration" -> animationDuration(pov, pref),
"coords" -> pref.coords,
"replay" -> pref.replay,
"autoQueen" -> (pov.game.variant == chess.variant.Antichess).fold(Pref.AutoQueen.NEVER, pref.autoQueen),
"autoQueen" -> (if (pov.game.variant == chess.variant.Antichess) Pref.AutoQueen.NEVER else pref.autoQueen),
"clockTenths" -> pref.clockTenths,
"moveEvent" -> pref.moveEvent
).add("is3d" -> pref.is3d)
@ -276,10 +276,10 @@ final class JsonView(
}
private def animationDuration(pov: Pov, pref: Pref) = math.round {
animationFactor(pref) * baseAnimationDuration.toMillis * pov.game.finished.fold(
1,
math.max(0, math.min(1.2, ((pov.game.estimateTotalTime - 60) / 60) * 0.2))
)
animationFactor(pref) * baseAnimationDuration.toMillis * {
if (pov.game.finished) 1
else math.max(0, math.min(1.2, ((pov.game.estimateTotalTime - 60) / 60) * 0.2))
}
}
}

View File

@ -6,9 +6,9 @@ import chess.format.{ Forsyth, FEN, Uci }
import chess.{ MoveMetrics, Centis, Status, Color, MoveOrDrop }
import actorApi.round.{ HumanPlay, DrawNo, TooManyPlies, TakebackNo, ForecastPlay }
import lila.hub.actorApi.round.BotPlay
import akka.actor.ActorRef
import lila.game.{ Game, Progress, Pov, UciMemo }
import lila.hub.actorApi.round.BotPlay
private[round] final class Player(
fishnetPlayer: lila.fishnet.Player,
@ -73,17 +73,17 @@ private[round] final class Player(
)(implicit proxy: GameProxy): Fu[Events] = {
if (pov.game.hasAi) uciMemo.add(pov.game, moveOrDrop)
notifyMove(moveOrDrop, progress.game)
progress.game.finished.fold(
moveFinish(progress.game, pov.color) dmap { progress.events ::: _ }, {
if (progress.game.playableByAi) requestFishnet(progress.game, round)
if (pov.opponent.isOfferingDraw) round ! DrawNo(pov.player.id)
if (pov.player.isProposingTakeback) round ! TakebackNo(pov.player.id)
if (pov.game.forecastable) moveOrDrop.left.toOption.foreach { move =>
round ! ForecastPlay(move)
}
fuccess(progress.events)
val res = if (progress.game.finished) moveFinish(progress.game, pov.color) dmap { progress.events ::: _ }
else {
if (progress.game.playableByAi) requestFishnet(progress.game, round)
if (pov.opponent.isOfferingDraw) round ! DrawNo(pov.player.id)
if (pov.player.isProposingTakeback) round ! TakebackNo(pov.player.id)
if (pov.game.forecastable) moveOrDrop.left.toOption.foreach { move =>
round ! ForecastPlay(move)
}
) >>- promiseOption.foreach(_.success(()))
fuccess(progress.events)
}
res >>- promiseOption.foreach(_.success(()))
}
private[round] def fishnet(game: Game, uci: Uci, currentFen: FEN, round: ActorRef)(implicit proxy: GameProxy): Fu[Events] =
@ -95,11 +95,10 @@ private[round] final class Player(
case MoveApplied(progress, moveOrDrop) =>
proxy.save(progress) >>-
uciMemo.add(progress.game, moveOrDrop) >>-
notifyMove(moveOrDrop, progress.game) >>
progress.game.finished.fold(
moveFinish(progress.game, game.turnColor) dmap { progress.events ::: _ },
fuccess(progress.events)
)
notifyMove(moveOrDrop, progress.game) >> {
if (progress.game.finished) moveFinish(progress.game, game.turnColor) dmap { progress.events ::: _ }
else fuccess(progress.events)
}
}
else requestFishnet(game, round) >> fufail(FishnetError("Invalid AI move current FEN"))
} else fufail(FishnetError("Not AI turn"))

View File

@ -71,7 +71,7 @@ private[round] final class Socket(
}
def isGone: Fu[Boolean] = {
time < (nowMillis - isBye.fold(ragequitTimeout, disconnectTimeout).toMillis) &&
time < (nowMillis - (if (isBye) ragequitTimeout else disconnectTimeout).toMillis) &&
!botConnected
} ?? !isHostingSimul

View File

@ -66,7 +66,8 @@ private[round] final class Takebacker(
private def IfAllowed[A](game: Game)(f: => Fu[A]): Fu[A] =
if (!game.playable) fufail(ClientError("[takebacker] game is over " + game.id))
else isAllowedByPrefs(game) flatMap {
_.fold(f, fufail(ClientError("[takebacker] disallowed by preferences " + game.id)))
case true => f
case _ => fufail(ClientError("[takebacker] disallowed by preferences " + game.id))
}
private def single(game: Game)(implicit proxy: GameProxy): Fu[Events] = for {

View File

@ -17,9 +17,9 @@ object Range {
def apply[A](a: Option[A], b: Option[A])(implicit o: Ordering[A]): Range[A] =
(a, b) match {
case (Some(aa), Some(bb)) => o.lt(aa, bb).fold(
new Range(a, b), new Range(b, a)
)
case (Some(aa), Some(bb)) =>
if (o.lt(aa, bb)) new Range(a, b)
else new Range(b, a)
case (x, y) => new Range(x, y)
}

View File

@ -37,7 +37,7 @@ case class AiConfig(
Player.make(chess.Black, user, perfPicker)
),
mode = chess.Mode.Casual,
source = (chessGame.board.variant.fromPosition).fold(Source.Position, Source.Ai),
source = if (chessGame.board.variant.fromPosition) Source.Position else Source.Ai,
daysPerTurn = makeDaysPerTurn,
pgnImport = None
)

View File

@ -36,14 +36,14 @@ private[setup] trait Config {
def makeGame: ChessGame = makeGame(variant)
def validClock = hasClock.fold(clockHasTime, true)
def validClock = !hasClock || clockHasTime
def clockHasTime = time + increment > 0
def makeClock = hasClock option justMakeClock
protected def justMakeClock =
Clock.Config((time * 60).toInt, clockHasTime.fold(increment, 1))
Clock.Config((time * 60).toInt, if (clockHasTime) increment else 1)
def makeDaysPerTurn: Option[Int] = (timeMode == TimeMode.Correspondence) option days
}

View File

@ -25,9 +25,9 @@ case class FilterConfig(
)
def nonEmpty = copy(
variant = variant.isEmpty.fold(FilterConfig.default.variant, variant),
mode = mode.isEmpty.fold(FilterConfig.default.mode, mode),
speed = speed.isEmpty.fold(FilterConfig.default.speed, speed)
variant = if (variant.isEmpty) FilterConfig.default.variant else variant,
mode = if (mode.isEmpty) FilterConfig.default.mode else mode,
speed = if (speed.isEmpty) FilterConfig.default.speed else speed
)
}

View File

@ -44,7 +44,7 @@ case class HookConfig(
uid = uid,
variant = variant,
clock = clock,
mode = lila.game.Game.allowRated(variant, clock.some).fold(mode, Mode.Casual),
mode = if (lila.game.Game.allowRated(variant, clock.some)) mode else Mode.Casual,
color = color.name,
user = user,
blocking = blocking,

View File

@ -34,7 +34,7 @@ case class AnaDrop(
opening = Variant.openingSensibleVariants(variant) ?? {
FullOpeningDB findByFen fen
},
drops = movable.fold(game.situation.drops, Some(Nil)),
drops = if (movable) game.situation.drops else Some(Nil),
crazyData = game.situation.board.crazyData
)
}

View File

@ -42,7 +42,7 @@ case class AnaMove(
opening = (game.turns <= 30 && Variant.openingSensibleVariants(variant)) ?? {
FullOpeningDB findByFen fen
},
drops = movable.fold(game.situation.drops, Some(Nil)),
drops = if (movable) game.situation.drops else Some(Nil),
crazyData = game.situation.board.crazyData
)
}

View File

@ -40,10 +40,9 @@ object Handler {
case ("startWatching", o) => o str "d" foreach { ids =>
hub.actor.moveBroadcast ! StartWatching(uid.value, member, ids.split(' ').toSet)
}
case ("moveLat", o) => hub.channel.roundMoveTime ! (~(o boolean "d")).fold(
Channel.Sub(member),
Channel.UnSub(member)
)
case ("moveLat", o) => hub.channel.roundMoveTime ! {
if (~(o boolean "d")) Channel.Sub(member) else Channel.UnSub(member)
}
case ("anaMove", o) => AnaRateLimit(uid.value, member) {
AnaMove parse o foreach { anaMove =>
member push {

View File

@ -140,7 +140,7 @@ final class StudyRepo(private[study] val coll: Coll) {
countLikes(studyId).flatMap {
case None => fuccess(Study.Likes(0))
case Some((prevLikes, createdAt)) =>
val likes = Study.Likes(prevLikes.value + v.fold(1, -1))
val likes = Study.Likes(prevLikes.value + (if (v) 1 else -1))
coll.update(
$id(studyId),
$set(

View File

@ -38,7 +38,7 @@ private[team] final class DataForm(
)(TeamEdit.apply)(TeamEdit.unapply)) fill TeamEdit(
location = team.location,
description = team.description,
open = team.open.fold(1, 0)
open = if (team.open) 1 else 0
)
val request = Form(mapping(

View File

@ -70,6 +70,6 @@ object Team {
def nameToId(name: String) = (lila.common.String slugify name) |> { slug =>
// if most chars are not latin, go for random slug
(slug.size > (name.size / 2)).fold(slug, Random nextString 8)
if (slug.size > (name.size / 2)) slug else Random nextString 8
}
}

View File

@ -62,10 +62,8 @@ private[timeline] final class Push(
private def makeEntry(users: List[String], data: Atom): Fu[Entry] = {
val entry = Entry.make(data)
entryApi.findRecent(entry.typ, DateTime.now minusMinutes 60, 1000) flatMap { entries =>
entries.exists(_ similarTo entry) fold (
fufail[Entry]("[timeline] a similar entry already exists"),
entryApi insert Entry.ForUsers(entry, users) inject entry
)
if (entries.exists(_ similarTo entry)) fufail[Entry]("[timeline] a similar entry already exists")
else entryApi insert Entry.ForUsers(entry, users) inject entry
}
}
}

View File

@ -149,7 +149,10 @@ object BSONHandlers {
status = chess.Status(r int "s") err "tournament pairing status",
user1 = user1,
user2 = user2,
winner = r boolO "w" map (_.fold(user1, user2)),
winner = r boolO "w" map {
case true => user1
case _ => user2
},
turns = r intO "t",
berserk1 = r.intO("b1").fold(r.boolD("b1"))(1 ==), // it used to be int = 0/1
berserk2 = r.intO("b2").fold(r.boolD("b2"))(1 ==)

View File

@ -35,8 +35,8 @@ object PairingRepo {
).sort(recentSort).cursor[Bdoc]().fold(Map.empty[User.ID, User.ID], nb) { (acc, doc) =>
~doc.getAs[List[User.ID]]("u") match {
case List(u1, u2) =>
val acc1 = acc.contains(u1).fold(acc, acc.updated(u1, u2))
acc.contains(u2).fold(acc1, acc1.updated(u2, u1))
val acc1 = if (acc.contains(u1)) acc else acc.updated(u1, u2)
if (acc.contains(u2)) acc1 else acc1.updated(u2, u1)
}
} map Pairing.LastOpponents.apply

View File

@ -18,7 +18,7 @@ final class Authenticator(
def compare(auth: AuthData, p: ClearPassword): Boolean = {
val newP = auth.salt.fold(p) { s =>
val salted = s"${p.value}{$s}" // BC
ClearPassword((~auth.sha512).fold(salted.sha512, salted.sha1))
ClearPassword(if (~auth.sha512) salted.sha512 else salted.sha1)
}
passHasher.check(auth.bpass, newP)
}

View File

@ -32,17 +32,16 @@ final class NoteApi(
def get(user: User, me: User, myFriendIds: Set[String], isMod: Boolean): Fu[List[Note]] =
coll.find(
$doc("to" -> user.id) ++
me.troll.fold($empty, $doc("troll" -> false)) ++
isMod.fold(
$or(
"from" $in (myFriendIds + me.id),
"mod" $eq true
),
(!me.troll ?? $doc("troll" -> false)) ++
(if (isMod) $or(
"from" $in (myFriendIds + me.id),
"mod" $eq true
)
else
$doc(
"from" $in (myFriendIds + me.id),
"mod" -> false
)
)
))
).sort($doc("date" -> -1)).list[Note](20)
def forMod(id: User.ID): Fu[List[Note]] =

View File

@ -124,8 +124,8 @@ object UserRepo {
doc.getAs[User.ID]("_id") contains u1
}
}.addEffect { v =>
incColor(u1, v.fold(1, -1))
incColor(u2, v.fold(-1, 1))
incColor(u1, if (v) 1 else -1)
incColor(u2, if (v) -1 else 1)
}
def firstGetsWhite(u1O: Option[User.ID], u2O: Option[User.ID]): Fu[Boolean] =
@ -183,9 +183,9 @@ object UserRepo {
coll.primitiveOne[User.PlayTime]($id(id), F.playTime)
val enabledSelect = $doc(F.enabled -> true)
def engineSelect(v: Boolean) = $doc(F.engine -> v.fold[BSONValue]($boolean(true), $ne(true)))
def trollSelect(v: Boolean) = $doc(F.troll -> v.fold[BSONValue]($boolean(true), $ne(true)))
def boosterSelect(v: Boolean) = $doc(F.booster -> v.fold[BSONValue]($boolean(true), $ne(true)))
def engineSelect(v: Boolean) = $doc(F.engine -> (if (v) $boolean(true) else $ne(true)))
def trollSelect(v: Boolean) = $doc(F.troll -> (if (v) $boolean(true) else $ne(true)))
def boosterSelect(v: Boolean) = $doc(F.booster -> (if (v) $boolean(true) else $ne(true)))
def stablePerfSelect(perf: String) = $doc(
s"perfs.$perf.nb" -> $gte(30),
s"perfs.$perf.gl.d" -> $lt(lila.rating.Glicko.provisionalDeviation)