app/ migration WIP
parent
e2c18cb6fd
commit
6bc20d9b75
|
@ -11,6 +11,7 @@ import lila.user.User
|
|||
|
||||
final class Env(
|
||||
val config: Configuration,
|
||||
val db: lila.db.Env,
|
||||
val playApp: Application,
|
||||
val api: lila.api.Env,
|
||||
val user: lila.user.Env,
|
||||
|
@ -31,7 +32,7 @@ final class Env(
|
|||
val teamSearch: lila.teamSearch.Env,
|
||||
val analyse: lila.analyse.Env,
|
||||
val mod: lila.mod.Env,
|
||||
val notifyModule: lila.notify.Env,
|
||||
val notify: lila.notify.Env,
|
||||
val round: lila.round.Env,
|
||||
val lobby: lila.lobby.Env,
|
||||
val setup: lila.setup.Env,
|
||||
|
@ -106,9 +107,9 @@ final class Env(
|
|||
}
|
||||
|
||||
def closeAccount(userId: lila.user.User.ID, self: Boolean): Funit = for {
|
||||
u <- user.userRepo byId userId orFail s"No such user $userId"
|
||||
u <- user.repo byId userId orFail s"No such user $userId"
|
||||
goodUser <- !u.lameOrTroll ?? { !playban.api.hasCurrentBan(u.id) }
|
||||
_ <- user.userRepo.disable(u, keepEmail = !goodUser)
|
||||
_ <- user.repo.disable(u, keepEmail = !goodUser)
|
||||
_ <- !goodUser ?? relation.api.fetchFollowing(u.id) flatMap {
|
||||
activity.write.unfollowAll(u, _)
|
||||
}
|
||||
|
@ -131,7 +132,7 @@ final class Env(
|
|||
|
||||
Bus.subscribeFun("garbageCollect") {
|
||||
case lila.hub.actorApi.security.GarbageCollect(userId, _) =>
|
||||
user.userRepo.isTroll(userId) foreach { troll =>
|
||||
user.repo.isTroll(userId) foreach { troll =>
|
||||
if (troll) kill(userId) // GC can be aborted by reverting the initial SB mark
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ final class Account(
|
|||
FormFuResult(env.user.forms.profile) { err =>
|
||||
fuccess(html.account.profile(me, err))
|
||||
} { profile =>
|
||||
env.user.userRepo.setProfile(me.id, profile) inject Redirect(routes.User show me.username)
|
||||
env.user.repo.setProfile(me.id, profile) inject Redirect(routes.User show me.username)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ final class Account(
|
|||
FormFuResult(env.user.forms.username(me)) { err =>
|
||||
fuccess(html.account.username(me, err))
|
||||
} { username =>
|
||||
env.user.userRepo.setUsernameCased(me.id, username) inject Redirect(routes.User show me.username) recoverWith {
|
||||
env.user.repo.setUsernameCased(me.id, username) inject Redirect(routes.User show me.username) recoverWith {
|
||||
case e => fuccess(html.account.username(me, env.user.forms.username(me).withGlobalError(e.getMessage)))
|
||||
}
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ final class Account(
|
|||
}
|
||||
}
|
||||
|
||||
private def emailForm(user: UserModel) = env.user.userRepo email user.id flatMap {
|
||||
private def emailForm(user: UserModel) = env.user.repo email user.id flatMap {
|
||||
env.security.forms.changeEmail(user, _)
|
||||
}
|
||||
|
||||
|
@ -138,7 +138,7 @@ final class Account(
|
|||
}
|
||||
|
||||
def apiEmail = Scoped(_.Email.Read) { _ => me =>
|
||||
env.user.userRepo email me.id map {
|
||||
env.user.repo email me.id map {
|
||||
_ ?? { email =>
|
||||
JsonOk(Json.obj("email" -> email.value))
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ final class Account(
|
|||
implicit val req = ctx.body
|
||||
helpForm.bindFromRequest.fold(
|
||||
err => BadRequest(html.account.emailConfirmHelp(err, none)).fuccess,
|
||||
username => getStatus(env.user.userRepo, username) map { status =>
|
||||
username => getStatus(env.user.repo, username) map { status =>
|
||||
Ok(html.account.emailConfirmHelp(helpForm fill username, status.some))
|
||||
}
|
||||
)
|
||||
|
@ -214,7 +214,7 @@ final class Account(
|
|||
FormFuResult(form) { err =>
|
||||
fuccess(html.account.twoFactor.setup(me, err))
|
||||
} { data =>
|
||||
env.user.userRepo.setupTwoFactor(me.id, TotpSecret(data.secret)) >>
|
||||
env.user.repo.setupTwoFactor(me.id, TotpSecret(data.secret)) >>
|
||||
env.security.store.closeUserExceptSessionId(me.id, currentSessionId) >>
|
||||
env.push.webSubscriptionApi.unsubscribeByUserExceptSession(me, currentSessionId) inject
|
||||
Redirect(routes.Account.twoFactor)
|
||||
|
@ -230,7 +230,7 @@ final class Account(
|
|||
FormFuResult(form) { err =>
|
||||
fuccess(html.account.twoFactor.disable(me, err))
|
||||
} { _ =>
|
||||
env.user.userRepo.disableTwoFactor(me.id) inject Redirect(routes.Account.twoFactor)
|
||||
env.user.repo.disableTwoFactor(me.id) inject Redirect(routes.Account.twoFactor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -264,14 +264,14 @@ final class Account(
|
|||
|
||||
// App BC
|
||||
def kidToggle = Auth { ctx => me =>
|
||||
env.user.userRepo.setKid(me, !me.kid) inject Ok
|
||||
env.user.repo.setKid(me, !me.kid) inject Ok
|
||||
}
|
||||
|
||||
def kidPost = Auth { implicit ctx => me =>
|
||||
env.user.userRepo.setKid(me, getBool("v")) inject Redirect(routes.Account.kid)
|
||||
env.user.repo.setKid(me, getBool("v")) inject Redirect(routes.Account.kid)
|
||||
}
|
||||
def apiKidPost = Scoped(_.Preference.Write) { req => me =>
|
||||
env.user.userRepo.setKid(me, getBool("v", req)) inject jsonOkResult
|
||||
env.user.repo.setKid(me, getBool("v", req)) inject jsonOkResult
|
||||
}
|
||||
|
||||
private def currentSessionId(implicit ctx: Context) =
|
||||
|
|
|
@ -74,7 +74,7 @@ final class Api(
|
|||
UsersRateLimitPerIP(ip, cost = cost) {
|
||||
UsersRateLimitGlobal("-", cost = cost, msg = ip.value) {
|
||||
lila.mon.api.users.cost(cost)
|
||||
env.user.userRepo nameds usernames map {
|
||||
env.user.repo nameds usernames map {
|
||||
_.map { env.user.jsonView(_, none) }
|
||||
} map toApiResult map toHttp
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ final class Api(
|
|||
val cost = page * nb.value + 10
|
||||
UserGamesRateLimit(cost, req) {
|
||||
lila.mon.api.userGames.cost(cost)
|
||||
env.user.userRepo named name flatMap {
|
||||
env.user.repo named name flatMap {
|
||||
_ ?? { user =>
|
||||
gameApi.byUser(
|
||||
user = user,
|
||||
|
@ -269,7 +269,7 @@ final class Api(
|
|||
}
|
||||
|
||||
def tournamentsByOwner(name: String) = Action.async { req =>
|
||||
(name != "lichess") ?? env.user.userRepo.named(name) flatMap {
|
||||
(name != "lichess") ?? env.user.repo.named(name) flatMap {
|
||||
_ ?? { user =>
|
||||
GlobalLinearLimitPerIP(HTTPRequest lastRemoteAddress req) {
|
||||
val nb = getInt("nb", req) | Int.MaxValue
|
||||
|
@ -309,7 +309,7 @@ final class Api(
|
|||
def activity(name: String) = ApiRequest { req =>
|
||||
UserActivityRateLimitPerIP(HTTPRequest lastRemoteAddress req, cost = 1) {
|
||||
lila.mon.api.activity.cost(1)
|
||||
env.user.userRepo named name flatMap {
|
||||
env.user.repo named name flatMap {
|
||||
_ ?? { user =>
|
||||
env.activity.read.recent(user) flatMap {
|
||||
_.map { env.activity.jsonView(_, user) }.sequenceFu
|
||||
|
|
|
@ -109,7 +109,7 @@ final class Auth(
|
|||
result => result.toOption match {
|
||||
case None => InternalServerError("Authentication error").fuccess
|
||||
case Some(u) =>
|
||||
env.user.userRepo.email(u.id) foreach {
|
||||
env.user.repo.email(u.id) foreach {
|
||||
_ foreach { garbageCollect(u, _) }
|
||||
}
|
||||
authenticateUser(u, Some(redirectTo))
|
||||
|
@ -210,7 +210,7 @@ final class Auth(
|
|||
lila.mon.user.register.mustConfirmEmail(mustConfirm.toString)()
|
||||
val email = env.security.emailAddressValidator.validate(data.realEmail) err s"Invalid email ${data.email}"
|
||||
val passwordHash = env.user.authenticator passEnc ClearPassword(data.password)
|
||||
env.user.userRepo.create(data.username, passwordHash, email.acceptable, ctx.blind, none,
|
||||
env.user.repo.create(data.username, passwordHash, email.acceptable, ctx.blind, none,
|
||||
mustConfirmEmail = mustConfirm.value)
|
||||
.orFail(s"No user could be created for ${data.username}")
|
||||
.addEffect { logSignup(_, email.acceptable, data.fingerPrint, mustConfirm) }
|
||||
|
@ -242,7 +242,7 @@ final class Auth(
|
|||
lila.mon.user.register.mobile()
|
||||
lila.mon.user.register.mustConfirmEmail(mustConfirm.toString)()
|
||||
val passwordHash = env.user.authenticator passEnc ClearPassword(data.password)
|
||||
env.user.userRepo.create(data.username, passwordHash, email.acceptable, false, apiVersion.some,
|
||||
env.user.repo.create(data.username, passwordHash, email.acceptable, false, apiVersion.some,
|
||||
mustConfirmEmail = mustConfirm.value)
|
||||
.orFail(s"No user could be created for ${data.username}")
|
||||
.addEffect { logSignup(_, email.acceptable, none, mustConfirm) }
|
||||
|
@ -289,7 +289,7 @@ final class Auth(
|
|||
case None => lila.security.EmailConfirm.cookie get ctx.req match {
|
||||
case None => Ok(accountC.renderCheckYourEmail).fuccess
|
||||
case Some(userEmail) =>
|
||||
env.user.userRepo nameExists userEmail.username map {
|
||||
env.user.repo nameExists userEmail.username map {
|
||||
case false => Redirect(routes.Auth.signup) withCookies env.lilaCookie.newSession(ctx.req)
|
||||
case true => Ok(accountC.renderCheckYourEmail)
|
||||
}
|
||||
|
@ -303,15 +303,15 @@ final class Auth(
|
|||
implicit val req = ctx.body
|
||||
forms.preloadEmailDns >> forms.fixEmail(userEmail.email).bindFromRequest.fold(
|
||||
err => BadRequest(html.auth.checkYourEmail(userEmail.some, err.some)).fuccess,
|
||||
email => env.user.userRepo.named(userEmail.username) flatMap {
|
||||
email => env.user.repo.named(userEmail.username) flatMap {
|
||||
_.fold(Redirect(routes.Auth.signup).fuccess) { user =>
|
||||
env.user.userRepo.mustConfirmEmail(user.id) flatMap {
|
||||
env.user.repo.mustConfirmEmail(user.id) flatMap {
|
||||
case false => Redirect(routes.Auth.login).fuccess
|
||||
case _ =>
|
||||
val newUserEmail = userEmail.copy(email = EmailAddress(email))
|
||||
EmailConfirmRateLimit(newUserEmail, ctx.req) {
|
||||
lila.mon.email.types.fix()
|
||||
env.user.userRepo.setEmail(user.id, newUserEmail.email) >>
|
||||
env.user.repo.setEmail(user.id, newUserEmail.email) >>
|
||||
env.security.emailConfirm.send(user, newUserEmail.email) inject {
|
||||
Redirect(routes.Auth.checkYourEmail) withCookies
|
||||
lila.security.EmailConfirm.cookie.make(env.lilaCookie, user, newUserEmail.email)(ctx.req)
|
||||
|
@ -336,7 +336,7 @@ final class Auth(
|
|||
Redirect(routes.Auth.login).fuccess
|
||||
case Result.JustConfirmed(user) =>
|
||||
lila.mon.user.register.confirmEmailResult(true)()
|
||||
env.user.userRepo.email(user.id).flatMap {
|
||||
env.user.repo.email(user.id).flatMap {
|
||||
_.?? { email =>
|
||||
authLog(user.username, email.value, s"Confirmed email ${email.value}")
|
||||
welcome(user, email)
|
||||
|
@ -359,7 +359,7 @@ final class Auth(
|
|||
_ ?? { hash =>
|
||||
!me.lame ?? (for {
|
||||
otherIds <- api.recentUserIdsByFingerHash(hash).map(_.filter(me.id!=))
|
||||
autoReport <- (otherIds.size >= 2) ?? env.user.userRepo.countEngines(otherIds).flatMap {
|
||||
autoReport <- (otherIds.size >= 2) ?? env.user.repo.countEngines(otherIds).flatMap {
|
||||
case nb if nb >= 2 && nb >= otherIds.size / 2 => env.report.api.autoCheatPrintReport(me.id)
|
||||
case _ => funit
|
||||
}
|
||||
|
@ -381,7 +381,7 @@ final class Auth(
|
|||
BadRequest(html.auth.bits.passwordReset(err, captcha, false.some))
|
||||
},
|
||||
data => {
|
||||
env.user.userRepo.enabledWithEmail(data.realEmail.normalize) flatMap {
|
||||
env.user.repo.enabledWithEmail(data.realEmail.normalize) flatMap {
|
||||
case Some((user, storedEmail)) => {
|
||||
lila.mon.user.auth.passwordResetRequest("success")()
|
||||
env.security.passwordReset.send(user, storedEmail) inject Redirect(routes.Auth.passwordResetSent(storedEmail.conceal))
|
||||
|
@ -430,8 +430,8 @@ final class Auth(
|
|||
} { data =>
|
||||
HasherRateLimit(user.username, ctx.req) { _ =>
|
||||
env.user.authenticator.setPassword(user.id, ClearPassword(data.newPasswd1)) >>
|
||||
env.user.userRepo.setEmailConfirmed(user.id).flatMap { _ ?? { e => welcome(user, e) } } >>
|
||||
env.user.userRepo.disableTwoFactor(user.id) >>
|
||||
env.user.repo.setEmailConfirmed(user.id).flatMap { _ ?? { e => welcome(user, e) } } >>
|
||||
env.user.repo.disableTwoFactor(user.id) >>
|
||||
env.security.store.disconnect(user.id) >>
|
||||
env.push.webSubscriptionApi.unsubscribeByUser(user) >>
|
||||
authenticateUser(user) >>-
|
||||
|
@ -454,7 +454,7 @@ final class Auth(
|
|||
BadRequest(html.auth.bits.magicLink(err, captcha, false.some))
|
||||
},
|
||||
data =>
|
||||
env.user.userRepo.enabledWithEmail(data.realEmail.normalize) flatMap {
|
||||
env.user.repo.enabledWithEmail(data.realEmail.normalize) flatMap {
|
||||
case Some((user, storedEmail)) => {
|
||||
MagicLinkRateLimit(user, storedEmail, ctx.req) {
|
||||
lila.mon.user.auth.magicLinkRequest("success")()
|
||||
|
|
|
@ -28,7 +28,7 @@ final class Bot(
|
|||
def command(cmd: String) = ScopedBody(_.Bot.Play) { implicit req => me =>
|
||||
cmd.split('/') match {
|
||||
case Array("account", "upgrade") =>
|
||||
env.user.userRepo.setBot(me) >>
|
||||
env.user.repo.setBot(me) >>
|
||||
env.pref.api.setBot(me) >>-
|
||||
env.user.lightUserApi.invalidate(me.id) inject jsonOkResult recover {
|
||||
case e: lila.base.LilaException => BadRequest(jsonError(e.getMessage))
|
||||
|
|
|
@ -49,7 +49,7 @@ final class Challenge(
|
|||
case None => Ok(html.challenge.mine(c, json, none))
|
||||
}
|
||||
}
|
||||
else (c.challengerUserId ?? env.user.userRepo.named) map { user =>
|
||||
else (c.challengerUserId ?? env.user.repo.named) map { user =>
|
||||
Ok(html.challenge.theirs(c, json, user))
|
||||
},
|
||||
api = _ => Ok(json).fuccess
|
||||
|
@ -138,7 +138,7 @@ final class Challenge(
|
|||
"username" -> lila.user.DataForm.historicalUsernameField
|
||||
)).bindFromRequest.fold(
|
||||
err => funit,
|
||||
username => env.user.userRepo named username flatMap {
|
||||
username => env.user.repo named username flatMap {
|
||||
case None => Redirect(routes.Challenge.show(c.id)).fuccess
|
||||
case Some(dest) => env.challenge.granter(ctx.me, dest, c.perfType.some) flatMap {
|
||||
case Some(denied) => showChallenge(c, lila.challenge.ChallengeDenied.translated(denied).some)
|
||||
|
@ -155,7 +155,7 @@ final class Challenge(
|
|||
setupC.PostRateLimit(HTTPRequest lastRemoteAddress req) {
|
||||
env.setup.forms.api.bindFromRequest.fold(
|
||||
jsonFormErrorDefaultLang,
|
||||
config => env.user.userRepo enabledById userId.toLowerCase flatMap { destUser =>
|
||||
config => env.user.repo enabledById userId.toLowerCase flatMap { destUser =>
|
||||
destUser ?? { env.challenge.granter(me.some, _, config.perfType) } flatMap {
|
||||
case Some(denied) =>
|
||||
BadRequest(jsonError(lila.challenge.ChallengeDenied.translated(denied))).fuccess
|
||||
|
@ -189,7 +189,7 @@ final class Challenge(
|
|||
|
||||
def rematchOf(gameId: String) = Auth { implicit ctx => me =>
|
||||
OptionFuResult(env.game.gameRepo game gameId) { g =>
|
||||
Pov.opponentOfUserId(g, me.id).flatMap(_.userId) ?? env.user.userRepo.byId flatMap {
|
||||
Pov.opponentOfUserId(g, me.id).flatMap(_.userId) ?? env.user.repo.byId flatMap {
|
||||
_ ?? { opponent =>
|
||||
env.challenge.granter(me.some, opponent, g.perfType) flatMap {
|
||||
case Some(d) => BadRequest(jsonError {
|
||||
|
|
|
@ -84,7 +84,7 @@ final class ForumTopic(env: Env) extends LilaController(env) with ForumControlle
|
|||
def participants(topicId: String) = Auth { _ => _ =>
|
||||
for {
|
||||
userIds <- postApi userIds topicId
|
||||
usernames <- env.user.userRepo usernamesByIds userIds
|
||||
usernames <- env.user.repo usernamesByIds userIds
|
||||
} yield Ok(Json.toJson(usernames.sortBy(_.toLowerCase)))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ final class Game(
|
|||
)
|
||||
|
||||
private def handleExport(username: String, me: Option[lila.user.User], req: RequestHeader, oauth: Boolean) =
|
||||
env.user.userRepo named username flatMap {
|
||||
env.user.repo named username flatMap {
|
||||
_ ?? { user =>
|
||||
apiC.GlobalLinearLimitPerIP(HTTPRequest lastRemoteAddress req) {
|
||||
apiC.GlobalLinearLimitPerUserOption(me) {
|
||||
|
@ -119,7 +119,7 @@ final class Game(
|
|||
private def WithVs(req: RequestHeader)(f: Option[lila.user.User] => Fu[Result]): Fu[Result] =
|
||||
get("vs", req) match {
|
||||
case None => f(none)
|
||||
case Some(name) => env.user.userRepo named name flatMap {
|
||||
case Some(name) => env.user.repo named name flatMap {
|
||||
case None => notFoundJson(s"No such opponent: $name")
|
||||
case Some(user) => f(user.some)
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ final class I18n(env: Env) extends LilaController(env) {
|
|||
code => {
|
||||
val lang = toLang(code) err "Universe is collapsing"
|
||||
ctx.me.filterNot(_.lang contains lang.code).?? { me =>
|
||||
env.user.userRepo.setLang(me.id, lang.code)
|
||||
env.user.repo.setLang(me.id, lang.code)
|
||||
} >> negotiate(
|
||||
html = {
|
||||
val redir = Redirect {
|
||||
|
|
|
@ -57,7 +57,7 @@ final class Insight(env: Env) extends LilaController(env) {
|
|||
}
|
||||
|
||||
private def Accessible(username: String)(f: lila.user.User => Fu[Result])(implicit ctx: Context) =
|
||||
env.user.userRepo named username flatMap {
|
||||
env.user.repo named username flatMap {
|
||||
_.fold(notFound) { u =>
|
||||
env.insight.share.grant(u, ctx.me) flatMap {
|
||||
case true => f(u)
|
||||
|
|
|
@ -392,7 +392,7 @@ private[controllers] abstract class LilaController(val env: Env)
|
|||
env.relation.online.friendsOf(me.id) zip
|
||||
env.team.api.nbRequests(me.id) zip
|
||||
env.challenge.api.countInFor.get(me.id) zip
|
||||
env.notifyModule.api.unreadCount(Notifies(me.id)).dmap(_.value) zip
|
||||
env.notify.api.unreadCount(Notifies(me.id)).dmap(_.value) zip
|
||||
env.mod.inquiryApi.forMod(me)
|
||||
} else fuccess {
|
||||
((((OnlineFriends.empty, 0), 0), 0), none)
|
||||
|
|
|
@ -88,9 +88,9 @@ final class Main(
|
|||
import chess.format.pgn.Glyph
|
||||
import lila.tree.Node.glyphWriter
|
||||
Ok(Json.obj(
|
||||
"move" -> Glyph.MoveAssessment.display,
|
||||
"position" -> Glyph.PositionAssessment.display,
|
||||
"observation" -> Glyph.Observation.display
|
||||
"move" -> (Glyph.MoveAssessment.display: List[Glyph]),
|
||||
"position" -> (Glyph.PositionAssessment.display: List[Glyph]),
|
||||
"observation" -> (Glyph.Observation.display: List[Glyph])
|
||||
)) as JSON
|
||||
}
|
||||
val glyphs = Action(glyphsResult)
|
||||
|
@ -147,14 +147,14 @@ Disallow: /games/export
|
|||
if (ctx.isAuth) fuccess(Redirect(routes.Lobby.home))
|
||||
else fuccess {
|
||||
Redirect(s"${routes.Lobby.home}#pool/10+0").withCookies(
|
||||
lila.common.LilaCookie.withSession { s =>
|
||||
env.lilaCookie.withSession { s =>
|
||||
s + ("theme" -> "ic") + ("pieceSet" -> "icpieces")
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
def legacyQaQuestion(id: Int, slug: String) = Open { implicit ctx =>
|
||||
def legacyQaQuestion(id: Int, slug: String) = Open { _ =>
|
||||
MovedPermanently {
|
||||
val faq = routes.Main.faq.url
|
||||
id match {
|
||||
|
@ -179,6 +179,4 @@ Disallow: /games/export
|
|||
}
|
||||
}.fuccess
|
||||
}
|
||||
|
||||
def versionedAsset(version: String, file: String) = Assets.at(path = "/public", file)
|
||||
}
|
||||
|
|
|
@ -132,7 +132,7 @@ final class Message(env: Env) extends LilaController(env) {
|
|||
}
|
||||
|
||||
private def renderForm(me: UserModel, title: Option[String], f: Form[_] => Form[_])(implicit ctx: Context): Fu[Frag] =
|
||||
get("user") ?? env.user.userRepo.named flatMap { user =>
|
||||
get("user") ?? env.user.repo.named flatMap { user =>
|
||||
user.fold(fuTrue)(u => security.canMessage(me.id, u.id)) map { canMessage =>
|
||||
html.message.form(
|
||||
f(forms thread me),
|
||||
|
|
|
@ -5,7 +5,7 @@ import lila.app._
|
|||
import lila.chat.Chat
|
||||
import lila.common.{ IpAddress, EmailAddress, HTTPRequest }
|
||||
import lila.mod.UserSearch
|
||||
import lila.report.{ Suspect, Mod => AsMod, SuspectId }
|
||||
import lila.report.{ Suspect, Mod => AsMod }
|
||||
import lila.security.{ Permission, FingerHash }
|
||||
import lila.user.{ User => UserModel, Title }
|
||||
import ornicar.scalalib.Zero
|
||||
|
@ -14,9 +14,12 @@ import views._
|
|||
import play.api.data._
|
||||
import play.api.data.Forms._
|
||||
import play.api.mvc._
|
||||
import scala.concurrent.duration._
|
||||
|
||||
final class Mod(env: Env) extends LilaController(env) {
|
||||
final class Mod(
|
||||
env: Env,
|
||||
reportC: Report,
|
||||
userC: User
|
||||
) extends LilaController(env) {
|
||||
|
||||
private def modApi = env.mod.api
|
||||
private def modLogApi = env.mod.logApi
|
||||
|
@ -30,7 +33,7 @@ final class Mod(env: Env) extends LilaController(env) {
|
|||
} yield (inquiry, sus).some
|
||||
}
|
||||
}(ctx => me => {
|
||||
case (inquiry, suspect) => Report.onInquiryClose(inquiry, me, suspect.some)(ctx)
|
||||
case (inquiry, suspect) => reportC.onInquiryClose(inquiry, me, suspect.some)(ctx)
|
||||
})
|
||||
|
||||
def publicChat = Secure(_.ChatTimeout) { implicit ctx => _ =>
|
||||
|
@ -48,7 +51,7 @@ final class Mod(env: Env) extends LilaController(env) {
|
|||
} yield (inquiry, suspect).some
|
||||
}
|
||||
}(ctx => me => {
|
||||
case (inquiry, suspect) => Report.onInquiryClose(inquiry, me, suspect.some)(ctx)
|
||||
case (inquiry, suspect) => reportC.onInquiryClose(inquiry, me, suspect.some)(ctx)
|
||||
})
|
||||
|
||||
def troll(username: String, v: Boolean) = OAuthModBody(_.Shadowban) { me =>
|
||||
|
@ -59,7 +62,7 @@ final class Mod(env: Env) extends LilaController(env) {
|
|||
} yield (inquiry, suspect).some
|
||||
}
|
||||
}(ctx => me => {
|
||||
case (inquiry, suspect) => Report.onInquiryClose(inquiry, me, suspect.some)(ctx)
|
||||
case (inquiry, suspect) => reportC.onInquiryClose(inquiry, me, suspect.some)(ctx)
|
||||
})
|
||||
|
||||
def warn(username: String, subject: String) = OAuthModBody(_.ModMessage) { me =>
|
||||
|
@ -74,7 +77,7 @@ final class Mod(env: Env) extends LilaController(env) {
|
|||
}
|
||||
}
|
||||
}(ctx => me => {
|
||||
case (inquiry, suspect) => Report.onInquiryClose(inquiry, me, suspect.some)(ctx)
|
||||
case (inquiry, suspect) => reportC.onInquiryClose(inquiry, me, suspect.some)(ctx)
|
||||
})
|
||||
|
||||
def ipBan(username: String, v: Boolean) = OAuthMod(_.IpBan) { _ => me =>
|
||||
|
@ -91,14 +94,14 @@ final class Mod(env: Env) extends LilaController(env) {
|
|||
}(actionResult(username))
|
||||
|
||||
def disableTwoFactor(username: String) = Secure(_.DisableTwoFactor) { implicit ctx => me =>
|
||||
modApi.disableTwoFactor(me.id, username) >> User.modZoneOrRedirect(username, me)
|
||||
modApi.disableTwoFactor(me.id, username) >> userC.modZoneOrRedirect(username, me)
|
||||
}
|
||||
|
||||
def closeAccount(username: String) = OAuthMod(_.CloseAccount) { _ => me =>
|
||||
env.user.userRepo named username flatMap {
|
||||
env.user.repo named username flatMap {
|
||||
_ ?? { user =>
|
||||
modLogApi.closeAccount(me.id, user.id) >>
|
||||
env.current.closeAccount(user.id, self = false) map some
|
||||
env.closeAccount(user.id, self = false) map some
|
||||
}
|
||||
}
|
||||
}(actionResult(username))
|
||||
|
@ -124,7 +127,7 @@ final class Mod(env: Env) extends LilaController(env) {
|
|||
env.mod.impersonate.stop(me)
|
||||
Redirect(routes.User.show(me.username))
|
||||
}
|
||||
else if (isGranted(_.Impersonate)) OptionFuRedirect(env.user.userRepo named username) { user =>
|
||||
else if (isGranted(_.Impersonate)) OptionFuRedirect(env.user.repo named username) { user =>
|
||||
env.mod.impersonate.start(me, user)
|
||||
fuccess(routes.User.show(user.username))
|
||||
}
|
||||
|
@ -144,7 +147,7 @@ final class Mod(env: Env) extends LilaController(env) {
|
|||
|
||||
def setEmail(username: String) = SecureBody(_.SetEmail) { implicit ctx => me =>
|
||||
implicit def req = ctx.body
|
||||
OptionFuResult(env.user.userRepo named username) { user =>
|
||||
OptionFuResult(env.user.repo named username) { user =>
|
||||
env.security.forms.modEmail(user).bindFromRequest.fold(
|
||||
err => BadRequest(err.toString).fuccess,
|
||||
rawEmail => {
|
||||
|
@ -168,13 +171,13 @@ final class Mod(env: Env) extends LilaController(env) {
|
|||
private def communications(username: String, priv: Boolean) = Secure {
|
||||
perms => if (priv) perms.ViewPrivateComms else perms.Shadowban
|
||||
} { implicit ctx => me =>
|
||||
OptionFuOk(env.user.userRepo named username) { user =>
|
||||
OptionFuOk(env.user.repo named username) { user =>
|
||||
env.game.gameRepo.recentPovsByUserFromSecondary(user, 80) flatMap { povs =>
|
||||
priv.?? {
|
||||
env.chat.api.playerChat optionsByOrderedIds povs.map(_.gameId).map(Chat.Id.apply)
|
||||
} zip
|
||||
priv.?? {
|
||||
lila.message.ThreadRepo.visibleOrDeletedByUser(user.id, 60).map {
|
||||
env.message.repo.visibleOrDeletedByUser(user.id, 60).map {
|
||||
_ filter (_ hasPostsWrittenBy user.id) take 30
|
||||
}
|
||||
} zip
|
||||
|
@ -184,7 +187,7 @@ final class Mod(env: Env) extends LilaController(env) {
|
|||
env.mod.logApi.userHistory(user.id) zip
|
||||
env.report.api.inquiries.ofModId(me.id) flatMap {
|
||||
case chats ~ threads ~ publicLines ~ spy ~ notes ~ history ~ inquiry =>
|
||||
lila.security.UserSpy.withMeSortedWithEmails(user, spy.otherUsers) map { othersWithEmail =>
|
||||
lila.security.UserSpy.withMeSortedWithEmails(env.user.repo, user, spy.otherUsers) map { othersWithEmail =>
|
||||
if (priv && !inquiry.??(_.isRecentCommOf(Suspect(user))))
|
||||
env.slack.api.commlog(mod = me, user = user, inquiry.map(_.oldestAtom.by.value))
|
||||
val povWithChats = (povs zip chats) collect {
|
||||
|
@ -214,15 +217,15 @@ final class Mod(env: Env) extends LilaController(env) {
|
|||
s"${routes.User.show(username).url}${mod ?? "?mod"}"
|
||||
|
||||
def refreshUserAssess(username: String) = Secure(_.MarkEngine) { implicit ctx => me =>
|
||||
OptionFuResult(env.user.userRepo named username) { user =>
|
||||
OptionFuResult(env.user.repo named username) { user =>
|
||||
assessApi.refreshAssessByUsername(username) >>
|
||||
env.irwin.api.requests.fromMod(Suspect(user), AsMod(me)) >>
|
||||
User.renderModZoneActions(username)
|
||||
userC.renderModZoneActions(username)
|
||||
}
|
||||
}
|
||||
|
||||
def spontaneousInquiry(username: String) = Secure(_.SeeReport) { implicit ctx => me =>
|
||||
OptionFuResult(env.user.userRepo named username) { user =>
|
||||
OptionFuResult(env.user.repo named username) { user =>
|
||||
env.report.api.inquiries.spontaneous(AsMod(me), Suspect(user)) inject redirect(user.username, true)
|
||||
}
|
||||
}
|
||||
|
@ -259,8 +262,8 @@ final class Mod(env: Env) extends LilaController(env) {
|
|||
val hash = FingerHash(fh)
|
||||
for {
|
||||
uids <- env.security.api recentUserIdsByFingerHash hash
|
||||
users <- env.user.userRepo usersFromSecondary uids.reverse
|
||||
withEmails <- env.user.userRepo withEmailsU users
|
||||
users <- env.user.repo usersFromSecondary uids.reverse
|
||||
withEmails <- env.user.repo withEmailsU users
|
||||
uas <- env.security.api.printUas(hash)
|
||||
} yield Ok(html.mod.search.print(hash, withEmails, uas, env.security.printBan blocks hash))
|
||||
}
|
||||
|
@ -271,14 +274,14 @@ final class Mod(env: Env) extends LilaController(env) {
|
|||
}
|
||||
|
||||
def chatUser(username: String) = Secure(_.ChatTimeout) { implicit ctx => me =>
|
||||
implicit val lightUser = env.user.lightUserSync _
|
||||
implicit val lightUser = env.user.lightUserSync
|
||||
JsonOptionOk {
|
||||
env.chat.api.userChat userModInfo username map2 lila.chat.JsonView.userModInfo
|
||||
}
|
||||
}
|
||||
|
||||
def permissions(username: String) = Secure(_.ChangePermission) { implicit ctx => me =>
|
||||
OptionOk(env.user.userRepo named username) { user =>
|
||||
OptionOk(env.user.repo named username) { user =>
|
||||
html.mod.permissions(user)
|
||||
}
|
||||
}
|
||||
|
@ -286,7 +289,7 @@ final class Mod(env: Env) extends LilaController(env) {
|
|||
def savePermissions(username: String) = SecureBody(_.ChangePermission) { implicit ctx => me =>
|
||||
implicit def req = ctx.body
|
||||
import lila.security.Permission
|
||||
OptionFuResult(env.user.userRepo named username) { user =>
|
||||
OptionFuResult(env.user.repo named username) { user =>
|
||||
Form(single(
|
||||
"permissions" -> list(text.verifying { str =>
|
||||
Permission.allButSuperAdmin.exists(_.name == str)
|
||||
|
@ -317,7 +320,7 @@ final class Mod(env: Env) extends LilaController(env) {
|
|||
lila.mon.user.register.modConfirmEmail()
|
||||
modApi.setEmail(me.id, user.id, setEmail)
|
||||
} >>
|
||||
env.user.userRepo.email(user.id) map { email =>
|
||||
env.user.repo.email(user.id) map { email =>
|
||||
Ok(html.mod.emailConfirm("", user.some, email)).some
|
||||
}
|
||||
case _ => fuccess(none)
|
||||
|
@ -342,7 +345,7 @@ final class Mod(env: Env) extends LilaController(env) {
|
|||
}(ctx => me => _ => Redirect(routes.Mod.chatPanic).fuccess)
|
||||
|
||||
def eventStream = OAuthSecure(_.Admin) { req => me =>
|
||||
noProxyBuffer(Ok.chunked(env.mod.stream.enumerator)).fuccess
|
||||
noProxyBuffer(Ok.chunked(env.mod.stream())).fuccess
|
||||
}
|
||||
|
||||
private def withSuspect[A](username: String)(f: Suspect => Fu[A])(implicit zero: Zero[A]): Fu[A] =
|
||||
|
@ -368,6 +371,6 @@ final class Mod(env: Env) extends LilaController(env) {
|
|||
)
|
||||
|
||||
private def actionResult(username: String)(ctx: Context)(me: UserModel)(res: Any) =
|
||||
if (HTTPRequest isSynchronousHttp ctx.req) fuccess(Mod.redirect(username))
|
||||
else User.renderModZoneActions(username)(ctx)
|
||||
if (HTTPRequest isSynchronousHttp ctx.req) fuccess(redirect(username))
|
||||
else userC.renderModZoneActions(username)(ctx)
|
||||
}
|
||||
|
|
|
@ -7,14 +7,12 @@ import play.api.libs.json._
|
|||
|
||||
final class Notify(env: Env) extends LilaController(env) {
|
||||
|
||||
val env = env.notifyModule
|
||||
|
||||
import env.jsonHandlers._
|
||||
import env.notify.jsonHandlers._
|
||||
|
||||
def recent(page: Int) = Auth { implicit ctx => me =>
|
||||
XhrOrRedirectHome {
|
||||
val notifies = Notifies(me.id)
|
||||
env.api.getNotificationsAndCount(notifies, page) map { res =>
|
||||
env.notify.api.getNotificationsAndCount(notifies, page) map { res =>
|
||||
Ok(Json toJson res) as JSON
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,56 +1,53 @@
|
|||
package controllers
|
||||
|
||||
import play.api.libs.json.JsValue
|
||||
import play.api.mvc._
|
||||
|
||||
import lila.api.Context
|
||||
import lila.app._
|
||||
import lila.oauth.{ OAuthApp => App }
|
||||
import views._
|
||||
|
||||
final class OAuthApp(env: Env) extends LilaController(env) {
|
||||
|
||||
private val env = env.oAuth
|
||||
private val appApi = env.oAuth.appApi
|
||||
private val forms = env.oAuth.forms
|
||||
|
||||
def index = Auth { implicit ctx => me =>
|
||||
env.appApi.list(me) map { apps =>
|
||||
appApi.list(me) map { apps =>
|
||||
Ok(html.oAuth.app.index(apps))
|
||||
}
|
||||
}
|
||||
|
||||
def create = Auth { implicit ctx => me =>
|
||||
Ok(html.oAuth.app.form.create(env.forms.app.create)).fuccess
|
||||
Ok(html.oAuth.app.form.create(forms.app.create)).fuccess
|
||||
}
|
||||
|
||||
def createApply = AuthBody { implicit ctx => me =>
|
||||
implicit val req = ctx.body
|
||||
env.forms.app.create.bindFromRequest.fold(
|
||||
forms.app.create.bindFromRequest.fold(
|
||||
err => BadRequest(html.oAuth.app.form.create(err)).fuccess,
|
||||
setup => {
|
||||
val app = setup make me
|
||||
env.appApi.create(app) inject Redirect(routes.OAuthApp.edit(app.clientId.value))
|
||||
appApi.create(app) inject Redirect(routes.OAuthApp.edit(app.clientId.value))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
def edit(id: String) = Auth { implicit ctx => me =>
|
||||
OptionFuResult(env.appApi.findBy(App.Id(id), me)) { app =>
|
||||
Ok(html.oAuth.app.form.edit(app, env.forms.app.edit(app))).fuccess
|
||||
OptionFuResult(appApi.findBy(App.Id(id), me)) { app =>
|
||||
Ok(html.oAuth.app.form.edit(app, forms.app.edit(app))).fuccess
|
||||
}
|
||||
}
|
||||
|
||||
def update(id: String) = AuthBody { implicit ctx => me =>
|
||||
OptionFuResult(env.appApi.findBy(App.Id(id), me)) { app =>
|
||||
OptionFuResult(appApi.findBy(App.Id(id), me)) { app =>
|
||||
implicit val req = ctx.body
|
||||
env.forms.app.edit(app).bindFromRequest.fold(
|
||||
forms.app.edit(app).bindFromRequest.fold(
|
||||
err => BadRequest(html.oAuth.app.form.edit(app, err)).fuccess,
|
||||
data => env.appApi.update(app) { data.update(_) } map { r => Redirect(routes.OAuthApp.edit(app.clientId.value)) }
|
||||
data => appApi.update(app) { data.update(_) } map { r => Redirect(routes.OAuthApp.edit(app.clientId.value)) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
def delete(id: String) = Auth { implicit ctx => me =>
|
||||
env.appApi.deleteBy(App.Id(id), me) inject
|
||||
def delete(id: String) = Auth { _ => me =>
|
||||
appApi.deleteBy(App.Id(id), me) inject
|
||||
Redirect(routes.OAuthApp.index)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,38 +1,34 @@
|
|||
package controllers
|
||||
|
||||
import play.api.libs.json.JsValue
|
||||
import play.api.mvc._
|
||||
|
||||
import lila.api.Context
|
||||
import lila.app._
|
||||
import lila.oauth.AccessToken
|
||||
import views._
|
||||
|
||||
final class OAuthToken(env: Env) extends LilaController(env) {
|
||||
|
||||
private val env = env.oAuth
|
||||
private val tokenApi = env.oAuth.tokenApi
|
||||
|
||||
def index = Auth { implicit ctx => me =>
|
||||
env.tokenApi.list(me) map { tokens =>
|
||||
tokenApi.list(me) map { tokens =>
|
||||
Ok(html.oAuth.token.index(tokens))
|
||||
}
|
||||
}
|
||||
|
||||
def create = Auth { implicit ctx => me =>
|
||||
Ok(html.oAuth.token.create(env.forms.token.create, me)).fuccess
|
||||
Ok(html.oAuth.token.create(env.oAuth.forms.token.create, me)).fuccess
|
||||
}
|
||||
|
||||
def createApply = AuthBody { implicit ctx => me =>
|
||||
implicit val req = ctx.body
|
||||
env.forms.token.create.bindFromRequest.fold(
|
||||
env.oAuth.forms.token.create.bindFromRequest.fold(
|
||||
err => BadRequest(html.oAuth.token.create(err, me)).fuccess,
|
||||
setup => env.tokenApi.create(setup make me) inject
|
||||
setup => tokenApi.create(setup make me) inject
|
||||
Redirect(routes.OAuthToken.index)
|
||||
)
|
||||
}
|
||||
|
||||
def delete(id: String) = Auth { implicit ctx => me =>
|
||||
env.tokenApi.deleteBy(AccessToken.Id(id), me) inject
|
||||
def delete(id: String) = Auth { _ => me =>
|
||||
tokenApi.deleteBy(AccessToken.Id(id), me) inject
|
||||
Redirect(routes.OAuthToken.index)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
package controllers
|
||||
|
||||
import play.api.mvc._
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import lila.app._
|
||||
import lila.common.HTTPRequest.isApiOrApp
|
||||
import lila.common.ResponseHeaders.allowMethods
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package controllers
|
||||
|
||||
import lila.app._
|
||||
import views._
|
||||
|
||||
final class Page(env: Env) extends LilaController(env) {
|
||||
final class Page(
|
||||
env: Env,
|
||||
prismicC: Prismic
|
||||
) extends LilaController(env) {
|
||||
|
||||
val thanks = helpBookmark("thanks")
|
||||
val help = helpBookmark("help")
|
||||
|
@ -14,7 +16,7 @@ final class Page(env: Env) extends LilaController(env) {
|
|||
|
||||
private def helpBookmark(name: String) = Open { implicit ctx =>
|
||||
pageHit
|
||||
OptionOk(Prismic getBookmark name) {
|
||||
OptionOk(prismicC getBookmark name) {
|
||||
case (doc, resolver) => views.html.site.help.page(name, doc, resolver)
|
||||
}
|
||||
}
|
||||
|
@ -23,14 +25,14 @@ final class Page(env: Env) extends LilaController(env) {
|
|||
|
||||
private def bookmark(name: String) = Open { implicit ctx =>
|
||||
pageHit
|
||||
OptionOk(Prismic getBookmark name) {
|
||||
OptionOk(prismicC getBookmark name) {
|
||||
case (doc, resolver) => views.html.site.page(doc, resolver)
|
||||
}
|
||||
}
|
||||
|
||||
def source = Open { implicit ctx =>
|
||||
pageHit
|
||||
OptionOk(Prismic getBookmark "source") {
|
||||
OptionOk(prismicC getBookmark "source") {
|
||||
case (doc, resolver) => views.html.site.help.source(doc, resolver)
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +40,7 @@ final class Page(env: Env) extends LilaController(env) {
|
|||
def variantHome = Open { implicit ctx =>
|
||||
import play.api.libs.json._
|
||||
negotiate(
|
||||
html = OptionOk(Prismic getBookmark "variant") {
|
||||
html = OptionOk(prismicC getBookmark "variant") {
|
||||
case (doc, resolver) => views.html.site.variant.home(doc, resolver)
|
||||
},
|
||||
api = _ => Ok(JsArray(chess.variant.Variant.all.map { v =>
|
||||
|
@ -55,7 +57,7 @@ final class Page(env: Env) extends LilaController(env) {
|
|||
(for {
|
||||
variant <- chess.variant.Variant.byKey get key
|
||||
perfType <- lila.rating.PerfType byVariant variant
|
||||
} yield OptionOk(Prismic getVariant variant) {
|
||||
} yield OptionOk(prismicC getVariant variant) {
|
||||
case (doc, resolver) => views.html.site.variant.show(doc, resolver, variant, perfType)
|
||||
}) | notFound
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ final class Plan(env: Env) extends LilaController(env) {
|
|||
import lila.plan.PlanApi.SyncResult._
|
||||
env.plan.api.sync(me) flatMap {
|
||||
case ReloadUser => Redirect(routes.Plan.index).fuccess
|
||||
case Synced(Some(patron), None) => env.user.userRepo email me.id flatMap { email =>
|
||||
case Synced(Some(patron), None) => env.user.repo email me.id flatMap { email =>
|
||||
renderIndex(email, patron.some)
|
||||
}
|
||||
case Synced(Some(patron), Some(customer)) => indexPatron(me, patron, customer)
|
||||
|
@ -42,7 +42,7 @@ final class Plan(env: Env) extends LilaController(env) {
|
|||
private def indexAnon(implicit ctx: Context) = renderIndex(email = none, patron = none)
|
||||
|
||||
private def indexFreeUser(me: UserModel)(implicit ctx: Context) =
|
||||
env.user.userRepo email me.id flatMap { email =>
|
||||
env.user.repo email me.id flatMap { email =>
|
||||
renderIndex(email, patron = none)
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ final class Plan(env: Env) extends LilaController(env) {
|
|||
env.plan.api.customerInfo(me, customer) flatMap {
|
||||
case Some(info: MonthlyCustomerInfo) => Ok(html.plan.indexStripe(me, patron, info)).fuccess
|
||||
case Some(info: OneTimeCustomerInfo) => renderIndex(info.customer.email map EmailAddress.apply, patron.some)
|
||||
case None => env.user.userRepo email me.id flatMap { email =>
|
||||
case None => env.user.repo email me.id flatMap { email =>
|
||||
renderIndex(email, patron.some)
|
||||
}
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ final class Plan(env: Env) extends LilaController(env) {
|
|||
) inject Redirect(routes.Plan.index)
|
||||
}
|
||||
|
||||
def cancel = AuthBody { implicit ctx => me =>
|
||||
def cancel = AuthBody { _ => me =>
|
||||
env.plan.api.cancel(me) inject Redirect(routes.Plan.index())
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,7 @@ final class Plan(env: Env) extends LilaController(env) {
|
|||
name = ipn.name,
|
||||
txnId = ipn.txnId,
|
||||
ip = lila.common.HTTPRequest.lastRemoteAddress(req).value,
|
||||
key = lila.plan.PayPalIpnKey(get("key", req) | "N/A")
|
||||
key = get("key", req) | "N/A"
|
||||
) inject Ok
|
||||
)
|
||||
}
|
||||
|
|
|
@ -11,23 +11,28 @@ import lila.study.{ Chapter, Study => StudyModel }
|
|||
import lila.tree.Node.partitionTreeJsonWriter
|
||||
import views._
|
||||
|
||||
final class Practice(env: Env) extends LilaController(env) {
|
||||
final class Practice(
|
||||
env: Env,
|
||||
userAnalysisC: UserAnalysis
|
||||
) extends LilaController(env) {
|
||||
|
||||
val api = env.practice.api
|
||||
|
||||
def index = Open { implicit ctx =>
|
||||
pageHit
|
||||
env.api.get(ctx.me) flatMap { up =>
|
||||
api.get(ctx.me) flatMap { up =>
|
||||
NoCache(Ok(html.practice.index(up))).fuccess
|
||||
}
|
||||
}
|
||||
|
||||
def show(sectionId: String, studySlug: String, studyId: String) = Open { implicit ctx =>
|
||||
pageHit
|
||||
OptionFuResult(env.api.getStudyWithFirstOngoingChapter(ctx.me, studyId))(showUserPractice)
|
||||
OptionFuResult(api.getStudyWithFirstOngoingChapter(ctx.me, studyId))(showUserPractice)
|
||||
}
|
||||
|
||||
def showChapter(sectionId: String, studySlug: String, studyId: String, chapterId: String) = Open { implicit ctx =>
|
||||
pageHit
|
||||
OptionFuResult(env.api.getStudyWithChapter(ctx.me, studyId, chapterId))(showUserPractice)
|
||||
OptionFuResult(api.getStudyWithChapter(ctx.me, studyId, chapterId))(showUserPractice)
|
||||
}
|
||||
|
||||
def showSection(sectionId: String) =
|
||||
|
@ -37,7 +42,7 @@ final class Practice(env: Env) extends LilaController(env) {
|
|||
redirectTo(sectionId)(_.studies.find(_.slug == studySlug))
|
||||
|
||||
private def redirectTo(sectionId: String)(select: PracticeSection => Option[PracticeStudy]) = Open { implicit ctx =>
|
||||
env.api.structure.get.flatMap { struct =>
|
||||
api.structure.get.flatMap { struct =>
|
||||
struct.sections.find(_.id == sectionId).fold(notFound) { section =>
|
||||
select(section) ?? { study =>
|
||||
Redirect(routes.Practice.show(section.id, study.slug, study.id.value)).fuccess
|
||||
|
@ -57,7 +62,7 @@ final class Practice(env: Env) extends LilaController(env) {
|
|||
}
|
||||
|
||||
def chapter(studyId: String, chapterId: String) = Open { implicit ctx =>
|
||||
OptionFuResult(env.api.getStudyWithChapter(ctx.me, studyId, chapterId)) { us =>
|
||||
OptionFuResult(api.getStudyWithChapter(ctx.me, studyId, chapterId)) { us =>
|
||||
analysisJson(us) map {
|
||||
case (analysisJson, studyJson) => Ok(Json.obj(
|
||||
"study" -> studyJson,
|
||||
|
@ -69,9 +74,9 @@ final class Practice(env: Env) extends LilaController(env) {
|
|||
|
||||
private def analysisJson(us: UserStudy)(implicit ctx: Context): Fu[(JsObject, JsObject)] = us match {
|
||||
case UserStudy(_, _, chapters, WithChapter(study, chapter), _) =>
|
||||
studyenv.jsonView(study, chapters, chapter, ctx.me) map { studyJson =>
|
||||
env.study.jsonView(study, chapters, chapter, ctx.me) map { studyJson =>
|
||||
val initialFen = chapter.root.fen.some
|
||||
val pov = UserAnalysis.makePov(initialFen, chapter.setup.variant)
|
||||
val pov = userAnalysisC.makePov(initialFen, chapter.setup.variant)
|
||||
val baseData = env.round.jsonView.userAnalysisJson(pov, ctx.pref, initialFen, chapter.setup.orientation, owner = false, me = ctx.me)
|
||||
val analysis = baseData ++ Json.obj(
|
||||
"treeParts" -> partitionTreeJsonWriter.writes {
|
||||
|
@ -84,28 +89,28 @@ final class Practice(env: Env) extends LilaController(env) {
|
|||
}
|
||||
|
||||
def complete(chapterId: String, nbMoves: Int) = Auth { implicit ctx => me =>
|
||||
env.api.progress.setNbMoves(me, chapterId, lila.practice.PracticeProgress.NbMoves(nbMoves))
|
||||
api.progress.setNbMoves(me, chapterId, lila.practice.PracticeProgress.NbMoves(nbMoves))
|
||||
}
|
||||
|
||||
def reset = AuthBody { implicit ctx => me =>
|
||||
env.api.progress.reset(me) inject Redirect(routes.Practice.index)
|
||||
def reset = AuthBody { _ => me =>
|
||||
api.progress.reset(me) inject Redirect(routes.Practice.index)
|
||||
}
|
||||
|
||||
def config = Auth { implicit ctx => me =>
|
||||
for {
|
||||
struct <- env.api.structure.get
|
||||
form <- env.api.config.form
|
||||
struct <- api.structure.get
|
||||
form <- api.config.form
|
||||
} yield Ok(html.practice.config(struct, form))
|
||||
}
|
||||
|
||||
def configSave = SecureBody(_.PracticeConfig) { implicit ctx => me =>
|
||||
implicit val req = ctx.body
|
||||
env.api.config.form.flatMap { form =>
|
||||
api.config.form.flatMap { form =>
|
||||
FormFuResult(form) { err =>
|
||||
env.api.structure.get map { html.practice.config(_, err) }
|
||||
api.structure.get map { html.practice.config(_, err) }
|
||||
} { text =>
|
||||
~env.api.config.set(text).right.toOption >>-
|
||||
env.api.structure.clear >>
|
||||
~api.config.set(text).right.toOption >>-
|
||||
api.structure.clear >>
|
||||
env.mod.logApi.practiceConfig(me.id) inject Redirect(routes.Practice.config)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import play.api.mvc._
|
|||
|
||||
import lila.api.Context
|
||||
import lila.app._
|
||||
import lila.common.LilaCookie
|
||||
import views._
|
||||
|
||||
final class Pref(env: Env) extends LilaController(env) {
|
||||
|
@ -43,9 +42,8 @@ final class Pref(env: Env) extends LilaController(env) {
|
|||
}
|
||||
|
||||
def set(name: String) = OpenBody { implicit ctx =>
|
||||
implicit val req = ctx.body
|
||||
if (name == "zoom") {
|
||||
Ok.withCookies(LilaCookie.session("zoom2", (getInt("v") | 185).toString)).fuccess
|
||||
Ok.withCookies(env.lilaCookie.session("zoom2", (getInt("v") | 185).toString)).fuccess
|
||||
} else {
|
||||
implicit val req = ctx.body
|
||||
(setters get name) ?? {
|
||||
|
@ -82,5 +80,5 @@ final class Pref(env: Env) extends LilaController(env) {
|
|||
private def save(name: String)(value: String, ctx: Context): Fu[Cookie] =
|
||||
ctx.me ?? {
|
||||
api.setPrefString(_, name, value)
|
||||
} inject LilaCookie.session(name, value)(ctx.req)
|
||||
} inject env.lilaCookie.session(name, value)(ctx.req)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package controllers
|
|||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import io.prismic.Fragment.DocumentLink
|
||||
import io.prismic.{ Api => PrismicApi, _ }
|
||||
import lila.app._
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ final class Push(env: Env) extends LilaController(env) {
|
|||
env.push.unregisterDevices(me)
|
||||
}
|
||||
|
||||
def webSubscribe = AuthBody(BodyParsers.parse.json) { implicit ctx => me =>
|
||||
def webSubscribe = AuthBody(parse.json) { implicit ctx => me =>
|
||||
val currentSessionId = ~env.security.api.reqSessionId(ctx.req)
|
||||
ctx.body.body.validate[WebSubscription].fold(
|
||||
err => BadRequest(err.toString).fuccess,
|
||||
|
|
|
@ -5,12 +5,16 @@ import play.api.mvc._
|
|||
|
||||
import lila.api.Context
|
||||
import lila.app._
|
||||
import lila.common.{ HTTPRequest, IpAddress, MaxPerSecond }
|
||||
import lila.common.config.MaxPerSecond
|
||||
import lila.common.{ HTTPRequest, IpAddress }
|
||||
import lila.game.PgnDump
|
||||
import lila.puzzle.{ PuzzleId, Result, Puzzle => PuzzleModel, UserInfos }
|
||||
import views._
|
||||
|
||||
final class Puzzle(env: Env) extends LilaController(env) {
|
||||
final class Puzzle(
|
||||
env: Env,
|
||||
apiC: Api
|
||||
) extends LilaController(env) {
|
||||
|
||||
private def renderJson(
|
||||
puzzle: PuzzleModel,
|
||||
|
@ -19,7 +23,7 @@ final class Puzzle(env: Env) extends LilaController(env) {
|
|||
voted: Option[Boolean],
|
||||
round: Option[lila.puzzle.Round] = None,
|
||||
result: Option[Result] = None
|
||||
)(implicit ctx: Context): Fu[JsObject] = env.jsonView(
|
||||
)(implicit ctx: Context): Fu[JsObject] = env.puzzle.jsonView(
|
||||
puzzle = puzzle,
|
||||
userInfos = userInfos,
|
||||
round = round,
|
||||
|
@ -30,16 +34,16 @@ final class Puzzle(env: Env) extends LilaController(env) {
|
|||
)
|
||||
|
||||
private def renderShow(puzzle: PuzzleModel, mode: String)(implicit ctx: Context) =
|
||||
env userInfos ctx.me flatMap { infos =>
|
||||
env.puzzle userInfos ctx.me flatMap { infos =>
|
||||
renderJson(puzzle = puzzle, userInfos = infos, mode = mode, voted = none) map { json =>
|
||||
views.html.puzzle.show(puzzle, data = json, pref = env.jsonView.pref(ctx.pref))
|
||||
views.html.puzzle.show(puzzle, data = json, pref = env.puzzle.jsonView.pref(ctx.pref))
|
||||
}
|
||||
}
|
||||
|
||||
def daily = Open { implicit ctx =>
|
||||
NoBot {
|
||||
OptionFuResult(env.daily.get flatMap {
|
||||
_.map(_.id) ?? env.api.puzzle.find
|
||||
OptionFuResult(env.puzzle.daily.get flatMap {
|
||||
_.map(_.id) ?? env.puzzle.api.puzzle.find
|
||||
}) { puzzle =>
|
||||
negotiate(
|
||||
html = renderShow(puzzle, "play") map { Ok(_) },
|
||||
|
@ -51,7 +55,7 @@ final class Puzzle(env: Env) extends LilaController(env) {
|
|||
|
||||
def home = Open { implicit ctx =>
|
||||
NoBot {
|
||||
env.selector(ctx.me) flatMap { puzzle =>
|
||||
env.puzzle.selector(ctx.me) flatMap { puzzle =>
|
||||
renderShow(puzzle, if (ctx.isAuth) "play" else "try") map { Ok(_) }
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +63,7 @@ final class Puzzle(env: Env) extends LilaController(env) {
|
|||
|
||||
def show(id: PuzzleId) = Open { implicit ctx =>
|
||||
NoBot {
|
||||
OptionFuOk(env.api.puzzle find id) { puzzle =>
|
||||
OptionFuOk(env.puzzle.api.puzzle find id) { puzzle =>
|
||||
renderShow(puzzle, "play")
|
||||
}
|
||||
}
|
||||
|
@ -68,13 +72,13 @@ final class Puzzle(env: Env) extends LilaController(env) {
|
|||
def load(id: PuzzleId) = Open { implicit ctx =>
|
||||
NoBot {
|
||||
XhrOnly {
|
||||
OptionFuOk(env.api.puzzle find id)(puzzleJson) map (_ as JSON)
|
||||
OptionFuOk(env.puzzle.api.puzzle find id)(puzzleJson) map (_ as JSON)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private def puzzleJson(puzzle: PuzzleModel)(implicit ctx: Context) =
|
||||
env userInfos ctx.me flatMap { infos =>
|
||||
env.puzzle userInfos ctx.me flatMap { infos =>
|
||||
renderJson(puzzle, infos, if (ctx.isAuth) "play" else "try", voted = none)
|
||||
}
|
||||
|
||||
|
@ -82,7 +86,7 @@ final class Puzzle(env: Env) extends LilaController(env) {
|
|||
def newPuzzle = Open { implicit ctx =>
|
||||
NoBot {
|
||||
XhrOnly {
|
||||
env.selector(ctx.me) flatMap puzzleJson map { json =>
|
||||
env.puzzle.selector(ctx.me) flatMap puzzleJson map { json =>
|
||||
Ok(json) as JSON
|
||||
}
|
||||
}
|
||||
|
@ -92,19 +96,19 @@ final class Puzzle(env: Env) extends LilaController(env) {
|
|||
// mobile app BC
|
||||
def round(id: PuzzleId) = OpenBody { implicit ctx =>
|
||||
implicit val req = ctx.body
|
||||
OptionFuResult(env.api.puzzle find id) { puzzle =>
|
||||
OptionFuResult(env.puzzle.api.puzzle find id) { puzzle =>
|
||||
if (puzzle.mate) lila.mon.puzzle.round.mate()
|
||||
else lila.mon.puzzle.round.material()
|
||||
env.forms.round.bindFromRequest.fold(
|
||||
env.puzzle.forms.round.bindFromRequest.fold(
|
||||
jsonFormError,
|
||||
resultInt => {
|
||||
val result = Result(resultInt == 1)
|
||||
ctx.me match {
|
||||
case Some(me) => for {
|
||||
(round, mode) <- env.finisher(puzzle, me, result, mobile = true)
|
||||
me2 <- if (mode.rated) env.user.userRepo byId me.id map (_ | me) else fuccess(me)
|
||||
infos <- env userInfos me2
|
||||
voted <- ctx.me.?? { env.api.vote.value(puzzle.id, _) }
|
||||
(round, mode) <- env.puzzle.finisher(puzzle, me, result, mobile = true)
|
||||
me2 <- if (mode.rated) env.user.repo byId me.id map (_ | me) else fuccess(me)
|
||||
infos <- env.puzzle userInfos me2
|
||||
voted <- ctx.me.?? { env.puzzle.api.vote.value(puzzle.id, _) }
|
||||
data <- renderJson(puzzle, infos.some, "view", voted = voted, result = result.some, round = round.some)
|
||||
} yield {
|
||||
lila.mon.puzzle.round.user()
|
||||
|
@ -113,7 +117,7 @@ final class Puzzle(env: Env) extends LilaController(env) {
|
|||
}
|
||||
case None =>
|
||||
lila.mon.puzzle.round.anon()
|
||||
env.finisher.incPuzzleAttempts(puzzle)
|
||||
env.puzzle.finisher.incPuzzleAttempts(puzzle)
|
||||
renderJson(puzzle, none, "view", result = result.some, voted = none) map { data =>
|
||||
val d2 = data ++ Json.obj("win" -> result.win)
|
||||
Ok(d2)
|
||||
|
@ -128,22 +132,22 @@ final class Puzzle(env: Env) extends LilaController(env) {
|
|||
def round2(id: PuzzleId) = OpenBody { implicit ctx =>
|
||||
NoBot {
|
||||
implicit val req = ctx.body
|
||||
OptionFuResult(env.api.puzzle find id) { puzzle =>
|
||||
OptionFuResult(env.puzzle.api.puzzle find id) { puzzle =>
|
||||
if (puzzle.mate) lila.mon.puzzle.round.mate()
|
||||
else lila.mon.puzzle.round.material()
|
||||
env.forms.round.bindFromRequest.fold(
|
||||
env.puzzle.forms.round.bindFromRequest.fold(
|
||||
jsonFormError,
|
||||
resultInt => ctx.me match {
|
||||
case Some(me) => for {
|
||||
(round, mode) <- env.finisher(
|
||||
(round, mode) <- env.puzzle.finisher(
|
||||
puzzle = puzzle,
|
||||
user = me,
|
||||
result = Result(resultInt == 1),
|
||||
mobile = lila.api.Mobile.Api.requested(ctx.req)
|
||||
)
|
||||
me2 <- if (mode.rated) env.user.userRepo byId me.id map (_ | me) else fuccess(me)
|
||||
infos <- env userInfos me2
|
||||
voted <- ctx.me.?? { env.api.vote.value(puzzle.id, _) }
|
||||
me2 <- if (mode.rated) env.user.repo byId me.id map (_ | me) else fuccess(me)
|
||||
infos <- env.puzzle userInfos me2
|
||||
voted <- ctx.me.?? { env.puzzle.api.vote.value(puzzle.id, _) }
|
||||
} yield {
|
||||
lila.mon.puzzle.round.user()
|
||||
Ok(Json.obj(
|
||||
|
@ -154,7 +158,7 @@ final class Puzzle(env: Env) extends LilaController(env) {
|
|||
}
|
||||
case None =>
|
||||
lila.mon.puzzle.round.anon()
|
||||
env.finisher.incPuzzleAttempts(puzzle)
|
||||
env.puzzle.finisher.incPuzzleAttempts(puzzle)
|
||||
Ok(Json.obj("user" -> false)).fuccess
|
||||
}
|
||||
) map (_ as JSON)
|
||||
|
@ -165,10 +169,10 @@ final class Puzzle(env: Env) extends LilaController(env) {
|
|||
def vote(id: PuzzleId) = AuthBody { implicit ctx => me =>
|
||||
NoBot {
|
||||
implicit val req = ctx.body
|
||||
env.forms.vote.bindFromRequest.fold(
|
||||
env.puzzle.forms.vote.bindFromRequest.fold(
|
||||
jsonFormError,
|
||||
vote => env.api.vote.find(id, me) flatMap {
|
||||
v => env.api.vote.update(id, me, v, vote == 1)
|
||||
vote => env.puzzle.api.vote.find(id, me) flatMap {
|
||||
v => env.puzzle.api.vote.update(id, me, v, vote == 1)
|
||||
} map {
|
||||
case (p, a) =>
|
||||
if (vote == 1) lila.mon.puzzle.vote.up()
|
||||
|
@ -184,28 +188,28 @@ final class Puzzle(env: Env) extends LilaController(env) {
|
|||
negotiate(
|
||||
html = notFound,
|
||||
api = _ => for {
|
||||
puzzles <- env.batch.select(
|
||||
puzzles <- env.puzzle.batch.select(
|
||||
me,
|
||||
nb = getInt("nb") getOrElse 50 atLeast 1 atMost 100,
|
||||
after = getInt("after")
|
||||
)
|
||||
userInfo <- env userInfos me
|
||||
json <- env.jsonView.batch(puzzles, userInfo)
|
||||
userInfo <- env.puzzle userInfos me
|
||||
json <- env.puzzle.jsonView.batch(puzzles, userInfo)
|
||||
} yield Ok(json) as JSON
|
||||
)
|
||||
}
|
||||
|
||||
/* Mobile API: tell the server about puzzles solved while offline */
|
||||
def batchSolve = AuthBody(BodyParsers.parse.json) { implicit ctx => me =>
|
||||
def batchSolve = AuthBody(parse.json) { implicit ctx => me =>
|
||||
import lila.puzzle.PuzzleBatch._
|
||||
ctx.body.body.validate[SolveData].fold(
|
||||
err => BadRequest(err.toString).fuccess,
|
||||
data => negotiate(
|
||||
html = notFound,
|
||||
api = _ => for {
|
||||
_ <- env.batch.solve(me, data)
|
||||
me2 <- env.user.userRepo byId me.id map (_ | me)
|
||||
infos <- env userInfos me2
|
||||
_ <- env.puzzle.batch.solve(me, data)
|
||||
me2 <- env.user.repo byId me.id map (_ | me)
|
||||
infos <- env.puzzle userInfos me2
|
||||
} yield Ok(Json.obj(
|
||||
"user" -> lila.puzzle.JsonView.infos(false)(infos)
|
||||
))
|
||||
|
@ -224,21 +228,21 @@ final class Puzzle(env: Env) extends LilaController(env) {
|
|||
}
|
||||
|
||||
def frame = Action.async { implicit req =>
|
||||
env.daily.get map {
|
||||
env.puzzle.daily.get map {
|
||||
case None => NotFound
|
||||
case Some(daily) => html.puzzle.embed(daily)
|
||||
}
|
||||
}
|
||||
|
||||
def activity = Scoped(_.Puzzle.Read) { req => me =>
|
||||
Api.GlobalLinearLimitPerIP(HTTPRequest lastRemoteAddress req) {
|
||||
Api.GlobalLinearLimitPerUserOption(me.some) {
|
||||
apiC.GlobalLinearLimitPerIP(HTTPRequest lastRemoteAddress req) {
|
||||
apiC.GlobalLinearLimitPerUserOption(me.some) {
|
||||
val config = lila.puzzle.PuzzleActivity.Config(
|
||||
user = me,
|
||||
max = getInt("max", req) map (_ atLeast 1),
|
||||
perSecond = MaxPerSecond(20)
|
||||
)
|
||||
Ok.chunked(env.activity.stream(config)).withHeaders(
|
||||
Ok.chunked(env.puzzle.activity.stream(config)).withHeaders(
|
||||
noProxyBufferHeader,
|
||||
CONTENT_TYPE -> ndJsonContentType
|
||||
).fuccess
|
||||
|
|
|
@ -1,24 +1,29 @@
|
|||
package controllers
|
||||
|
||||
import play.api.libs.iteratee._
|
||||
import play.api.libs.json.Json
|
||||
import play.api.mvc._
|
||||
|
||||
import lila.api.Context
|
||||
import lila.app._
|
||||
import lila.common.config.MaxPerSecond
|
||||
import lila.common.HTTPRequest
|
||||
import lila.common.paginator.{ Paginator, AdapterLike, PaginatorJson }
|
||||
import lila.common.{ HTTPRequest, MaxPerSecond }
|
||||
import lila.relation.Related
|
||||
import lila.relation.RelationStream._
|
||||
import lila.user.{ User => UserModel }
|
||||
import views._
|
||||
|
||||
final class Relation(env: Env) extends LilaController(env) {
|
||||
final class Relation(
|
||||
env: Env,
|
||||
apiC: Api
|
||||
) extends LilaController(env) {
|
||||
|
||||
val api = env.relation.api
|
||||
|
||||
private def renderActions(userId: String, mini: Boolean)(implicit ctx: Context) =
|
||||
(ctx.userId ?? { env.api.fetchRelation(_, userId) }) zip
|
||||
(ctx.userId ?? { api.fetchRelation(_, userId) }) zip
|
||||
(ctx.isAuth ?? { env.pref.api followable userId }) zip
|
||||
(ctx.userId ?? { env.api.fetchBlocks(userId, _) }) flatMap {
|
||||
(ctx.userId ?? { api.fetchBlocks(userId, _) }) flatMap {
|
||||
case relation ~ followable ~ blocked => negotiate(
|
||||
html = fuccess(Ok {
|
||||
if (mini) html.relation.mini(userId, blocked = blocked, followable = followable, relation = relation)
|
||||
|
@ -33,33 +38,33 @@ final class Relation(env: Env) extends LilaController(env) {
|
|||
}
|
||||
|
||||
def follow(userId: String) = Auth { implicit ctx => me =>
|
||||
env.api.reachedMaxFollowing(me.id) flatMap {
|
||||
api.reachedMaxFollowing(me.id) flatMap {
|
||||
case true => env.message.api.sendPresetFromLichess(
|
||||
me,
|
||||
lila.message.ModPreset.maxFollow(me.username, env.relation.MaxFollow)
|
||||
lila.message.ModPreset.maxFollow(me.username, env.relation.maxFollow.value)
|
||||
).void
|
||||
case _ => env.api.follow(me.id, UserModel normalize userId).nevermind >> renderActions(userId, getBool("mini"))
|
||||
case _ => api.follow(me.id, UserModel normalize userId).nevermind >> renderActions(userId, getBool("mini"))
|
||||
}
|
||||
}
|
||||
|
||||
def unfollow(userId: String) = Auth { implicit ctx => me =>
|
||||
env.api.unfollow(me.id, UserModel normalize userId).nevermind >> renderActions(userId, getBool("mini"))
|
||||
api.unfollow(me.id, UserModel normalize userId).nevermind >> renderActions(userId, getBool("mini"))
|
||||
}
|
||||
|
||||
def block(userId: String) = Auth { implicit ctx => me =>
|
||||
env.api.block(me.id, UserModel normalize userId).nevermind >> renderActions(userId, getBool("mini"))
|
||||
api.block(me.id, UserModel normalize userId).nevermind >> renderActions(userId, getBool("mini"))
|
||||
}
|
||||
|
||||
def unblock(userId: String) = Auth { implicit ctx => me =>
|
||||
env.api.unblock(me.id, UserModel normalize userId).nevermind >> renderActions(userId, getBool("mini"))
|
||||
api.unblock(me.id, UserModel normalize userId).nevermind >> renderActions(userId, getBool("mini"))
|
||||
}
|
||||
|
||||
def following(username: String, page: Int) = Open { implicit ctx =>
|
||||
Reasonable(page, 20) {
|
||||
OptionFuResult(env.user.userRepo named username) { user =>
|
||||
RelatedPager(env.api.followingPaginatorAdapter(user.id), page) flatMap { pag =>
|
||||
OptionFuResult(env.user.repo named username) { user =>
|
||||
RelatedPager(api.followingPaginatorAdapter(user.id), page) flatMap { pag =>
|
||||
negotiate(
|
||||
html = env.api countFollowers user.id map { nbFollowers =>
|
||||
html = api countFollowers user.id map { nbFollowers =>
|
||||
Ok(html.relation.bits.following(user, pag, nbFollowers))
|
||||
},
|
||||
api = _ => Ok(jsonRelatedPaginator(pag)).fuccess
|
||||
|
@ -71,10 +76,10 @@ final class Relation(env: Env) extends LilaController(env) {
|
|||
|
||||
def followers(username: String, page: Int) = Open { implicit ctx =>
|
||||
Reasonable(page, 20) {
|
||||
OptionFuResult(env.user.userRepo named username) { user =>
|
||||
RelatedPager(env.api.followersPaginatorAdapter(user.id), page) flatMap { pag =>
|
||||
OptionFuResult(env.user.repo named username) { user =>
|
||||
RelatedPager(api.followersPaginatorAdapter(user.id), page) flatMap { pag =>
|
||||
negotiate(
|
||||
html = env.api countFollowing user.id map { nbFollowing =>
|
||||
html = api countFollowing user.id map { nbFollowing =>
|
||||
Ok(html.relation.bits.followers(user, pag, nbFollowing))
|
||||
},
|
||||
api = _ => Ok(jsonRelatedPaginator(pag)).fuccess
|
||||
|
@ -89,12 +94,12 @@ final class Relation(env: Env) extends LilaController(env) {
|
|||
def apiFollowers(name: String) = apiRelation(name, Direction.Followers)
|
||||
|
||||
private def apiRelation(name: String, direction: Direction) = Action.async { req =>
|
||||
env.user.userRepo.named(name) flatMap {
|
||||
env.user.repo.named(name) flatMap {
|
||||
_ ?? { user =>
|
||||
import Api.limitedDefault
|
||||
Api.GlobalLinearLimitPerIP(HTTPRequest lastRemoteAddress req) {
|
||||
Api.jsonStream {
|
||||
env.stream.follow(user, direction, MaxPerSecond(20)) &> Enumeratee.map(env.api.userApi.one)
|
||||
import apiC.limitedDefault
|
||||
apiC.GlobalLinearLimitPerIP(HTTPRequest lastRemoteAddress req) {
|
||||
apiC.jsonStream {
|
||||
env.stream.follow(user, direction, MaxPerSecond(20)) &> Enumeratee.map(api.userApi.one)
|
||||
} |> fuccess
|
||||
}
|
||||
}
|
||||
|
@ -115,7 +120,7 @@ final class Relation(env: Env) extends LilaController(env) {
|
|||
|
||||
def blocks(page: Int) = Auth { implicit ctx => me =>
|
||||
Reasonable(page, 20) {
|
||||
RelatedPager(env.api.blockingPaginatorAdapter(me.id), page) map { pag =>
|
||||
RelatedPager(api.blockingPaginatorAdapter(me.id), page) map { pag =>
|
||||
html.relation.bits.blocks(me, pag)
|
||||
}
|
||||
}
|
||||
|
@ -124,14 +129,14 @@ final class Relation(env: Env) extends LilaController(env) {
|
|||
private def RelatedPager(adapter: AdapterLike[String], page: Int)(implicit ctx: Context) = Paginator(
|
||||
adapter = adapter mapFutureList followship,
|
||||
currentPage = page,
|
||||
maxPerPage = lila.common.MaxPerPage(30)
|
||||
maxPerPage = lila.common.config.MaxPerPage(30)
|
||||
)
|
||||
|
||||
private def followship(userIds: Seq[String])(implicit ctx: Context): Fu[List[Related]] =
|
||||
env.user.userRepo usersFromSecondary userIds.map(UserModel.normalize) flatMap { users =>
|
||||
env.user.repo usersFromSecondary userIds.map(UserModel.normalize) flatMap { users =>
|
||||
(ctx.isAuth ?? { env.pref.api.followableIds(users map (_.id)) }) flatMap { followables =>
|
||||
users.map { u =>
|
||||
ctx.userId ?? { env.api.fetchRelation(_, u.id) } map { rel =>
|
||||
ctx.userId ?? { api.fetchRelation(_, u.id) } map { rel =>
|
||||
lila.relation.Related(u, none, followables(u.id), rel)
|
||||
}
|
||||
}.sequenceFu
|
||||
|
|
|
@ -10,7 +10,11 @@ import lila.common.HTTPRequest
|
|||
import lila.report.{ Room, Report => ReportModel, Mod => AsMod, Reporter, Suspect }
|
||||
import lila.user.{ User => UserModel }
|
||||
|
||||
final class Report(env: Env) extends LilaController(env) {
|
||||
final class Report(
|
||||
env: Env,
|
||||
userC: User,
|
||||
modC: Mod
|
||||
) extends LilaController(env) {
|
||||
|
||||
private def api = env.report.api
|
||||
|
||||
|
@ -43,7 +47,7 @@ final class Report(env: Env) extends LilaController(env) {
|
|||
private def onInquiryStart(inquiry: ReportModel) =
|
||||
inquiry.room match {
|
||||
case Room.Comm => Redirect(routes.Mod.communicationPrivate(inquiry.user))
|
||||
case _ => Mod.redirect(inquiry.user)
|
||||
case _ => modC.redirect(inquiry.user)
|
||||
}
|
||||
|
||||
protected[controllers] def onInquiryClose(
|
||||
|
@ -53,7 +57,7 @@ final class Report(env: Env) extends LilaController(env) {
|
|||
force: Boolean = false
|
||||
)(implicit ctx: BodyContext[_]) = {
|
||||
goTo.ifTrue(HTTPRequest isXhr ctx.req) match {
|
||||
case Some(suspect) => User.renderModZoneActions(suspect.user.username)
|
||||
case Some(suspect) => userC.renderModZoneActions(suspect.user.username)
|
||||
case None =>
|
||||
val dataOpt = ctx.body.body match {
|
||||
case AnyContentAsFormUrlEncoded(data) => data.some
|
||||
|
@ -62,12 +66,12 @@ final class Report(env: Env) extends LilaController(env) {
|
|||
inquiry match {
|
||||
case None =>
|
||||
goTo.fold(Redirect(routes.Report.list).fuccess) { s =>
|
||||
User.modZoneOrRedirect(s.user.username, me)
|
||||
userC.modZoneOrRedirect(s.user.username, me)
|
||||
}
|
||||
case Some(prev) =>
|
||||
def thenGoTo = dataOpt.flatMap(_ get "then").flatMap(_.headOption) flatMap {
|
||||
case "back" => HTTPRequest referer ctx.req
|
||||
case "profile" => Mod.userUrl(prev.user, true).some
|
||||
case "profile" => modC.userUrl(prev.user, true).some
|
||||
case url => url.some
|
||||
}
|
||||
thenGoTo match {
|
||||
|
@ -82,7 +86,7 @@ final class Report(env: Env) extends LilaController(env) {
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (force) User.modZoneOrRedirect(prev.user, me)
|
||||
else if (force) userC.modZoneOrRedirect(prev.user, me)
|
||||
else api.inquiries.toggle(AsMod(me), prev.id) map {
|
||||
_.fold(redirectToList)(onInquiryStart)
|
||||
}
|
||||
|
@ -102,7 +106,7 @@ final class Report(env: Env) extends LilaController(env) {
|
|||
}
|
||||
|
||||
def currentCheatInquiry(username: String) = Secure(_.Hunter) { implicit ctx => me =>
|
||||
OptionFuResult(env.user.userRepo named username) { user =>
|
||||
OptionFuResult(env.user.repo named username) { user =>
|
||||
env.api.currentCheatReport(lila.report.Suspect(user)) flatMap {
|
||||
_ ?? { report =>
|
||||
env.api.inquiries.toggle(lila.report.Mod(me), report.id)
|
||||
|
@ -112,7 +116,7 @@ final class Report(env: Env) extends LilaController(env) {
|
|||
}
|
||||
|
||||
def form = Auth { implicit ctx => implicit me =>
|
||||
get("username") ?? env.user.userRepo.named flatMap { user =>
|
||||
get("username") ?? env.user.repo.named flatMap { user =>
|
||||
env.forms.createWithCaptcha map {
|
||||
case (form, captcha) => Ok(html.report.form(form, user, captcha))
|
||||
}
|
||||
|
@ -122,7 +126,7 @@ final class Report(env: Env) extends LilaController(env) {
|
|||
def create = AuthBody { implicit ctx => implicit me =>
|
||||
implicit val req = ctx.body
|
||||
env.forms.create.bindFromRequest.fold(
|
||||
err => get("username") ?? env.user.userRepo.named flatMap { user =>
|
||||
err => get("username") ?? env.user.repo.named flatMap { user =>
|
||||
env.forms.anyCaptcha map { captcha =>
|
||||
BadRequest(html.report.form(err, user, captcha))
|
||||
}
|
||||
|
@ -139,7 +143,7 @@ final class Report(env: Env) extends LilaController(env) {
|
|||
implicit val req = ctx.body
|
||||
env.forms.flag.bindFromRequest.fold(
|
||||
err => BadRequest.fuccess,
|
||||
data => env.user.userRepo named data.username flatMap {
|
||||
data => env.user.repo named data.username flatMap {
|
||||
_ ?? { user =>
|
||||
if (user == me) BadRequest.fuccess
|
||||
else api.commFlag(Reporter(me), Suspect(user), data.resource, data.text) inject Ok
|
||||
|
|
|
@ -44,7 +44,7 @@ final class Setup(env: Env) extends LilaController(env) with TheftPrevention {
|
|||
if (HTTPRequest isXhr ctx.req)
|
||||
env.forms friendFilled get("fen").map(FEN) flatMap { form =>
|
||||
val validFen = form("fen").value flatMap ValidFen(false)
|
||||
userId ?? env.user.userRepo.named flatMap {
|
||||
userId ?? env.user.repo.named flatMap {
|
||||
case None => Ok(html.setup.forms.friend(form, none, none, validFen)).fuccess
|
||||
case Some(user) => env.challenge.granter(ctx.me, user, none) map {
|
||||
case Some(denied) => BadRequest(lila.challenge.ChallengeDenied.translated(denied))
|
||||
|
@ -65,7 +65,7 @@ final class Setup(env: Env) extends LilaController(env) with TheftPrevention {
|
|||
html = keyPages.home(Results.BadRequest),
|
||||
api = _ => jsonFormError(err)
|
||||
),
|
||||
config => userId ?? env.user.userRepo.enabledById flatMap { destUser =>
|
||||
config => userId ?? env.user.repo.enabledById flatMap { destUser =>
|
||||
destUser ?? { env.challenge.granter(ctx.me, _, config.perfType) } flatMap {
|
||||
case Some(denied) =>
|
||||
val message = lila.challenge.ChallengeDenied.translated(denied)
|
||||
|
|
|
@ -58,7 +58,7 @@ final class Study(env: Env) extends LilaController(env) {
|
|||
def byOwnerDefault(username: String, page: Int) = byOwner(username, Order.default.key, page)
|
||||
|
||||
def byOwner(username: String, order: String, page: Int) = Open { implicit ctx =>
|
||||
userRepo.named(username).flatMap {
|
||||
env.user.repo.named(username).flatMap {
|
||||
_.fold(notFound(ctx)) { owner =>
|
||||
env.pager.byOwner(owner, ctx.me, Order(order), page) flatMap { pag =>
|
||||
negotiate(
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package controllers
|
||||
|
||||
import play.api.data.Form
|
||||
import play.api.libs.iteratee._
|
||||
import play.api.libs.json._
|
||||
import play.api.mvc._
|
||||
import scala.concurrent.duration._
|
||||
|
@ -24,7 +23,7 @@ final class User(env: Env) extends LilaController(env) {
|
|||
private def userGameSearch = env.gameSearch.userGameSearch
|
||||
|
||||
def tv(username: String) = Open { implicit ctx =>
|
||||
OptionFuResult(env.user.userRepo named username) { user =>
|
||||
OptionFuResult(env.user.repo named username) { user =>
|
||||
currentlyPlaying(user) orElse
|
||||
env.game.gameRepo.lastPlayed(user) flatMap {
|
||||
_.fold(fuccess(Redirect(routes.User.show(username)))) { pov =>
|
||||
|
@ -35,7 +34,7 @@ final class User(env: Env) extends LilaController(env) {
|
|||
}
|
||||
|
||||
def studyTv(username: String) = Open { implicit ctx =>
|
||||
OptionResult(env.user.userRepo named username) { user =>
|
||||
OptionResult(env.user.repo named username) { user =>
|
||||
Redirect {
|
||||
env.relation.online.studying getIfPresent user.id match {
|
||||
case None => routes.Study.byOwnerDefault(user.id)
|
||||
|
@ -106,12 +105,12 @@ final class User(env: Env) extends LilaController(env) {
|
|||
}
|
||||
|
||||
private def EnabledUser(username: String)(f: UserModel => Fu[Result])(implicit ctx: Context): Fu[Result] =
|
||||
env.user.userRepo named username flatMap {
|
||||
env.user.repo named username flatMap {
|
||||
case None if isGranted(_.UserSpy) => Mod.searchTerm(username.trim)
|
||||
case None => notFound
|
||||
case Some(u) if (u.enabled || isGranted(_.UserSpy)) => f(u)
|
||||
case Some(u) => negotiate(
|
||||
html = env.user.userRepo isErased u flatMap { erased =>
|
||||
html = env.user.repo isErased u flatMap { erased =>
|
||||
if (erased.value) notFound
|
||||
else NotFound(html.user.show.page.disabled(u)).fuccess
|
||||
},
|
||||
|
@ -120,7 +119,7 @@ final class User(env: Env) extends LilaController(env) {
|
|||
}
|
||||
|
||||
def showMini(username: String) = Open { implicit ctx =>
|
||||
OptionFuResult(env.user.userRepo named username) { user =>
|
||||
OptionFuResult(env.user.repo named username) { user =>
|
||||
if (user.enabled || isGranted(_.UserSpy)) for {
|
||||
blocked <- ctx.userId ?? { relationApi.fetchBlocks(user.id, _) }
|
||||
crosstable <- ctx.userId ?? { env.game.crosstableApi(user.id, _) map some }
|
||||
|
@ -270,7 +269,7 @@ final class User(env: Env) extends LilaController(env) {
|
|||
}
|
||||
|
||||
protected[controllers] def renderModZone(username: String, me: UserModel)(implicit ctx: Context): Fu[Result] = {
|
||||
env.user.userRepo withEmails username flatten s"No such user $username" map {
|
||||
env.user.repo withEmails username flatten s"No such user $username" map {
|
||||
case UserModel.WithEmails(user, emails) =>
|
||||
val parts =
|
||||
env.mod.logApi.userHistory(user.id).logTimeIfGt(s"$username logApi.userHistory", 2 seconds) zip
|
||||
|
@ -282,7 +281,7 @@ final class User(env: Env) extends LilaController(env) {
|
|||
env.user.lightUserApi.preloadMany(reports.userIds).logTimeIfGt(s"$username lightUserApi.preloadMany", 2 seconds) inject
|
||||
html.user.mod.parts(user, history, charges, reports, pref, rageSit).some
|
||||
}
|
||||
val actions = env.user.userRepo.isErased(user) map { erased =>
|
||||
val actions = env.user.repo.isErased(user) map { erased =>
|
||||
html.user.mod.actions(user, emails, erased).some
|
||||
}
|
||||
val spyFu = env.security.userSpy(user).logTimeIfGt(s"$username security.userSpy", 2 seconds)
|
||||
|
@ -323,9 +322,9 @@ final class User(env: Env) extends LilaController(env) {
|
|||
}
|
||||
|
||||
protected[controllers] def renderModZoneActions(username: String)(implicit ctx: Context) =
|
||||
env.user.userRepo withEmails username flatten s"No such user $username" flatMap {
|
||||
env.user.repo withEmails username orFail s"No such user $username" flatMap {
|
||||
case UserModel.WithEmails(user, emails) =>
|
||||
env.user.userRepo.isErased(user) map { erased =>
|
||||
env.user.repo.isErased(user) map { erased =>
|
||||
Ok(html.user.mod.actions(user, emails, erased))
|
||||
}
|
||||
}
|
||||
|
@ -345,7 +344,7 @@ final class User(env: Env) extends LilaController(env) {
|
|||
}
|
||||
|
||||
private def doWriteNote(username: String, me: UserModel)(err: Form[_] => UserModel => Fu[Result], suc: => Result)(implicit req: Request[_]) =
|
||||
env.user.userRepo named username flatMap {
|
||||
env.user.repo named username flatMap {
|
||||
_ ?? { user =>
|
||||
env.forms.note.bindFromRequest.fold(
|
||||
e => err(e)(user),
|
||||
|
@ -375,7 +374,7 @@ final class User(env: Env) extends LilaController(env) {
|
|||
}
|
||||
|
||||
def perfStat(username: String, perfKey: String) = Open { implicit ctx =>
|
||||
OptionFuResult(env.user.userRepo named username) { u =>
|
||||
OptionFuResult(env.user.repo named username) { u =>
|
||||
if ((u.disabled || (u.lame && !ctx.is(u))) && !isGranted(_.UserSpy)) notFound
|
||||
else PerfType(perfKey).fold(notFound) { perfType =>
|
||||
for {
|
||||
|
@ -409,15 +408,15 @@ final class User(env: Env) extends LilaController(env) {
|
|||
def autocomplete = Open { implicit ctx =>
|
||||
get("term", ctx.req).filter(_.nonEmpty).filter(lila.user.User.couldBeUsername) match {
|
||||
case None => BadRequest("No search term provided").fuccess
|
||||
case Some(term) if getBool("exists") => env.user.userRepo nameExists term map { r => Ok(JsBoolean(r)) }
|
||||
case Some(term) if getBool("exists") => env.user.repo nameExists term map { r => Ok(JsBoolean(r)) }
|
||||
case Some(term) => {
|
||||
get("tour") match {
|
||||
case Some(tourId) => env.tournament.playerRepo.searchPlayers(tourId, term, 10)
|
||||
case None => ctx.me.ifTrue(getBool("friend")) match {
|
||||
case None => env.user.userRepo userIdsLike term
|
||||
case None => env.user.repo userIdsLike term
|
||||
case Some(follower) =>
|
||||
env.relation.api.searchFollowedBy(follower, term, 10) flatMap {
|
||||
case Nil => env.user.userRepo userIdsLike term
|
||||
case Nil => env.user.repo userIdsLike term
|
||||
case userIds => fuccess(userIds)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ final class UserTournament(env: Env) extends LilaController(env) {
|
|||
|
||||
def path(username: String, path: String, page: Int) = Open { implicit ctx =>
|
||||
Reasonable(page) {
|
||||
OptionFuResult(env.user.userRepo named username) { user =>
|
||||
OptionFuResult(env.user.repo named username) { user =>
|
||||
path match {
|
||||
case "recent" =>
|
||||
env.tournament.leaderboardApi.recentByUser(user, page).map { entries =>
|
||||
|
|
|
@ -7,7 +7,6 @@ import lila.i18n.{ I18nKeys => trans }
|
|||
import lila.pref.Pref
|
||||
import lila.report.Reason
|
||||
import lila.setup.TimeMode
|
||||
import lila.tournament.System
|
||||
|
||||
trait SetupHelper { self: I18nHelper =>
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ lazy val api = module("api", moduleCPDeps)
|
|||
lazy val puzzle = module("puzzle", Seq(
|
||||
common, memo, hub, history, db, user, rating, pref, tree, game
|
||||
)).settings(
|
||||
libraryDependencies ++= provided(play.api) ++ reactivemongo.bundle
|
||||
libraryDependencies ++= provided(play.api, play.joda) ++ reactivemongo.bundle
|
||||
)
|
||||
|
||||
lazy val quote = module("quote", Seq()).settings(
|
||||
|
|
|
@ -601,9 +601,7 @@ POST /jsmon/:event controllers.Main.jsmon(event: String)
|
|||
|
||||
GET /swag controllers.Main.movedPermanently(to: String = "https://shop.spreadshirt.com/lichess-org")
|
||||
|
||||
# Assets
|
||||
GET /assets/$version<_\w{6}>/*file controllers.Main.versionedAsset(version: String, file: String)
|
||||
GET /assets/*file controllers.Assets.at(path = "/public", file: String)
|
||||
GET /assets/*file controllers.Assets.versioned(file)
|
||||
|
||||
GET /robots.txt controllers.Main.robots
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import play.api.Configuration
|
|||
import reactivemongo.api._
|
||||
import reactivemongo.api.commands.Command
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.{ Await, ExecutionContext, Future }
|
||||
import scala.concurrent.Await
|
||||
import scala.util.{ Failure, Success }
|
||||
|
||||
import dsl.Coll
|
||||
|
@ -42,10 +42,10 @@ final class Env(name: String, config: DbConfig) {
|
|||
object image {
|
||||
private lazy val imageColl = config.imageCollName map apply
|
||||
import dsl._
|
||||
// import DbImage.DbImageBSONHandler
|
||||
// def fetch(id: String): Fu[Option[DbImage]] = imageColl ?? {
|
||||
// _.byId[DbImage](id)
|
||||
// }
|
||||
import DbImage.DbImageBSONHandler
|
||||
def fetch(id: String): Fu[Option[DbImage]] = imageColl ?? {
|
||||
_.byId[DbImage](id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ final class PngExport(
|
|||
).flatten
|
||||
|
||||
ws.url(url)
|
||||
.withQueryString(queryString: _*)
|
||||
.withQueryStringParameters(queryString: _*)
|
||||
.withMethod("GET")
|
||||
.stream() flatMap {
|
||||
case res if res.status != 200 =>
|
||||
|
|
|
@ -21,7 +21,7 @@ private final class UserCacheApi(coll: Coll) {
|
|||
|
||||
def find(id: String) = coll.uno[UserCache]($id(id))
|
||||
|
||||
def save(u: UserCache) = coll.update($id(u.id), u, upsert = true).void
|
||||
def save(u: UserCache) = coll.update.one($id(u.id), u, upsert = true).void
|
||||
|
||||
def remove(id: String) = coll.remove($id(id)).void
|
||||
def remove(id: String) = coll.delete.one($id(id)).void
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ final class Env(
|
|||
|
||||
private lazy val threadColl = db(config.threadColl)
|
||||
|
||||
private lazy val repo = wire[ThreadRepo]
|
||||
lazy val repo = wire[ThreadRepo]
|
||||
|
||||
lazy val forms = wire[DataForm]
|
||||
|
||||
|
|
|
@ -44,10 +44,7 @@ final class Env(
|
|||
asyncCache: lila.memo.AsyncCache.Builder,
|
||||
securityStore: lila.security.Store,
|
||||
emailValidator: lila.security.EmailAddressValidator
|
||||
)(implicit
|
||||
system: ActorSystem,
|
||||
mat: akka.stream.Materializer
|
||||
) {
|
||||
)(implicit system: ActorSystem) {
|
||||
|
||||
private val config = appConfig.get[ModConfig]("mod")(AutoConfig.loader)
|
||||
|
||||
|
|
|
@ -25,13 +25,12 @@ final class ModStream(implicit mat: akka.stream.Materializer) {
|
|||
}
|
||||
.map { js => s"${Json.stringify(js)}\n" }
|
||||
|
||||
def plugTo(sink: Sink[String, Fu[akka.Done]]): Unit = {
|
||||
|
||||
val (queue, done) = blueprint.toMat(sink)(Keep.both).run()
|
||||
def apply(): Source[String, _] = blueprint mapMaterializedValue { queue =>
|
||||
|
||||
val sub = Bus.subscribeFun(classifier) {
|
||||
case signup: Signup => queue offer signup
|
||||
}
|
||||
done onComplete { _ => Bus.unsubscribe(sub, classifier) }
|
||||
|
||||
queue.watchCompletion foreach { _ => Bus.unsubscribe(sub, classifier) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package lila.plan
|
|||
|
||||
import com.softwaremill.macwire._
|
||||
import io.methvin.play.autoconfig._
|
||||
import lila.memo.SettingStore.{ StringReader, Formable }
|
||||
import play.api.Configuration
|
||||
import play.api.libs.ws.WSClient
|
||||
import scala.concurrent.duration._
|
||||
|
@ -32,6 +31,8 @@ final class Env(
|
|||
import StripeClient.configLoader
|
||||
private val config = appConfig.get[PlanConfig]("plan")(AutoConfig.loader)
|
||||
|
||||
val stripePublicKey = config.stripe.publicKey
|
||||
|
||||
private lazy val patronColl = db(config.patronColl)
|
||||
private lazy val chargeColl = db(config.chargeColl)
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ private final class StripeClient(
|
|||
private def debugInput(data: Seq[(String, Any)]) = fixInput(data) map { case (k, v) => s"$k=$v" } mkString " "
|
||||
}
|
||||
|
||||
private object StripeClient {
|
||||
object StripeClient {
|
||||
|
||||
class StripeException(msg: String) extends Exception(msg)
|
||||
class DeletedException(msg: String) extends StripeException(msg)
|
||||
|
@ -178,10 +178,10 @@ private object StripeClient {
|
|||
class InvalidRequestException(msg: String) extends StatusException(msg)
|
||||
|
||||
import io.methvin.play.autoconfig._
|
||||
case class Config(
|
||||
private[plan] case class Config(
|
||||
endpoint: String,
|
||||
@ConfigName("keys.public") publicKey: String,
|
||||
@ConfigName("keys.public") secretKey: Secret
|
||||
)
|
||||
implicit val configLoader = AutoConfig.loader[Config]
|
||||
private[plan] implicit val configLoader = AutoConfig.loader[Config]
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ final class PracticeApi(
|
|||
private def save(p: PracticeProgress): Funit =
|
||||
coll.update.one($id(p.id), p, upsert = true).void
|
||||
|
||||
def setNbMoves(user: User, chapterId: Chapter.Id, score: NbMoves) = {
|
||||
def setNbMoves(user: User, chapterId: Chapter.Id, score: NbMoves): Funit = {
|
||||
get(user) flatMap { prog =>
|
||||
save(prog.withNbMoves(chapterId, score))
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package lila.puzzle
|
||||
|
||||
import akka.stream.scaladsl._
|
||||
import org.joda.time.DateTime
|
||||
import play.api.libs.json._
|
||||
import play.api.libs.json.JodaWrites._
|
||||
import reactivemongo.akkastream.{ AkkaStreamCursor, cursorProducer }
|
||||
import reactivemongo.api.ReadPreference
|
||||
import scala.concurrent.duration._
|
||||
|
||||
|
@ -14,66 +17,44 @@ final class PuzzleActivity(
|
|||
roundColl: Coll
|
||||
)(implicit system: akka.actor.ActorSystem) {
|
||||
|
||||
// import PuzzleActivity._
|
||||
// import Round.RoundBSONHandler
|
||||
import PuzzleActivity._
|
||||
import Round.RoundBSONHandler
|
||||
|
||||
// def stream(config: Config): Enumerator[String] = {
|
||||
def stream(config: Config): Source[String, _] = roundColl
|
||||
.ext.find($doc("_id" $startsWith config.user.id))
|
||||
.sort($sort desc "_id")
|
||||
.batchSize(config.perSecond.value)
|
||||
.cursor[Round](ReadPreference.secondaryPreferred)
|
||||
.documentSource()
|
||||
.take(config.max | Int.MaxValue)
|
||||
.grouped(config.perSecond.value)
|
||||
.delay(1 second)
|
||||
.mapAsync(1)(enrich)
|
||||
.mapConcat(identity)
|
||||
.map { json => s"${Json.stringify(json)}\n" }
|
||||
|
||||
// val selector = $doc("_id" $startsWith config.user.id)
|
||||
|
||||
// val query = roundColl.find(selector).sort($sort desc "_id")
|
||||
|
||||
// val infinite = query.copy(options = query.options.batchSize(config.perSecond.value))
|
||||
// .cursor[Round](ReadPreference.secondaryPreferred)
|
||||
// .bulkEnumerator() &>
|
||||
// Enumeratee.mapM[Iterator[Round]].apply[Seq[JsObject]] { rounds =>
|
||||
// enrich(rounds.toSeq)
|
||||
// } &>
|
||||
// lila.common.Iteratee.delay(1 second) &>
|
||||
// Enumeratee.mapConcat(_.toSeq)
|
||||
|
||||
// val stream = config.max.fold(infinite) { max =>
|
||||
// // I couldn't figure out how to do it properly :( :( :(
|
||||
// // the nb can't be set as bulkEnumerator(nb)
|
||||
// // because games are further filtered after being fetched
|
||||
// var nb = 0
|
||||
// infinite &> Enumeratee.mapInput { in =>
|
||||
// nb = nb + 1
|
||||
// if (nb <= max) in
|
||||
// else Input.EOF
|
||||
// }
|
||||
// }
|
||||
|
||||
// stream &> formatter
|
||||
// }
|
||||
|
||||
// private def enrich(rounds: Seq[Round]): Fu[Seq[JsObject]] =
|
||||
// puzzleColl.primitiveMap[Int, Double](
|
||||
// ids = rounds.map(_.id.puzzleId).toSeq,
|
||||
// field = "perf.gl.r",
|
||||
// fieldExtractor = obj => for {
|
||||
// perf <- obj.getAs[Bdoc]("perf")
|
||||
// gl <- perf.getAs[Bdoc]("gl")
|
||||
// rating <- gl.getAs[Double]("r")
|
||||
// } yield rating
|
||||
// ) map { ratings =>
|
||||
// rounds.toSeq flatMap { round =>
|
||||
// ratings get round.id.puzzleId map { puzzleRating =>
|
||||
// Json.obj(
|
||||
// "id" -> round.id.puzzleId,
|
||||
// "date" -> round.date,
|
||||
// "rating" -> round.rating,
|
||||
// "ratingDiff" -> round.ratingDiff,
|
||||
// "puzzleRating" -> puzzleRating.toInt
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// private def formatter =
|
||||
// Enumeratee.map[JsObject].apply[String] { json =>
|
||||
// s"${Json.stringify(json)}\n"
|
||||
// }
|
||||
private def enrich(rounds: Seq[Round]): Fu[Seq[JsObject]] =
|
||||
puzzleColl.primitiveMap[Int, Double](
|
||||
ids = rounds.map(_.id.puzzleId).toSeq,
|
||||
field = "perf.gl.r",
|
||||
fieldExtractor = obj => for {
|
||||
perf <- obj.child("perf")
|
||||
gl <- perf.child("gl")
|
||||
rating <- gl.double("r")
|
||||
} yield rating
|
||||
) map { ratings =>
|
||||
rounds.toSeq flatMap { round =>
|
||||
ratings get round.id.puzzleId map { puzzleRating =>
|
||||
Json.obj(
|
||||
"id" -> round.id.puzzleId,
|
||||
"date" -> round.date,
|
||||
"rating" -> round.rating,
|
||||
"ratingDiff" -> round.ratingDiff,
|
||||
"puzzleRating" -> puzzleRating.toInt
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object PuzzleActivity {
|
||||
|
|
|
@ -2,9 +2,10 @@ package lila.report
|
|||
|
||||
import org.joda.time.DateTime
|
||||
import ornicar.scalalib.Random
|
||||
import scala.math.Ordering.Float.TotalOrdering
|
||||
import scalaz.NonEmptyList
|
||||
|
||||
import lila.user.{ User, Note }
|
||||
import lila.user.User
|
||||
|
||||
case class Report(
|
||||
_id: Report.ID, // also the url slug
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
package lila.report
|
||||
|
||||
import reactivemongo.api.bson._
|
||||
|
||||
import lila.db.dsl._
|
||||
import lila.user.{ User, UserRepo, Title }
|
||||
|
||||
private final class ReportScore(
|
||||
|
|
|
@ -48,7 +48,7 @@ final class Env(
|
|||
|
||||
lazy val geoIP: GeoIP = wire[GeoIP]
|
||||
|
||||
lazy val userSpyApi = wire[UserSpyApi]
|
||||
lazy val userSpy = wire[UserSpyApi]
|
||||
|
||||
lazy val store = new Store(db(config.collection.security))
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ private final class RequestRepo(val coll: Coll) {
|
|||
def teamsQuery(teamIds: List[ID]) = $doc("team" $in teamIds)
|
||||
|
||||
def getByUserId(userId: lila.user.User.ID) =
|
||||
coll.find($doc("user" -> userId)).list[Request]()
|
||||
coll.ext.find($doc("user" -> userId)).list[Request]()
|
||||
|
||||
def remove(id: ID) = coll.remove($id(id))
|
||||
def remove(id: ID) = coll.delete.one($id(id))
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ final class TeamMemberStream(
|
|||
|
||||
def apply(team: Team, perSecond: MaxPerSecond): Source[User, _] =
|
||||
memberRepo.coll
|
||||
.find($doc("team" -> team.id), $doc("user" -> true))
|
||||
.ext.find($doc("team" -> team.id), $doc("user" -> true))
|
||||
.sort($sort desc "date")
|
||||
.batchSize(perSecond.value)
|
||||
.cursor[Bdoc](ReadPreference.secondaryPreferred)
|
||||
|
|
|
@ -29,7 +29,7 @@ final class EntryApi(
|
|||
coll.find($doc(
|
||||
"users" -> userId,
|
||||
"date" $gt DateTime.now.minusWeeks(2)
|
||||
), projection)
|
||||
), projection.some)
|
||||
.sort($sort desc "date")
|
||||
.cursor[Entry](ReadPreference.secondaryPreferred)
|
||||
.gather[Vector](max)
|
||||
|
@ -37,17 +37,17 @@ final class EntryApi(
|
|||
def findRecent(typ: String, since: DateTime, max: Int) =
|
||||
coll.find(
|
||||
$doc("typ" -> typ, "date" $gt since),
|
||||
projection
|
||||
projection.some
|
||||
).sort($sort desc "date")
|
||||
.cursor[Entry](ReadPreference.secondaryPreferred)
|
||||
.gather[Vector](max)
|
||||
|
||||
def channelUserIdRecentExists(channel: String, userId: User.ID): Fu[Boolean] =
|
||||
coll.count($doc(
|
||||
coll.countSel($doc(
|
||||
"users" -> userId,
|
||||
"chan" -> channel,
|
||||
"date" $gt DateTime.now.minusDays(7)
|
||||
).some) map (0 !=)
|
||||
)) map (0 !=)
|
||||
|
||||
def insert(e: Entry.ForUsers) =
|
||||
coll.insert(EntryBSONHandler.writeTry(e.entry).get ++ $doc("users" -> e.userIds)) void
|
||||
|
@ -55,7 +55,7 @@ final class EntryApi(
|
|||
// can't remove from capped collection,
|
||||
// so we set a date in the past instead.
|
||||
private[timeline] def removeRecentFollowsBy(userId: User.ID): Funit =
|
||||
coll.update(
|
||||
coll.update.one(
|
||||
$doc("typ" -> "follow", "data.u1" -> userId, "date" $gt DateTime.now().minusHours(1)),
|
||||
$set("date" -> DateTime.now().minusDays(365)),
|
||||
multi = true
|
||||
|
@ -71,7 +71,7 @@ final class EntryApi(
|
|||
expireAfter = _.ExpireAfterWrite(1 hour)
|
||||
)
|
||||
|
||||
private def fetch: Fu[Vector[Entry]] = coll
|
||||
private def fetch: Fu[Vector[Entry]] = coll.ext
|
||||
.find($doc(
|
||||
"users" $exists false,
|
||||
"date" $gt DateTime.now.minusWeeks(2)
|
||||
|
|
|
@ -8,7 +8,6 @@ import play.api.libs.ws.WSClient
|
|||
import scala.concurrent.duration._
|
||||
|
||||
import lila.common.config._
|
||||
import lila.common.LightUser
|
||||
import lila.db.dsl.Coll
|
||||
|
||||
private class UserConfig(
|
||||
|
@ -34,7 +33,7 @@ final class Env(
|
|||
|
||||
private val config = appConfig.get[UserConfig]("user")(AutoConfig.loader)
|
||||
|
||||
val userRepo = new UserRepo(db(config.collectionUser))
|
||||
val repo = new UserRepo(db(config.collectionUser))
|
||||
|
||||
val lightUserApi: LightUserApi = wire[LightUserApi]
|
||||
val lightUser = lightUserApi.async
|
||||
|
@ -85,7 +84,7 @@ final class Env(
|
|||
"adjustCheater" -> {
|
||||
case lila.hub.actorApi.mod.MarkCheater(userId, true) =>
|
||||
rankingApi remove userId
|
||||
userRepo.setRoles(userId, Nil)
|
||||
repo.setRoles(userId, Nil)
|
||||
},
|
||||
"adjustBooster" -> {
|
||||
case lila.hub.actorApi.mod.MarkBooster(userId) => rankingApi remove userId
|
||||
|
@ -95,7 +94,7 @@ final class Env(
|
|||
},
|
||||
"gdprErase" -> {
|
||||
case User.GDPRErase(user) =>
|
||||
userRepo erase user
|
||||
repo erase user
|
||||
noteApi erase user
|
||||
}
|
||||
)
|
||||
|
|
|
@ -2,7 +2,7 @@ package lila.user
|
|||
|
||||
import reactivemongo.api.bson._
|
||||
import scala.concurrent.duration._
|
||||
import scala.util.{ Try, Success, Failure }
|
||||
import scala.util.Success
|
||||
|
||||
import lila.common.LightUser
|
||||
import lila.db.dsl._
|
||||
|
|
|
@ -2,7 +2,6 @@ package lila.user
|
|||
|
||||
import lila.db.dsl._
|
||||
import org.joda.time.DateTime
|
||||
import reactivemongo.api.ReadPreference
|
||||
|
||||
case class Note(
|
||||
_id: String,
|
||||
|
|
|
@ -2,7 +2,6 @@ package lila.user
|
|||
|
||||
import org.apache.commons.codec.binary.Base32
|
||||
import reactivemongo.api.bson._
|
||||
import scala.util.{ Try, Success, Failure }
|
||||
|
||||
import java.security.SecureRandom
|
||||
import javax.crypto.Mac
|
||||
|
|
|
@ -53,11 +53,10 @@ object BuildSettings {
|
|||
"-language:reflectiveCalls", // #TODO remove me for perfs
|
||||
"-feature",
|
||||
"-deprecation",
|
||||
"-unchecked",
|
||||
"-Wunused:imports,locals,implicits",
|
||||
"inaccessible,infer-any",
|
||||
"-Xmaxerrs", "5",
|
||||
"-Xmaxwarns", "5"
|
||||
// "-unchecked",
|
||||
// "-Wunused:imports,locals,implicits",// "inaccessible,infer-any",
|
||||
"-Xmaxerrs", "6",
|
||||
"-Xmaxwarns", "6"
|
||||
)
|
||||
|
||||
val srcMain = Seq(
|
||||
|
|
Loading…
Reference in New Issue