upgrade prismic and add support for preview

TODO: custom prismic build with netty 3
pull/4707/head
Thibault Duplessis 2018-11-16 16:49:47 +07:00
parent d7c358b8ee
commit 132dec8aca
11 changed files with 54 additions and 27 deletions

View File

@ -14,8 +14,8 @@ object Blog extends LilaController {
def index(page: Int, ref: Option[String]) = Open { implicit ctx =>
pageHit
blogApi context ref flatMap { implicit prismic =>
blogApi.recent(prismic.api, ref, page, lila.common.MaxPerPage(10)) flatMap {
blogApi context ctx.req flatMap { implicit prismic =>
blogApi.recent(prismic, page, lila.common.MaxPerPage(10)) flatMap {
case Some(response) => fuccess(Ok(views.html.blog.index(response)))
case _ => notFound
}
@ -24,8 +24,8 @@ object Blog extends LilaController {
def show(id: String, slug: String, ref: Option[String]) = Open { implicit ctx =>
pageHit
blogApi context ref flatMap { implicit prismic =>
blogApi.one(prismic.api, ref, id) flatMap { maybeDocument =>
blogApi context ctx.req flatMap { implicit prismic =>
blogApi.one(prismic, 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))
@ -36,8 +36,17 @@ object Blog extends LilaController {
}
}
def preview(token: String) = Action.async { implicit req =>
blogApi context req flatMap { implicit prismic =>
prismic.api.previewSession(token, prismic.linkResolver, routes.Lobby.home.url) map { redirectUrl =>
Redirect(redirectUrl)
.withCookies(Cookie(io.prismic.Prismic.previewCookie, token, path = "/", maxAge = Some(30 * 60 * 1000), httpOnly = false))
}
}
}
def atom = Action.async { implicit req =>
blogApi context none flatMap { implicit prismic =>
blogApi context req flatMap { implicit prismic =>
blogApi.recent(prismic.api, none, 1, lila.common.MaxPerPage(50)) map {
_ ?? { docs =>
Ok(views.xml.blog.atom(docs)) as XML
@ -52,7 +61,7 @@ object Blog extends LilaController {
val redirect = Redirect(routes.ForumTopic.show(categSlug, topicSlug))
lila.forum.TopicRepo.existsByTree(categSlug, topicSlug) flatMap {
case true => fuccess(redirect)
case _ => blogApi context none flatMap { implicit prismic =>
case _ => blogApi context ctx.req flatMap { implicit prismic =>
blogApi.one(prismic.api, none, id) flatMap {
_ ?? { doc =>
lila.forum.CategRepo.bySlug(categSlug) flatMap {

View File

@ -26,7 +26,7 @@ object Prismic {
implicit def makeLinkResolver(prismicApi: PrismicApi, ref: Option[String] = None) =
DocumentLinkResolver(prismicApi) {
case (DocumentLink(id, _, _, slug, false), _) => routes.Blog.show(id, slug, ref).url
case (link, _) => routes.Blog.show(link.id, link.slug, ref).url
case _ => routes.Lobby.home.url
}

View File

@ -8,7 +8,7 @@ import play.twirl.api.Html
import lila.api.Context
import lila.common.{ AssetVersion, ContentSecurityPolicy }
trait AssetHelper { self: I18nHelper =>
trait AssetHelper { self: I18nHelper with SecurityHelper =>
def isProd: Boolean
@ -75,6 +75,13 @@ trait AssetHelper { self: I18nHelper =>
val infiniteScrollTag = jsTag("vendor/jquery.infinitescroll.min.js")
def prismicJs(implicit ctx: Context) = Html {
isGranted(_.Prismic) ?? {
embedJsUnsafe("""window.prismic={endpoint:'https://lichess.prismic.io/api/v2'}""").body ++
"""<script type="text/javascript" src="//static.cdn.prismic.io/prismic.min.js"></script>"""
}
}
def basicCsp(implicit req: RequestHeader): ContentSecurityPolicy = {
val assets = if (req.secure) "https://" + assetDomain else assetDomain
val socket = (if (req.secure) "wss://" else "ws://") + socketDomain + (if (socketDomain.contains(":")) "" else ":*")

View File

@ -2,6 +2,7 @@
@base.layout(
title = "Page not found",
moreJs = prismicJs,
moreCss = cssTag("notFound.css")) {
<div class="content_box small_box">

View File

@ -3,6 +3,7 @@
@pageJs = {
@moreJs
@jsTag("embed-analyse.js")
@prismicJs
}
@base.layout(

View File

@ -608,6 +608,7 @@ GET /variant/:key controllers.Page.variant(key)
GET /help/contribute controllers.Page.bookmark(name = "help")
GET /help/master controllers.Page.bookmark(name = "master")
GET /prismic-preview controllers.Blog.preview(token: String)
POST /jslog/$id<\w{12}> controllers.Main.jslog(id: String)
POST /jsmon/:event controllers.Main.jsmon(event: String)

View File

@ -1,6 +1,7 @@
package lila.blog
import io.prismic._
import play.api.mvc.RequestHeader
import scala.concurrent.duration._
import lila.common.MaxPerPage
@ -13,30 +14,36 @@ final class BlogApi(
) {
def recent(api: Api, ref: Option[String], page: Int, maxPerPage: MaxPerPage): Fu[Option[Paginator[Document]]] =
api.forms(collection).ref(resolveRef(api)(ref) | api.master.ref)
api.forms(collection).ref(ref | api.master.ref)
.orderings(s"[my.$collection.date desc]")
.pageSize(maxPerPage.value).page(page).submit().fold(_ => none, some _) map2 { (res: Response) =>
PrismicPaginator(res, page, maxPerPage)
}
def recent(prismic: BlogApi.Context, page: Int, maxPerPage: MaxPerPage): Fu[Option[Paginator[Document]]] =
recent(prismic.api, prismic.ref.some, page, maxPerPage)
def one(api: Api, ref: Option[String], id: String) =
def one(api: Api, ref: Option[String], id: String): Fu[Option[Document]] =
api.forms(collection)
.query(s"""[[:d = at(document.id, "$id")]]""")
.ref(resolveRef(api)(ref) | api.master.ref).submit() map (_.results.headOption)
.ref(ref | api.master.ref).submit() map (_.results.headOption)
// -- Build a Prismic context
def context(refName: Option[String])(implicit linkResolver: (Api, Option[String]) => DocumentLinkResolver) =
def one(prismic: BlogApi.Context, id: String): Fu[Option[Document]] = one(prismic.api, prismic.ref.some, id)
def context(req: RequestHeader)(implicit linkResolver: (Api, Option[String]) => DocumentLinkResolver) = {
prismicApi map { api =>
val ref = resolveRef(api)(refName)
BlogApi.Context(api, ref | api.master.ref, linkResolver(api, ref))
val ref = resolveRef(api) {
req.cookies.get(Prismic.previewCookie).map(_.value)
.orElse(req.queryString get "ref" flatMap (_.headOption) filter (_.nonEmpty))
}
BlogApi.Context(api, ref.pp | api.master.ref, linkResolver(api, ref))
}
}
private def resolveRef(api: Api)(ref: Option[String]) =
ref.map(_.trim).filterNot(_.isEmpty).flatMap { reqRef =>
ref.map(_.trim).filterNot(_.isEmpty) map { reqRef =>
api.refs.values.collectFirst {
case r if r.label == reqRef => r.ref
case r if r.ref == reqRef => r.ref
}
} getOrElse reqRef
}
private val cache = BuiltInCache(200)
@ -57,11 +64,11 @@ final class BlogApi(
object BlogApi {
def extract(body: Fragment.StructuredText): String =
def extract(body: fragments.StructuredText): String =
body.blocks
.takeWhile(_.isInstanceOf[Fragment.StructuredText.Block.Paragraph])
.take(2).map {
case Fragment.StructuredText.Block.Paragraph(text, _, _) => s"<p>$text</p>"
case Fragment.StructuredText.Block.Paragraph(text, _, _, _) => s"<p>$text</p>"
case _ => ""
}.mkString

View File

@ -10,10 +10,10 @@ private[blog] final class Notifier(
timelineApi: EntryApi
) {
def apply(prismicId: String): Funit =
def apply(id: String): Funit =
blogApi.prismicApi flatMap { prismicApi =>
blogApi.one(prismicApi, none, prismicId) flatten
s"No such document: $prismicId" flatMap doSend
blogApi.one(prismicApi, none, id) flatten
s"No such document: $id" flatMap doSend
}
private def doSend(post: Document): Funit = post.getText("blog.title") ?? { title =>

View File

@ -72,7 +72,7 @@ object Paginator {
def empty[A]: Paginator[A] = new Paginator(0, MaxPerPage(0), Nil, 0)
def fromResults[A](
currentPageResults: List[A],
currentPageResults: Seq[A],
nbResults: Int,
currentPage: Int,
maxPerPage: MaxPerPage

View File

@ -56,6 +56,7 @@ object Permission {
case object Settings extends Permission("ROLE_SETTINGS")
case object Streamers extends Permission("ROLE_STREAMERS")
case object Verified extends Permission("ROLE_VERIFIED")
case object Prismic extends Permission("ROLE_PRISMIC")
case object Hunter extends Permission("ROLE_HUNTER", List(
ViewBlurs, MarkEngine, MarkBooster, StaffForum,
@ -68,7 +69,7 @@ object Permission {
ChatTimeout, MarkTroll, SetTitle, SetEmail, ModerateQa, StreamConfig,
MessageAnyone, ManageTeam, TerminateTournament, ManageTournament, ManageEvent,
PracticeConfig, RemoveRanking, ReportBan, DisapproveCoachReview,
Relay, Streamers, DisableTwoFactor
Relay, Streamers, DisableTwoFactor, Prismic
))
case object SuperAdmin extends Permission("ROLE_SUPER_ADMIN", List(
@ -80,7 +81,7 @@ object Permission {
UserSpy, MarkEngine, MarkBooster, IpBan, ModerateQa, StreamConfig, PracticeConfig,
Beta, MessageAnyone, UserSearch, ManageTeam, TerminateTournament, ManageTournament, ManageEvent,
PublicMod, Developer, Coach, ModNote, RemoveRanking, ReportBan,
Relay, Cli, Settings, Streamers, DisableTwoFactor, Verified
Relay, Cli, Settings, Streamers, DisableTwoFactor, Verified, Prismic
)
lazy private val all: List[Permission] = SuperAdmin :: allButSuperAdmin

View File

@ -31,7 +31,7 @@ object Dependencies {
val chess = "org.lichess" %% "scalachess" % "8.6.18"
val compression = "org.lichess" %% "compression" % "1.4"
val maxmind = "com.sanoma.cda" %% "maxmind-geoip2-scala" % "1.2.3-THIB"
val prismic = "io.prismic" %% "scala-kit" % "1.2.11-THIB"
val prismic = "io.prismic" %% "scala-kit" % "2.4.2"
val java8compat = "org.scala-lang.modules" %% "scala-java8-compat" % "0.8.0"
val semver = "com.gilt" %% "gfc-semver" % "0.0.5"
val scrimage = "com.sksamuel.scrimage" %% "scrimage-core" % "2.1.8"