Skip to content

Commit 9d27f26

Browse files
committed
rewrite rendering
1 parent 1964a78 commit 9d27f26

File tree

3 files changed

+61
-73
lines changed

3 files changed

+61
-73
lines changed

src/main/scala/gitbucket/plugin/pages/PagesHook.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,7 @@ trait PagesHookBase extends RepositoryHook {
2525
renameUserName(oldOwner, newOwner, repository)
2626

2727
override def forked(owner: String, newOwner: String, repository: String)(implicit session: Session): Unit = {
28-
val source = getPageOptions(owner, repository) match {
29-
case Some(p) => p.source
30-
case None => PageSourceType.GH_PAGES
31-
}
28+
val source = getPageSource(owner, repository)
3229
registerPageOptions(newOwner, repository, source)
3330
}
3431
}

src/main/scala/gitbucket/plugin/pages/pages.scala

Lines changed: 57 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -29,65 +29,24 @@ trait PagesControllerBase extends ControllerBase {
2929
self: AccountService with RepositoryService with PagesService with ReferrerAuthenticator with OwnerAuthenticator =>
3030
import PagesControllerBase._
3131

32-
case class OptionsForm(source: PageSourceType)
33-
3432
val optionsForm = mapping(
3533
"source" -> trim(label("Pages Source", text(required, pagesOption)))
3634
)(
37-
(source) => OptionsForm(PageSourceType.valueOf(source))
38-
)
35+
(source) => OptionsForm(PageSourceType.valueOf(source))
36+
)
3937

4038
val PAGES_BRANCHES = List("gb-pages", "gh-pages")
4139

