diff --git a/app/views/wiki/layout.scala.html b/_views/wiki/layout.scala.html similarity index 100% rename from app/views/wiki/layout.scala.html rename to _views/wiki/layout.scala.html diff --git a/app/views/wiki/menu.scala.html b/_views/wiki/menu.scala.html similarity index 100% rename from app/views/wiki/menu.scala.html rename to _views/wiki/menu.scala.html diff --git a/app/views/wiki/show.scala.html b/_views/wiki/show.scala.html similarity index 100% rename from app/views/wiki/show.scala.html rename to _views/wiki/show.scala.html diff --git a/app/Modules.scala b/app/Modules.scala new file mode 100644 index 0000000000..5d1db8f3c6 --- /dev/null +++ b/app/Modules.scala @@ -0,0 +1,7 @@ +package lila.app + +trait Modules { + + def userEnv = lila.user.Env.current + def gameEnv = lila.game.Env.current +} diff --git a/app/controllers/Auth.scala b/app/controllers/Auth.scala index 32fb39c40b..3b2873ee25 100644 --- a/app/controllers/Auth.scala +++ b/app/controllers/Auth.scala @@ -2,7 +2,7 @@ package controllers import lila.app._ import lila.api._ -import lila.http.LilaCookie +import lila.common.LilaCookie import play.api.mvc._ import play.api.mvc.Results._ @@ -25,6 +25,16 @@ object Auth extends LilaController { // Redirect(routes.User.show(username)) withCookies LilaCookie.session("sessionId", sessionId) // } + def login = TODO + // Open { implicit ctx ⇒ + // Ok(html.auth.login(loginForm)) + // } + + def authenticate = TODO + def logout = TODO + def signup = TODO + def signupPost = TODO + protected def gotoLogoutSucceeded(implicit req: RequestHeader) = { req.session get "sessionId" foreach lila.security.Store.delete logoutSucceeded(req) withCookies LilaCookie.newSession diff --git a/app/controllers/ForumCateg.scala b/app/controllers/ForumCateg.scala new file mode 100644 index 0000000000..58bb2aad70 --- /dev/null +++ b/app/controllers/ForumCateg.scala @@ -0,0 +1,22 @@ +package controllers + +import lila.app._ +import views._ + +object ForumCateg extends LilaController with ForumController { + + // def index = Open { implicit ctx ⇒ + // IOk(categApi list ~ctx.me.map(teamCache.teamIds) map { + // html.forum.categ.index(_) + // }) + // } + + def show(slug: String, page: Int) = TODO + // Open { implicit ctx ⇒ + // CategGrantRead(slug) { + // IOptionOk(categApi.show(slug, page)) { + // case (categ, topics) ⇒ html.forum.categ.show(categ, topics) + // } + // } + // } +} diff --git a/app/controllers/ForumController.scala b/app/controllers/ForumController.scala index c092984256..cd5657db9d 100644 --- a/app/controllers/ForumController.scala +++ b/app/controllers/ForumController.scala @@ -3,13 +3,15 @@ package controllers import lila.app._ import lila.user.Context import lila.forum +import lila.team.Env.{ current ⇒ teamEnv } import play.api.mvc._ import play.api.mvc.Results._ -trait Controller extends forum.Granter { self: LilaController ⇒ +trait ForumController extends forum.Granter { self: LilaController ⇒ - // protected def userBelongsToTeam = env.team.api.belongsTo _ + protected def userBelongsToTeam(teamId: String, userId: String): Fu[Boolean] = + teamEnv.api.belongsTo(teamId, userId) protected def CategGrantRead[A <: Result](categSlug: String)(a: ⇒ A)(implicit ctx: Context): Result = isGrantedRead(categSlug).fold(a, diff --git a/app/controllers/I18n.scala b/app/controllers/I18n.scala new file mode 100644 index 0000000000..99683ca7e3 --- /dev/null +++ b/app/controllers/I18n.scala @@ -0,0 +1,73 @@ +package controllers + +import lila.app._ +import views._ +import lila.user.Context +import lila.common.LilaCookie +import lila.i18n._ + +import play.api.data.Form + +object I18n extends LilaController { + + // private def transInfos = env.i18n.transInfos + // private def pool = env.i18n.pool + // private def translator = env.i18n.translator + // private def forms = env.i18n.forms + // private def i18nKeys = env.i18n.keys + // private def repo = env.i18n.translationRepo + + def contribute = TODO + // Open { implicit ctx ⇒ + // val mines = (pool fixedReqAcceptLanguages ctx.req map { lang ⇒ + // transInfos get lang + // }).toList.flatten + // Ok(html.i18n.contribute(transInfos.all, mines)) + // } + + // def translationForm(lang: String) = Open { implicit ctx ⇒ + // OptionOk(transInfos get lang) { info ⇒ + // val (form, captcha) = forms.translationWithCaptcha + // renderTranslationForm(form, info, captcha) + // } + // } + + // def translationPost(lang: String) = OpenBody { implicit ctx ⇒ + // OptionResult(transInfos get lang) { info ⇒ + // implicit val req = ctx.body + // val data = forms.decodeTranslationBody + // FormIOResult(forms.translation) { form ⇒ + // renderTranslationForm(form, info, forms.captchaCreate, data) + // } { metadata ⇒ + // forms.process(lang, metadata, data) map { _ ⇒ + // Redirect(routes.I18n.contribute).flashing("success" -> "1") + // } + // } + // } + // } + + // private def renderTranslationForm(form: Form[_], info: TransInfo, captcha: Captcha.Challenge, data: Map[String, String] = Map.empty)(implicit ctx: Context) = + // html.i18n.translationForm( + // info, + // form, + // i18nKeys, + // pool.default, + // translator.rawTranslation(info.lang) _, + // captcha, + // data) + + // def fetch(from: Int) = Open { implicit ctx ⇒ + // JsonOk((repo findFrom from map { + // _ map (_.toJson) + // }).unsafePerformIO) + // } + + // val hideCalls = Open { implicit ctx ⇒ + // implicit val req = ctx.req + // val cookie = LilaCookie.cookie( + // env.i18n.hideCallsCookieName, + // "1", + // maxAge = env.i18n.hideCallsCookieMaxAge.some) + // Redirect(routes.Lobby.home()) withCookies cookie + // } +} diff --git a/app/controllers/LilaController.scala b/app/controllers/LilaController.scala index d1e566d04f..9aa0407b12 100644 --- a/app/controllers/LilaController.scala +++ b/app/controllers/LilaController.scala @@ -1,7 +1,7 @@ package controllers import lila.app._ -import lila.http.LilaCookie +import lila.common.LilaCookie import lila.user.{ Context, HeaderContext, BodyContext, User ⇒ UserModel } import lila.user.Env.{ current ⇒ userEnv } import lila.security.{ Permission, Granter } @@ -16,6 +16,7 @@ import play.api.libs.concurrent.Execution.Implicits._ trait LilaController extends Controller + with Modules with ContentTypes with RequestGetter with ResponseWriter { @@ -26,10 +27,6 @@ trait LilaController // protected def toJson[A: WritesJson](data: A) = Json toJson data - val TODO = Action { - NotImplemented[play.api.templates.Html](views.html.defaultpages.todo()) - } - protected def Open(f: Context ⇒ Fu[Result]): Action[AnyContent] = Open(BodyParsers.parse.anyContent)(f) @@ -104,11 +101,10 @@ trait LilaController // protected def ValidIOk(valid: IO[Valid[Unit]]): Result = ValidOk(valid.unsafePerformIO) - // protected def FormResult[A](form: Form[A])(op: A ⇒ Result)(implicit req: Request[_]) = - // form.bindFromRequest.fold( - // form ⇒ BadRequest(form.errors mkString "\n"), - // data ⇒ op(data) - // ) + protected def FormResult[A](form: Form[A])(op: A ⇒ Fu[Result])(implicit req: Request[_]): Fu[Result] = + form.bindFromRequest.fold( + form ⇒ fuccess(BadRequest(form.errors mkString "\n")), + op) // protected def FormIOResult[A, B](form: Form[A])(err: Form[A] ⇒ B)(op: A ⇒ IO[Result])( // implicit writer: Writeable[B], @@ -173,7 +169,7 @@ trait LilaController // protected def IOptionResult[A](ioa: IO[Option[A]])(op: A ⇒ Result)(implicit ctx: Context) = // ioa.unsafePerformIO.fold(notFound(ctx))(a ⇒ op(a)) - protected def notFound(implicit ctx: Context): Fu[Result] = + protected def notFound(implicit ctx: Context): Fu[Result] = Lobby handleNotFound ctx // protected def todo = Open { implicit ctx ⇒ diff --git a/app/controllers/Main.scala b/app/controllers/Main.scala new file mode 100644 index 0000000000..abe812f61c --- /dev/null +++ b/app/controllers/Main.scala @@ -0,0 +1,40 @@ +package controllers + +import lila.app._ +import views._ + +import play.api.mvc._ +import play.api.mvc.Results._ +import play.api.data._ +import play.api.data.Forms._ +import play.api.libs.json._ +import play.api.libs.iteratee._ +import play.api.libs.concurrent.Akka + +object Main extends LilaController { + + // def websocket = WebSocket.async[JsValue] { implicit req ⇒ + // implicit val ctx = reqToCtx(req) + // env.site.socket.join( + // uidOption = get("sri"), + // username = ctx.me map (_.username), + // flag = get("flag") + // ) + // } + + // def captchaCheck(id: String) = Open { implicit ctx ⇒ + // Ok(env.site.captcha get id valid ~get("solution") fold (1, 0)) + // } + + // def embed = Open { implicit ctx ⇒ + // JsOk("""document.write("");""" + // .format(env.settings.NetBaseUrl, getInt("w") | 820, getInt("h") | 650), + // CACHE_CONTROL -> "max-age=86400" + // ) + // } + + def developers = TODO + // Open { implicit ctx ⇒ + // Ok(views.html.site.developers()) + // } +} diff --git a/app/controllers/Monitor.scala b/app/controllers/Monitor.scala new file mode 100644 index 0000000000..ff1f0a2bf0 --- /dev/null +++ b/app/controllers/Monitor.scala @@ -0,0 +1,46 @@ +package controllers + +import play.api.mvc._ +import play.api.libs.Comet +import play.api.libs.concurrent._ +import play.api.libs.json._ +import akka.pattern.ask +import play.api.libs.concurrent.Execution.Implicits._ + +import lila.app._ +import lila.socket.actorApi.GetNbMembers +// import lila.monitor._ +import makeTimeout.short + +object Monitor extends LilaController { + + // private def reporting = env.monitor.reporting + // private def usernameMemo = env.user.usernameMemo + // private def userRepo = env.user.userRepo + // private def gameRepo = env.game.gameRepo + + def index = TODO + // Action { + // Ok(views.html.monitor.monitor()) + // } + + // def websocket = WebSocket.async[JsValue] { implicit req ⇒ + // env.monitor.socket.join(uidOption = get("sri", req)) + // } + + // def status = Open { implicit ctx ⇒ + // Async { + // import lila.common.Futuristic.ioToFuture + // (~get("key") match { + // case "elo" ⇒ + // userRepo.idsAverageElo(usernameMemo.keys).toFuture zip + // gameRepo.recentAverageElo(5).toFuture map { + // case (users, (rated, casual)) ⇒ List(users, rated, casual) mkString " " + // } + // case "moves" ⇒ (reporting ? GetNbMoves).mapTo[Int] + // case "players" ⇒ (reporting ? GetNbMembers).mapTo[Int] map { "%d %d".format(_, usernameMemo.preciseCount) } + // case _ ⇒ (reporting ? GetStatus).mapTo[String] + // }) map { x ⇒ Ok(x.toString) } + // } + // } +} diff --git a/app/controllers/Setting.scala b/app/controllers/Setting.scala new file mode 100644 index 0000000000..c543eb0f86 --- /dev/null +++ b/app/controllers/Setting.scala @@ -0,0 +1,48 @@ +package controllers + +import lila.app._ +import views._ +import lila.user.{ Context, BodyContext, Setting ⇒ UserSetting } + +import play.api.data.Form +import play.api.mvc.{ Result, Cookie } +import play.api.mvc.Results._ +import play.api.libs.concurrent.Execution.Implicits._ + +object Setting extends LilaController { + + def set(name: String) = OpenBody { implicit ctx ⇒ + implicit val req = ctx.body + (setters get name) zmap { + case (form, fn) ⇒ FormResult(form) { v ⇒ + fn(UserSetting(ctx), v) map { Ok() withCookies _ } + } + } + } + + private type Setter = (Form[String], (UserSetting, String) ⇒ Fu[Cookie]) + + private def forms = userEnv.forms + + private lazy val setters = Map( + "theme" -> setTheme, + "sound" -> setSound, + "chat" -> setChat, + "bg" -> setBg) + + private lazy val setTheme: Setter = forms.theme -> { + (setting, v) ⇒ setting.theme(v) + } + + private lazy val setSound: Setter = forms.sound -> { + (setting, v) ⇒ setting.sound(v) + } + + private lazy val setChat: Setter = forms.chat -> { + (setting, v) ⇒ setting.chat(v) + } + + private lazy val setBg: Setter = forms.bg -> { + (setting, v) ⇒ setting.bg(v) + } +} diff --git a/app/controllers/Team.scala b/app/controllers/Team.scala index 7f3b3c78eb..c7e4e3512f 100644 --- a/app/controllers/Team.scala +++ b/app/controllers/Team.scala @@ -9,4 +9,6 @@ import play.api.mvc.Results._ object Team extends LilaController { def show(id: String, page: Int) = TODO + + def requests = TODO } diff --git a/app/controllers/User.scala b/app/controllers/User.scala index dd5ccc8469..0e4a7b7209 100644 --- a/app/controllers/User.scala +++ b/app/controllers/User.scala @@ -4,7 +4,7 @@ import lila.app._ import views._ import lila.security.Permission import lila.user.{ Context, User ⇒ UserModel } -import lila.http.LilaCookie +import lila.common.LilaCookie import lila.user.Env.{ current ⇒ userEnv } import lila.security.Env.{ current ⇒ securityEnv } diff --git a/app/package.scala b/app/package.scala index f69da5d6de..a66a9d5d9d 100644 --- a/app/package.scala +++ b/app/package.scala @@ -1,3 +1,11 @@ package lila -package object app extends PackageObject with WithPlay +import scalaz.Zero +import play.api.mvc.{ Result, Results } + +package object app extends PackageObject with WithPlay { + + implicit val LilaResultZero = new Zero[Result] { + val zero = Results.NotFound + } +} diff --git a/app/templating/Environment.scala b/app/templating/Environment.scala index 534bc90905..36763de894 100644 --- a/app/templating/Environment.scala +++ b/app/templating/Environment.scala @@ -17,6 +17,7 @@ object Environment with PaginatorHelper with FormHelper with SetupHelper + with SettingHelper with MessageHelper with RoundHelper with AiHelper @@ -25,9 +26,9 @@ object Environment with ForumHelper with I18nHelper with BookmarkHelper - with NotificationHelper { + with NotificationHelper + with TeamHelper { // with tournament.TournamentHelper - // with team.TeamHelper { def netDomain = apiEnv.Net.Domain def netBaseUrl = apiEnv.Net.BaseUrl diff --git a/app/templating/ForumHelper.scala b/app/templating/ForumHelper.scala index 186d35acb3..a04a7fd54c 100644 --- a/app/templating/ForumHelper.scala +++ b/app/templating/ForumHelper.scala @@ -2,11 +2,15 @@ package lila.app package templating import lila.forum.{ Granter, Post } +import lila.team.Env.{ current ⇒ teamEnv } import play.api.templates.Html trait ForumHelper extends Granter { self: UserHelper with StringHelper ⇒ + protected def userBelongsToTeam(teamId: String, userId: String): Fu[Boolean] = + teamEnv.api.belongsTo(teamId, userId) + def authorName(post: Post) = post.userId.fold(escape(post.showAuthor))(userIdToUsername) diff --git a/old/templating/SettingHelper.scala b/app/templating/SettingHelper.scala similarity index 83% rename from old/templating/SettingHelper.scala rename to app/templating/SettingHelper.scala index a92b60d12d..64797e00f8 100644 --- a/old/templating/SettingHelper.scala +++ b/app/templating/SettingHelper.scala @@ -1,8 +1,7 @@ package lila.app package templating -import http.{ Context, Setting } -import lila.user.Theme +import lila.user.{ Theme, Setting, Context } import play.api.templates.Html diff --git a/app/templating/TeamHelper.scala b/app/templating/TeamHelper.scala index e523480a41..14df782dc9 100644 --- a/app/templating/TeamHelper.scala +++ b/app/templating/TeamHelper.scala @@ -6,27 +6,29 @@ import lila.user.Context import controllers.routes import play.api.templates.Html +import play.api.libs.concurrent.Execution.Implicits._ -// TODO -// trait TeamHelper { +trait TeamHelper { -// private def cached = env.team.cached + private def api = teamEnv.api -// def myTeam(teamId: String)(implicit ctx: Context): Boolean = -// ctx.me.zmap(me ⇒ teamEnv.api.belongsTo(teamId, me.id)) + def myTeam(teamId: String)(implicit ctx: Context): Boolean = + ctx.me.zmap(me ⇒ api.belongsTo(teamId, me.id).await) -// def teamIds(userId: String): List[String] = env.team.cached.teamIds(userId) + def teamIds(userId: String): List[String] = + api.teamIds(userId).await -// def teamIdToName(id: String): String = (cached name id) | id + def teamIdToName(id: String): String = (api teamName id).await | id -// def teamLink(id: String, cssClass: Option[String] = None): Html = Html { -// """%s""".format( -// ~cssClass.map(" " + _), -// routes.Team.show(id), -// teamIdToName(id)) -// } + def teamLink(id: String, cssClass: Option[String] = None): Html = Html { + """%s""".format( + cssClass.zmap(" " + _), + routes.Team.show(id), + teamIdToName(id)) + } -// def teamForumUrl(id: String) = routes.ForumCateg.show("team-" + id) + def teamForumUrl(id: String) = routes.ForumCateg.show("team-" + id) -// def teamNbRequests(ctx: Context) = ~ctx.me.map(cached.nbRequests) -// } + def teamNbRequests(ctx: Context) = + (ctx.userId zmap api.nbRequests).await +} diff --git a/app/templating/UiHelper.scala b/app/templating/UiHelper.scala index 9212f84a01..4144234095 100644 --- a/app/templating/UiHelper.scala +++ b/app/templating/UiHelper.scala @@ -6,7 +6,7 @@ import play.api.templates.Html // TODO trait UiHelper { self: I18nHelper ⇒ - // lazy val siteMenu = new SiteMenu(trans) + lazy val siteMenu = new lila.app.ui.SiteMenu(trans) // lazy val lobbyMenu = new LobbyMenu(trans) } diff --git a/app/ui/SiteMenu.scala b/app/ui/SiteMenu.scala index 5555a0eea5..f89e78aebd 100644 --- a/app/ui/SiteMenu.scala +++ b/app/ui/SiteMenu.scala @@ -12,7 +12,7 @@ final class SiteMenu(trans: I18nKeys) { import SiteMenu._ // TODO - // val play = new Elem("play", routes.Lobby.home, trans.play) + val play = new Elem("play", routes.Lobby.home, trans.play) // val game = new Elem("game", routes.Game.realtime, trans.games) // val tournament = new Elem("tournament", routes.Tournament.home, trans.tournament) // val user = new Elem("user", routes.User.list(page = 1), trans.people) @@ -20,10 +20,10 @@ final class SiteMenu(trans: I18nKeys) { // val forum = new Elem("forum", routes.ForumCateg.index, trans.forum) // val message = new Elem("message", routes.Message.inbox(page = 1), trans.inbox) - // private val authenticated = List(play, game, tournament, user, team, forum, message) - // private val anonymous = List(play, game, tournament, user, team, forum) + private val authenticated = List(play)//, game, tournament, user, team, forum, message) + private val anonymous = List(play)//, game, tournament, user, team, forum) - // def all(me: Option[User]) = me.isDefined.fold(authenticated, anonymous) + def all(me: Option[User]) = me.isDefined.fold(authenticated, anonymous) } object SiteMenu { diff --git a/old/views/auth/loggedIn.scala.html b/app/views/auth/loggedIn.scala.html similarity index 100% rename from old/views/auth/loggedIn.scala.html rename to app/views/auth/loggedIn.scala.html diff --git a/old/views/auth/miniLogin.scala.html b/app/views/auth/miniLogin.scala.html similarity index 100% rename from old/views/auth/miniLogin.scala.html rename to app/views/auth/miniLogin.scala.html diff --git a/old/views/base/layout.scala.html b/app/views/base/layout.scala.html similarity index 93% rename from old/views/base/layout.scala.html rename to app/views/base/layout.scala.html index 4ef9b893e3..f72dad0959 100644 --- a/old/views/base/layout.scala.html +++ b/app/views/base/layout.scala.html @@ -1,4 +1,15 @@ -@(title: String, active: Option[ui.SiteMenu.Elem] = None, baseline: Option[Html] = None, goodies: Option[Html] = None, menu: Option[Html] = None, chat: Option[Html] = None, underchat: Option[Html] = None, robots: Boolean = true, moreCss: Html = Html(""), moreJs: Html = Html(""), signedJs: Option[String] = None)(body: Html)(implicit ctx: Context) +@( +title: String, +active: Option[lila.app.ui.SiteMenu.Elem] = None, +baseline: Option[Html] = None, +goodies: Option[Html] = None, +menu: Option[Html] = None, +chat: Option[Html] = None, +underchat: Option[Html] = None, +robots: Boolean = true, +moreCss: Html = Html(""), +moreJs: Html = Html(""), +signedJs: Option[String] = None)(body: Html)(implicit ctx: Context)
@@ -123,5 +134,5 @@ @if(lang.language != "en") { } - - +