forked from lichess-org/lila
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBlog.scala
157 lines (140 loc) · 4.67 KB
/
Blog.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package controllers
import io.prismic.Document
import play.api.mvc._
import lila.api.Context
import lila.app._
import lila.blog.BlogApi
import lila.common.config.MaxPerPage
final class Blog(
env: Env,
prismicC: Prismic
)(implicit ws: play.api.libs.ws.WSClient)
extends LilaController(env) {
import prismicC._
private def blogApi = env.blog.api
def index(page: Int) =
WithPrismic { implicit ctx => implicit prismic =>
pageHit
blogApi.recent(prismic, page, MaxPerPage(12)) flatMap {
case Some(response) => fuccess(Ok(views.html.blog.index(response)))
case _ => notFound
}
}
def show(id: String, slug: String, ref: Option[String]) =
WithPrismic { implicit ctx => implicit prismic =>
pageHit
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))
}
} recoverWith {
case e: RuntimeException if e.getMessage contains "Not Found" => notFound
}
}
def preview(token: String) =
WithPrismic { _ => 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
)
)
}
}
import scala.concurrent.duration._
import lila.memo.CacheApi._
private val atomCache = env.memo.cacheApi.unit[String] {
_.refreshAfterWrite(30.minutes)
.buildAsyncFuture { _ =>
blogApi.masterContext flatMap { implicit prismic =>
blogApi.recent(prismic.api, 1, MaxPerPage(50), none) map {
_ ?? { docs =>
views.html.blog.atom(docs, env.net.baseUrl).render
}
}
}
}
}
def atom =
Action.async {
atomCache.getUnit map { xml =>
Ok(xml) as XML
}
}
private val sitemapCache = env.memo.cacheApi.unit[String] {
_.refreshAfterWrite(3.hours)
.buildAsyncFuture { _ =>
blogApi.masterContext flatMap { implicit prismic =>
blogApi.all() map {
_.map { doc =>
s"${env.net.baseUrl}${routes.Blog.show(doc.id, doc.slug)}"
} mkString "\n"
}
}
}
}
def sitemapTxt =
Action.async {
sitemapCache.getUnit map { txt =>
Ok(txt) as TEXT
}
}
def all =
WithPrismic { implicit ctx => implicit prismic =>
blogApi.byYear(prismic, lila.blog.thisYear) map { posts =>
Ok(views.html.blog.index.byYear(lila.blog.thisYear, posts))
}
}
def year(year: Int) =
WithPrismic { implicit ctx => implicit prismic =>
if (lila.blog.allYears contains year)
blogApi.byYear(prismic, year) map { posts =>
Ok(views.html.blog.index.byYear(year, posts))
}
else notFound
}
def discuss(id: String) =
WithPrismic { _ => implicit prismic =>
val categSlug = "general-chess-discussion"
val topicSlug = s"blog-$id"
val redirect = Redirect(routes.ForumTopic.show(categSlug, topicSlug))
env.forum.topicRepo.existsByTree(categSlug, topicSlug) flatMap {
case true => fuccess(redirect)
case _ =>
blogApi.one(prismic.api, none, id) flatMap {
_ ?? { doc =>
env.forum.categRepo.bySlug(categSlug) flatMap {
_ ?? { categ =>
env.forum.topicApi.makeBlogDiscuss(
categ = categ,
slug = topicSlug,
name = doc.getText("blog.title") | "New blog post",
url = s"${env.net.baseUrl}${routes.Blog.show(doc.id, doc.slug)}"
)
}
} inject redirect
}
}
}
}
private def WithPrismic(f: Context => BlogApi.Context => Fu[Result]): Action[Unit] =
Open { ctx =>
blogApi context ctx.req flatMap { prismic =>
f(ctx)(prismic)
}
}
// -- 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] => Result
)(implicit ctx: lila.api.Context) =
document.collect {
case document if document.slug == slug => fuccess(callback(Right(document)))
case document if document.slugs.contains(slug) => fuccess(callback(Left(document.slug)))
} getOrElse notFound
}