@@ -29,65 +29,24 @@ trait PagesControllerBase extends ControllerBase {
29
29
self : AccountService with RepositoryService with PagesService with ReferrerAuthenticator with OwnerAuthenticator =>
30
30
import PagesControllerBase ._
31
31
32
- case class OptionsForm (source : PageSourceType )
33
-
34
32
val optionsForm = mapping(
35
33
" source" -> trim(label(" Pages Source" , text(required, pagesOption)))
36
34
)(
37
- (source) => OptionsForm (PageSourceType .valueOf(source))
38
- )
35
+ (source) => OptionsForm (PageSourceType .valueOf(source))
36
+ )
39
37
40
38
val PAGES_BRANCHES = List (" gb-pages" , " gh-pages" )
41
39
42
40
get(" /:owner/:repository/pages/*" )(referrersOnly { repository =>
43
41
val path = params(" splat" )
44
42
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 {
70
44
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, _)))
77
46
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" ))
84
48
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" ))
91
50
case PageSourceType .NONE =>
92
51
NotFound ()
93
52
}
@@ -99,10 +58,7 @@ trait PagesControllerBase extends ControllerBase {
99
58
})
100
59
101
60
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)
106
62
html.options(repository, source, flash.get(" info" ))
107
63
})
108
64
@@ -112,51 +68,83 @@ trait PagesControllerBase extends ControllerBase {
112
68
redirect(s " / ${repository.owner}/ ${repository.name}/settings/pages " )
113
69
})
114
70
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
+
115
94
def resolveBranch (git : Git , name : String ) = Option (git.getRepository.resolve(name))
116
95
96
+ // redirect [owner/repo/pages/path] -> [owner/repo/pages/path/]
117
97
def shouldRedirect (path : String , path0 : String ): Boolean =
118
98
! isRoot(path) && path0 != path && path0.startsWith(path) && ! path.endsWith(" /" )
119
99
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, _))
124
106
}
125
107
126
- def getPathObjectId0 (git : Git , path : String , revCommit : RevCommit ): Option [(String , ObjectId )] = {
108
+ def getPathObjectIdPair (git : Git , path : String , revCommit : RevCommit ): Option [(String , ObjectId )] = {
127
109
getPathObjectId(git, path, revCommit).map(path -> _)
128
110
}
129
111
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
134
116
}
135
117
136
118
def isRoot (path : String ): Boolean = path == " "
137
119
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" )
144
122
}
145
- }
146
123
124
+ }
147
125
148
126
object PagesControllerBase {
127
+ case class OptionsForm (source : PageSourceType )
128
+
149
129
implicit class listCollectFirst [A ](private val lst : List [A ]) extends AnyVal {
150
130
@ tailrec
151
- final def collectFirst [B ](f : A => Option [B ]): Option [B ] = {
131
+ final def collectFirstOpt [B ](f : A => Option [B ]): Option [B ] = {
152
132
lst match {
153
133
case head :: tail =>
154
134
f(head) match {
155
135
case Some (x) => Some (x)
156
- case None => tail.collectFirst (f)
136
+ case None => tail.collectFirstOpt (f)
157
137
}
158
138
case Nil => None
159
139
}
160
140
}
161
141
}
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
+ }
162
150
}
0 commit comments