wire all the things

rm0193-mapreduce
Thibault Duplessis 2019-12-04 22:32:03 -06:00
parent 6bc20d9b75
commit 547641f69b
67 changed files with 312 additions and 189 deletions

View File

@ -2,15 +2,19 @@ package lila.app
import akka.actor._
import com.softwaremill.macwire._
import play.api.{ Application, Configuration, Mode }
import play.api.mvc.SessionCookieBaker
import play.api.{ Application, Configuration, Mode }
import scala.concurrent.duration._
import play.api.libs.ws.ahc.AhcWSComponents
import play.api.libs.ws.WSClient
import lila.common.Bus
import lila.common.config._
import lila.user.User
final class Env(
val config: Configuration,
val common: lila.common.Env,
val db: lila.db.Env,
val playApp: Application,
val api: lila.api.Env,
@ -76,12 +80,10 @@ final class Env(
val rating: lila.rating.Env
)(implicit system: ActorSystem) {
Env.bootMessage()
val isProd = playApp.mode == Mode.Prod
val isStage = config.get[Boolean]("app.stage")
def net = api.net
def net = common.netConfig
lazy val preloader = wire[mashup.Preload]
@ -149,11 +151,82 @@ final class Env(
templating.Environment setEnv this
}
private object Env {
final class EnvBoot(
app: Application
) extends AhcWSComponents {
lila.log.boot.info(s"Java: ${System.getProperty("java.version")}, memory: ${Runtime.getRuntime().maxMemory() / 1024 / 1024}MB")
def bootMessage(): Unit = {
val version = System.getProperty("java.version")
val memory = Runtime.getRuntime().maxMemory() / 1024 / 1024
lila.log.boot.info(s"Java: $version, memory: ${memory}MB")
}
implicit val system = app.actorSystem
implicit val scheduler = system.scheduler
def config = app.configuration
def appPath = AppPath(app.path)
def mode = app.mode
implicit lazy val ws: WSClient = wsClient
lazy val common: lila.common.Env = wire[lila.common.Env]
lazy val baseUrl = common.netConfig.baseUrl
lazy val memo: lila.memo.Env = wire[lila.memo.Env]
lazy val db: lila.db.Env = lila.db.Env.main(config)
lazy val user: lila.user.Env = wire[lila.user.Env]
lazy val security: lila.security.Env = wire[lila.security.Env]
lazy val hub: lila.hub.Env = wire[lila.hub.Env]
lazy val socket: lila.socket.Env = wire[lila.socket.Env]
lazy val message: lila.message.Env = wire[lila.message.Env]
lazy val i18n: lila.i18n.Env = wire[lila.i18n.Env]
lazy val game: lila.game.Env = wire[lila.game.Env]
implicit def idGenerator = game.idGenerator
lazy val bookmark: lila.bookmark.Env = wire[lila.bookmark.Env]
lazy val search: lila.search.Env = wire[lila.search.Env]
lazy val gameSearch: lila.gameSearch.Env = wire[lila.gameSearch.Env]
lazy val timeline: lila.timeline.Env = wire[lila.timeline.Env]
lazy val forum: lila.forum.Env = wire[lila.forum.Env]
lazy val forumSearch: lila.forumSearch.Env = wire[lila.forumSearch.Env]
lazy val team: lila.team.Env = wire[lila.team.Env]
lazy val teamSearch: lila.teamSearch.Env = wire[lila.teamSearch.Env]
lazy val analyse: lila.analyse.Env = wire[lila.analyse.Env]
lazy val mod: lila.mod.Env = wire[lila.mod.Env]
lazy val notify: lila.notify.Env = wire[lila.notify.Env]
lazy val round: lila.round.Env = wire[lila.round.Env]
lazy val lobby: lila.lobby.Env = wire[lila.lobby.Env]
lazy val setup: lila.setup.Env = wire[lila.setup.Env]
lazy val importer: lila.importer.Env = wire[lila.importer.Env]
lazy val tournament: lila.tournament.Env = wire[lila.tournament.Env]
lazy val simul: lila.simul.Env = wire[lila.simul.Env]
lazy val relation: lila.relation.Env = wire[lila.relation.Env]
lazy val report: lila.report.Env = wire[lila.report.Env]
lazy val pref: lila.pref.Env = wire[lila.pref.Env]
lazy val chat: lila.chat.Env = wire[lila.chat.Env]
lazy val puzzle: lila.puzzle.Env = wire[lila.puzzle.Env]
lazy val coordinate: lila.coordinate.Env = wire[lila.coordinate.Env]
lazy val tv: lila.tv.Env = wire[lila.tv.Env]
lazy val blog: lila.blog.Env = wire[lila.blog.Env]
lazy val history: lila.history.Env = wire[lila.history.Env]
lazy val video: lila.video.Env = wire[lila.video.Env]
lazy val playban: lila.playban.Env = wire[lila.playban.Env]
lazy val shutup: lila.shutup.Env = wire[lila.shutup.Env]
lazy val insight: lila.insight.Env = wire[lila.insight.Env]
lazy val push: lila.push.Env = wire[lila.push.Env]
lazy val perfStat: lila.perfStat.Env = wire[lila.perfStat.Env]
lazy val slack: lila.slack.Env = wire[lila.slack.Env]
lazy val challenge: lila.challenge.Env = wire[lila.challenge.Env]
lazy val explorer: lila.explorer.Env = wire[lila.explorer.Env]
lazy val fishnet: lila.fishnet.Env = wire[lila.fishnet.Env]
lazy val study: lila.study.Env = wire[lila.study.Env]
lazy val studySearch: lila.studySearch.Env = wire[lila.studySearch.Env]
lazy val learn: lila.learn.Env = wire[lila.learn.Env]
lazy val plan: lila.plan.Env = wire[lila.plan.Env]
lazy val event: lila.event.Env = wire[lila.event.Env]
lazy val coach: lila.coach.Env = wire[lila.coach.Env]
lazy val pool: lila.pool.Env = wire[lila.pool.Env]
lazy val practice: lila.practice.Env = wire[lila.practice.Env]
lazy val irwin: lila.irwin.Env = wire[lila.irwin.Env]
lazy val activity: lila.activity.Env = wire[lila.activity.Env]
lazy val relay: lila.relay.Env = wire[lila.relay.Env]
lazy val streamer: lila.streamer.Env = wire[lila.streamer.Env]
lazy val oAuth: lila.oauth.Env = wire[lila.oauth.Env]
lazy val bot: lila.bot.Env = wire[lila.bot.Env]
lazy val evalCache: lila.evalCache.Env = wire[lila.evalCache.Env]
lazy val rating: lila.rating.Env = wire[lila.rating.Env]
lazy val api: lila.api.Env = wire[lila.api.Env]
lazy val env: lila.app.Env = wire[lila.app.Env]
}

View File

@ -99,7 +99,9 @@ final class Relation(
import apiC.limitedDefault
apiC.GlobalLinearLimitPerIP(HTTPRequest lastRemoteAddress req) {
apiC.jsonStream {
env.stream.follow(user, direction, MaxPerSecond(20)) &> Enumeratee.map(api.userApi.one)
env.relation.stream
.follow(user, direction, MaxPerSecond(20))
.map(env.api.userApi.one)
} |> fuccess
}
}

View File

@ -8,47 +8,48 @@ import lila.app._
import lila.relay.{ Relay => RelayModel }
import views._
final class Relay(env: Env) extends LilaController(env) {
private val env = env.relay
final class Relay(
env: Env,
studyC: Study
) extends LilaController(env) {
def index(page: Int) = Open { implicit ctx =>
Reasonable(page) {
for {
fresh <- (page == 1).??(env.api.fresh(ctx.me) map some)
pager <- env.pager.finished(ctx.me, page)
fresh <- (page == 1).??(env.relay.api.fresh(ctx.me) map some)
pager <- env.relay.pager.finished(ctx.me, page)
} yield Ok(html.relay.index(fresh, pager, routes.Relay.index()))
}
}
def form = Auth { implicit ctx => me =>
NoLame {
Ok(html.relay.form.create(env.forms.create)).fuccess
Ok(html.relay.form.create(env.relay.forms.create)).fuccess
}
}
def create = AuthBody { implicit ctx => me =>
implicit val req = ctx.body
env.forms.create.bindFromRequest.fold(
env.relay.forms.create.bindFromRequest.fold(
err => BadRequest(html.relay.form.create(err)).fuccess,
setup => env.api.create(setup, me) map { relay =>
setup => env.relay.api.create(setup, me) map { relay =>
Redirect(showRoute(relay))
}
)
}
def edit(slug: String, id: String) = Auth { implicit ctx => me =>
OptionFuResult(env.api.byIdAndContributor(id, me)) { relay =>
Ok(html.relay.form.edit(relay, env.forms.edit(relay))).fuccess
OptionFuResult(env.relay.api.byIdAndContributor(id, me)) { relay =>
Ok(html.relay.form.edit(relay, env.relay.forms.edit(relay))).fuccess
}
}
def update(slug: String, id: String) = AuthBody { implicit ctx => me =>
OptionFuResult(env.api.byIdAndContributor(id, me)) { relay =>
OptionFuResult(env.relay.api.byIdAndContributor(id, me)) { relay =>
implicit val req = ctx.body
env.forms.edit(relay).bindFromRequest.fold(
env.relay.forms.edit(relay).bindFromRequest.fold(
err => BadRequest(html.relay.form.edit(relay, err)).fuccess,
data => env.api.update(relay) { data.update(_, me) } map { r =>
data => env.relay.api.update(relay) { data.update(_, me) } map { r =>
Redirect(showRoute(r))
}
)
@ -56,8 +57,8 @@ final class Relay(env: Env) extends LilaController(env) {
}
def reset(slug: String, id: String) = Auth { implicit ctx => me =>
OptionFuResult(env.api.byIdAndContributor(id, me)) { relay =>
env.api.reset(relay, me) inject Redirect(showRoute(relay))
OptionFuResult(env.relay.api.byIdAndContributor(id, me)) { relay =>
env.relay.api.reset(relay, me) inject Redirect(showRoute(relay))
}
}
@ -85,19 +86,19 @@ final class Relay(env: Env) extends LilaController(env) {
}
private def WithRelay(slug: String, id: String)(f: RelayModel => Fu[Result])(implicit ctx: Context): Fu[Result] =
OptionFuResult(env.api byId id) { relay =>
OptionFuResult(env.relay.api byId id) { relay =>
if (relay.slug != slug) Redirect(showRoute(relay)).fuccess
else f(relay)
}
private def doShow(relay: RelayModel, oldSc: lila.study.Study.WithChapter)(implicit ctx: Context): Fu[Result] =
Study.CanViewResult(oldSc.study) {
studyC.CanViewResult(oldSc.study) {
for {
(sc, studyData) <- Study.getJsonData(oldSc)
data = env.jsonView.makeData(relay, studyData)
chat <- Study.chatOf(sc.study)
(sc, studyData) <- studyC.getJsonData(oldSc)
data = env.relay.jsonView.makeData(relay, studyData)
chat <- studyC.chatOf(sc.study)
sVersion <- env.study.version(sc.study.id)
streams <- Study.streamsOf(sc.study)
streams <- studyC.streamsOf(sc.study)
} yield Ok(html.relay.show(relay, sc.study, data, chat, sVersion, streams))
}

View File

@ -20,11 +20,11 @@ final class Report(
def list = Secure(_.SeeReport) { implicit ctx => me =>
if (env.streamer.liveStreamApi.isStreaming(me.id) && !getBool("force")) fuccess(Forbidden(html.site.message.streamingMod))
else renderList(env.modFilters.get(me).fold("all")(_.key))
else renderList(env.report.modFilters.get(me).fold("all")(_.key))
}
def listWithFilter(room: String) = Secure(_.SeeReport) { implicit ctx => me =>
env.modFilters.set(me, Room(room))
env.report.modFilters.set(me, Room(room))
renderList(room)
}
@ -39,7 +39,7 @@ final class Report(
def inquiry(id: String) = Secure(_.SeeReport) { implicit ctx => me =>
for {
current <- env.report.api.inquiries ofModId me.id
current <- api.inquiries ofModId me.id
newInquiry <- api.inquiries.toggle(AsMod(me), id)
} yield newInquiry.fold(Redirect(routes.Report.list))(onInquiryStart)
}
@ -96,7 +96,7 @@ final class Report(
}
def process(id: String) = SecureBody(_.SeeReport) { implicit ctx => me =>
env.report.api.inquiries ofModId me.id flatMap { inquiry =>
api.inquiries ofModId me.id flatMap { inquiry =>
api.process(AsMod(me), id) >> onInquiryClose(inquiry, me, none, force = true)
}
}
@ -107,17 +107,17 @@ final class Report(
def currentCheatInquiry(username: String) = Secure(_.Hunter) { implicit ctx => me =>
OptionFuResult(env.user.repo named username) { user =>
env.api.currentCheatReport(lila.report.Suspect(user)) flatMap {
api.currentCheatReport(lila.report.Suspect(user)) flatMap {
_ ?? { report =>
env.api.inquiries.toggle(lila.report.Mod(me), report.id)
} inject Mod.redirect(username, true)
api.inquiries.toggle(lila.report.Mod(me), report.id)
} inject modC.redirect(username, true)
}
}
}
def form = Auth { implicit ctx => implicit me =>
get("username") ?? env.user.repo.named flatMap { user =>
env.forms.createWithCaptcha map {
env.report.forms.createWithCaptcha map {
case (form, captcha) => Ok(html.report.form(form, user, captcha))
}
}
@ -125,9 +125,9 @@ final class Report(
def create = AuthBody { implicit ctx => implicit me =>
implicit val req = ctx.body
env.forms.create.bindFromRequest.fold(
env.report.forms.create.bindFromRequest.fold(
err => get("username") ?? env.user.repo.named flatMap { user =>
env.forms.anyCaptcha map { captcha =>
env.report.forms.anyCaptcha map { captcha =>
BadRequest(html.report.form(err, user, captcha))
}
},
@ -141,7 +141,7 @@ final class Report(
def flag = AuthBody { implicit ctx => implicit me =>
implicit val req = ctx.body
env.forms.flag.bindFromRequest.fold(
env.report.forms.flag.bindFromRequest.fold(
err => BadRequest.fuccess,
data => env.user.repo named data.username flatMap {
_ ?? { user =>

View File

@ -12,7 +12,10 @@ import lila.tournament.{ TourMiniView, Tournament => Tour }
import lila.user.{ User => UserModel }
import views._
final class Round(env: Env) extends LilaController(env) with TheftPrevention {
final class Round(
env: Env,
gameC: Game
) extends LilaController(env) with TheftPrevention {
private def analyser = env.analyse.analyser
@ -21,7 +24,7 @@ final class Round(env: Env) extends LilaController(env) with TheftPrevention {
else PreventTheft(pov) {
pov.game.playableByAi ?? env.fishnet.player(pov.game)
myTour(pov.game.tournamentId, true) flatMap { tour =>
Game.preloadUsers(pov.game) zip
gameC.preloadUsers(pov.game) zip
(pov.game.simulId ?? env.simul.repo.find) zip
getPlayerChat(pov.game, tour.map(_.tour)) zip
(ctx.noBlind ?? env.game.crosstableApi.withMatchup(pov.game)) zip // probably what raises page mean time?
@ -44,7 +47,7 @@ final class Round(env: Env) extends LilaController(env) with TheftPrevention {
if (isTheft(pov)) fuccess(theftResponse)
else {
pov.game.playableByAi ?? env.fishnet.player(pov.game)
Game.preloadUsers(pov.game) zip
gameC.preloadUsers(pov.game) zip
env.api.roundApi.player(pov, apiVersion) zip
getPlayerChat(pov.game, none) map {
case _ ~ data ~ chat => Ok {
@ -56,14 +59,14 @@ final class Round(env: Env) extends LilaController(env) with TheftPrevention {
) map NoCache
def player(fullId: String) = Open { implicit ctx =>
OptionFuResult(env.proxy.pov(fullId)) { pov =>
OptionFuResult(env.proxyRepo.pov(fullId)) { pov =>
env.checkOutoftime(pov.game)
renderPlayer(pov)
}
}
private def otherPovs(game: GameModel)(implicit ctx: Context) = ctx.me ?? { user =>
env.round.proxy urgentGames user map {
env.round.proxyRepo urgentGames user map {
_ filter { pov =>
pov.gameId != game.id && pov.game.isSwitchable && pov.game.isSimul == game.isSimul
}
@ -76,7 +79,7 @@ final class Round(env: Env) extends LilaController(env) with TheftPrevention {
}
def whatsNext(fullId: String) = Open { implicit ctx =>
OptionFuResult(env.proxy.pov(fullId)) { currentPov =>
OptionFuResult(env.proxyRepo.pov(fullId)) { currentPov =>
if (currentPov.isMyTurn) fuccess {
Ok(Json.obj("nope" -> true))
}
@ -87,7 +90,7 @@ final class Round(env: Env) extends LilaController(env) with TheftPrevention {
}
def next(gameId: String) = Auth { implicit ctx => me =>
OptionFuResult(env.proxy game gameId) { currentGame =>
OptionFuResult(env.proxyRepo game gameId) { currentGame =>
otherPovs(currentGame) map getNext(currentGame) map {
_ orElse Pov(currentGame, me)
} flatMap {

View File

@ -66,11 +66,10 @@ trait UserHelper { self: I18nHelper with StringHelper with NumberHelper =>
case d => badTag(s"${-d}")
}
def lightUser(userId: String): Option[LightUser] = env.user lightUserSync userId
def lightUser(userId: Option[String]): Option[LightUser] = userId flatMap lightUser
def lightUser = env.user.lightUserSync
def usernameOrId(userId: String) = lightUser(userId).fold(userId)(_.titleName)
def usernameOrAnon(userId: Option[String]) = lightUser(userId).fold(User.anonymous)(_.titleName)
def usernameOrAnon(userId: Option[String]) = userId.flatMap(lightUser).fold(User.anonymous)(_.titleName)
def isOnline(userId: String) = Env.socket isOnline userId

View File

@ -82,7 +82,7 @@ object list {
),
p(cls := List(
"text" -> true,
"large" -> (atom.text.size > 100 || atom.text.lines.size > 3)
"large" -> (atom.text.size > 100 || atom.text.linesIterator.size > 3)
))(shorten(atom.text, 200))
)
},

View File

@ -470,13 +470,7 @@ simulation {
players = 300
watchers = 200
}
slack {
incoming {
url = ""
default_channel = tavern
}
domain = ${net.domain}
}
slack.incoming.url = ""
plan {
stripe {
endpoint="https://api.stripe.com/v1"

View File

@ -10,7 +10,7 @@ import lila.common.config._
@Module
final class Env(
appConfig: Configuration,
val net: NetConfig,
net: NetConfig,
securityEnv: lila.security.Env,
i18nEnv: lila.i18n.Env,
teamSearchEnv: lila.teamSearch.Env,
@ -30,6 +30,7 @@ final class Env(
bookmarkApi: lila.bookmark.BookmarkApi,
prefApi: lila.pref.PrefApi,
playBanApi: lila.playban.PlaybanApi,
socketEnv: lila.socket.Env,
userEnv: lila.user.Env,
streamerEnv: lila.streamer.Env,
relationEnv: lila.relation.Env,

View File

@ -22,7 +22,7 @@ private[api] final class UserApi(
prefApi: lila.pref.PrefApi,
liveStreamApi: lila.streamer.LiveStreamApi,
onlineDoing: lila.relation.OnlineDoing,
isOnline: lila.user.IsOnline,
isOnline: lila.socket.IsOnline,
gameProxyRepo: lila.round.GameProxyRepo,
net: NetConfig
)(implicit system: akka.actor.ActorSystem) {

View File

@ -4,6 +4,7 @@ import com.softwaremill.macwire._
import lila.game.{ Game, Pov }
@Module
final class Env(
chatApi: lila.chat.ChatApi,
gameRepo: lila.game.GameRepo,

View File

@ -18,7 +18,7 @@ final class Env(
onStart: lila.round.OnStart,
gameCache: lila.game.Cached,
lightUser: lila.common.LightUser.GetterSync,
isOnline: lila.user.IsOnline,
isOnline: lila.socket.IsOnline,
db: lila.db.Env,
asyncCache: lila.memo.AsyncCache.Builder,
prefApi: lila.pref.PrefApi,

View File

@ -9,7 +9,7 @@ import lila.socket.UserLagCache
final class JsonView(
getLightUser: lila.common.LightUser.GetterSync,
isOnline: lila.user.User.ID => Boolean
isOnline: lila.socket.IsOnline
) {
import lila.game.JsonView._

View File

@ -15,8 +15,8 @@ final class ChatApi(
chatTimeout: ChatTimeout,
flood: lila.security.Flood,
spam: lila.security.Spam,
shutup: akka.actor.ActorSelection,
modLog: akka.actor.ActorSelection,
shutup: lila.hub.actors.Shutup,
modActor: lila.hub.actors.Mod,
asyncCache: lila.memo.AsyncCache.Builder,
maxLinesPerChat: Chat.MaxLines,
net: NetConfig
@ -130,7 +130,7 @@ final class ChatApi(
cached invalidate chat.id
publish(chat.id, actorApi.OnTimeout(user.id))
line foreach { l => publish(chat.id, actorApi.ChatLine(chat.id, l)) }
if (isMod(mod)) modLog ! lila.hub.actorApi.mod.ChatTimeout(
if (isMod(mod)) modActor ! lila.hub.actorApi.mod.ChatTimeout(
mod = mod.id, user = user.id, reason = reason.key
)
else logger.info(s"${mod.username} times out ${user.username} in #${c.id} for ${reason.key}")

View File

@ -1,6 +1,6 @@
package lila.chat
import akka.actor.{ ActorSystem, Props, ActorSelection }
import akka.actor.{ ActorSystem, Props }
import com.softwaremill.macwire._
import io.methvin.play.autoconfig._
import play.api.Configuration
@ -18,14 +18,15 @@ private case class ChatConfig(
@ConfigName("timeout.check_every") timeoutCheckEvery: FiniteDuration
)
@Module
final class Env(
appConfig: Configuration,
userRepo: lila.user.UserRepo,
db: lila.db.Env,
flood: lila.security.Flood,
spam: lila.security.Spam,
shutup: ActorSelection,
modLog: ActorSelection,
shutup: lila.hub.actors.Shutup,
mod: lila.hub.actors.Mod,
asyncCache: lila.memo.AsyncCache.Builder
)(implicit system: ActorSystem) {
@ -33,25 +34,25 @@ final class Env(
private val config = appConfig.get[ChatConfig]("chat")(AutoConfig.loader)
import config._
val timeout = new ChatTimeout(
lazy val timeout = new ChatTimeout(
coll = db(timeoutColl),
duration = timeoutDuration
)
val api = new ChatApi(
lazy val api = new ChatApi(
coll = db(chatColl),
userRepo = userRepo,
chatTimeout = timeout,
flood = flood,
spam = spam,
shutup = shutup,
modLog = modLog,
modActor = mod,
asyncCache = asyncCache,
maxLinesPerChat = maxLines,
net = net
)
val panic = wire[ChatPanic]
lazy val panic = wire[ChatPanic]
system.scheduler.scheduleWithFixedDelay(timeoutCheckEvery, timeoutCheckEvery) {
() => timeout.checkExpired foreach api.userChat.reinstate

View File

@ -1,7 +1,7 @@
package lila.common
import play.api.libs.json._
import play.api.libs.ws._
import play.api.libs.ws.WSClient
import io.methvin.play.autoconfig._
import scala.math.Ordering.Float.TotalOrdering

View File

@ -1,13 +1,22 @@
package lila.common
import play.api.Configuration
import com.softwaremill.macwire._
import io.methvin.play.autoconfig._
import play.api.Configuration
import play.api.libs.ws.WSClient
import config._
@Module
final class Env(
appConfig: Configuration
appConfig: Configuration,
ws: WSClient
) {
val netConfig = appConfig.get[NetConfig]("net")(AutoConfig.loader)
val netConfig = appConfig.get[NetConfig]("net")
private lazy val detectLanguageConfig =
appConfig.get[DetectLanguage.Config]("detect_language.api")
lazy val detectLanguage = wire[DetectLanguage]
}

View File

@ -15,7 +15,7 @@ object config {
case class BaseUrl(value: String) extends AnyVal with StringValue
case class AppPath(value: String) extends AnyVal with StringValue
case class AppPath(value: java.io.File) extends AnyVal
case class Max(value: Int) extends AnyVal with IntValue with Ordered[Int] {
def compare(other: Int) = Integer.compare(value, other)
@ -43,7 +43,6 @@ object config {
implicit val secretLoader = strLoader(Secret.apply)
implicit val baseUrlLoader = strLoader(BaseUrl.apply)
implicit val emailAddressLoader = strLoader(EmailAddress.apply)
implicit val appPathLoader = strLoader(AppPath.apply)
implicit val domainLoader = strLoader(Domain.unsafe)
implicit val netLoader = AutoConfig.loader[NetConfig]

View File

@ -10,6 +10,7 @@ import lila.common.config.CollName
import lila.hub.actorApi.socket.remote.{ TellSriIn, TellSriOut }
import lila.socket.Socket.Sri
@Module
final class Env(
appConfig: Configuration,
userRepo: lila.user.UserRepo,

View File

@ -6,6 +6,7 @@ import scala.concurrent.duration._
case class InternalEndpoint(value: String) extends AnyVal with StringValue
@Module
final class Env(
appConfig: Configuration,
gameRepo: lila.game.GameRepo,

View File

@ -23,6 +23,7 @@ private class FishnetConfig(
@ConfigName("redis.uri") val redisUri: String
)
@Module
final class Env(
appConfig: Configuration,
uciMemo: lila.game.UciMemo,

View File

@ -40,7 +40,7 @@ final class Env(
lazy val categRepo = new CategRepo(db(CollName("f_categ")))
lazy val topicRepo = new TopicRepo(db(CollName("f_topic")))
private lazy val postColl = new PostRepo(db(CollName("f_post")))
lazy val postRepo = new PostRepo(db(CollName("f_post")))
lazy val categApi: CategApi = wire[CategApi]

View File

@ -41,6 +41,8 @@ final class Env(
lazy val gameRepo = new GameRepo(db(config.gameColl))
lazy val idGenerator = wire[IdGenerator]
lazy val pngExport = new PngExport(ws, config.pngUrl, config.pngSize)
lazy val divider = wire[Divider]

View File

@ -1,6 +1,7 @@
package lila.hub
import akka.actor._
import com.softwaremill.macwire._
import com.typesafe.config.Config
import play.api.Configuration
@ -25,6 +26,7 @@ object actors {
case class Captcher(actor: ActorSelection) extends Actor
}
@Module
final class Env(
appConfig: Configuration,
system: ActorSystem
@ -32,7 +34,7 @@ final class Env(
import actors._
val config = appConfig.get[Config]("hub")
private val config = appConfig.get[Config]("hub")
val gameSearch = GameSearch(select("actor.game.search"))
val renderer = Renderer(select("actor.renderer"))

View File

@ -2,6 +2,7 @@ package lila.importer
import com.softwaremill.macwire._
@Module
final class Env(
gameRepo: lila.game.GameRepo,
scheduler: akka.actor.Scheduler

View File

@ -20,7 +20,7 @@ final class SeekApi(
private object ForUser extends CacheKey
private def allCursor =
coll.find($empty)
coll.ext.find($empty)
.sort($doc("createdAt" -> -1))
.cursor[Seek]()
@ -63,42 +63,42 @@ final class SeekApi(
}._1.reverse
def find(id: String): Fu[Option[Seek]] =
coll.find($id(id)).uno[Seek]
coll.ext.find($id(id)).uno[Seek]
def insert(seek: Seek) = coll.insert(seek) >> findByUser(seek.user.id).flatMap {
def insert(seek: Seek) = coll.insert.one(seek) >> findByUser(seek.user.id).flatMap {
case seeks if maxPerUser >= seeks.size => funit
case seeks => seeks.drop(maxPerUser.value).map(remove).sequenceFu
}.void >>- cacheClear
def findByUser(userId: String): Fu[List[Seek]] =
coll.find($doc("user.id" -> userId))
coll.ext.find($doc("user.id" -> userId))
.sort($doc("createdAt" -> -1))
.cursor[Seek]().gather[List]()
def remove(seek: Seek) =
coll.remove($doc("_id" -> seek.id)).void >>- cacheClear
coll.delete.one($doc("_id" -> seek.id)).void >>- cacheClear
def archive(seek: Seek, gameId: String) = {
val archiveDoc = Seek.seekBSONHandler.writeTry(seek).get ++ $doc(
"gameId" -> gameId,
"archivedAt" -> DateTime.now
)
coll.remove($doc("_id" -> seek.id)).void >>-
coll.delete.one($doc("_id" -> seek.id)).void >>-
cacheClear >>
archiveColl.insert(archiveDoc)
archiveColl.insert.one(archiveDoc)
}
def findArchived(gameId: String): Fu[Option[Seek]] =
archiveColl.find($doc("gameId" -> gameId)).uno[Seek]
archiveColl.ext.find($doc("gameId" -> gameId)).uno[Seek]
def removeBy(seekId: String, userId: String) =
coll.remove($doc(
coll.delete.one($doc(
"_id" -> seekId,
"user.id" -> userId
)).void >>- cacheClear
def removeByUser(user: User) =
coll.remove($doc("user.id" -> user.id)).void >>- cacheClear
coll.delete.one($doc("user.id" -> user.id)).void >>- cacheClear
}
private object SeekApi {

View File

@ -12,6 +12,7 @@ case class MemoConfig(
@ConfigName("collection.config") configColl: CollName
)
@Module
final class Env(appConfig: Configuration, db: lila.db.Env)(implicit system: akka.actor.ActorSystem) {
private val config = appConfig.get[MemoConfig]("memo")(AutoConfig.loader)

View File

@ -14,16 +14,17 @@ private class MessageConfig(
@ConfigName("thread.max_per_page") val threadMaxPerPage: MaxPerPage
)
@Module
final class Env(
appConfig: Configuration,
db: lila.db.Env,
shutup: ActorSelection,
shutup: lila.hub.actors.Shutup,
notifyApi: lila.notify.NotifyApi,
relationApi: lila.relation.RelationApi,
userRepo: UserRepo,
getPref: User.ID => Fu[lila.pref.Pref],
prefApi: lila.pref.PrefApi,
spam: lila.security.Spam,
isOnline: lila.user.User.ID => Boolean,
isOnline: lila.socket.IsOnline,
lightUser: lila.common.LightUser.GetterSync
)(implicit system: ActorSystem) {

View File

@ -13,7 +13,7 @@ final class MessageApi(
coll: Coll,
userRepo: UserRepo,
threadRepo: ThreadRepo,
shutup: akka.actor.ActorSelection,
shutup: lila.hub.actors.Shutup,
maxPerPage: lila.common.config.MaxPerPage,
relationApi: lila.relation.RelationApi,
notifyApi: lila.notify.NotifyApi,

View File

@ -7,7 +7,7 @@ import lila.user.User
private[message] final class MessageSecurity(
relationApi: lila.relation.RelationApi,
getPref: User.ID => Fu[lila.pref.Pref],
prefApi: lila.pref.PrefApi,
spam: lila.security.Spam
) {
@ -16,7 +16,7 @@ private[message] final class MessageSecurity(
def canMessage(from: User.ID, to: User.ID): Fu[Boolean] =
relationApi.fetchBlocks(to, from) flatMap {
case true => fuFalse
case false => getPref(to).map(_.message) flatMap {
case false => prefApi.getPref(to).dmap(_.message) flatMap {
case NEVER => fuFalse
case FRIEND => relationApi.fetchFollows(to, from)
case ALWAYS => fuTrue

View File

@ -20,6 +20,7 @@ private class ModConfig(
@ConfigName("boosting.ratio_games_to_mark") val boostingRatioToMark: Int
)
@Module
final class Env(
appConfig: Configuration,
db: lila.db.Env,
@ -29,7 +30,7 @@ final class Env(
firewall: Firewall,
reportApi: lila.report.ReportApi,
lightUserApi: lila.user.LightUserApi,
userSpy: User => Fu[UserSpy],
userSpyApi: lila.security.UserSpyApi,
securityApi: lila.security.SecurityApi,
tournamentApi: lila.tournament.TournamentApi,
gameRepo: lila.game.GameRepo,

View File

@ -9,7 +9,7 @@ import lila.user.{ User, UserRepo, Title, LightUserApi }
final class ModApi(
userRepo: UserRepo,
logApi: ModlogApi,
userSpy: User => Fu[UserSpy],
userSpyApi: lila.security.UserSpyApi,
firewall: Firewall,
reportApi: lila.report.ReportApi,
reporter: lila.hub.actors.Report,
@ -83,7 +83,7 @@ final class ModApi(
}
def setBan(mod: Mod, prev: Suspect, value: Boolean): Funit = for {
spy <- userSpy(prev.user)
spy <- userSpyApi(prev.user)
sus = prev.set(_.copy(ipBan = value))
_ <- userRepo.setIpBan(sus.user.id, sus.user.ipBan)
_ <- logApi.ban(mod, sus)

View File

@ -13,6 +13,7 @@ private class NotifyConfig(
@ConfigName("actor.name") val actorName: String
)
@Module
final class Env(
appConfig: Configuration,
db: lila.db.Env,
@ -24,7 +25,7 @@ final class Env(
private val config = appConfig.get[NotifyConfig]("notify")(AutoConfig.loader)
val jsonHandlers = wire[JSONHandlers]
lazy val jsonHandlers = wire[JSONHandlers]
private lazy val repo = new NotificationRepo(coll = db(config.notifyColl))

View File

@ -17,6 +17,7 @@ private case class OauthConfig(
@ConfigName("collection.app") appColl: CollName
)
@Module
final class Env(
appConfig: Configuration,
asyncCache: lila.memo.AsyncCache.Builder,

View File

@ -7,6 +7,7 @@ import lila.common.Bus
import lila.game.Game
import lila.hub.FutureSequencer
@Module
final class Env(
userRepo: lila.user.UserRepo,
gameRepo: lila.game.GameRepo,
@ -16,8 +17,6 @@ final class Env(
private lazy val hookThieve = wire[HookThieve]
private lazy val configs = PoolList.all
private lazy val sequencer = new FutureSequencer(
executionTimeout = 5.seconds.some,
logger = logger
@ -28,4 +27,6 @@ final class Env(
private lazy val gameStarter = wire[GameStarter]
lazy val api = wire[PoolApi]
def poolConfigs = PoolList.all
}

View File

@ -5,6 +5,7 @@ import play.api.Configuration
import lila.common.config._
@Module
final class Env(
appConfig: Configuration,
configStoreApi: lila.memo.ConfigStore.Builder,

View File

@ -2,7 +2,7 @@ package lila.puzzle
import scala.concurrent.duration._
import akka.actor.{ ActorSelection, Scheduler }
import akka.actor.Scheduler
import akka.pattern.ask
import org.joda.time.DateTime
@ -11,7 +11,7 @@ import Puzzle.{ BSONFields => F }
private[puzzle] final class Daily(
coll: Coll,
renderer: ActorSelection,
renderer: lila.hub.actors.Renderer,
asyncCache: lila.memo.AsyncCache.Builder,
scheduler: Scheduler
) {
@ -37,7 +37,7 @@ private[puzzle] final class Daily(
private def makeDaily(puzzle: Puzzle): Fu[Option[DailyPuzzle]] = {
import makeTimeout.short
~puzzle.fenAfterInitialMove.map { fen =>
renderer ? RenderDaily(puzzle, fen, puzzle.initialMove.uci) map {
renderer.actor ? RenderDaily(puzzle, fen, puzzle.initialMove.uci) map {
case html: String => DailyPuzzle(html, puzzle.color, puzzle.id).some
}
}

View File

@ -1,6 +1,6 @@
package lila.puzzle
import akka.actor.{ ActorSelection, ActorSystem }
import akka.actor.ActorSystem
import com.softwaremill.macwire._
import io.methvin.play.autoconfig._
import scala.concurrent.duration.FiniteDuration
@ -23,7 +23,7 @@ private class CoachConfig(
final class Env(
appConfig: Configuration,
renderer: ActorSelection,
renderer: lila.hub.actors.Renderer,
historyApi: lila.history.HistoryApi,
lightUserApi: lila.user.LightUserApi,
asyncCache: lila.memo.AsyncCache.Builder,

View File

@ -1,12 +1,17 @@
package lila.rating
import com.softwaremill.macwire._
@Module
final class Env(settingStore: lila.memo.SettingStore.Builder) {
import RatingFactor.implicits._
val ratingFactorsSetting = settingStore[RatingFactors](
lazy val ratingFactorsSetting = settingStore[RatingFactors](
"ratingFactor",
default = Map.empty,
text = "Rating gain factor per perf type".some
)
val getFactors = () => ratingFactorsSetting.get
}

View File

@ -25,6 +25,7 @@ final class Env(
relation: actors.Relation,
timeline: actors.Timeline,
report: actors.Report,
userRepo: lila.user.UserRepo,
onlineUserIds: () => Set[lila.user.User.ID],
lightUserSync: lila.common.LightUser.GetterSync,
followable: String => Fu[Boolean],

View File

@ -1,5 +1,7 @@
package lila.relation
import akka.stream.scaladsl._
import reactivemongo.akkastream.{ AkkaStreamCursor, cursorProducer }
import reactivemongo.api.ReadPreference
import scala.concurrent.duration._
@ -7,29 +9,35 @@ import lila.common.config.MaxPerSecond
import lila.db.dsl._
import lila.user.{ User, UserRepo }
final class RelationStream(coll: Coll)(implicit system: akka.actor.ActorSystem) {
final class RelationStream(
coll: Coll,
userRepo: UserRepo
)(implicit mat: akka.stream.Materializer) {
// import RelationStream._
import RelationStream._
// def follow(user: User, direction: Direction, perSecond: MaxPerSecond): Enumerator[User] = {
// val field = direction match {
// case Direction.Following => "u2"
// case Direction.Followers => "u1"
// }
// val projection = $doc(field -> true, "_id" -> false)
// val query = direction match {
// case Direction.Following => coll.find($doc("u1" -> user.id, "r" -> Follow), projection)
// case Direction.Followers => coll.find($doc("u2" -> user.id, "r" -> Follow), projection)
// }
// query.copy(options = query.options.batchSize(perSecond.value))
// .cursor[Bdoc](readPreference = ReadPreference.secondaryPreferred)
// .bulkEnumerator() &>
// lila.common.Iteratee.delay(1 second) &>
// Enumeratee.mapM { docs =>
// UserRepo usersFromSecondary docs.toSeq.flatMap(_.getAs[User.ID](field))
// } &>
// Enumeratee.mapConcat(_.toSeq)
// }
def follow(user: User, direction: Direction, perSecond: MaxPerSecond): Source[User, _] = coll
.find(
$doc(selectField(direction) -> user.id, "r" -> Follow),
$doc(projectField(direction) -> true, "_id" -> false).some
)
.batchSize(perSecond.value)
.cursor[Bdoc](ReadPreference.secondaryPreferred)
.documentSource()
.grouped(perSecond.value)
.map(_.flatMap(_.getAsOpt[User.ID](projectField(direction))))
.delay(1 second)
.mapAsync(1)(userRepo.usersFromSecondary)
.mapConcat(identity)
private def selectField(d: Direction) = d match {
case Direction.Following => "u1"
case Direction.Followers => "u2"
}
private def projectField(d: Direction) = d match {
case Direction.Following => "u2"
case Direction.Followers => "u1"
}
}
object RelationStream {

View File

@ -19,10 +19,11 @@ private class CoachConfig(
private case class Thresholds(score: () => Int, slack: () => Int)
@Module
final class Env(
appConfig: Configuration,
db: lila.db.Env,
isOnline: lila.user.User.ID => Boolean,
isOnline: lila.socket.IsOnline,
noteApi: lila.user.NoteApi,
userRepo: lila.user.UserRepo,
gameRepo: lila.game.GameRepo,
@ -40,13 +41,13 @@ final class Env(
private lazy val reportColl = db(config.reportColl)
val scoreThresholdSetting = settingStore[Int](
lazy val scoreThresholdSetting = settingStore[Int](
"reportScoreThreshold",
default = config.scoreThreshold,
text = "Report score threshold. Reports with lower scores are concealed to moderators".some
)
val slackScoreThresholdSetting = settingStore[Int](
lazy val slackScoreThresholdSetting = settingStore[Int](
"slackScoreThreshold",
default = 80,
text = "Slack score threshold. Comm reports with higher scores are notified in slack".some

View File

@ -17,7 +17,7 @@ final class ReportApi(
userSpyApi: lila.security.UserSpyApi,
playbanApi: lila.playban.PlaybanApi,
slackApi: lila.slack.SlackApi,
isOnline: User.ID => Boolean,
isOnline: lila.socket.IsOnline,
asyncCache: lila.memo.AsyncCache.Builder,
thresholds: Thresholds
) {

View File

@ -13,6 +13,7 @@ private class SearchConfig(
val endpoint: String
)
@Module
final class Env(
appConfig: Configuration,
ws: WSClient

View File

@ -13,6 +13,7 @@ import lila.memo.SettingStore.Strings._
import lila.oauth.OAuthServer
import lila.user.{ UserRepo, Authenticator }
@Module
final class Env(
appConfig: Configuration,
ws: WSClient,

View File

@ -16,8 +16,8 @@ private class ShutupConfig(
final class Env(
appConfig: Configuration,
reporter: akka.actor.ActorSelection,
follows: (User.ID, User.ID) => Fu[Boolean],
reporter: lila.hub.actors.Report,
relationApi: lila.relation.RelationApi,
gameRepo: lila.game.GameRepo,
userRepo: UserRepo,
db: lila.db.Env

View File

@ -11,8 +11,8 @@ final class ShutupApi(
coll: Coll,
gameRepo: GameRepo,
userRepo: UserRepo,
follows: (User.ID, User.ID) => Fu[Boolean],
reporter: akka.actor.ActorSelection
relationApi: lila.relation.RelationApi,
reporter: lila.hub.actors.Report
) {
private implicit val UserRecordBSONHandler = Macros.handler[UserRecord]
@ -48,7 +48,7 @@ final class ShutupApi(
): Funit =
userRepo isTroll userId flatMap {
case true => funit
case false => toUserId ?? { follows(_, userId) } flatMap {
case false => toUserId ?? { relationApi.fetchFollows(_, userId) } flatMap {
case true => funit
case false =>
val analysed = Analyser(text)

View File

@ -29,7 +29,7 @@ final class Env(
chatApi: lila.chat.ChatApi,
lightUser: lila.common.LightUser.Getter,
onGameStart: lila.round.OnStart,
isOnline: lila.user.IsOnline,
isOnline: lila.socket.IsOnline,
asyncCache: lila.memo.AsyncCache.Builder,
remoteSocketApi: lila.socket.RemoteSocket,
proxyRepo: lila.round.GameProxyRepo

View File

@ -1,35 +1,31 @@
package lila.slack
import akka.actor._
import com.softwaremill.macwire._
import play.api.Configuration
import play.api.libs.ws.WSClient
import lila.common.config._
import lila.hub.actorApi.plan.ChargeEvent
import lila.hub.actorApi.slack.Event
import lila.hub.actorApi.user.Note
import lila.hub.actorApi.{ DeployPre, DeployPost }
@Module
final class Env(
appConfig: Configuration,
getLightUser: lila.common.LightUser.Getter,
net: NetConfig,
mode: play.api.Mode,
ws: WSClient,
system: ActorSystem
) {
private val config = appConfig.get[Configuration]("slack")
private val IncomingUrl = config.get[String]("incoming.url")
private val IncomingDefaultChannel = config.get[String]("incoming.default_channel")
private val NetDomain = config.get[String]("domain")
private val incomingUrl = appConfig.get[Secret]("slack.incoming.url")
private val isProd = NetDomain == "lichess.org"
private lazy val client = wire[SlackClient]
lazy val api = new SlackApi(client, isProd, getLightUser)
private lazy val client = new SlackClient(
ws = ws,
url = IncomingUrl,
defaultChannel = IncomingDefaultChannel
)
lazy val api: SlackApi = wire[SlackApi]
lila.common.Bus.subscribeFun("deploy", "slack", "plan", "userNote") {
case d: ChargeEvent => api charge d

View File

@ -1,6 +1,7 @@
package lila.slack
import org.joda.time.DateTime
import play.api.Mode
import lila.common.{ LightUser, IpAddress, EmailAddress }
import lila.hub.actorApi.slack._
@ -8,7 +9,7 @@ import lila.user.User
final class SlackApi(
client: SlackClient,
isProd: Boolean,
mode: Mode,
implicit val lightUser: LightUser.Getter
) {
@ -150,6 +151,7 @@ final class SlackApi(
channel = rooms.devNoise
))
private val isProd = mode == Mode.Prod
private def link(url: String, name: String) = s"<$url|$name>"
private def lichessLink(path: String, name: String) = s"<https://lichess.org$path|$name>"
private def userLink(name: String): String = lichessLink(s"/@/$name?mod", name)

View File

@ -6,8 +6,11 @@ import play.api.libs.json._
import play.api.libs.ws.WSClient
import lila.memo.RateLimit
import lila.common.config.Secret
private final class SlackClient(ws: WSClient, url: String, defaultChannel: String) {
private final class SlackClient(ws: WSClient, url: Secret) {
private val defaultChannel = "tavern"
private val limiter = new RateLimit[SlackMessage](
credits = 1,
@ -17,8 +20,8 @@ private final class SlackClient(ws: WSClient, url: String, defaultChannel: Strin
)
def apply(msg: SlackMessage): Funit = limiter(msg) {
if (url.isEmpty) fuccess(lila.log("slack").info(msg.toString))
else ws.url(url)
if (url.value.isEmpty) fuccess(lila.log("slack").info(msg.toString))
else ws.url(url.value)
.post(Json.obj(
"username" -> msg.username,
"text" -> msg.text,

View File

@ -4,6 +4,7 @@ import com.softwaremill.macwire._
import io.lettuce.core._
import play.api.Configuration
@Module
final class Env(
appConfig: Configuration,
lifecycle: play.api.inject.ApplicationLifecycle,
@ -14,11 +15,11 @@ final class Env(
private val redisClient = RedisClient create RedisURI.create(RedisUri)
val remoteSocket = wire[RemoteSocket]
val remoteSocket: RemoteSocket = wire[RemoteSocket]
remoteSocket.subscribe("site-in", RemoteSocket.Protocol.In.baseReader)(remoteSocket.baseHandler)
val onlineUserIds: () => Set[String] = () => remoteSocket.onlineUserIds.get
val onlineIds = new OnlineIds(() => remoteSocket.onlineUserIds.get)
val isOnline: String => Boolean = userId => onlineUserIds() contains userId
val isOnline = new IsOnline(userId => onlineIds() contains userId)
}

View File

@ -0,0 +1,9 @@
package lila.socket
final class IsOnline(f: (String => Boolean)) extends (String => Boolean) {
def apply(id: String) = f(id)
}
final class OnlineIds(f: (() => Set[String])) extends (() => Set[String]) {
def apply() = f()
}

View File

@ -23,8 +23,8 @@ final class Env(
appConfig: Configuration,
ws: play.api.libs.ws.WSClient,
settingStore: lila.memo.SettingStore.Builder,
renderer: ActorSelection,
isOnline: lila.user.User.ID => Boolean,
renderer: lila.hub.actors.Renderer,
isOnline: lila.socket.IsOnline,
asyncCache: lila.memo.AsyncCache.Builder,
notifyApi: lila.notify.NotifyApi,
lightUserApi: lila.user.LightUserApi,

View File

@ -12,7 +12,7 @@ import lila.user.User
private final class Streaming(
ws: WSClient,
renderer: ActorSelection,
renderer: lila.hub.actors.Renderer,
api: StreamerApi,
isOnline: User.ID => Boolean,
timeline: lila.hub.actors.Timeline,
@ -63,7 +63,7 @@ private final class Streaming(
import makeTimeout.short
import akka.pattern.ask
if (newStreams != liveStreams) {
renderer ? newStreams.autoFeatured.withTitles(lightUserApi) foreach {
renderer.actor ? newStreams.autoFeatured.withTitles(lightUserApi) foreach {
case html: String =>
Bus.publish(lila.hub.actorApi.streamer.StreamsOnAir(html), "streams")
}

View File

@ -44,7 +44,7 @@ final class Env(
private val socket = wire[StudySocket]
lazy val studyRepo = new StudyRepo(db(CollName("study")))
private lazy val chapterRepo = new ChapterRepo(db(CollName("study_chapter")))
lazy val chapterRepo = new ChapterRepo(db(CollName("study_chapter")))
lazy val jsonView = wire[JsonView]

View File

@ -19,9 +19,9 @@ final class Env(
db: lila.db.Env
)(implicit system: ActorSystem) {
private val teamRepo = new TeamRepo(db(CollName("team")))
private val memberRepo = new MemberRepo(db(CollName("team_member")))
private val requestRepo = new RequestRepo(db(CollName("team_request")))
lazy val teamRepo = new TeamRepo(db(CollName("team")))
private lazy val memberRepo = new MemberRepo(db(CollName("team_member")))
private lazy val requestRepo = new RequestRepo(db(CollName("team_request")))
lazy val forms = wire[DataForm]

View File

@ -7,7 +7,7 @@ private final class CreatedOrganizer(
api: TournamentApi,
tournamentRepo: TournamentRepo,
playerRepo: PlayerRepo,
isOnline: lila.user.IsOnline
isOnline: lila.socket.IsOnline
) extends Actor {
override def preStart: Unit = {

View File

@ -30,7 +30,7 @@ final class Env(
asyncCache: lila.memo.AsyncCache.Builder,
gameRepo: lila.game.GameRepo,
userRepo: lila.user.UserRepo,
isOnline: lila.user.IsOnline,
isOnline: lila.socket.IsOnline,
proxyRepo: lila.round.GameProxyRepo,
flood: lila.security.Flood,
renderer: lila.hub.actors.Renderer,

View File

@ -16,10 +16,10 @@ final class Env(
gameRepo: lila.game.GameRepo,
renderer: lila.hub.actors.Renderer,
lightUser: lila.common.LightUser.GetterSync,
proxyGame: Game.ID => Fu[Option[Game]],
gameProxyRepo: lila.round.GameProxyRepo,
system: ActorSystem,
recentTvGames: lila.round.RecentTvGames,
rematchOf: Game.ID => Option[Game.ID]
rematches: lila.game.Rematches
) {
private val tvTrouper = wire[TvTrouper]

View File

@ -9,12 +9,14 @@ import lila.hub.Trouper
final class Tv(
gameRepo: GameRepo,
trouper: Trouper,
roundProxyGame: Game.ID => Fu[Option[Game]]
gameProxyRepo: lila.round.GameProxyRepo
) {
import Tv._
import ChannelTrouper._
private def roundProxyGame = gameProxyRepo.game _
def getGame(channel: Tv.Channel): Fu[Option[Game]] =
trouper.ask[Option[Game.ID]](TvTrouper.GetGameId(channel, _)) flatMap { _ ?? roundProxyGame }

View File

@ -15,8 +15,8 @@ private[tv] final class TvTrouper(
renderer: lila.hub.actors.Renderer,
lightUser: LightUser.GetterSync,
recentTvGames: lila.round.RecentTvGames,
proxyGame: Game.ID => Fu[Option[Game]],
rematchOf: Game.ID => Option[Game.ID]
gameProxyRepo: lila.round.GameProxyRepo,
rematches: lila.game.Rematches
) extends Trouper {
import TvTrouper._
@ -24,7 +24,7 @@ private[tv] final class TvTrouper(
Bus.subscribe(this, "startGame")
private val channelTroupers: Map[Tv.Channel, ChannelTrouper] = Tv.Channel.all.map { c =>
c -> new ChannelTrouper(c, lightUser, onSelect = this.!, proxyGame, rematchOf)
c -> new ChannelTrouper(c, lightUser, onSelect = this.!, gameProxyRepo.game, rematches.of)
}.toMap
private var channelChampions = Map[Tv.Channel, Tv.Champion]()

View File

@ -8,6 +8,7 @@ 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(
@ -27,8 +28,9 @@ final class Env(
db: lila.db.Env,
mongoCache: lila.memo.MongoCache.Builder,
asyncCache: lila.memo.AsyncCache.Builder,
timeline: ActorSelection,
onlineUserIds: () => Set[User.ID]
timeline: lila.hub.actors.Timeline,
isOnline: lila.socket.IsOnline,
onlineIds: lila.socket.OnlineIds
)(implicit system: ActorSystem, ws: WSClient) {
private val config = appConfig.get[UserConfig]("user")(AutoConfig.loader)
@ -38,8 +40,7 @@ final class Env(
val lightUserApi: LightUserApi = wire[LightUserApi]
val lightUser = lightUserApi.async
val lightUserSync = lightUserApi.sync
val isOnline = new IsOnline(userId => onlineUserIds() contains userId)
val isBotSync = new LightUser.IsBotSync(id => lightUserApi.sync(id).exists(_.isBot))
lazy val botIds = new GetBotIds(() => cached.botIds.get)

View File

@ -5,7 +5,7 @@ import play.api.libs.json._
import play.api.libs.json.JodaWrites._
import User.{ PlayTime, LightPerf }
final class JsonView(isOnline: User.ID => Boolean) {
final class JsonView(isOnline: lila.socket.IsOnline) {
import JsonView._
private implicit val profileWrites = Json.writes[Profile]

View File

@ -24,8 +24,6 @@ final class LightUserApi(repo: UserRepo)(implicit system: akka.actor.ActorSystem
def preloadMany = cache preloadMany _
def preloadUser(user: User) = cache.setOneIfAbsent(user.id, user.light.some)
def isBotSync(id: User.ID) = new LightUser.IsBotSync(id => sync(id).exists(_.isBot))
private val cacheName = "user.light"
private val cache = new Syncache[User.ID, Option[LightUser]](

View File

@ -21,7 +21,7 @@ case class UserNotes(user: User, notes: List[Note])
final class NoteApi(
userRepo: UserRepo,
coll: Coll,
timeline: akka.actor.ActorSelection
timeline: lila.hub.actors.Timeline
)(implicit ws: play.api.libs.ws.WSClient) {
import reactivemongo.api.bson._

View File

@ -1,9 +1,5 @@
package lila.user
final class IsOnline(f: User.ID => Boolean) extends (User.ID => Boolean) {
def apply(u: User.ID) = f(u)
}
final class GetBotIds(f: () => Fu[Set[User.ID]]) extends (() => Fu[Set[User.ID]]) {
def apply() = f()
}