more WIP
parent
5a8f45ff99
commit
b7a77cc3f4
|
@ -15,16 +15,16 @@ trait RequestGetter {
|
|||
req.queryString get name flatMap (_.headOption) filter (_.nonEmpty)
|
||||
|
||||
protected def getInt(name: String)(implicit ctx: UserContext) =
|
||||
get(name) flatMap parseIntOption
|
||||
get(name) flatMap (_.toIntOption)
|
||||
|
||||
protected def getInt(name: String, req: RequestHeader): Option[Int] =
|
||||
req.queryString get name flatMap (_.headOption) flatMap parseIntOption
|
||||
req.queryString get name flatMap (_.headOption) flatMap (_.toIntOption)
|
||||
|
||||
protected def getLong(name: String)(implicit ctx: UserContext) =
|
||||
get(name) flatMap parseLongOption
|
||||
get(name) flatMap (_.toLongOption)
|
||||
|
||||
protected def getLong(name: String, req: RequestHeader) =
|
||||
get(name, req) flatMap parseLongOption
|
||||
get(name, req) flatMap (_.toLongOption)
|
||||
|
||||
protected def getBool(name: String)(implicit ctx: UserContext) =
|
||||
(getInt(name) exists trueish) || (get(name) exists trueish)
|
||||
|
|
|
@ -32,14 +32,14 @@ trait StringHelper { self: NumberHelper =>
|
|||
val rendered = s.render
|
||||
rendered match {
|
||||
case NumberFirstRegex(number, html) => frag(
|
||||
strong((~parseIntOption(number)).localize),
|
||||
strong((~number.toIntOption).localize),
|
||||
br,
|
||||
raw(html)
|
||||
)
|
||||
case NumberLastRegex(n) if rendered.length > n.length + 1 => frag(
|
||||
raw(rendered.dropRight(n.length + 1)),
|
||||
br,
|
||||
strong((~parseIntOption(n)).localize)
|
||||
strong((~n.toIntOption).localize)
|
||||
)
|
||||
case h => raw(h.replaceIf('\n', "<br>"))
|
||||
}
|
||||
|
|
|
@ -110,7 +110,7 @@ lazy val evaluation = module("evaluation", Seq(
|
|||
)
|
||||
|
||||
lazy val common = module("common", Seq()).settings(
|
||||
libraryDependencies ++= provided(play.api, kamon.core, scalatags, ws, jodaForms) ++ Seq(scaffeine) ++ reactivemongo.bundle
|
||||
libraryDependencies ++= provided(play.api, kamon.core, scalatags, jodaForms) ++ Seq(scaffeine) ++ reactivemongo.bundle
|
||||
)
|
||||
|
||||
lazy val rating = module("rating", Seq(common, db, memo)).settings(
|
||||
|
|
|
@ -58,8 +58,8 @@ object Info {
|
|||
|
||||
def start(ply: Int) = Info(ply, Eval.initial, Nil)
|
||||
|
||||
private def strCp(s: String) = parseIntOption(s) map Cp.apply
|
||||
private def strMate(s: String) = parseIntOption(s) map Mate.apply
|
||||
private def strCp(s: String) = s.toIntOption map Cp.apply
|
||||
private def strMate(s: String) = s.toIntOption map Mate.apply
|
||||
|
||||
private def decode(ply: Int, str: String): Option[Info] = str.split(separator) match {
|
||||
case Array() => Info(ply, Eval.empty).some
|
||||
|
|
|
@ -77,7 +77,7 @@ sealed trait Context extends lila.user.UserContextWrapper {
|
|||
def requiresFingerprint = isAuth && !pageData.hasFingerprint
|
||||
|
||||
def zoom: Int = {
|
||||
req.session get "zoom2" flatMap parseIntOption map (_ - 100) filter (0 <=) filter (100 >=)
|
||||
req.session get "zoom2" flatMap (_.toIntOption) map (_ - 100) filter (0 <=) filter (100 >=)
|
||||
} | 85
|
||||
}
|
||||
|
||||
|
|
|
@ -56,8 +56,8 @@ object Mobile {
|
|||
|
||||
def requestVersion(req: RequestHeader): Option[ApiVersion] = {
|
||||
(req.headers.get(HeaderNames.ACCEPT), req.path) match {
|
||||
case (Some(HeaderPattern(v)), _) => parseIntOption(v) map ApiVersion.apply
|
||||
case (_, PathPattern(v)) => parseIntOption(v) map ApiVersion.apply
|
||||
case (Some(HeaderPattern(v)), _) => v.toIntOption map ApiVersion.apply
|
||||
case (_, PathPattern(v)) => v.toIntOption map ApiVersion.apply
|
||||
case _ => none
|
||||
}
|
||||
} filter acceptedVersions.contains
|
||||
|
|
|
@ -18,16 +18,16 @@ object Youtube {
|
|||
|
||||
private def parseSeconds(text: String) = text match {
|
||||
case HourMinSecRegex(hourS, minS, secS) => for {
|
||||
hour <- parseIntOption(hourS)
|
||||
min <- parseIntOption(minS)
|
||||
sec <- parseIntOption(secS)
|
||||
hour <- hourS.toIntOption
|
||||
min <- minS.toIntOption
|
||||
sec <- secS.toIntOption
|
||||
} yield 3600 * hour + 60 * min + sec
|
||||
case MinSecRegex(minS, secS) => for {
|
||||
min <- parseIntOption(minS)
|
||||
sec <- parseIntOption(secS)
|
||||
min <- minS.toIntOption
|
||||
sec <- secS.toIntOption
|
||||
} yield 60 * min + sec
|
||||
case SecRegex(secS) => for {
|
||||
sec <- parseIntOption(secS)
|
||||
sec <- secS.toIntOption
|
||||
} yield sec
|
||||
case _ => None
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package lila.common
|
||||
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.{ Future => ScalaFu }
|
||||
|
||||
object Future {
|
||||
|
||||
|
@ -19,9 +20,11 @@ object Future {
|
|||
}
|
||||
}
|
||||
|
||||
def filter[A](list: List[A])(f: A => Fu[Boolean]): Fu[List[A]] = list.map {
|
||||
element => f(element) dmap (_ option element)
|
||||
}.sequenceFu.dmap(_.flatten)
|
||||
def filter[A](list: List[A])(f: A => Fu[Boolean]): Fu[List[A]] = ScalaFu.sequence {
|
||||
list.map {
|
||||
element => f(element) dmap (_ option element)
|
||||
}
|
||||
}.dmap(_.flatten)
|
||||
|
||||
def filterNot[A](list: List[A])(f: A => Fu[Boolean]): Fu[List[A]] =
|
||||
filter(list)(a => !f(a))
|
||||
|
|
|
@ -42,8 +42,6 @@ trait Lilaisms
|
|||
@inline implicit def toPimpedFutureBoolean(f: Fu[Boolean]) = new PimpedFutureBoolean(f)
|
||||
@inline implicit def toPimpedFutureOption[A](f: Fu[Option[A]]) = new PimpedFutureOption(f)
|
||||
@inline implicit def toPimpedFutureValid[A](f: Fu[Valid[A]]) = new PimpedFutureValid(f)
|
||||
@inline implicit def toPimpedIterableFuture[A, M[X] <: IterableOnce[X]](t: M[Fu[A]]) =
|
||||
new PimpedIterableFuture(t)
|
||||
|
||||
@inline implicit def toPimpedJsObject(jo: JsObject) = new PimpedJsObject(jo)
|
||||
@inline implicit def toPimpedJsValue(jv: JsValue) = new PimpedJsValue(jv)
|
||||
|
|
|
@ -38,22 +38,6 @@ trait PackageObject extends Lilaisms {
|
|||
def unapply[A, B](x: Tuple2[A, B]): Option[Tuple2[A, B]] = Some(x)
|
||||
}
|
||||
|
||||
@deprecated
|
||||
def parseIntOption(str: String): Option[Int] =
|
||||
str.toIntOption
|
||||
|
||||
@deprecated
|
||||
def parseFloatOption(str: String): Option[Float] =
|
||||
Try(java.lang.Float.parseFloat(str)).toOption
|
||||
|
||||
@deprecated
|
||||
def parseLongOption(str: String): Option[Long] =
|
||||
Try(java.lang.Long.parseLong(str)).toOption
|
||||
|
||||
@deprecated
|
||||
def parseDoubleOption(str: String): Option[Double] =
|
||||
Try(java.lang.Double.parseDouble(str)).toOption
|
||||
|
||||
def intBox(in: Range.Inclusive)(v: Int): Int =
|
||||
math.max(in.start, math.min(v, in.end))
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package lila.base
|
|||
|
||||
import LilaTypes._
|
||||
import ornicar.scalalib.Zero
|
||||
import scala.collection.BuildFrom
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.{ Future, ExecutionContext }
|
||||
|
@ -175,10 +176,3 @@ final class PimpedFutureValid[A](private val fua: Fu[Valid[A]]) extends AnyVal {
|
|||
_.fold[Fu[A]](fufail(_), fuccess(_))
|
||||
}(ExecutionContext.parasitic)
|
||||
}
|
||||
|
||||
final class PimpedIterableFuture[A, M[X] <: IterableOnce[X]](private val t: M[Fu[A]]) extends AnyVal {
|
||||
import scala.collection.generic.CanBuildFrom
|
||||
|
||||
def sequenceFu(implicit cbf: CanBuildFrom[M[Fu[A]], A, M[A]]): Fu[M[A]] =
|
||||
Future.sequence(t)
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ trait AdapterLike[A] {
|
|||
|
||||
def slice(offset: Int, length: Int) =
|
||||
AdapterLike.this.slice(offset, length) flatMap { results =>
|
||||
results.map(f).sequenceFu
|
||||
scala.concurrent.Future sequence results.map(f)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ final class Paginator[A] private[paginator] (
|
|||
withCurrentPageResults(currentPageResults map f)
|
||||
|
||||
def mapFutureResults[B](f: A => Fu[B]): Fu[Paginator[B]] =
|
||||
currentPageResults.map(f).sequenceFu map withCurrentPageResults
|
||||
scala.concurrent.Future.sequence(currentPageResults.map(f)) map withCurrentPageResults
|
||||
}
|
||||
|
||||
object Paginator {
|
||||
|
|
|
@ -17,8 +17,8 @@ private object BSONHandlers {
|
|||
implicit val PvsHandler = new BSONHandler[BSONString, NonEmptyList[Pv]] {
|
||||
private def scoreWrite(s: Score): String = s.value.fold(_.value.toString, m => s"#${m.value}")
|
||||
private def scoreRead(str: String): Option[Score] =
|
||||
if (str startsWith "#") parseIntOption(str drop 1) map { m => Score mate Mate(m) }
|
||||
else parseIntOption(str) map { c => Score cp Cp(c) }
|
||||
if (str startsWith "#") str.drop(1).toIntOption map { m => Score mate Mate(m) }
|
||||
else str.toIntOption map { c => Score cp Cp(c) }
|
||||
private def movesWrite(moves: Moves): String = Uci writeListPiotr moves.value.toList
|
||||
private def movesRead(str: String): Option[Moves] =
|
||||
Uci readListPiotr str flatMap (_.toNel) map Moves.apply
|
||||
|
@ -45,7 +45,7 @@ private object BSONHandlers {
|
|||
def read(bs: BSONString): Id = bs.value split ':' match {
|
||||
case Array(fen) => Id(chess.variant.Standard, SmallFen raw fen)
|
||||
case Array(variantId, fen) => Id(
|
||||
parseIntOption(variantId) flatMap chess.variant.Variant.apply err s"Invalid evalcache variant $variantId",
|
||||
variantId.toIntOption flatMap chess.variant.Variant.apply err s"Invalid evalcache variant $variantId",
|
||||
SmallFen raw fen
|
||||
)
|
||||
case _ => sys error s"Invalid evalcache id ${bs.value}"
|
||||
|
|
|
@ -29,7 +29,7 @@ final class FishnetRedis(
|
|||
|
||||
case Array(gameId, plyS, uci) => for {
|
||||
move <- Uci(uci)
|
||||
ply <- parseIntOption(plyS)
|
||||
ply <- plyS.toIntOption
|
||||
} Bus.publish(Tell(gameId, FishnetPlay(move, ply)), 'roundMapTell)
|
||||
case _ =>
|
||||
}
|
||||
|
|
|
@ -53,8 +53,8 @@ object JsonApi {
|
|||
threads: Option[String],
|
||||
hash: Option[String]
|
||||
) {
|
||||
def threadsInt = threads flatMap parseIntOption
|
||||
def hashInt = hash flatMap parseIntOption
|
||||
def threadsInt = threads flatMap (_.toIntOption)
|
||||
def hashInt = hash flatMap (_.toIntOption)
|
||||
}
|
||||
|
||||
case class Acquire(
|
||||
|
|
|
@ -61,7 +61,7 @@ case class Player(
|
|||
def withName(name: String) = copy(name = name.some)
|
||||
|
||||
def nameSplit: Option[(String, Option[Int])] = name map {
|
||||
case Player.nameSplitRegex(n, r) => n -> parseIntOption(r)
|
||||
case Player.nameSplitRegex(n, r) => n -> r.toIntOption
|
||||
case n => n -> none
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ object History {
|
|||
|
||||
private[history] implicit val RatingsMapReader = new BSONDocumentReader[RatingsMap] {
|
||||
def read(doc: BSONDocument): RatingsMap = doc.stream.flatMap {
|
||||
case scala.util.Success(BSONElement(k, BSONInteger(v))) => parseIntOption(k) map (_ -> v)
|
||||
case scala.util.Success(BSONElement(k, BSONInteger(v))) => k.toIntOption map (_ -> v)
|
||||
case _ => none[(Int, Int)]
|
||||
}.toList sortBy (_._1)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import com.github.benmanes.caffeine.cache._
|
|||
import ornicar.scalalib.Zero
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
import scala.collection.JavaConverters._
|
||||
import scala.jdk.CollectionConverters._
|
||||
import scala.concurrent.duration.FiniteDuration
|
||||
import scala.concurrent.Promise
|
||||
|
||||
|
|
|
@ -2,8 +2,14 @@ package lila.hub
|
|||
|
||||
import akka.actor._
|
||||
import com.typesafe.config.Config
|
||||
import play.api.Configuration
|
||||
|
||||
final class Env(config: Config, system: ActorSystem) {
|
||||
final class Env(
|
||||
appConfig: Configuration,
|
||||
system: ActorSystem
|
||||
) {
|
||||
|
||||
val config = appConfig.get[Config]("hub")
|
||||
|
||||
val gameSearch = select("actor.game.search")
|
||||
val renderer = select("actor.renderer")
|
||||
|
@ -23,11 +29,3 @@ final class Env(config: Config, system: ActorSystem) {
|
|||
private def select(name: String) =
|
||||
system.actorSelection("/user/" + config.getString(name))
|
||||
}
|
||||
|
||||
object Env {
|
||||
|
||||
lazy val current = "hub" boot new Env(
|
||||
config = lila.common.PlayApp loadConfig "hub",
|
||||
system = lila.common.PlayApp.system
|
||||
)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import com.github.benmanes.caffeine.cache._
|
|||
import ornicar.scalalib.Zero
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
import scala.collection.JavaConverters._
|
||||
import scala.jdk.CollectionConverters._
|
||||
import scala.concurrent.duration.FiniteDuration
|
||||
import scala.concurrent.Promise
|
||||
|
||||
|
|
|
@ -128,20 +128,20 @@ object Dimension {
|
|||
}
|
||||
|
||||
def valueByKey[X](d: Dimension[X], key: String): Option[X] = d match {
|
||||
case Period => parseIntOption(key) map lila.insight.Period.apply
|
||||
case Period => key.toIntOption map lila.insight.Period.apply
|
||||
case Date => None
|
||||
case Perf => PerfType.byKey get key
|
||||
case Phase => parseIntOption(key) flatMap lila.insight.Phase.byId.get
|
||||
case Result => parseIntOption(key) flatMap lila.insight.Result.byId.get
|
||||
case Termination => parseIntOption(key) flatMap lila.insight.Termination.byId.get
|
||||
case Phase => key.toIntOption flatMap lila.insight.Phase.byId.get
|
||||
case Result => key.toIntOption flatMap lila.insight.Result.byId.get
|
||||
case Termination => key.toIntOption flatMap lila.insight.Termination.byId.get
|
||||
case Color => chess.Color(key)
|
||||
case Opening => EcopeningDB.allByEco get key
|
||||
case OpponentStrength => parseIntOption(key) flatMap RelativeStrength.byId.get
|
||||
case OpponentStrength => key.toIntOption flatMap RelativeStrength.byId.get
|
||||
case PieceRole => chess.Role.all.find(_.name == key)
|
||||
case MovetimeRange => parseIntOption(key) flatMap lila.insight.MovetimeRange.byId.get
|
||||
case MyCastling | OpCastling => parseIntOption(key) flatMap lila.insight.Castling.byId.get
|
||||
case MovetimeRange => key.toIntOption flatMap lila.insight.MovetimeRange.byId.get
|
||||
case MyCastling | OpCastling => key.toIntOption flatMap lila.insight.Castling.byId.get
|
||||
case QueenTrade => lila.insight.QueenTrade(key == "true").some
|
||||
case MaterialRange => parseIntOption(key) flatMap lila.insight.MaterialRange.byId.get
|
||||
case MaterialRange => key.toIntOption flatMap lila.insight.MaterialRange.byId.get
|
||||
}
|
||||
|
||||
def valueToJson[X](d: Dimension[X])(v: X): play.api.libs.json.JsObject = {
|
||||
|
|
|
@ -65,7 +65,7 @@ object SettingStore {
|
|||
case "off" | "no" | "false" | "0" => false.some
|
||||
case _ => none
|
||||
})
|
||||
implicit val intReader = new StringReader[Int](parseIntOption)
|
||||
implicit val intReader = new StringReader[Int](_.toIntOption)
|
||||
implicit val stringReader = new StringReader[String](some)
|
||||
def fromIso[A](iso: lila.common.Iso[String, A]) = new StringReader[A](v => iso.from(v).some)
|
||||
}
|
||||
|
|
|
@ -23,14 +23,14 @@ object PracticeGoal {
|
|||
def apply(chapter: lila.study.Chapter): PracticeGoal =
|
||||
chapter.tags(_.Termination).map(v => MultiSpaceR.replaceAllIn(v.trim, " ")).flatMap {
|
||||
case MateR() => Mate.some
|
||||
case MateInR(movesStr) => parseIntOption(movesStr) map MateIn.apply
|
||||
case DrawInR(movesStr) => parseIntOption(movesStr) map DrawIn.apply
|
||||
case EqualInR(movesStr) => parseIntOption(movesStr) map EqualIn.apply
|
||||
case MateInR(movesStr) => movesStr.toIntOption map MateIn.apply
|
||||
case DrawInR(movesStr) => movesStr.toIntOption map DrawIn.apply
|
||||
case EqualInR(movesStr) => movesStr.toIntOption map EqualIn.apply
|
||||
case EvalInR(cpStr, movesStr) => for {
|
||||
cp <- parseIntOption(cpStr)
|
||||
moves <- parseIntOption(movesStr)
|
||||
cp <- cpStr.toIntOption
|
||||
moves <- movesStr.toIntOption
|
||||
} yield EvalIn(cp, moves)
|
||||
case PromotionR(cpStr) => parseIntOption(cpStr) map Promotion.apply
|
||||
case PromotionR(cpStr) => cpStr.toIntOption map Promotion.apply
|
||||
case _ => none
|
||||
} | Mate // default to mate
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package lila.push
|
||||
|
||||
import akka.actor._
|
||||
import collection.JavaConverters._
|
||||
import scala.jdk.CollectionConverters._
|
||||
import com.google.auth.oauth2.{ GoogleCredentials, ServiceAccountCredentials }
|
||||
import com.typesafe.config.Config
|
||||
import play.api.Play
|
||||
|
|
|
@ -83,7 +83,7 @@ final class Env(
|
|||
|
||||
def cli = new lila.common.Cli {
|
||||
def process = {
|
||||
case "puzzle" :: "disable" :: id :: Nil => parseIntOption(id) ?? { id =>
|
||||
case "puzzle" :: "disable" :: id :: Nil => id.toIntOption ?? { id =>
|
||||
api.puzzle disable id inject "Done"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ case class Puzzle(
|
|||
|
||||
// ply after "initial move" when we start solving
|
||||
def initialPly: Int = {
|
||||
fen.split(' ').lastOption flatMap parseIntOption map { move =>
|
||||
fen.split(' ').lastOption flatMap (_.toIntOption) map { move =>
|
||||
move * 2 - color.fold(0, 1)
|
||||
}
|
||||
} | 0
|
||||
|
|
|
@ -19,7 +19,7 @@ object RatingFactor {
|
|||
s.split(separator).toList.map(_.trim.split('=')) flatMap {
|
||||
case Array(ptk, fs) => for {
|
||||
pt <- PerfType(ptk)
|
||||
f <- parseDoubleOption(fs)
|
||||
f <- fs.toDoubleOption
|
||||
} yield pt -> RatingFactor(f)
|
||||
case _ => None
|
||||
} toMap
|
||||
|
|
|
@ -28,9 +28,9 @@ object RatingRange {
|
|||
|
||||
// ^\d{3,4}\-\d{3,4}$
|
||||
def apply(from: String): Option[RatingRange] = for {
|
||||
min <- parseIntOption(from takeWhile ('-' !=))
|
||||
min <- from.takeWhile('-' !=).toIntOption
|
||||
if acceptable(min)
|
||||
max <- parseIntOption(from dropWhile ('-' !=) tail)
|
||||
max <- from.dropWhile('-' !=).tail.toIntOption
|
||||
if acceptable(max)
|
||||
if min < max
|
||||
} yield RatingRange(min, max)
|
||||
|
|
|
@ -104,7 +104,7 @@ object Relay {
|
|||
case class Upstream(url: String) extends AnyVal {
|
||||
def isLocal = url.contains("://127.0.0.1") || url.contains("://localhost")
|
||||
def withRound = url.split(" ", 2) match {
|
||||
case Array(u, round) => UpstreamWithRound(u, parseIntOption(round))
|
||||
case Array(u, round) => UpstreamWithRound(u, round.toIntOption)
|
||||
case _ => UpstreamWithRound(url, none)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -208,7 +208,7 @@ private object RelayFetch {
|
|||
val strMoves = moves.map(_ split ' ') map { move =>
|
||||
chess.format.pgn.Move(
|
||||
san = ~move.headOption,
|
||||
secondsLeft = move.lift(1).map(_.takeWhile(_.isDigit)) flatMap parseIntOption
|
||||
secondsLeft = move.lift(1).map(_.takeWhile(_.isDigit)) flatMap (_.toIntOption)
|
||||
)
|
||||
} mkString " "
|
||||
s"${extraTags}\n\n$strMoves"
|
||||
|
|
|
@ -208,8 +208,8 @@ object RoundSocket {
|
|||
case "r/bye" => Bye(Game.FullId(raw.args)).some
|
||||
case "r/hold" => raw.get(4) {
|
||||
case Array(fullId, ip, meanS, sdS) => for {
|
||||
mean <- parseIntOption(meanS)
|
||||
sd <- parseIntOption(sdS)
|
||||
mean <- meanS.toIntOption
|
||||
sd <- sdS.toIntOption
|
||||
} yield HoldAlert(FullId(fullId), IpAddress(ip), mean, sd)
|
||||
}
|
||||
case "r/report" => raw.get(4) {
|
||||
|
@ -228,7 +228,7 @@ object RoundSocket {
|
|||
|
||||
private def centis(s: String): Option[Centis] =
|
||||
if (s == "-") none
|
||||
else parseIntOption(s) map Centis.apply
|
||||
else s.toIntOption map Centis.apply
|
||||
|
||||
private def readColor(s: String) =
|
||||
if (s == "w") Some(White)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package lila.search
|
||||
|
||||
import play.api.libs.json._
|
||||
import play.api.libs.ws._
|
||||
|
||||
sealed trait ESClient {
|
||||
|
||||
|
@ -18,14 +19,12 @@ sealed trait ESClient {
|
|||
}
|
||||
|
||||
final class ESClientHttp(
|
||||
endpoint: String,
|
||||
val index: Index,
|
||||
writeable: Boolean
|
||||
ws: WSClient,
|
||||
config: SearchConfig,
|
||||
val index: Index
|
||||
) extends ESClient {
|
||||
import play.api.libs.ws.WS
|
||||
import play.api.Play.current
|
||||
|
||||
def store(id: Id, doc: JsObject) = writeable ?? monitor("store") {
|
||||
def store(id: Id, doc: JsObject) = config.writeable ?? monitor("store") {
|
||||
HTTP(s"store/${index.name}/${id.value}", doc)
|
||||
}
|
||||
|
||||
|
@ -37,10 +36,10 @@ final class ESClientHttp(
|
|||
HTTP(s"count/${index.name}", query, CountResponse.apply)
|
||||
}
|
||||
|
||||
def deleteById(id: lila.search.Id) = writeable ??
|
||||
def deleteById(id: lila.search.Id) = config.writeable ??
|
||||
HTTP(s"delete/id/${index.name}/${id.value}", Json.obj())
|
||||
|
||||
def deleteByIds(ids: List[lila.search.Id]) = writeable ??
|
||||
def deleteByIds(ids: List[lila.search.Id]) = config.writeable ??
|
||||
HTTP(s"delete/ids/${index.name}", Json.obj("ids" -> ids.map(_.value)))
|
||||
|
||||
def putMapping =
|
||||
|
@ -55,7 +54,7 @@ final class ESClientHttp(
|
|||
HTTP(s"refresh/${index.name}", Json.obj())
|
||||
|
||||
private[search] def HTTP[D: Writes, R](url: String, data: D, read: String => R): Fu[R] =
|
||||
WS.url(s"$endpoint/$url").post(Json toJson data) flatMap {
|
||||
ws.url(s"${config.endpoint}/$url").post(Json toJson data) flatMap {
|
||||
case res if res.status == 200 => fuccess(read(res.body))
|
||||
case res => fufail(s"$url ${res.status}")
|
||||
}
|
||||
|
|
|
@ -1,28 +1,21 @@
|
|||
package lila.search
|
||||
|
||||
import akka.actor.ActorSystem
|
||||
import com.typesafe.config.Config
|
||||
import com.softwaremill.macwire._
|
||||
import io.methvin.play.autoconfig._
|
||||
import play.api.Configuration
|
||||
import play.api.libs.ws._
|
||||
|
||||
final class Env(
|
||||
config: Config,
|
||||
appConfig: Configuration,
|
||||
system: ActorSystem,
|
||||
scheduler: lila.common.Scheduler
|
||||
ws: WSClient
|
||||
) {
|
||||
val config = appConfig.get[SearchConfig]("search")(AutoConfig.loader)
|
||||
|
||||
private val Enabled = config getBoolean "enabled"
|
||||
private val Writeable = config getBoolean "writeable"
|
||||
private val Endpoint = config getString "endpoint"
|
||||
def makeHttp(index: Index): ESClientHttp = wire[ESClientHttp]
|
||||
|
||||
val makeClient = (index: Index) =>
|
||||
if (Enabled) new ESClientHttp(Endpoint, index, Writeable)
|
||||
else new ESClientStub
|
||||
}
|
||||
|
||||
object Env {
|
||||
|
||||
lazy val current = "search" boot new Env(
|
||||
config = lila.common.PlayApp loadConfig "search",
|
||||
system = lila.common.PlayApp.system,
|
||||
scheduler = lila.common.PlayApp.scheduler
|
||||
)
|
||||
if (config.enabled) makeHttp(index)
|
||||
else wire[ESClientStub]
|
||||
}
|
||||
|
|
|
@ -17,5 +17,5 @@ object SearchResponse {
|
|||
case class CountResponse(count: Int) extends AnyVal
|
||||
|
||||
object CountResponse {
|
||||
def apply(txt: String): CountResponse = CountResponse(~parseIntOption(txt))
|
||||
def apply(txt: String): CountResponse = CountResponse(~txt.toIntOption)
|
||||
}
|
||||
|
|
|
@ -7,4 +7,10 @@ package object search extends PackageObject {
|
|||
val format = "YYYY-MM-dd HH:mm:ss"
|
||||
val formatter: DateTimeFormatter = DateTimeFormat forPattern format
|
||||
}
|
||||
|
||||
case class SearchConfig(
|
||||
enabled: Boolean,
|
||||
writeable: Boolean,
|
||||
endpoint: String
|
||||
)
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ final class IpIntel(asyncCache: lila.memo.AsyncCache.Builder, contactEmail: Emai
|
|||
f = ip => {
|
||||
val url = s"https://check.getipintel.net/check.php?ip=$ip&contact=${contactEmail.value}"
|
||||
WS.url(url).get().map(_.body).mon(_.security.proxy.request.time).flatMap { str =>
|
||||
parseFloatOption(str).fold[Fu[Int]](fufail(s"Invalid ratio ${str.take(140)}")) { ratio =>
|
||||
str.toFloatOption.fold[Fu[Int]](fufail(s"Invalid ratio ${str.take(140)}")) { ratio =>
|
||||
if (ratio < 0) fufail(s"IpIntel error $ratio on $url")
|
||||
else fuccess((ratio * 100).toInt)
|
||||
}
|
||||
|
|
|
@ -29,6 +29,6 @@ private object LoginToken {
|
|||
|
||||
object DateStr {
|
||||
def toStr(date: DateTime) = date.getMillis.toString
|
||||
def toDate(str: String) = parseLongOption(str) map { new DateTime(_) }
|
||||
def toDate(str: String) = str.toLongOption map { new DateTime(_) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,17 +169,17 @@ object RemoteSocket {
|
|||
}.some
|
||||
case "disconnect/sris" => DisconnectSris(commas(raw.args) map Sri.apply).some
|
||||
case "notified/batch" => NotifiedBatch(commas(raw.args)).some
|
||||
case "lag" => raw.all |> { s => s lift 1 flatMap parseIntOption map Centis.apply map { Lag(s(0), _) } }
|
||||
case "lag" => raw.all |> { s => s lift 1 flatMap (_.toIntOption) map Centis.apply map { Lag(s(0), _) } }
|
||||
case "lags" => Lags(commas(raw.args).flatMap {
|
||||
_ split ':' match {
|
||||
case Array(user, l) => parseIntOption(l) map { lag => user -> Centis(lag) }
|
||||
case Array(user, l) => l.toIntOption map { lag => user -> Centis(lag) }
|
||||
case _ => None
|
||||
}
|
||||
}.toMap).some
|
||||
case "friends/batch" => FriendsBatch(commas(raw.args)).some
|
||||
case "tell/sri" => raw.get(3)(tellSriMapper)
|
||||
case "req/response" => raw.get(2) {
|
||||
case Array(reqId, response) => parseIntOption(reqId) map { ReqResponse(_, response) }
|
||||
case Array(reqId, response) => reqId.toIntOption map { ReqResponse(_, response) }
|
||||
}
|
||||
case "boot" => WsBoot.some
|
||||
case _ => none
|
||||
|
|
|
@ -32,9 +32,9 @@ private[study] object CommentParser {
|
|||
private type ClockAndComment = (Option[Centis], String)
|
||||
|
||||
private def readCentis(hours: String, minutes: String, seconds: String): Option[Centis] = for {
|
||||
h <- parseIntOption(hours)
|
||||
m <- parseIntOption(minutes)
|
||||
cs <- parseDoubleOption(seconds) match {
|
||||
h <- hours.toIntOption
|
||||
m <- minutes.toIntOption
|
||||
cs <- seconds.toDoubleOption match {
|
||||
case Some(s) => Some(Maths.roundAt(s * 100, 0).toInt)
|
||||
case _ => none
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ private final class PgnFetch {
|
|||
private val ChessbaseRegex = """chessgames\.com/.*[\?&]gid=(\d+)""".r.unanchored
|
||||
|
||||
def fromUrl(url: String): Fu[Option[Pgn]] = url match {
|
||||
case ChessbaseRegex(id) => parseIntOption(id) ?? downloadChessbase
|
||||
case ChessbaseRegex(id) => id.toIntOption ?? downloadChessbase
|
||||
case _ => fuccess(none)
|
||||
}
|
||||
|
||||
|
|
|
@ -117,8 +117,8 @@ object StudyMultiBoard {
|
|||
wName <- tags(_.White)
|
||||
bName <- tags(_.Black)
|
||||
} yield Color.Map(
|
||||
white = Player(wName, tags(_.WhiteTitle), tags(_.WhiteElo) flatMap parseIntOption),
|
||||
black = Player(bName, tags(_.BlackTitle), tags(_.BlackElo) flatMap parseIntOption)
|
||||
white = Player(wName, tags(_.WhiteTitle), tags(_.WhiteElo) flatMap (_.toIntOption)),
|
||||
black = Player(bName, tags(_.BlackTitle), tags(_.BlackElo) flatMap (_.toIntOption))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ object DataForm {
|
|||
val validVariants = List(Standard, Chess960, KingOfTheHill, ThreeCheck, Antichess, Atomic, Horde, RacingKings, Crazyhouse)
|
||||
|
||||
def guessVariant(from: String): Option[Variant] = validVariants.find { v =>
|
||||
v.key == from || parseIntOption(from).exists(v.id ==)
|
||||
v.key == from || from.toIntOption.exists(v.id ==)
|
||||
}
|
||||
|
||||
def startingPosition(fen: String, variant: Variant): StartingPosition =
|
||||
|
|
|
@ -49,8 +49,8 @@ object Title {
|
|||
private val NewFideProfileUrlRegex = """(?:https?://)ratings\.fide\.com/profile/(\d+)""".r
|
||||
|
||||
def apply(url: String): Fu[Option[Title]] = url.trim match {
|
||||
case FideProfileUrlRegex(id) => parseIntOption(id) ?? fromFideProfile
|
||||
case NewFideProfileUrlRegex(id) => parseIntOption(id) ?? fromFideProfile
|
||||
case FideProfileUrlRegex(id) => id.toIntOption ?? fromFideProfile
|
||||
case NewFideProfileUrlRegex(id) => id.toIntOption ?? fromFideProfile
|
||||
case _ => fuccess(none)
|
||||
}
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ object Sheet {
|
|||
def youtubeId = `gsx$youtubeid`.toString.trim
|
||||
def author = `gsx$youtubeauthor`.toString.trim
|
||||
def title = `gsx$title`.toString.trim
|
||||
def targets = `gsx$target`.toString.split(';').map(_.trim).toList flatMap parseIntOption
|
||||
def targets = `gsx$target`.toString.split(';').map(_.trim).toList flatMap (_.toIntOption)
|
||||
def tags = `gsx$tags`.toString.split(';').map(_.trim.toLowerCase).toList.filter(_.nonEmpty) ::: {
|
||||
if (targets contains 1) List("beginner")
|
||||
else if (targets contains 3) List("advanced")
|
||||
|
@ -98,6 +98,6 @@ object Sheet {
|
|||
def lang = `gsx$language`.toString.trim
|
||||
def ads = `gsx$ads`.toString.trim == "yes"
|
||||
def include = `gsx$include`.toString.trim == "yes"
|
||||
def startTime = ~parseIntOption(`gsx$starttimeinseconds`.toString.trim)
|
||||
def startTime = ~`gsx$starttimeinseconds`.toString.trim.toIntOption
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,9 +24,9 @@ private[video] final class Youtube(
|
|||
def updateAll: Funit = fetch flatMap { entries =>
|
||||
entries.map { entry =>
|
||||
api.video.setMetadata(entry.id, Metadata(
|
||||
views = ~parseIntOption(entry.statistics.viewCount),
|
||||
likes = ~parseIntOption(entry.statistics.likeCount) -
|
||||
~parseIntOption(entry.statistics.dislikeCount),
|
||||
views = ~entry.statistics.viewCount.toIntOption,
|
||||
likes = ~entry.statistics.likeCount.toIntOption -
|
||||
~entry.statistics.dislikeCount.toIntOption,
|
||||
description = entry.snippet.description,
|
||||
duration = Some(entry.contentDetails.seconds),
|
||||
publishedAt = entry.snippet.publishedAt.flatMap { at =>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import com.typesafe.sbt.SbtScalariform.autoImport.scalariformPreferences
|
||||
import play.sbt.Play.autoImport._
|
||||
import play.sbt.PlayImport._
|
||||
import sbt._, Keys._
|
||||
import scalariform.formatter.preferences._
|
||||
|
||||
|
@ -27,7 +27,7 @@ object BuildSettings {
|
|||
.setPreference(DanglingCloseParenthesis, Force)
|
||||
.setPreference(DoubleIndentConstructorArguments, true)
|
||||
|
||||
def defaultDeps = Seq(scalaz, chess, scalalib, jodaTime, macwire) // , specs2, specs2Scalaz)
|
||||
def defaultDeps = Seq(scalaz, chess, scalalib, jodaTime, ws, macwire, autoconfig) // , specs2, specs2Scalaz)
|
||||
|
||||
def compile(deps: ModuleID*): Seq[ModuleID] = deps map (_ % "compile")
|
||||
def provided(deps: ModuleID*): Seq[ModuleID] = deps map (_ % "provided")
|
||||
|
|
|
@ -43,6 +43,7 @@ object Dependencies {
|
|||
val epoll = "io.netty" % "netty-transport-native-epoll" % "4.1.43.Final" classifier "linux-x86_64"
|
||||
val markdown = "com.vladsch.flexmark" % "flexmark-all" % "0.59.58"
|
||||
val macwire = "com.softwaremill.macwire" %% "macros" % "2.3.3" % "provided"
|
||||
val autoconfig = "io.methvin.play" %% "autoconfig-macros" % "0.3.0"
|
||||
|
||||
object reactivemongo {
|
||||
val version = "0.19.1"
|
||||
|
|
Loading…
Reference in New Issue