create blog module
This commit is contained in:
parent
724e29e1a9
commit
cd7e29d865
|
@ -48,7 +48,7 @@ final class Env(
|
|||
|
||||
if (!Env.ai.ServerOnly) {
|
||||
loginfo("[boot] Preloading modules")
|
||||
(Env.socket,
|
||||
List(Env.socket,
|
||||
Env.site,
|
||||
Env.tournament,
|
||||
Env.lobby,
|
||||
|
@ -69,7 +69,8 @@ final class Env(
|
|||
Env.evaluation,
|
||||
Env.chat,
|
||||
Env.puzzle,
|
||||
Env.tv)
|
||||
Env.tv,
|
||||
Env.blog)
|
||||
loginfo("[boot] Preloading complete")
|
||||
}
|
||||
|
||||
|
@ -124,4 +125,5 @@ object Env {
|
|||
def puzzle = lila.puzzle.Env.current
|
||||
def coordinate = lila.coordinate.Env.current
|
||||
def tv = lila.tv.Env.current
|
||||
def blog = lila.blog.Env.current
|
||||
}
|
||||
|
|
|
@ -2,32 +2,40 @@ package controllers
|
|||
|
||||
import play.api.mvc._, Results._
|
||||
|
||||
import io.prismic.Document
|
||||
import io.prismic.{ Document, DocumentLinkResolver, Fragment }
|
||||
|
||||
import lila.app._
|
||||
import views._
|
||||
|
||||
object Blog extends LilaController {
|
||||
|
||||
private def blogApi = Env.blog.api
|
||||
|
||||
def index(ref: Option[String]) = Open { implicit ctx =>
|
||||
Prismic.WithPrismic(ref) { implicit prismic =>
|
||||
prismic.api.forms("blog").ref(prismic.ref).pageSize(20).page(1).submit() map { response =>
|
||||
blogApi context ref flatMap { implicit prismic =>
|
||||
blogApi recent 20 map { response =>
|
||||
Ok(views.html.blog.index(response))
|
||||
}
|
||||
}(ctx.req)
|
||||
}
|
||||
}
|
||||
|
||||
def show(id: String, slug: String, ref: Option[String]) = Open { implicit ctx =>
|
||||
Prismic.WithPrismic(ref) { implicit prismic =>
|
||||
Prismic getDocument id flatMap { maybeDocument =>
|
||||
blogApi context ref flatMap { implicit prismic =>
|
||||
blogApi one id flatMap { maybeDocument =>
|
||||
checkSlug(maybeDocument, slug) {
|
||||
case Left(newSlug) => MovedPermanently(routes.Blog.show(id, newSlug, ref).url)
|
||||
case Right(doc) => Ok(views.html.blog.show(doc))
|
||||
}
|
||||
}
|
||||
}(ctx.req)
|
||||
}
|
||||
}
|
||||
|
||||
implicit def makeLinkResolver(prismicApi: io.prismic.Api, ref: Option[String]): DocumentLinkResolver =
|
||||
DocumentLinkResolver(prismicApi) {
|
||||
case (Fragment.DocumentLink(id, _, _, slug, false), _) => routes.Blog.show(id, slug, ref).url
|
||||
case (Fragment.DocumentLink(_, _, _, _, true), _) => routes.Lobby.home.url
|
||||
}
|
||||
|
||||
// -- Helper: Check if the slug is valid and redirect to the most recent version id needed
|
||||
private def checkSlug(document: Option[Document], slug: String)(callback: Either[String, Document] => SimpleResult)(implicit ctx: lila.api.Context) =
|
||||
document.collect {
|
||||
|
|
|
@ -1,125 +0,0 @@
|
|||
package controllers
|
||||
|
||||
import play.api._
|
||||
import play.api.mvc._
|
||||
|
||||
import play.api.libs.json._
|
||||
import play.api.libs.ws._
|
||||
|
||||
import play.api.libs.concurrent.Execution.Implicits._
|
||||
import scala.concurrent._
|
||||
|
||||
import io.prismic.{ Api => PrismicApi, _ }
|
||||
|
||||
object Prismic {
|
||||
|
||||
private val ACCESS_TOKEN = "PRISMIC_TK"
|
||||
private val Cache = BuiltInCache(200)
|
||||
private val Logger = (level: Symbol, message: String) => level match {
|
||||
case 'DEBUG => play.api.Logger("prismic").debug(message)
|
||||
case 'ERROR => play.api.Logger("prismic").error(message)
|
||||
case _ => play.api.Logger("prismic").info(message)
|
||||
}
|
||||
|
||||
private lazy val config = lila.common.PlayApp loadConfig "prismic"
|
||||
private lazy val prismicToken = scala.util.Try(config getString "token").toOption
|
||||
private lazy val apiUrl = config getString "api"
|
||||
|
||||
def linkResolver(api: PrismicApi, ref: Option[String])(implicit request: RequestHeader) = DocumentLinkResolver(api) {
|
||||
case (Fragment.DocumentLink(id, docType, tags, slug, false), maybeBookmarked) =>
|
||||
routes.Blog.show(id, slug, ref).absoluteURL()
|
||||
case (link@Fragment.DocumentLink(_, _, _, _, true), _) =>
|
||||
routes.Lobby.home.absoluteURL()
|
||||
}
|
||||
|
||||
// Compute the callback URL to use for the OAuth worklow
|
||||
// private def callbackUrl(implicit rh: RequestHeader) =
|
||||
// routes.Prismic.callback(code = None, redirect_uri = rh.headers.get("referer")).absoluteURL()
|
||||
|
||||
// -- A Prismic context that help to keep the reference to useful primisc.io contextual data
|
||||
case class Context(api: PrismicApi, ref: String, accessToken: Option[String], linkResolver: DocumentLinkResolver) {
|
||||
def maybeRef = Option(ref).filterNot(_ == api.master.ref)
|
||||
def hasPrivilegedAccess = accessToken.isDefined
|
||||
}
|
||||
|
||||
// -- Build a Prismic context
|
||||
def buildContext(ref: Option[String])(implicit request: RequestHeader) =
|
||||
apiHome(request.session.get(ACCESS_TOKEN).orElse(prismicToken)) map { api =>
|
||||
Context(api,
|
||||
ref.map(_.trim).filterNot(_.isEmpty).getOrElse(api.master.ref),
|
||||
request.session.get(ACCESS_TOKEN),
|
||||
linkResolver(api, ref.filterNot(_ == api.master.ref))(request))
|
||||
}
|
||||
|
||||
def WithPrismic(ref: Option[String] = None)(block: Context => Future[SimpleResult])(implicit req: RequestHeader): Future[SimpleResult] =
|
||||
buildContext(ref) flatMap block
|
||||
|
||||
// -- Fetch the API entry document
|
||||
def apiHome(accessToken: Option[String] = None) =
|
||||
PrismicApi.get(apiUrl, accessToken = accessToken, cache = Cache, logger = Logger)
|
||||
|
||||
// -- Helper: Retrieve a single document by Id
|
||||
def getDocument(id: String)(implicit ctx: Prismic.Context): Future[Option[Document]] =
|
||||
ctx.api.forms("everything")
|
||||
.query(s"""[[:d = at(document.id, "$id")]]""")
|
||||
.ref(ctx.ref).submit() map (_.results.headOption)
|
||||
|
||||
// -- Helper: Retrieve several documents by Id
|
||||
def getDocuments(ids: String*)(implicit ctx: Prismic.Context): Future[Seq[Document]] =
|
||||
ids match {
|
||||
case Nil => Future.successful(Nil)
|
||||
case ids => ctx.api.forms("everything")
|
||||
.query(s"""[[:d = any(document.id, ${ids.mkString("[\"", "\",\"", "\"]")})]]""")
|
||||
.ref(ctx.ref).submit() map (_.results)
|
||||
}
|
||||
|
||||
// -- Helper: Retrieve a single document from its bookmark
|
||||
def getBookmark(bookmark: String)(implicit ctx: Prismic.Context): Future[Option[Document]] =
|
||||
ctx.api.bookmarks.get(bookmark).map(id => getDocument(id)).getOrElse(Future.successful(None))
|
||||
|
||||
// --
|
||||
// -- OAuth actions
|
||||
// --
|
||||
|
||||
// def signin = Action.async { implicit req =>
|
||||
// apiHome().map(_.oauthInitiateEndpoint).recover {
|
||||
// case InvalidToken(_, url) => url
|
||||
// case AuthorizationNeeded(_, url) => url
|
||||
// } map { url =>
|
||||
// Redirect(url, Map(
|
||||
// "client_id" -> Seq(config("prismic.clientId")),
|
||||
// "redirect_uri" -> Seq(callbackUrl),
|
||||
// "scope" -> Seq("master+releases")
|
||||
// ))
|
||||
// }
|
||||
// }
|
||||
|
||||
// def signout = Action {
|
||||
// Redirect(routes.Application.index(ref = None)).withNewSession
|
||||
// }
|
||||
|
||||
// def callback(code: Option[String], redirect_uri: Option[String]) =
|
||||
// Action.async { implicit req =>
|
||||
// (
|
||||
// for {
|
||||
// api <- apiHome()
|
||||
// tokenResponse <- WS.url(api.oauthTokenEndpoint).post(Map(
|
||||
// "grant_type" -> Seq("authorization_code"),
|
||||
// "code" -> Seq(code.get),
|
||||
// "redirect_uri" -> Seq(callbackUrl),
|
||||
// "client_id" -> Seq(config("prismic.clientId")),
|
||||
// "client_secret" -> Seq(config("prismic.clientSecret"))
|
||||
// )).filter(_.status == 200).map(_.json)
|
||||
// } yield {
|
||||
// Redirect(redirect_uri.getOrElse(routes.Application.index(ref = None).url)).withSession(
|
||||
// ACCESS_TOKEN -> (tokenResponse \ "access_token").as[String]
|
||||
// )
|
||||
// }
|
||||
// ).recover {
|
||||
// case x: Throwable =>
|
||||
// Logger('ERROR, s"""Can't retrieve the OAuth token for code $code: ${x.getMessage}""".stripMargin)
|
||||
// Unauthorized("Can't sign you in")
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
@(pager: io.prismic.Response)(implicit ctx: Context, prismic: Prismic.Context)
|
||||
@(pager: io.prismic.Response)(implicit ctx: Context, prismic: lila.blog.BlogApi.Context)
|
||||
|
||||
@layout(
|
||||
title = "Blog") {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@(doc: io.prismic.Document)(implicit ctx: Context, prismic: Prismic.Context)
|
||||
@(doc: io.prismic.Document)(implicit ctx: Context, prismic: lila.blog.BlogApi.Context)
|
||||
<div class="meta">
|
||||
@doc.getText("blog.date").map { date =>
|
||||
<span data-icon="p"> @date</span>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@(doc: io.prismic.Document)(implicit ctx: Context, prismic: Prismic.Context)
|
||||
@(doc: io.prismic.Document)(implicit ctx: Context, prismic: lila.blog.BlogApi.Context)
|
||||
|
||||
@goodies = {
|
||||
<br />
|
||||
|
@ -30,5 +30,5 @@ goodies = goodies.some) {
|
|||
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
||||
})();
|
||||
</script>
|
||||
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments.</a></noscript>
|
||||
<noscript>Please enable JavaScript to view the comments.</noscript>
|
||||
}
|
||||
|
|
40
modules/blog/src/main/BlogApi.scala
Normal file
40
modules/blog/src/main/BlogApi.scala
Normal file
|
@ -0,0 +1,40 @@
|
|||
package lila.blog
|
||||
|
||||
import io.prismic._
|
||||
import play.api.mvc.RequestHeader
|
||||
|
||||
final class BlogApi(prismicUrl: String, collection: String) {
|
||||
|
||||
def recent(nb: Int)(implicit ctx: BlogApi.Context) =
|
||||
ctx.api.forms(collection).ref(ctx.ref).pageSize(nb).page(1).submit()
|
||||
|
||||
def one(id: String)(implicit ctx: BlogApi.Context) =
|
||||
ctx.api.forms(collection)
|
||||
.query(s"""[[:d = at(document.id, "$id")]]""")
|
||||
.ref(ctx.ref).submit() map (_.results.headOption)
|
||||
|
||||
// -- Build a Prismic context
|
||||
def context(ref: Option[String])(implicit linkResolver: (Api, Option[String]) => DocumentLinkResolver) =
|
||||
prismicApi map { api =>
|
||||
BlogApi.Context(
|
||||
api,
|
||||
ref.map(_.trim).filterNot(_.isEmpty).getOrElse(api.master.ref),
|
||||
linkResolver(api, ref))
|
||||
}
|
||||
|
||||
private val cache = BuiltInCache(200)
|
||||
private val logger = (level: Symbol, message: String) => level match {
|
||||
case 'DEBUG => play.api.Logger("prismic") debug message
|
||||
case 'ERROR => play.api.Logger("prismic") error message
|
||||
case _ => play.api.Logger("prismic") info message
|
||||
}
|
||||
|
||||
private def prismicApi = Api.get(prismicUrl, cache = cache, logger = logger)
|
||||
}
|
||||
|
||||
object BlogApi {
|
||||
|
||||
case class Context(api: Api, ref: String, linkResolver: DocumentLinkResolver) {
|
||||
def maybeRef = Option(ref).filterNot(_ == api.master.ref)
|
||||
}
|
||||
}
|
22
modules/blog/src/main/Env.scala
Normal file
22
modules/blog/src/main/Env.scala
Normal file
|
@ -0,0 +1,22 @@
|
|||
package lila.blog
|
||||
|
||||
import com.typesafe.config.Config
|
||||
|
||||
import lila.common.PimpedConfig._
|
||||
|
||||
final class Env(
|
||||
config: Config) {
|
||||
|
||||
private val PrismicApiUrl = config getString "prismic.api_url"
|
||||
private val PrismicCollection = config getString "prismic.collection"
|
||||
|
||||
lazy val api = new BlogApi(
|
||||
prismicUrl = PrismicApiUrl,
|
||||
collection = PrismicCollection)
|
||||
}
|
||||
|
||||
object Env {
|
||||
|
||||
lazy val current: Env = "[boot] blog" describes new Env(
|
||||
config = lila.common.PlayApp loadConfig "blog")
|
||||
}
|
3
modules/blog/src/main/package.scala
Normal file
3
modules/blog/src/main/package.scala
Normal file
|
@ -0,0 +1,3 @@
|
|||
package lila
|
||||
|
||||
package object blog extends PackageObject with WithPlay
|
|
@ -32,7 +32,7 @@ object ApplicationBuild extends Build {
|
|||
gameSearch, timeline, forum, forumSearch, team, teamSearch,
|
||||
ai, analyse, mod, monitor, site, round, lobby, setup,
|
||||
importer, tournament, relation, report, pref, simulation,
|
||||
evaluation, chat, puzzle, tv, coordinate)
|
||||
evaluation, chat, puzzle, tv, coordinate, blog)
|
||||
|
||||
lazy val moduleRefs = modules map projectToRef
|
||||
lazy val moduleCPDeps = moduleRefs map { new sbt.ClasspathDependency(_, None) }
|
||||
|
@ -53,6 +53,10 @@ object ApplicationBuild extends Build {
|
|||
libraryDependencies ++= provided(play.api, RM, PRM)
|
||||
)
|
||||
|
||||
lazy val blog = project("blog", Seq(common, message)).settings(
|
||||
libraryDependencies ++= provided(play.api, prismic)
|
||||
)
|
||||
|
||||
lazy val evaluation = project("evaluation", Seq(
|
||||
common, hub, db, user, game)).settings(
|
||||
libraryDependencies ++= provided(play.api, RM, PRM)
|
||||
|
|
Loading…
Reference in a new issue