4240
get("/:owner/:repository/pages/*")(referrersOnly { repository =>
4341
val path = params("splat")
4442
using(Git.open(Directory.getRepositoryDir(repository.owner, repository.name))) { git =>
45-
46-
def resolvePath(objectId: Option[(String, ObjectId)], path: String) = {
47-
objectId match {
48-
case Some((path0, objId)) =>
49-
// redirect [owner/repo/pages/path] -> [owner/repo/pages/path/]
50-
if (shouldRedirect(path, path0)) {
51-
redirect(s"/${repository.owner}/${repository.name}/pages/$path/")
52-
} else {
53-
JGitUtil.getObjectLoaderFromId(git, objId) { loader =>
54-
contentType = Option(servletContext.getMimeType(path0)).getOrElse("application/octet-stream")
55-
response.setContentLength(loader.getSize.toInt)
56-
loader.copyTo(response.getOutputStream)
57-
}
58-
()
59-
}
60-
case None =>
61-
NotFound()
62-
}
63-
}
64-
65-
val source = getPageOptions(repository.owner, repository.name) match {
66-
case Some(p) => p.source
67-
case None => PageSourceType.GH_PAGES
68-
}
69-
source match {
43+
getPageSource(repository.owner, repository.name) match {
7044
case PageSourceType.GH_PAGES =>
71-
val objectId = PAGES_BRANCHES.collectFirst(resolveBranch(git, _))
72-
.map(JGitUtil.getRevCommitFromId(git, _))
73-
.flatMap { revCommit =>
74-
getPathIndexObjectId(git, path, revCommit)
75-
}
76-
resolvePath(objectId, path)
45+
renderFromBranch(repository, git, path, PAGES_BRANCHES.collectFirstOpt(resolveBranch(git, _)))
7746
case PageSourceType.MASTER =>
78-
val objectId = Option(git.getRepository.resolve("master"))
79-
.map(JGitUtil.getRevCommitFromId(git, _))
80-
.flatMap { revCommit =>
81-
getPathIndexObjectId(git, path, revCommit)
82-
}
83-
resolvePath(objectId, path)
47+
renderFromBranch(repository, git, path, resolveBranch(git, "master"))
8448
case PageSourceType.MASTER_DOCS =>
85-
val objectId = Option(git.getRepository.resolve("master"))
86-
.map(JGitUtil.getRevCommitFromId(git, _))
87-
.flatMap { revCommit =>
88-
getPathIndexObjectId(git, s"docs/$path", revCommit)
89-
}
90-
resolvePath(objectId, path)
49+
renderFromBranch(repository, git, joinPath("docs", path), resolveBranch(git, "master"))
9150
case PageSourceType.NONE =>
9251
NotFound()
9352
}
@@ -99,10 +58,7 @@ trait PagesControllerBase extends ControllerBase {
9958
})
10059

10160
get("/:owner/:repository/settings/pages")(ownerOnly { repository =>
102-
val source = getPageOptions(repository.owner, repository.name) match {
103-
case Some(p) => p.source
104-
case None => PageSourceType.GH_PAGES
105-
}
61+
val source = getPageSource(repository.owner, repository.name)
10662
html.options(repository, source, flash.get("info"))
10763
})
10864

@@ -112,51 +68,83 @@ trait PagesControllerBase extends ControllerBase {
11268
redirect(s"/${repository.owner}/${repository.name}/settings/pages")
11369
})
11470

71+
def renderPageObject(git: Git, path: String, obj: ObjectId): Unit = {
72+
JGitUtil.getObjectLoaderFromId(git, obj) { loader =>
73+
contentType = guessContentType(path)
74+
response.setContentLength(loader.getSize.toInt)
75+
loader.copyTo(response.getOutputStream)
76+
}
77+
}
78+
79+
def renderFromBranch(repository: RepositoryService.RepositoryInfo, git: Git, path: String, branchObject: Option[ObjectId]): Any = {
80+
val pagePair = branchObject
81+
.map(JGitUtil.getRevCommitFromId(git, _))
82+
.flatMap(getPageObjectId(git, path, _))
83+
84+
pagePair match {
85+
case Some((realPath, _)) if shouldRedirect(path, realPath) =>
86+
redirect(s"/${repository.owner}/${repository.name}/pages/$path/")
87+
case Some((realPath, pageObject)) =>
88+
renderPageObject(git, realPath, pageObject)
89+
case None =>
90+
NotFound()
91+
}
92+
}
93+
11594
def resolveBranch(git: Git, name: String) = Option(git.getRepository.resolve(name))
11695

96+
// redirect [owner/repo/pages/path] -> [owner/repo/pages/path/]
11797
def shouldRedirect(path: String, path0: String): Boolean =
11898
!isRoot(path) && path0 != path && path0.startsWith(path) && !path.endsWith("/")
11999

120-
def getPathIndexObjectId(git: Git, path: String, revCommit: RevCommit): Option[(String, ObjectId)] = {
121-
getPathObjectId0(git, path, revCommit)
122-
.orElse(getPathObjectId0(git, appendPath(path, "index.html"), revCommit))
123-
.orElse(getPathObjectId0(git, appendPath(path, "index.htm"), revCommit))
100+
def getPageObjectId(git: Git, path: String, revCommit: RevCommit): Option[(String, ObjectId)] = {
101+
listProbablePages(path).collectFirstOpt(getPathObjectIdPair(git, _, revCommit))
102+
}
103+
104+
def listProbablePages(path: String): List[String] = {
105+
path :: List("index.html", "index.htm").map(joinPath(path, _))
124106
}
125107

126-
def getPathObjectId0(git: Git, path: String, revCommit: RevCommit): Option[(String, ObjectId)] = {
108+
def getPathObjectIdPair(git: Git, path: String, revCommit: RevCommit): Option[(String, ObjectId)] = {
127109
getPathObjectId(git, path, revCommit).map(path -> _)
128110
}
129111

130-
def appendPath(base: String, suffix: String): String = {
131-
if (isRoot(base)) suffix
132-
else if (base.endsWith("/")) base + suffix
133-
else base + "/" + suffix
112+
def joinPath(base: String, suffix: String): String = {
113+
val sfx = suffix.stripPrefix("/")
114+
if (isRoot(base)) sfx
115+
else base.stripSuffix("/") + "/" + sfx
134116
}
135117

136118
def isRoot(path: String): Boolean = path == ""
137119

138-
private def pagesOption: Constraint = new Constraint() {
139-
override def validate(name: String, value: String, messages: Messages): Option[String] =
140-
PageSourceType.valueOpt(value) match {
141-
case Some(_) => None
142-
case None => Some("Pages source is invalid.")
143-
}
120+
def guessContentType(path: String): String = {
121+
Option(servletContext.getMimeType(path)).getOrElse("application/octet-stream")
144122
}
145-
}
146123

124+
}
147125

148126
object PagesControllerBase {
127+
case class OptionsForm(source: PageSourceType)
128+
149129
implicit class listCollectFirst[A](private val lst: List[A]) extends AnyVal {
150130
@tailrec
151-
final def collectFirst[B](f: A => Option[B]): Option[B] = {
131+
final def collectFirstOpt[B](f: A => Option[B]): Option[B] = {
152132
lst match {
153133
case head :: tail =>
154134
f(head) match {
155135
case Some(x) => Some(x)
156-
case None => tail.collectFirst(f)
136+
case None => tail.collectFirstOpt(f)
157137
}
158138
case Nil => None
159139
}
160140
}
161141
}
142+
143+
def pagesOption: Constraint = new Constraint() {
144+
override def validate(name: String, value: String, messages: Messages): Option[String] =
145+
PageSourceType.valueOpt(value) match {
146+
case Some(_) => None
147+
case None => Some("Pages source is invalid.")
148+
}
149+
}
162150
}

src/main/scala/gitbucket/plugin/service/PagesService.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import gitbucket.plugin.model.Profile.profile.blockingApi._
66

77
trait PagesService {
88

9+
def getPageSource(userName: String, repositoryName: String)(implicit s: Session): PageSourceType =
10+
getPageOptions(userName, repositoryName).map(_.source).getOrElse(PageSourceType.GH_PAGES)
11+
912
def getPageOptions(userName: String, repositoryName: String)(implicit s: Session): Option[Page] =
1013
Pages.filter(t => (t.userName === userName.bind) && (t.repositoryName === repositoryName.bind)).firstOption
1114

0 commit comments

Comments
 (0)