migration WIP
parent
3cdc627520
commit
234432b226
|
@ -165,7 +165,7 @@ lazy val game = module("game", Seq(common, memo, db, hub, user, chat)).settings(
|
|||
)
|
||||
|
||||
lazy val gameSearch = module("gameSearch", Seq(common, hub, search, game)).settings(
|
||||
libraryDependencies ++= provided(play.api) ++ reactivemongo.bundle
|
||||
libraryDependencies ++= provided(play.api, play.joda) ++ reactivemongo.bundle
|
||||
)
|
||||
|
||||
lazy val tv = module("tv", Seq(common, db, hub, socket, game, round, user)).settings(
|
||||
|
@ -270,7 +270,7 @@ lazy val studySearch = module("studySearch", Seq(common, hub, study, search)).se
|
|||
)
|
||||
|
||||
lazy val learn = module("learn", Seq(common, db, user)).settings(
|
||||
libraryDependencies ++= provided(play.api) ++ reactivemongo.bundle
|
||||
libraryDependencies ++= provided(play.api, play.joda) ++ reactivemongo.bundle
|
||||
)
|
||||
|
||||
lazy val evalCache = module("evalCache", Seq(common, db, user, security, socket, tree)).settings(
|
||||
|
|
|
@ -2,6 +2,7 @@ package lila.coach
|
|||
|
||||
import org.joda.time.DateTime
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.Future
|
||||
|
||||
import lila.db.dsl._
|
||||
import lila.db.Photographer
|
||||
|
@ -12,6 +13,7 @@ import lila.user.{ User, UserRepo }
|
|||
final class CoachApi(
|
||||
coachColl: Coll,
|
||||
reviewColl: Coll,
|
||||
userRepo: UserRepo,
|
||||
photographer: Photographer,
|
||||
notifyApi: NotifyApi
|
||||
) {
|
||||
|
@ -21,7 +23,7 @@ final class CoachApi(
|
|||
def byId(id: Coach.Id): Fu[Option[Coach]] = coachColl.byId[Coach](id.value)
|
||||
|
||||
def find(username: String): Fu[Option[Coach.WithUser]] =
|
||||
UserRepo named username flatMap { _ ?? find }
|
||||
userRepo named username flatMap { _ ?? find }
|
||||
|
||||
def find(user: User): Fu[Option[Coach.WithUser]] = Granter(_.Coach)(user) ?? {
|
||||
byId(Coach.Id(user.id)) map2 withUser(user)
|
||||
|
@ -30,7 +32,7 @@ final class CoachApi(
|
|||
def findOrInit(user: User): Fu[Option[Coach.WithUser]] = Granter(_.Coach)(user) ?? {
|
||||
find(user) orElse {
|
||||
val c = Coach.WithUser(Coach make user, user)
|
||||
coachColl insert c.coach inject c.some
|
||||
coachColl.insert.one(c.coach) inject c.some
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,29 +40,29 @@ final class CoachApi(
|
|||
Granter(_.Coach)(user) ?? coachColl.exists($id(user.id) ++ $doc("listed" -> true))
|
||||
|
||||
def setSeenAt(user: User): Funit =
|
||||
Granter(_.Coach)(user) ?? coachColl.update($id(user.id), $set("user.seenAt" -> DateTime.now)).void
|
||||
Granter(_.Coach)(user) ?? coachColl.update.one($id(user.id), $set("user.seenAt" -> DateTime.now)).void
|
||||
|
||||
def setRating(userPre: User): Funit =
|
||||
Granter(_.Coach)(userPre) ?? {
|
||||
UserRepo.byId(userPre.id) flatMap {
|
||||
userRepo.byId(userPre.id) flatMap {
|
||||
_ ?? { user =>
|
||||
coachColl.update($id(user.id), $set("user.rating" -> user.perfs.bestStandardRating)).void
|
||||
coachColl.update.one($id(user.id), $set("user.rating" -> user.perfs.bestStandardRating)).void
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def update(c: Coach.WithUser, data: CoachProfileForm.Data): Funit =
|
||||
coachColl.update(
|
||||
coachColl.update.one(
|
||||
$id(c.coach.id),
|
||||
data(c.coach),
|
||||
upsert = true
|
||||
).void
|
||||
|
||||
def setNbReviews(id: Coach.Id, nb: Int): Funit =
|
||||
coachColl.update($id(id), $set("nbReviews" -> nb)).void
|
||||
coachColl.update.one($id(id), $set("nbReviews" -> nb)).void
|
||||
|
||||
private[coach] def toggleApproved(username: String, value: Boolean): Fu[String] =
|
||||
coachColl.update(
|
||||
coachColl.update.one(
|
||||
$id(User.normalize(username)),
|
||||
$set("approved" -> value)
|
||||
) map { result =>
|
||||
|
@ -72,11 +74,11 @@ final class CoachApi(
|
|||
|
||||
def uploadPicture(c: Coach.WithUser, picture: Photographer.Uploaded): Funit =
|
||||
photographer(c.coach.id.value, picture).flatMap { pic =>
|
||||
coachColl.update($id(c.coach.id), $set("picturePath" -> pic.path)).void
|
||||
coachColl.update.one($id(c.coach.id), $set("picturePath" -> pic.path)).void
|
||||
}
|
||||
|
||||
def deletePicture(c: Coach.WithUser): Funit =
|
||||
coachColl.update($id(c.coach.id), $unset("picturePath")).void
|
||||
coachColl.update.one($id(c.coach.id), $unset("picturePath")).void
|
||||
|
||||
private def withUser(user: User)(coach: Coach) = Coach.WithUser(coach, user)
|
||||
|
||||
|
@ -105,7 +107,7 @@ final class CoachApi(
|
|||
}
|
||||
if (me.troll) fuccess(review)
|
||||
else {
|
||||
reviewColl.update($id(id), review, upsert = true) >>
|
||||
reviewColl.update.one($id(id), review, upsert = true) >>
|
||||
notifyApi.addNotification(Notification.make(
|
||||
notifies = Notification.Notifies(coach.id.value),
|
||||
content = lila.notify.CoachReview
|
||||
|
@ -119,14 +121,14 @@ final class CoachApi(
|
|||
reviewColl.byId[CoachReview](CoachReview.makeId(user, coach))
|
||||
|
||||
def approve(r: CoachReview, v: Boolean) = {
|
||||
if (v) reviewColl.update(
|
||||
if (v) reviewColl.update.one(
|
||||
$id(r.id),
|
||||
$set("approved" -> v) ++ $unset("moddedAt")
|
||||
).void
|
||||
else reviewColl.remove($id(r.id)).void
|
||||
else reviewColl.delete.one($id(r.id)).void
|
||||
} >> refreshCoachNbReviews(r.coachId)
|
||||
|
||||
def mod(r: CoachReview) = reviewColl.update($id(r.id), $set(
|
||||
def mod(r: CoachReview) = reviewColl.update.one($id(r.id), $set(
|
||||
"approved" -> false,
|
||||
"moddedAt" -> DateTime.now
|
||||
)) >> refreshCoachNbReviews(r.coachId)
|
||||
|
@ -149,15 +151,17 @@ final class CoachApi(
|
|||
findRecent($doc("coachId" -> c.id.value))
|
||||
|
||||
def deleteAllBy(userId: User.ID): Funit = for {
|
||||
reviews <- reviewColl.find($doc("userId" -> userId)).list[CoachReview]
|
||||
_ <- reviews.map { review =>
|
||||
reviewColl.remove($doc("userId" -> review.userId)).void
|
||||
}.sequenceFu
|
||||
_ <- reviews.map(_.coachId).distinct.map(refreshCoachNbReviews).sequenceFu
|
||||
reviews <- reviewColl.ext.find($doc("userId" -> userId)).list[CoachReview]
|
||||
_ <- Future.sequence(reviews.map { review =>
|
||||
reviewColl.delete.one($doc("userId" -> review.userId)).void
|
||||
})
|
||||
_ <- Future sequence {
|
||||
reviews.map(_.coachId).distinct.map(refreshCoachNbReviews)
|
||||
}
|
||||
} yield ()
|
||||
|
||||
private def findRecent(selector: Bdoc): Fu[CoachReview.Reviews] =
|
||||
reviewColl.find(selector)
|
||||
reviewColl.ext.find(selector)
|
||||
.sort($sort desc "createdAt")
|
||||
.list[CoachReview](100) map CoachReview.Reviews.apply
|
||||
}
|
||||
|
|
|
@ -7,9 +7,12 @@ import lila.db.dsl._
|
|||
import lila.db.paginator.{ Adapter }
|
||||
import lila.user.{ User, UserRepo }
|
||||
|
||||
final class CoachPager(coll: Coll) {
|
||||
final class CoachPager(
|
||||
userRepo: UserRepo,
|
||||
coll: Coll
|
||||
) {
|
||||
|
||||
val maxPerPage = lila.common.MaxPerPage(10)
|
||||
val maxPerPage = lila.common.config.MaxPerPage(10)
|
||||
|
||||
import CoachPager._
|
||||
import BsonHandlers._
|
||||
|
@ -21,7 +24,7 @@ final class CoachPager(coll: Coll) {
|
|||
"listed" -> Coach.Listed(true),
|
||||
"approved" -> Coach.Approved(true)
|
||||
),
|
||||
projection = $empty,
|
||||
projection = none,
|
||||
sort = order.predicate
|
||||
) mapFutureList withUsers
|
||||
Paginator(
|
||||
|
@ -32,7 +35,7 @@ final class CoachPager(coll: Coll) {
|
|||
}
|
||||
|
||||
private def withUsers(coaches: Seq[Coach]): Fu[Seq[Coach.WithUser]] =
|
||||
UserRepo.withColl {
|
||||
userRepo.withColl {
|
||||
_.optionsByOrderedIds[User, User.ID](coaches.map(_.id.value), ReadPreference.secondaryPreferred)(_.id)
|
||||
} map { users =>
|
||||
coaches zip users collect {
|
||||
|
|
|
@ -1,36 +1,43 @@
|
|||
package lila.coach
|
||||
|
||||
import akka.actor._
|
||||
import com.softwaremill.macwire._
|
||||
import io.methvin.play.autoconfig._
|
||||
import play.api.Configuration
|
||||
import scala.concurrent.duration.FiniteDuration
|
||||
|
||||
import lila.common.config._
|
||||
import lila.security.Permission
|
||||
|
||||
import akka.actor._
|
||||
import com.typesafe.config.Config
|
||||
import scala.concurrent.duration._
|
||||
@Module
|
||||
private class CoachConfig(
|
||||
@ConfigName("collection.coach") val coachColl: CollName,
|
||||
@ConfigName("collection.review") val reviewColl: CollName,
|
||||
@ConfigName("collection.image") val imageColl: CollName
|
||||
)
|
||||
|
||||
final class Env(
|
||||
config: Config,
|
||||
appConfig: Configuration,
|
||||
userRepo: lila.user.UserRepo,
|
||||
notifyApi: lila.notify.NotifyApi,
|
||||
system: ActorSystem,
|
||||
db: lila.db.Env
|
||||
) {
|
||||
)(implicit system: ActorSystem) {
|
||||
|
||||
private val CollectionCoach = config getString "collection.coach"
|
||||
private val CollectionReview = config getString "collection.review"
|
||||
private val CollectionImage = config getString "collection.image"
|
||||
private val config = appConfig.get[CoachConfig]("coach")(AutoConfig.loader)
|
||||
|
||||
private lazy val coachColl = db(CollectionCoach)
|
||||
private lazy val reviewColl = db(CollectionReview)
|
||||
private lazy val imageColl = db(CollectionImage)
|
||||
private lazy val coachColl = db(config.coachColl)
|
||||
|
||||
private lazy val photographer = new lila.db.Photographer(imageColl, "coach")
|
||||
private lazy val photographer = new lila.db.Photographer(db(config.imageColl), "coach")
|
||||
|
||||
lazy val api = new CoachApi(
|
||||
coachColl = coachColl,
|
||||
reviewColl = reviewColl,
|
||||
userRepo = userRepo,
|
||||
reviewColl = db(config.reviewColl),
|
||||
photographer = photographer,
|
||||
notifyApi = notifyApi
|
||||
)
|
||||
|
||||
lazy val pager = new CoachPager(coachColl)
|
||||
lazy val pager = wire[CoachPager]
|
||||
|
||||
lila.common.Bus.subscribeFun("adjustCheater", "finishGame", "shadowban", "setPermissions") {
|
||||
case lila.hub.actorApi.mod.Shadowban(userId, true) =>
|
||||
|
@ -56,13 +63,3 @@ final class Env(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
object Env {
|
||||
|
||||
lazy val current: Env = "coach" boot new Env(
|
||||
config = lila.common.PlayApp loadConfig "coach",
|
||||
notifyApi = lila.notify.Env.current.api,
|
||||
system = lila.common.PlayApp.system,
|
||||
db = lila.db.Env.current
|
||||
)
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ object UrlList {
|
|||
case class Url(value: String) extends AnyVal
|
||||
|
||||
def apply(text: String): List[Url] =
|
||||
text.lines.toList.map(_.trim).filter(_.nonEmpty) flatMap toUrl take max
|
||||
text.linesIterator.toList.view.map(_.trim).filter(_.nonEmpty) flatMap toUrl take max to List
|
||||
|
||||
private val UrlRegex = """(?:youtube\.com|youtu\.be)/(?:watch)?(?:\?v=)?([^"&?/ ]{11})""".r.unanchored
|
||||
|
||||
|
@ -32,7 +32,7 @@ object UrlList {
|
|||
private val UrlRegex = """(?:lichess\.org)/study/(\w{8})""".r.unanchored
|
||||
|
||||
def apply(text: String): List[StudyId] =
|
||||
text.lines.toList.map(_.trim).filter(_.nonEmpty) flatMap toId take max
|
||||
text.linesIterator.toList.view.map(_.trim).filter(_.nonEmpty) flatMap toId take max to List
|
||||
|
||||
private def toId(line: String): Option[StudyId] = line match {
|
||||
case UrlRegex(id) => StudyId(id).some
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
package lila.coordinate
|
||||
|
||||
import play.api.Configuration
|
||||
import com.softwaremill.macwire._
|
||||
|
||||
import lila.common.config.CollName
|
||||
|
||||
final class Env(
|
||||
appConfig: Configuration,
|
||||
db: lila.db.Env
|
||||
) {
|
||||
|
||||
private val CollectionScore = appConfig.get[String]("coordinate.collection.score")
|
||||
private lazy val scoreColl = db(appConfig.get[CollName]("coordinate.collection.score"))
|
||||
|
||||
lazy val api = new CoordinateApi(scoreColl = scoreColl)
|
||||
lazy val api = wire[CoordinateApi]
|
||||
|
||||
lazy val forms = DataForm
|
||||
|
||||
private[coordinate] lazy val scoreColl = db(CollectionScore)
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ private object BSONHandlers {
|
|||
}
|
||||
}
|
||||
}.flatMap {
|
||||
_.toNel toTry lila.base.LilaException(s"Empty PVs ${value}")
|
||||
_.toNel toTry s"Empty PVs ${value}"
|
||||
}
|
||||
case b => lila.db.BSON.handlerBadType[NonEmptyList[Pv]](b)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package lila.event
|
||||
|
||||
import play.api.Configuration
|
||||
import com.softwaremill.macwire._
|
||||
|
||||
import lila.common.CollName
|
||||
import lila.common.config.CollName
|
||||
import lila.common.config._
|
||||
|
||||
final class Env(
|
||||
|
@ -13,5 +14,5 @@ final class Env(
|
|||
|
||||
private lazy val eventColl = db(appConfig.get[CollName]("event.collection.event"))
|
||||
|
||||
lazy val api = new EventApi(coll = eventColl, asyncCache = asyncCache)
|
||||
lazy val api = wire[EventApi]
|
||||
}
|
||||
|
|
|
@ -1,48 +1,41 @@
|
|||
package lila.gameSearch
|
||||
|
||||
import akka.actor._
|
||||
import com.typesafe.config.Config
|
||||
import akka.actor.ActorSystem
|
||||
import com.softwaremill.macwire._
|
||||
import io.methvin.play.autoconfig._
|
||||
import play.api.Configuration
|
||||
|
||||
import lila.game.actorApi.{ InsertGame, FinishGame }
|
||||
import lila.search._
|
||||
import lila.common.config._
|
||||
|
||||
@Module
|
||||
private class GameSearchConfig(
|
||||
@ConfigName("index") val indexName: String,
|
||||
@ConfigName("paginator.max_per_page") val paginatorMaxPerPage: MaxPerPage,
|
||||
@ConfigName("actor.name") val actorName: String
|
||||
)
|
||||
|
||||
final class Env(
|
||||
config: Config,
|
||||
system: ActorSystem,
|
||||
appConfig: Configuration,
|
||||
gameRepo: lila.game.GameRepo,
|
||||
makeClient: Index => ESClient
|
||||
) {
|
||||
)(implicit system: ActorSystem) {
|
||||
|
||||
private val IndexName = config getString "index"
|
||||
private val PaginatorMaxPerPage = config getInt "paginator.max_per_page"
|
||||
private val ActorName = config getString "actor.name"
|
||||
private val config = appConfig.get[GameSearchConfig]("gameSearch")(AutoConfig.loader)
|
||||
|
||||
private lazy val client = makeClient(Index(IndexName))
|
||||
private lazy val client = makeClient(Index(config.indexName))
|
||||
|
||||
lazy val api = new GameSearchApi(client, system)
|
||||
lazy val api = wire[GameSearchApi]
|
||||
|
||||
lazy val paginator = new PaginatorBuilder[lila.game.Game, Query](
|
||||
searchApi = api,
|
||||
maxPerPage = lila.common.MaxPerPage(PaginatorMaxPerPage)
|
||||
)
|
||||
lazy val paginator = wire[PaginatorBuilder[lila.game.Game, Query]]
|
||||
|
||||
lazy val forms = new DataForm
|
||||
lazy val forms = wire[DataForm]
|
||||
|
||||
lazy val userGameSearch = new UserGameSearch(
|
||||
forms = forms,
|
||||
paginator = paginator
|
||||
)
|
||||
lazy val userGameSearch = wire[UserGameSearch]
|
||||
|
||||
lila.common.Bus.subscribeFun("finishGame", "gameSearchInsert") {
|
||||
case FinishGame(game, _, _) if !game.aborted => api store game
|
||||
case InsertGame(game) => api store game
|
||||
}
|
||||
}
|
||||
|
||||
object Env {
|
||||
|
||||
lazy val current = "gameSearch" boot new Env(
|
||||
config = lila.common.PlayApp loadConfig "gameSearch",
|
||||
system = lila.common.PlayApp.system,
|
||||
makeClient = lila.search.Env.current.makeClient
|
||||
)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package lila.gameSearch
|
|||
|
||||
import org.joda.time.DateTime
|
||||
import org.joda.time.format.DateTimeFormat
|
||||
import play.api.libs.iteratee._
|
||||
import play.api.libs.json._
|
||||
import scala.concurrent.duration._
|
||||
import scala.util.Try
|
||||
|
@ -13,12 +12,12 @@ import lila.search._
|
|||
|
||||
final class GameSearchApi(
|
||||
client: ESClient,
|
||||
system: akka.actor.ActorSystem
|
||||
) extends SearchReadApi[Game, Query] {
|
||||
gameRepo: GameRepo
|
||||
)(implicit system: akka.actor.ActorSystem) extends SearchReadApi[Game, Query] {
|
||||
|
||||
def search(query: Query, from: From, size: Size) =
|
||||
client.search(query, from, size) flatMap { res =>
|
||||
GameRepo gamesFromSecondary res.ids
|
||||
gameRepo gamesFromSecondary res.ids
|
||||
}
|
||||
|
||||
def count(query: Query) =
|
||||
|
@ -28,13 +27,13 @@ final class GameSearchApi(
|
|||
client.search(query, From(0), Size(max)).map(_.ids)
|
||||
|
||||
def store(game: Game) = storable(game) ?? {
|
||||
GameRepo isAnalysed game.id flatMap { analysed =>
|
||||
gameRepo isAnalysed game.id flatMap { analysed =>
|
||||
lila.common.Future.retry(
|
||||
() => client.store(Id(game.id), toDoc(game, analysed)),
|
||||
delay = 20.seconds,
|
||||
retries = 2,
|
||||
logger.some
|
||||
)(system)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package lila.gameSearch
|
|||
|
||||
import chess.{ Mode, Status }
|
||||
import org.joda.time.DateTime
|
||||
import play.api.libs.json.JodaWrites._
|
||||
|
||||
import lila.rating.RatingRange
|
||||
import lila.search.Range
|
||||
|
@ -90,7 +91,7 @@ object Query {
|
|||
"%d move{s}"
|
||||
)
|
||||
|
||||
val averageRatings = (RatingRange.min to RatingRange.max by 100).toList map { e => e -> (e + " Rating") }
|
||||
val averageRatings = (RatingRange.min to RatingRange.max by 100).toList map { e => e -> s"$e Rating" }
|
||||
|
||||
val hasAis = List(0 -> "Human opponent", 1 -> "Computer opponent")
|
||||
|
||||
|
|
|
@ -1,31 +1,29 @@
|
|||
package lila.history
|
||||
|
||||
import com.typesafe.config.Config
|
||||
import com.softwaremill.macwire._
|
||||
import io.methvin.play.autoconfig._
|
||||
import play.api.Configuration
|
||||
import scala.concurrent.duration.FiniteDuration
|
||||
|
||||
import lila.common.config._
|
||||
|
||||
@Module
|
||||
private class HistoryConfig(
|
||||
@ConfigName("collection.history") val historyColl: CollName,
|
||||
@ConfigName("cached.rating_chart.ttl") val ratingChartTtl: FiniteDuration
|
||||
)
|
||||
|
||||
final class Env(
|
||||
config: Config,
|
||||
appConfig: Configuration,
|
||||
mongoCache: lila.memo.MongoCache.Builder,
|
||||
db: lila.db.Env
|
||||
) {
|
||||
|
||||
private val CachedRatingChartTtl = config duration "cached.rating_chart.ttl"
|
||||
private val config = appConfig.get[HistoryConfig]("history")(AutoConfig.loader)
|
||||
|
||||
private val Collectionhistory = config getString "collection.history"
|
||||
private lazy val coll = db(config.historyColl)
|
||||
|
||||
lazy val api = new HistoryApi(db(Collectionhistory))
|
||||
lazy val api = wire[HistoryApi]
|
||||
|
||||
lazy val ratingChartApi = new RatingChartApi(
|
||||
historyApi = api,
|
||||
mongoCache = mongoCache,
|
||||
cacheTtl = CachedRatingChartTtl
|
||||
)
|
||||
}
|
||||
|
||||
object Env {
|
||||
|
||||
lazy val current = "history" boot new Env(
|
||||
config = lila.common.PlayApp loadConfig "history",
|
||||
mongoCache = lila.memo.Env.current.mongoCache,
|
||||
db = lila.db.Env.current
|
||||
)
|
||||
lazy val ratingChartApi = wire[RatingChartApi]
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package lila.history
|
||||
|
||||
import scala.util.{ Try, Success, Failure }
|
||||
|
||||
import lila.rating.PerfType
|
||||
|
||||
case class History(
|
||||
|
@ -47,16 +49,15 @@ object History {
|
|||
import reactivemongo.api.bson._
|
||||
|
||||
private[history] implicit val RatingsMapReader = new BSONDocumentReader[RatingsMap] {
|
||||
def read(doc: BSONDocument): RatingsMap = doc.stream.flatMap {
|
||||
case scala.util.Success(BSONElement(k, BSONInteger(v))) => k.toIntOption map (_ -> v)
|
||||
def readDocument(doc: BSONDocument) = Success(doc.elements.flatMap {
|
||||
case BSONElement(k, BSONInteger(v)) => k.toIntOption map (_ -> v)
|
||||
case _ => none[(Int, Int)]
|
||||
}.toList sortBy (_._1)
|
||||
}.sortBy(_._1) to List)
|
||||
}
|
||||
|
||||
private[history] implicit val HistoryBSONReader = new BSONDocumentReader[History] {
|
||||
|
||||
def read(doc: BSONDocument): History = {
|
||||
def ratingsMap(key: String): RatingsMap = ~doc.getAs[RatingsMap](key)
|
||||
def readDocument(doc: BSONDocument) = Success {
|
||||
def ratingsMap(key: String): RatingsMap = ~doc.getAsOpt[RatingsMap](key)
|
||||
History(
|
||||
standard = ratingsMap("standard"),
|
||||
chess960 = ratingsMap("chess960"),
|
||||
|
|
|
@ -18,7 +18,7 @@ final class HistoryApi(coll: Coll) {
|
|||
|
||||
def addPuzzle(user: User, completedAt: DateTime, perf: Perf): Funit = {
|
||||
val days = daysBetween(user.createdAt, completedAt)
|
||||
coll.update(
|
||||
coll.update.one(
|
||||
$id(user.id),
|
||||
$set(s"puzzle.$days" -> $int(perf.intRating)),
|
||||
upsert = true
|
||||
|
@ -47,10 +47,10 @@ final class HistoryApi(coll: Coll) {
|
|||
case (k, p) => k -> p.intRating
|
||||
}
|
||||
val days = daysBetween(user.createdAt, game.movedAt)
|
||||
coll.update(
|
||||
coll.update.one(
|
||||
$id(user.id),
|
||||
$doc("$set" -> $doc(changes.map {
|
||||
case (perf, rating) => BSONElement(s"$perf.$days", $int(rating))
|
||||
case (perf, rating) => (s"$perf.$days", $int(rating))
|
||||
})),
|
||||
upsert = true
|
||||
).void
|
||||
|
@ -59,7 +59,7 @@ final class HistoryApi(coll: Coll) {
|
|||
// used for rating refunds
|
||||
def setPerfRating(user: User, perf: PerfType, rating: Int): Funit = {
|
||||
val days = daysBetween(user.createdAt, DateTime.now)
|
||||
coll.update(
|
||||
coll.update.one(
|
||||
$id(user.id),
|
||||
$set(s"${perf.key}.$days" -> $int(rating))
|
||||
).void
|
||||
|
@ -91,11 +91,11 @@ final class HistoryApi(coll: Coll) {
|
|||
val project = BSONDocument {
|
||||
("_id" -> BSONBoolean(false)) :: days.map { d => s"${perf.key}.$d" -> BSONBoolean(true) }
|
||||
}
|
||||
coll.find($id(user.id), project).uno[Bdoc](ReadPreference.secondaryPreferred).map {
|
||||
coll.find($id(user.id), project.some).uno[Bdoc](ReadPreference.secondaryPreferred).map {
|
||||
_.flatMap {
|
||||
_.getAs[Bdoc](perf.key) map {
|
||||
_.stream.foldLeft(currentRating) {
|
||||
case (max, scala.util.Success(BSONElement(_, BSONInteger(v)))) if v > max => v
|
||||
_.child(perf.key) map {
|
||||
_.elements.foldLeft(currentRating) {
|
||||
case (max, BSONElement(_, BSONInteger(v))) if v > max => v
|
||||
case (max, _) => max
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package lila.learn
|
||||
|
||||
import reactivemongo.api.bson.{ MapReader => _, MapWriter => _, _ }
|
||||
import reactivemongo.api.bson._
|
||||
|
||||
import lila.db.BSON
|
||||
import lila.db.dsl._
|
||||
|
||||
object BSONHandlers {
|
||||
|
@ -10,13 +9,11 @@ object BSONHandlers {
|
|||
import StageProgress.Score
|
||||
|
||||
private implicit val ScoreHandler = intAnyValHandler[Score](_.value, Score.apply)
|
||||
private implicit val ScoresHandler = bsonArrayToVectorHandler[Score]
|
||||
private implicit val StageProgressHandler =
|
||||
isoHandler[StageProgress, Vector[Score], BSONArray](
|
||||
isoHandler[StageProgress, Vector[Score]](
|
||||
(s: StageProgress) => s.scores, StageProgress.apply _
|
||||
)(ScoresHandler)
|
||||
)
|
||||
|
||||
private implicit val LearnProgressStagesHandler = BSON.MapValue.MapHandler[String, StageProgress]
|
||||
implicit val LearnProgressIdHandler = stringAnyValHandler[LearnProgress.Id](_.value, LearnProgress.Id.apply)
|
||||
implicit val LearnProgressHandler = Macros.handler[LearnProgress]
|
||||
}
|
||||
|
|
|
@ -1,23 +1,15 @@
|
|||
package lila.learn
|
||||
|
||||
import com.typesafe.config.Config
|
||||
import io.methvin.play.autoconfig._
|
||||
import play.api.Configuration
|
||||
|
||||
import lila.common.config._
|
||||
|
||||
final class Env(
|
||||
config: Config,
|
||||
appConfig: Configuration,
|
||||
db: lila.db.Env
|
||||
) {
|
||||
|
||||
private val CollectionProgress = config getString "collection.progress"
|
||||
|
||||
lazy val api = new LearnApi(
|
||||
coll = db(CollectionProgress)
|
||||
)
|
||||
}
|
||||
|
||||
object Env {
|
||||
|
||||
lazy val current: Env = "learn" boot new Env(
|
||||
config = lila.common.PlayApp loadConfig "learn",
|
||||
db = lila.db.Env.current
|
||||
coll = db(appConfig.get[CollName]("learn.collection.progress"))
|
||||
)
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package lila.learn
|
|||
|
||||
import lila.common.PimpedJson._
|
||||
import play.api.libs.json._
|
||||
import play.api.libs.json.JodaWrites._
|
||||
|
||||
object JSONHandlers {
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ final class LearnApi(coll: Coll) {
|
|||
coll.uno[LearnProgress]($id(user.id)) map { _ | LearnProgress.empty(LearnProgress.Id(user.id)) }
|
||||
|
||||
private def save(p: LearnProgress): Funit =
|
||||
coll.update($id(p.id), p, upsert = true).void
|
||||
coll.update.one($id(p.id), p, upsert = true).void
|
||||
|
||||
def setScore(user: User, stage: String, level: Int, score: StageProgress.Score) =
|
||||
get(user) flatMap { prog =>
|
||||
|
@ -19,5 +19,5 @@ final class LearnApi(coll: Coll) {
|
|||
}
|
||||
|
||||
def reset(user: User) =
|
||||
coll.remove($id(user.id)).void
|
||||
coll.delete.one($id(user.id)).void
|
||||
}
|
||||
|
|
|
@ -1,36 +1,31 @@
|
|||
package lila.perfStat
|
||||
|
||||
import akka.actor._
|
||||
import com.typesafe.config.Config
|
||||
import com.softwaremill.macwire._
|
||||
import play.api.Configuration
|
||||
|
||||
import akka.actor._
|
||||
import lila.common.config._
|
||||
|
||||
final class Env(
|
||||
config: Config,
|
||||
system: ActorSystem,
|
||||
appConfig: Configuration,
|
||||
lightUser: lila.common.LightUser.GetterSync,
|
||||
gameRepo: lila.game.GameRepo,
|
||||
db: lila.db.Env
|
||||
) {
|
||||
|
||||
private val settings = new {
|
||||
val CollectionPerfStat = config getString "collection.perf_stat"
|
||||
}
|
||||
import settings._
|
||||
)(implicit system: ActorSystem) {
|
||||
|
||||
lazy val storage = new PerfStatStorage(
|
||||
coll = db(CollectionPerfStat)
|
||||
coll = db(appConfig.get[CollName]("perfStat.collection.perf_stat"))
|
||||
)
|
||||
|
||||
lazy val indexer = new PerfStatIndexer(
|
||||
storage = storage,
|
||||
sequencer = new lila.hub.FutureSequencer(
|
||||
system = system,
|
||||
executionTimeout = None,
|
||||
logger = lila.log("perfStat")
|
||||
)
|
||||
private lazy val sequencer = new lila.hub.FutureSequencer(
|
||||
system = system,
|
||||
executionTimeout = None,
|
||||
logger = lila.log("perfStat")
|
||||
)
|
||||
|
||||
lazy val jsonView = new JsonView(lightUser)
|
||||
lazy val indexer = wire[PerfStatIndexer]
|
||||
|
||||
lazy val jsonView = wire[JsonView]
|
||||
|
||||
def get(user: lila.user.User, perfType: lila.rating.PerfType): Fu[PerfStat] =
|
||||
storage.find(user.id, perfType) orElse {
|
||||
|
@ -44,13 +39,3 @@ final class Env(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
object Env {
|
||||
|
||||
lazy val current: Env = "perfStat" boot new Env(
|
||||
config = lila.common.PlayApp loadConfig "perfStat",
|
||||
system = lila.common.PlayApp.system,
|
||||
lightUser = lila.user.Env.current.lightUserSync,
|
||||
db = lila.db.Env.current
|
||||
)
|
||||
}
|
||||
|
|
|
@ -12,19 +12,6 @@ final class JsonView(getLightUser: LightUser.GetterSync) {
|
|||
|
||||
import JsonView._
|
||||
|
||||
def apply(
|
||||
user: User,
|
||||
stat: PerfStat,
|
||||
rank: Option[Int],
|
||||
percentile: Option[Double]
|
||||
) = Json.obj(
|
||||
"user" -> user,
|
||||
"perf" -> user.perfs(stat.perfType),
|
||||
"rank" -> rank,
|
||||
"percentile" -> percentile,
|
||||
"stat" -> stat
|
||||
)
|
||||
|
||||
private implicit val userIdWriter: OWrites[UserId] = OWrites { u =>
|
||||
val light = getLightUser(u.value)
|
||||
Json.obj(
|
||||
|
@ -43,6 +30,19 @@ final class JsonView(getLightUser: LightUser.GetterSync) {
|
|||
implicit val resultStreakWrites = Json.writes[ResultStreak]
|
||||
implicit val countWrites = Json.writes[Count]
|
||||
implicit val perfStatWrites = Json.writes[PerfStat]
|
||||
|
||||
def apply(
|
||||
user: User,
|
||||
stat: PerfStat,
|
||||
rank: Option[Int],
|
||||
percentile: Option[Double]
|
||||
) = Json.obj(
|
||||
"user" -> user,
|
||||
"perf" -> user.perfs(stat.perfType),
|
||||
"rank" -> rank,
|
||||
"percentile" -> percentile,
|
||||
"stat" -> stat
|
||||
)
|
||||
}
|
||||
|
||||
object JsonView {
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
package lila.perfStat
|
||||
|
||||
import akka.actor.ActorRef
|
||||
import scala.concurrent.Future
|
||||
|
||||
import lila.game.{ Game, GameRepo, Pov, Query }
|
||||
import lila.hub.FutureSequencer
|
||||
import lila.rating.PerfType
|
||||
import lila.user.User
|
||||
|
||||
final class PerfStatIndexer(storage: PerfStatStorage, sequencer: FutureSequencer) {
|
||||
final class PerfStatIndexer(
|
||||
gameRepo: GameRepo,
|
||||
storage: PerfStatStorage,
|
||||
sequencer: FutureSequencer
|
||||
) {
|
||||
|
||||
def userPerf(user: User, perfType: PerfType): Funit = sequencer {
|
||||
GameRepo.sortedCursor(
|
||||
gameRepo.sortedCursor(
|
||||
Query.user(user.id) ++
|
||||
Query.finished ++
|
||||
Query.turnsGt(2) ++
|
||||
|
@ -23,11 +28,13 @@ final class PerfStatIndexer(storage: PerfStatStorage, sequencer: FutureSequencer
|
|||
} flatMap storage.insert recover lila.db.recoverDuplicateKey(_ => ())
|
||||
}
|
||||
|
||||
def addGame(game: Game): Funit = game.players.flatMap { player =>
|
||||
player.userId.map { userId =>
|
||||
addPov(Pov(game, player), userId)
|
||||
def addGame(game: Game): Funit = Future.sequence {
|
||||
game.players.flatMap { player =>
|
||||
player.userId.map { userId =>
|
||||
addPov(Pov(game, player), userId)
|
||||
}
|
||||
}
|
||||
}.sequenceFu.void
|
||||
}.void
|
||||
|
||||
private def addPov(pov: Pov, userId: String): Funit = pov.game.perfType ?? { perfType =>
|
||||
storage.find(userId, perfType) flatMap {
|
||||
|
|
|
@ -24,8 +24,8 @@ final class PerfStatStorage(coll: Coll) {
|
|||
coll.byId[PerfStat](PerfStat.makeId(userId, perfType))
|
||||
|
||||
def update(perfStat: PerfStat): Funit =
|
||||
coll.update($id(perfStat.id), perfStat).void
|
||||
coll.update.one($id(perfStat.id), perfStat).void
|
||||
|
||||
def insert(perfStat: PerfStat): Funit =
|
||||
coll.insert(perfStat).void
|
||||
coll.insert.one(perfStat).void
|
||||
}
|
||||
|
|
|
@ -187,7 +187,7 @@ final class PlaybanApi(
|
|||
|
||||
private def save(outcome: Outcome, userId: User.ID, rageSitDelta: Int): Funit = {
|
||||
lila.mon.playban.outcome(outcome.key)()
|
||||
coll.findAndUpdate(
|
||||
coll.ext.findAndUpdate(
|
||||
selector = $id(userId),
|
||||
update = $doc(
|
||||
$push("o" -> $doc("$each" -> List(outcome), "$slice" -> -30)),
|
||||
|
@ -230,7 +230,7 @@ final class PlaybanApi(
|
|||
lila.mon.playban.ban.count()
|
||||
lila.mon.playban.ban.mins(ban.mins)
|
||||
Bus.publish(lila.hub.actorApi.playban.Playban(record.userId, ban.mins), "playban")
|
||||
coll.update(
|
||||
coll.update.one(
|
||||
$id(record.userId),
|
||||
$unset("o") ++
|
||||
$push(
|
||||
|
|
|
@ -202,5 +202,5 @@ pid(a|o|)r
|
|||
чмо
|
||||
""")
|
||||
|
||||
private def dict(words: String) = words.lines.filter(_.nonEmpty)
|
||||
private def dict(words: String) = words.linesIterator.filter(_.nonEmpty)
|
||||
}
|
||||
|
|
|
@ -1,26 +1,33 @@
|
|||
package lila.shutup
|
||||
|
||||
import akka.actor._
|
||||
import com.typesafe.config.Config
|
||||
import com.softwaremill.macwire._
|
||||
import io.methvin.play.autoconfig._
|
||||
import play.api.Configuration
|
||||
|
||||
import lila.common.config._
|
||||
import lila.user.{ User, UserRepo }
|
||||
|
||||
@Module
|
||||
private class ShutupConfig(
|
||||
@ConfigName("collection.shutup") val shutupColl: CollName,
|
||||
@ConfigName("actor.name") val actorName: String
|
||||
)
|
||||
|
||||
final class Env(
|
||||
config: Config,
|
||||
appConfig: Configuration,
|
||||
reporter: akka.actor.ActorSelection,
|
||||
follows: (String, String) => Fu[Boolean],
|
||||
system: ActorSystem,
|
||||
follows: (User.ID, User.ID) => Fu[Boolean],
|
||||
gameRepo: lila.game.GameRepo,
|
||||
userRepo: UserRepo,
|
||||
db: lila.db.Env
|
||||
) {
|
||||
)(implicit system: ActorSystem) {
|
||||
|
||||
private val CollectionShutup = config getString "collection.shutup"
|
||||
private val ActorName = config getString "actor.name"
|
||||
private val config = appConfig.get[ShutupConfig]("shutup")(AutoConfig.loader)
|
||||
|
||||
lazy val api = new ShutupApi(
|
||||
coll = coll,
|
||||
follows = follows,
|
||||
reporter = reporter
|
||||
)
|
||||
private lazy val coll = db(config.shutupColl)
|
||||
|
||||
private lazy val coll = db(CollectionShutup)
|
||||
lazy val api = wire[ShutupApi]
|
||||
|
||||
// api actor
|
||||
system.actorOf(Props(new Actor {
|
||||
|
@ -37,16 +44,5 @@ final class Env(
|
|||
case RecordPublicChat(userId, text, source) =>
|
||||
api.publicChat(userId, text, source)
|
||||
}
|
||||
}), name = ActorName)
|
||||
}
|
||||
|
||||
object Env {
|
||||
|
||||
lazy val current: Env = "shutup" boot new Env(
|
||||
config = lila.common.PlayApp loadConfig "shutup",
|
||||
reporter = lila.hub.Env.current.report,
|
||||
system = lila.common.PlayApp.system,
|
||||
follows = lila.relation.Env.current.api.fetchFollows _,
|
||||
db = lila.db.Env.current
|
||||
)
|
||||
}), name = config.actorName)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package lila.shutup
|
||||
|
||||
import org.joda.time.DateTime
|
||||
import scala.util.{ Try, Success, Failure }
|
||||
|
||||
import lila.hub.actorApi.shutup.{ PublicSource => Source }
|
||||
|
||||
case class PublicLine(
|
||||
|
@ -16,32 +18,32 @@ object PublicLine {
|
|||
|
||||
import reactivemongo.api.bson._
|
||||
import lila.db.dsl._
|
||||
private implicit val SourceHandler = new BSONHandler[BSONString, Source] {
|
||||
def read(bs: BSONString): Source = bs.value split ':' match {
|
||||
case Array("t", id) => Source.Tournament(id)
|
||||
case Array("s", id) => Source.Simul(id)
|
||||
case Array("w", gameId) => Source.Watcher(gameId)
|
||||
case Array("u", id) => Source.Study(id)
|
||||
case a => sys error s"Invalid PublicLine source ${bs.value}"
|
||||
}
|
||||
def write(x: Source) = BSONString {
|
||||
x match {
|
||||
case Source.Tournament(id) => s"t:$id"
|
||||
case Source.Simul(id) => s"s:$id"
|
||||
case Source.Study(id) => s"u:$id"
|
||||
case Source.Watcher(gameId) => s"w:$gameId"
|
||||
private implicit val SourceHandler = lila.db.BSON.tryHandler[Source](
|
||||
{
|
||||
case BSONString(v) => v split ':' match {
|
||||
case Array("t", id) => Success(Source.Tournament(id))
|
||||
case Array("s", id) => Success(Source.Simul(id))
|
||||
case Array("w", gameId) => Success(Source.Watcher(gameId))
|
||||
case Array("u", id) => Success(Source.Study(id))
|
||||
case a => lila.db.BSON.handlerBadValue(s"Invalid PublicLine source $v")
|
||||
}
|
||||
}
|
||||
}
|
||||
implicit val PublicLineBSONHandler = new BSONHandler[BSONValue, PublicLine] {
|
||||
private val objectHandler = Macros.handler[PublicLine]
|
||||
def read(bv: BSONValue): PublicLine = bv match {
|
||||
case doc: BSONDocument => objectHandler read doc
|
||||
case BSONString(text) => PublicLine(text, none, none)
|
||||
case a => sys error s"Invalid PublicLine $a"
|
||||
}
|
||||
def write(x: PublicLine) =
|
||||
if (x.from.isDefined) objectHandler write x
|
||||
else BSONString(x.text)
|
||||
}
|
||||
},
|
||||
x => BSONString(x match {
|
||||
case Source.Tournament(id) => s"t:$id"
|
||||
case Source.Simul(id) => s"s:$id"
|
||||
case Source.Study(id) => s"u:$id"
|
||||
case Source.Watcher(gameId) => s"w:$gameId"
|
||||
})
|
||||
)
|
||||
|
||||
private val objectHandler = Macros.handler[PublicLine]
|
||||
|
||||
implicit val PublicLineBSONHandler = lila.db.BSON.tryHandler[PublicLine](
|
||||
{
|
||||
case doc: BSONDocument => objectHandler readTry doc
|
||||
case BSONString(text) => Success(PublicLine(text, none, none))
|
||||
case a => lila.db.BSON.handlerBadValue(s"Invalid PublicLine $a")
|
||||
},
|
||||
x => if (x.from.isDefined) objectHandler.writeTry(x).get else BSONString(x.text)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ import lila.user.{ User, UserRepo }
|
|||
|
||||
final class ShutupApi(
|
||||
coll: Coll,
|
||||
gameRepo: GameRepo,
|
||||
userRepo: UserRepo,
|
||||
follows: (User.ID, User.ID) => Fu[Boolean],
|
||||
reporter: akka.actor.ActorSelection
|
||||
) {
|
||||
|
@ -18,9 +20,9 @@ final class ShutupApi(
|
|||
import PublicLine.PublicLineBSONHandler
|
||||
|
||||
def getPublicLines(userId: User.ID): Fu[List[PublicLine]] =
|
||||
coll.find($doc("_id" -> userId), $doc("pub" -> 1))
|
||||
coll.find($doc("_id" -> userId), $doc("pub" -> 1).some)
|
||||
.uno[Bdoc].map {
|
||||
~_.flatMap(_.getAs[List[PublicLine]]("pub"))
|
||||
~_.flatMap(_.getAsOpt[List[PublicLine]]("pub"))
|
||||
}
|
||||
|
||||
def publicForumMessage(userId: User.ID, text: String) = record(userId, text, TextType.PublicForumMessage)
|
||||
|
@ -28,7 +30,7 @@ final class ShutupApi(
|
|||
def publicChat(userId: User.ID, text: String, source: PublicSource) = record(userId, text, TextType.PublicChat, source.some)
|
||||
|
||||
def privateChat(chatId: String, userId: User.ID, text: String) =
|
||||
GameRepo.getSourceAndUserIds(chatId) flatMap {
|
||||
gameRepo.getSourceAndUserIds(chatId) flatMap {
|
||||
case (source, _) if source.has(lila.game.Source.Friend) => funit // ignore challenges
|
||||
case (_, userIds) =>
|
||||
record(userId, text, TextType.PrivateChat, none, userIds find (userId !=))
|
||||
|
@ -45,7 +47,7 @@ final class ShutupApi(
|
|||
toUserId: Option[User.ID] = None,
|
||||
major: Boolean = false
|
||||
): Funit =
|
||||
UserRepo isTroll userId flatMap {
|
||||
userRepo isTroll userId flatMap {
|
||||
case true => funit
|
||||
case false => toUserId ?? { follows(_, userId) } flatMap {
|
||||
case true => funit
|
||||
|
@ -65,12 +67,12 @@ final class ShutupApi(
|
|||
"$slice" -> -textType.rotation
|
||||
)
|
||||
) ++ pushPublicLine
|
||||
coll.findAndUpdate(
|
||||
coll.ext.findAndUpdate(
|
||||
selector = $id(userId),
|
||||
update = $push(push),
|
||||
fetchNewObject = true,
|
||||
upsert = true
|
||||
).map(_.value) map2 UserRecordBSONHandler.read flatMap {
|
||||
).dmap(_.value flatMap UserRecordBSONHandler.readOpt) flatMap {
|
||||
case None => fufail(s"can't find user record for $userId")
|
||||
case Some(userRecord) => legiferate(userRecord, major)
|
||||
} logFailure lila.log("shutup")
|
||||
|
@ -81,7 +83,7 @@ final class ShutupApi(
|
|||
major || userRecord.reports.exists(_.unacceptable)
|
||||
} ?? {
|
||||
reporter ! lila.hub.actorApi.report.Shutup(userRecord.userId, reportText(userRecord), major)
|
||||
coll.update(
|
||||
coll.update.one(
|
||||
$id(userRecord.userId),
|
||||
$unset(
|
||||
TextType.PublicForumMessage.key,
|
||||
|
|
|
@ -2,55 +2,58 @@ package lila.video
|
|||
|
||||
import play.api.libs.ws.WSClient
|
||||
import play.api.{ Mode, Configuration }
|
||||
import com.softwaremill.macwire._
|
||||
import io.methvin.play.autoconfig._
|
||||
import play.api.Configuration
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import lila.common.CollName
|
||||
import lila.common.config._
|
||||
|
||||
@Module
|
||||
private class VideoConfig(
|
||||
@ConfigName("collection.video") val videoColl: CollName,
|
||||
@ConfigName("collection.view") val viewColl: CollName,
|
||||
@ConfigName("sheet.url") val sheetUrl: String,
|
||||
@ConfigName("sheet.delay") val sheetDelay: FiniteDuration,
|
||||
@ConfigName("youtube.url") val youtubeUrl: String,
|
||||
@ConfigName("youtube.api_key") val youtubeApiKey: Secret,
|
||||
@ConfigName("youtube.max") val youtubeMax: Max,
|
||||
@ConfigName("youtube.delay") val youtubeDelay: FiniteDuration
|
||||
)
|
||||
|
||||
final class Env(
|
||||
appConfig: Configuration,
|
||||
ws: WSClient,
|
||||
scheduler: akka.actor.Scheduler,
|
||||
db: lila.db.Env,
|
||||
asyncCache: lila.memo.AsyncCache.Builder,
|
||||
ws: WSClient,
|
||||
mode: Mode
|
||||
) {
|
||||
)(implicit system: akka.actor.ActorSystem) {
|
||||
|
||||
private val config = appConfig.get[Configuration]("video")
|
||||
private val CollectionVideo = config.get[CollName]("collection.video")
|
||||
private val CollectionView = config.get[CollName]("collection.view")
|
||||
private val SheetUrl = config.get[String]("sheet.url")
|
||||
private val SheetDelay = config.get[FiniteDuration]("sheet.delay")
|
||||
private val YoutubeUrl = config.get[String]("youtube.url")
|
||||
private val YoutubeApiKey = config.get[String]("youtube.api_key")
|
||||
private val YoutubeMax = config.get[Int]("youtube.max")
|
||||
private val YoutubeDelay = config.get[FiniteDuration]("youtube.delay")
|
||||
|
||||
private lazy val videoColl = db(CollectionVideo)
|
||||
private lazy val viewColl = db(CollectionView)
|
||||
private val config = appConfig.get[VideoConfig]("video")(AutoConfig.loader)
|
||||
|
||||
lazy val api = new VideoApi(
|
||||
asyncCache = asyncCache,
|
||||
videoColl = videoColl,
|
||||
viewColl = viewColl
|
||||
videoColl = db(config.videoColl),
|
||||
viewColl = db(config.viewColl)
|
||||
)
|
||||
|
||||
private lazy val sheet = new Sheet(ws, SheetUrl, api)
|
||||
private lazy val sheet = new Sheet(ws, config.sheetUrl, api)
|
||||
|
||||
private lazy val youtube = new Youtube(
|
||||
ws = ws,
|
||||
url = YoutubeUrl,
|
||||
apiKey = YoutubeApiKey,
|
||||
max = YoutubeMax,
|
||||
url = config.youtubeUrl,
|
||||
apiKey = config.youtubeApiKey,
|
||||
max = config.youtubeMax,
|
||||
api = api
|
||||
)
|
||||
|
||||
if (mode == Mode.Prod) {
|
||||
scheduler.scheduleWithFixedDelay(SheetDelay, SheetDelay) { () =>
|
||||
scheduler.scheduleWithFixedDelay(config.sheetDelay * 2, config.sheetDelay) { () =>
|
||||
sheet.fetchAll logFailure logger nevermind
|
||||
}
|
||||
|
||||
scheduler.scheduleWithFixedDelay(YoutubeDelay, YoutubeDelay) { () =>
|
||||
scheduler.scheduleWithFixedDelay(config.youtubeDelay * 2, config.youtubeDelay) { () =>
|
||||
youtube.updateAll logFailure logger nevermind
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ private[video] final class VideoApi(
|
|||
|
||||
object video {
|
||||
|
||||
private val maxPerPage = lila.common.MaxPerPage(18)
|
||||
private val maxPerPage = lila.common.config.MaxPerPage(18)
|
||||
|
||||
def find(id: Video.ID): Fu[Option[Video]] =
|
||||
videoColl.ext.find($id(id)).uno[Video]
|
||||
|
|
|
@ -5,11 +5,13 @@ import play.api.libs.json._
|
|||
import play.api.libs.ws.WSClient
|
||||
import scala.concurrent.Future
|
||||
|
||||
import lila.common.config._
|
||||
|
||||
private[video] final class Youtube(
|
||||
ws: WSClient,
|
||||
url: String,
|
||||
apiKey: String,
|
||||
max: Int,
|
||||
apiKey: Secret,
|
||||
max: Max,
|
||||
api: VideoApi
|
||||
) {
|
||||
|
||||
|
@ -40,10 +42,10 @@ private[video] final class Youtube(
|
|||
}
|
||||
|
||||
private def fetch: Fu[List[Entry]] = api.video.allIds flatMap { ids =>
|
||||
ws.url(url).withQueryString(
|
||||
"id" -> scala.util.Random.shuffle(ids).take(max).mkString(","),
|
||||
ws.url(url).withQueryStringParameters(
|
||||
"id" -> scala.util.Random.shuffle(ids).take(max.value).mkString(","),
|
||||
"part" -> "id,statistics,snippet,contentDetails",
|
||||
"key" -> apiKey
|
||||
"key" -> apiKey.value
|
||||
).get() flatMap {
|
||||
case res if res.status == 200 => readEntries reads res.json match {
|
||||
case JsError(err) => fufail(err.toString)
|
||||
|
|
Loading…
Reference in New Issue