diff --git a/app/ai/StupidAi.scala b/app/ai/StupidAi.scala index fe519c0fae..2e5c97f246 100644 --- a/app/ai/StupidAi.scala +++ b/app/ai/StupidAi.scala @@ -7,7 +7,7 @@ import game.DbGame import scalaz.effects._ import scala.concurrent.Future -final class StupidAi extends Ai with core.Futuristic { +final class StupidAi extends Ai with common.Futuristic { def play(dbGame: DbGame, pgn: String, initialFen: Option[String]): Future[Valid[(Game, Move)]] = Future { diff --git a/app/controllers/Monitor.scala b/app/controllers/Monitor.scala index cca0dc3703..a1b7fbdbe6 100644 --- a/app/controllers/Monitor.scala +++ b/app/controllers/Monitor.scala @@ -31,7 +31,7 @@ object Monitor extends LilaController { def status = Open { implicit ctx ⇒ Async { - import core.Futuristic.ioToFuture + import common.Futuristic.ioToFuture (~get("key") match { case "elo" ⇒ userRepo.idsAverageElo(usernameMemo.keys).toFuture zip diff --git a/app/controllers/Tournament.scala b/app/controllers/Tournament.scala index 9a9920723e..5d8a64c7b8 100644 --- a/app/controllers/Tournament.scala +++ b/app/controllers/Tournament.scala @@ -5,7 +5,7 @@ import views._ import game.Pov import tournament.{ Created, Started, Finished } import http.Context -import core.Futuristic.ioToFuture +import common.Futuristic.ioToFuture import scalaz.effects._ import play.api.mvc._ diff --git a/app/core/package.scala b/app/core/package.scala new file mode 100644 index 0000000000..d87316a025 --- /dev/null +++ b/app/core/package.scala @@ -0,0 +1,3 @@ +package lila + +package object core extends common.PackageObject diff --git a/app/forum/PostApi.scala b/app/forum/PostApi.scala index 025ff5bc3b..cbf770df9e 100644 --- a/app/forum/PostApi.scala +++ b/app/forum/PostApi.scala @@ -4,7 +4,7 @@ package forum import user.User import http.Context import mod.ModlogApi -import core.Futuristic._ +import common.Futuristic._ import scalaz.effects._ import com.github.ornicar.paginator._ diff --git a/app/forum/TopicRepo.scala b/app/forum/TopicRepo.scala index 227c069e3c..c7623fa346 100644 --- a/app/forum/TopicRepo.scala +++ b/app/forum/TopicRepo.scala @@ -30,7 +30,7 @@ final class TopicRepo( } def nextSlug(categ: Categ, name: String, it: Int = 1): IO[String] = { - val slug = core.String.slugify(name) + (it == 1).fold("", "-" + it) + val slug = common.String.slugify(name) + (it == 1).fold("", "-" + it) byTree(categ.slug, slug) flatMap { _.isDefined.fold( nextSlug(categ, name, it + 1), diff --git a/app/game/Handler.scala b/app/game/Handler.scala index d859acbaac..3ccee23ebf 100644 --- a/app/game/Handler.scala +++ b/app/game/Handler.scala @@ -4,7 +4,7 @@ package game import scalaz.effects._ import scala.concurrent.Future -abstract class Handler(gameRepo: GameRepo) extends core.Futuristic { +abstract class Handler(gameRepo: GameRepo) extends common.Futuristic { protected def attempt[A]( fullId: String, diff --git a/app/importer/Importer.scala b/app/importer/Importer.scala index db6e1e11a2..821d0cf762 100644 --- a/app/importer/Importer.scala +++ b/app/importer/Importer.scala @@ -2,7 +2,7 @@ package lila.app package importer import chess.{ Move, Status } -import core.Futuristic +import common.Futuristic import game.{ DbGame, GameRepo, PovRef } import round.{ Hand, Finisher } diff --git a/app/mod/ModApi.scala b/app/mod/ModApi.scala index 40581699d0..4478df9cc5 100644 --- a/app/mod/ModApi.scala +++ b/app/mod/ModApi.scala @@ -5,7 +5,7 @@ import user.{ User, UserRepo } import elo.EloUpdater import lobby.Messenger import security.{ Firewall, UserSpy, Store ⇒ SecurityStore } -import core.Futuristic._ +import common.Futuristic._ import scalaz.effects._ import play.api.libs.concurrent.Execution.Implicits._ diff --git a/app/package.scala b/app/package.scala index dbd098776b..6262a76002 100644 --- a/app/package.scala +++ b/app/package.scala @@ -1,40 +1,9 @@ import ornicar.scalalib -import play.api.libs.json.JsValue -import play.api.libs.concurrent.Promise -import play.api.libs.iteratee.{ Iteratee, Enumerator } -import play.api.libs.iteratee.Concurrent.Channel -import play.api.Play.current -import scala.concurrent.{ Future, Promise } - import com.novus.salat.{ Context, TypeHintFrequency, StringTypeHintStrategy } import com.mongodb.casbah.commons.conversions.scala.RegisterJodaTimeConversionHelpers -import scalaz.effects.{ io, IO } -import reactivemongo.api.{ DB, Collection } - -package object lila - extends scalalib.Validation - with scalalib.Common - with scalalib.Regex - with scalalib.IO - with scalalib.DateTime - with scalaz.Identitys - with scalaz.NonEmptyLists - with scalaz.Strings - with scalaz.Lists - with scalaz.Zeros - with scalaz.Booleans { - - type JsChannel = Channel[JsValue] - type JsEnumerator = Enumerator[JsValue] - type SocketFuture = Future[(Iteratee[JsValue, _], JsEnumerator)] - - type Fu[A] = Future[A] - type Funit = Fu[Unit] - type LilaDB = DB[Collection] - - val toVoid = (_: Any) ⇒ () +package object lila extends common.PackageObject { // custom salat context implicit val customSalatContext = new Context { @@ -42,41 +11,4 @@ package object lila override val typeHintStrategy = StringTypeHintStrategy(when = TypeHintFrequency.Never) } RegisterJodaTimeConversionHelpers() - - def !![A](msg: String): Valid[A] = msg.failNel[A] - - def nowMillis: Double = System.currentTimeMillis - def nowSeconds: Int = (nowMillis / 1000).toInt - - implicit def richerMap[A, B](m: Map[A, B]) = new { - def +?(bp: (Boolean, (A, B))): Map[A, B] = if (bp._1) m + bp._2 else m - } - - def parseIntOption(str: String): Option[Int] = try { - Some(java.lang.Integer.parseInt(str)) - } - catch { - case e: NumberFormatException ⇒ None - } - - def parseFloatOption(str: String): Option[Float] = try { - Some(java.lang.Float.parseFloat(str)) - } - catch { - case e: NumberFormatException ⇒ None - } - - def intBox(in: Range.Inclusive)(v: Int): Int = - math.max(in.start, math.min(v, in.end)) - - def floatBox(in: Range.Inclusive)(v: Float): Float = - math.max(in.start, math.min(v, in.end)) - - def printToFile(f: java.io.File)(op: java.io.PrintWriter ⇒ Unit): IO[Unit] = io { - val p = new java.io.PrintWriter(f) - try { op(p) } finally { p.close() } - } - - def printToFile(f: String)(op: java.io.PrintWriter ⇒ Unit): IO[Unit] = - printToFile(new java.io.File(f))(op) } diff --git a/app/search/DataForm.scala b/app/search/DataForm.scala index 8d9f784a55..166c7406a5 100644 --- a/app/search/DataForm.scala +++ b/app/search/DataForm.scala @@ -11,7 +11,7 @@ import chess.{ Mode } final class DataForm { - import lila.app.core.Form._ + import lila.common.Form._ val search = Form(mapping( "players" -> mapping( diff --git a/app/search/Query.scala b/app/search/Query.scala index a8d4400dcd..1ed465d738 100644 --- a/app/search/Query.scala +++ b/app/search/Query.scala @@ -81,7 +81,7 @@ case class Query( object Query { - import lila.app.core.Form._ + import lila.common.Form._ val durations = options(List(1, 2, 3, 5, 10, 15, 20, 30), "%d minute{s}") diff --git a/app/setup/Processor.scala b/app/setup/Processor.scala index e6f3fd3f85..231c1133aa 100644 --- a/app/setup/Processor.scala +++ b/app/setup/Processor.scala @@ -21,7 +21,7 @@ final class Processor( pgnRepo: PgnRepo, fisherman: Fisherman, timelinePush: DbGame ⇒ IO[Unit], - ai: () ⇒ Ai) extends core.Futuristic { + ai: () ⇒ Ai) extends common.Futuristic { def filter(config: FilterConfig)(implicit ctx: Context): IO[Unit] = saveConfig(_ withFilter config) diff --git a/app/team/DataForm.scala b/app/team/DataForm.scala index 75e5c79371..6b980c86a2 100644 --- a/app/team/DataForm.scala +++ b/app/team/DataForm.scala @@ -11,7 +11,7 @@ final class DataForm( repo: TeamRepo, captcher: Captcha) { - import lila.app.core.Form._ + import lila.common.Form._ object Fields { val name = "name" -> text(minLength = 3, maxLength = 60) diff --git a/app/team/Team.scala b/app/team/Team.scala index 8e29adfb72..98f29d4779 100644 --- a/app/team/Team.scala +++ b/app/team/Team.scala @@ -45,7 +45,7 @@ object Team { createdAt = DateTime.now, createdBy = createdBy.id) - def nameToId(name: String) = (core.String slugify name) |> { slug ⇒ + def nameToId(name: String) = (common.String slugify name) |> { slug ⇒ // if most chars are not latin, go for random slug (slug.size > (name.size / 2)).fold(slug, Random nextString 8) } diff --git a/app/templating/StringHelper.scala b/app/templating/StringHelper.scala index 89c89003c1..9450ecd46c 100644 --- a/app/templating/StringHelper.scala +++ b/app/templating/StringHelper.scala @@ -11,7 +11,7 @@ trait StringHelper { def netDomain: String - val slugify = core.String.slugify _ + val slugify = common.String.slugify _ def shorten(text: String, length: Int, sep: String = " [...]"): String = { val t = text.replace("\n", " ") diff --git a/app/tournament/DataForm.scala b/app/tournament/DataForm.scala index f0147c8534..e5cb7b869f 100644 --- a/app/tournament/DataForm.scala +++ b/app/tournament/DataForm.scala @@ -10,7 +10,7 @@ import play.api.data.validation.Constraints._ final class DataForm(isDev: Boolean) { - import lila.app.core.Form._ + import lila.common.Form._ val clockTimes = 0 to 7 by 1 val clockTimeDefault = 2 diff --git a/app/tournament/Tournament.scala b/app/tournament/Tournament.scala index ff98b085ee..23755f0eb0 100644 --- a/app/tournament/Tournament.scala +++ b/app/tournament/Tournament.scala @@ -272,7 +272,7 @@ case class RawTournament( object Tournament { - import lila.app.core.Form._ + import lila.common.Form._ def apply( createdBy: User, diff --git a/app/core/Form.scala b/common/Form.scala similarity index 95% rename from app/core/Form.scala rename to common/Form.scala index d881be9856..6146bc2e3a 100644 --- a/app/core/Form.scala +++ b/common/Form.scala @@ -1,5 +1,4 @@ -package lila.app -package core +package lila.common import play.api.data.Forms._ diff --git a/app/core/Futuristic.scala b/common/Futuristic.scala similarity index 97% rename from app/core/Futuristic.scala rename to common/Futuristic.scala index 92a94fb3e5..7071daf756 100644 --- a/app/core/Futuristic.scala +++ b/common/Futuristic.scala @@ -1,5 +1,5 @@ -package lila.app -package core +package lila +package common import play.api.Play.current import play.api.libs.concurrent._ diff --git a/common/PackageObject.scala b/common/PackageObject.scala new file mode 100644 index 0000000000..610d6def42 --- /dev/null +++ b/common/PackageObject.scala @@ -0,0 +1,75 @@ +package lila.common + +import ornicar.scalalib + +import play.api.libs.json.JsValue +import play.api.libs.concurrent.Promise +import play.api.libs.iteratee.{ Iteratee, Enumerator } +import play.api.libs.iteratee.Concurrent.Channel +import play.api.Play.current +import scala.concurrent.{ Future, Promise } + +import scalaz.effects.{ io, IO } + +import reactivemongo.api.{ DB, Collection } + +trait PackageObject + extends scalalib.Validation + with scalalib.Common + with scalalib.Regex + with scalalib.IO + with scalalib.DateTime + with scalaz.Identitys + with scalaz.NonEmptyLists + with scalaz.Strings + with scalaz.Lists + with scalaz.Zeros + with scalaz.Booleans { + + type JsChannel = Channel[JsValue] + type JsEnumerator = Enumerator[JsValue] + type SocketFuture = Future[(Iteratee[JsValue, _], JsEnumerator)] + + type Fu[A] = Future[A] + type Funit = Fu[Unit] + type LilaDB = DB[Collection] + + val toVoid = (_: Any) ⇒ () + + def !![A](msg: String): Valid[A] = msg.failNel[A] + + def nowMillis: Double = System.currentTimeMillis + def nowSeconds: Int = (nowMillis / 1000).toInt + + implicit def richerMap[A, B](m: Map[A, B]) = new { + def +?(bp: (Boolean, (A, B))): Map[A, B] = if (bp._1) m + bp._2 else m + } + + def parseIntOption(str: String): Option[Int] = try { + Some(java.lang.Integer.parseInt(str)) + } + catch { + case e: NumberFormatException ⇒ None + } + + def parseFloatOption(str: String): Option[Float] = try { + Some(java.lang.Float.parseFloat(str)) + } + catch { + case e: NumberFormatException ⇒ None + } + + def intBox(in: Range.Inclusive)(v: Int): Int = + math.max(in.start, math.min(v, in.end)) + + def floatBox(in: Range.Inclusive)(v: Float): Float = + math.max(in.start, math.min(v, in.end)) + + def printToFile(f: java.io.File)(op: java.io.PrintWriter ⇒ Unit): IO[Unit] = io { + val p = new java.io.PrintWriter(f) + try { op(p) } finally { p.close() } + } + + def printToFile(f: String)(op: java.io.PrintWriter ⇒ Unit): IO[Unit] = + printToFile(new java.io.File(f))(op) +} diff --git a/app/core/String.scala b/common/String.scala similarity index 90% rename from app/core/String.scala rename to common/String.scala index cc50207112..526a5b25fd 100644 --- a/app/core/String.scala +++ b/common/String.scala @@ -1,5 +1,5 @@ -package lila.app -package core +package lila +package common import java.text.Normalizer diff --git a/common/build.sbt b/common/build.sbt new file mode 100644 index 0000000000..7f26851bac --- /dev/null +++ b/common/build.sbt @@ -0,0 +1,21 @@ +name := "lila-common" + +organization := "org.lichess" + +scalaVersion := "2.10.0" + +resolvers ++= Seq( + "iliaz.com" at "http://scala.iliaz.com/", + "sonatype" at "http://oss.sonatype.org/content/repositories/releases", + "sonatype snapshots" at "http://oss.sonatype.org/content/repositories/snapshots", + "typesafe.com" at "http://repo.typesafe.com/typesafe/releases/" +) + +libraryDependencies ++= Seq( + "org.scalaz" %% "scalaz-core" % "6.0.4", + "com.github.ornicar" %% "scalalib" % "3.3", + // "play" %% "play" % "2.1.0" % "provided", + "joda-time" % "joda-time" % "2.1", + "org.joda" % "joda-convert" % "1.2", + "org.reactivemongo" %% "reactivemongo" % "0.9-SNAPSHOT" +) diff --git a/common/package.scala b/common/package.scala new file mode 100644 index 0000000000..47f85a0c51 --- /dev/null +++ b/common/package.scala @@ -0,0 +1,5 @@ +package lila + +package object common extends lila.common.PackageObject { + +} diff --git a/game/build.sbt b/game/build.sbt new file mode 100644 index 0000000000..ef9ccbe3f9 --- /dev/null +++ b/game/build.sbt @@ -0,0 +1,21 @@ +name := "lila-game" + +organization := "org.lichess" + +scalaVersion := "2.10.0" + +resolvers ++= Seq( + "iliaz.com" at "http://scala.iliaz.com/", + "sonatype" at "http://oss.sonatype.org/content/repositories/releases", + "sonatype snapshots" at "http://oss.sonatype.org/content/repositories/snapshots", + "typesafe.com" at "http://repo.typesafe.com/typesafe/releases/" +) + +libraryDependencies ++= Seq( + "org.scalaz" %% "scalaz-core" % "6.0.4", + "com.github.ornicar" %% "scalalib" % "3.3", + // "play" %% "play" % "2.1.0" % "provided", + "joda-time" % "joda-time" % "2.1", + "org.joda" % "joda-convert" % "1.2", + "org.reactivemongo" %% "reactivemongo" % "0.9-SNAPSHOT" +) diff --git a/project/Build.scala b/project/Build.scala index 759d4e3603..fe8c54e9b7 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -37,14 +37,13 @@ trait Dependencies { val findbugs = "com.google.code.findbugs" % "jsr305" % "1.3.+" val reactivemongo = "org.reactivemongo" %% "reactivemongo" % "0.9-SNAPSHOT" val playReactivemongo = "play.modules.reactivemongo" %% "play2-reactivemongo" % "0.1-SNAPSHOT" cross CrossVersion.full + val playProvided = "play" %% "play" % "2.1-SNAPSHOT" % "provided" } object ApplicationBuild extends Build with Resolvers with Dependencies { - private val buildSettings = Seq( - shellPrompt := { - (state: State) ⇒ "%s> ".format(Project.extract(state).currentProject.id) - }, + private val buildSettings = Defaults.defaultSettings ++ Seq( + scalaVersion := "2.10.0", scalacOptions := Seq( "-deprecation", "-unchecked", @@ -57,8 +56,7 @@ object ApplicationBuild extends Build with Resolvers with Dependencies { scalaz, scalalib, hasher, config, salat, guava, apache, scalaTime, paginator, paginatorSalat, csv, jgit, actuarius, scalastic, findbugs, reactivemongo, playReactivemongo - ), settings = Defaults.defaultSettings ++ buildSettings).settings( - scalaVersion := "2.10.0", + ), settings = buildSettings).settings( templatesImport ++= Seq( "lila.game.{ DbGame, DbPlayer, Pov }", "lila.user.User", @@ -68,11 +66,22 @@ object ApplicationBuild extends Build with Resolvers with Dependencies { "lila.http.Context", "com.github.ornicar.paginator.Paginator"), resolvers ++= Seq(awesomepom, sgodbillon, iliaz, sonatype, sonatypeS, typesafe, t2v, guice, jgitMaven, christophs) - ) dependsOn scalachess aggregate scalachess + ) dependsOn (scalachess, common, game) aggregate (scalachess, common, game) - lazy val scalachess = Project("scalachess", file("scalachess"), settings = Project.defaultSettings ++ buildSettings).settings( + lazy val common = project("common").settings( + resolvers := Seq(iliaz, sonatype), + libraryDependencies := Seq(scalaz, scalalib, jodaTime, jodaConvert, playProvided) + ) + + lazy val game = project("game").settings( + resolvers := Seq(iliaz, sonatype), + libraryDependencies := Seq(scalaz, scalalib, jodaTime, jodaConvert, playProvided) + ) + + lazy val scalachess = project("scalachess").settings( resolvers := Seq(iliaz, sonatype, awesomepom), - scalaVersion := "2.10.0", libraryDependencies := Seq(scalaz, scalalib, hasher, jodaTime, jodaConvert) ) + + private def project(name: String) = Project(name, file(name), settings = buildSettings) }