Merge branch 'master' into fork-and-pullreq

Conflicts:
	src/main/scala/app/CreateRepositoryController.scala
	src/main/scala/service/WikiService.scala
	src/main/scala/util/JGitUtil.scala
This commit is contained in:
takezoe
2013-07-12 15:50:53 +09:00
41 changed files with 488 additions and 258 deletions

View File

@@ -58,7 +58,10 @@ trait AccountControllerBase extends AccountManagementControllerBase with FlashMa
getAccountByUserName(userName).flatMap(_.image).map { image =>
contentType = FileUtil.getMimeType(image)
new java.io.File(getUserUploadDir(userName), image)
} getOrElse NotFound
} getOrElse {
contentType = "image/png"
Thread.currentThread.getContextClassLoader.getResourceAsStream("noimage.png")
}
}
get("/:userName/_edit")(oneselfOnly {
@@ -76,7 +79,7 @@ trait AccountControllerBase extends AccountManagementControllerBase with FlashMa
updateImage(userName, form.fileId, form.clearImage)
flash += "info" -> "Account information has been updated."
redirect("/%s/_edit".format(userName))
redirect(s"/${userName}/_edit")
} getOrElse NotFound
})

View File

@@ -69,9 +69,13 @@ trait CreateRepositoryControllerBase extends ControllerBase {
// Create README.md
FileUtils.writeStringToFile(new File(tmpdir, "README.md"),
if(form.description.nonEmpty){
form.name + "\n===============\n\n" + form.description.get
form.name + "\n" +
"===============\n" +
"\n" +
form.description.get
} else {
form.name + "\n===============\n"
form.name + "\n" +
"===============\n"
}, "UTF-8")
val git = Git.open(tmpdir)
@@ -91,7 +95,7 @@ trait CreateRepositoryControllerBase extends ControllerBase {
recordCreateRepositoryActivity(loginUserName, form.name, loginUserName)
// redirect to the repository
redirect("/%s/%s".format(loginUserName, form.name))
redirect(s"/${loginUserName}/${form.name}")
})
post("/:owner/:repository/_fork")(referrersOnly { repository =>

View File

@@ -9,10 +9,13 @@ trait IndexControllerBase extends ControllerBase { self: RepositoryService
with SystemSettingsService with ActivityService =>
get("/"){
val loginAccount = context.loginAccount
html.index(getRecentActivities(),
getAccessibleRepositories(context.loginAccount, baseUrl),
getAccessibleRepositories(loginAccount, baseUrl),
loadSystemSettings(),
context.loginAccount.map{ account => getRepositoryNamesOfUser(account.userName) }.getOrElse(Nil))
loginAccount.map{ account => getRepositoryNamesOfUser(account.userName) }.getOrElse(Nil)
)
}
}

View File

@@ -17,10 +17,9 @@ trait IssuesControllerBase extends ControllerBase {
case class IssueCreateForm(title: String, content: Option[String],
assignedUserName: Option[String], milestoneId: Option[Int], labelNames: Option[String])
case class IssueEditForm(title: String, content: Option[String])
case class CommentForm(issueId: Int, content: String)
case class IssueStateForm(issueId: Int, content: Option[String])
val issueCreateForm = mapping(
"title" -> trim(label("Title", text(required))),
@@ -40,6 +39,11 @@ trait IssuesControllerBase extends ControllerBase {
"content" -> trim(label("Comment", text(required)))
)(CommentForm.apply)
val issueStateForm = mapping(
"issueId" -> label("Issue Id", number()),
"content" -> trim(optional(text()))
)(IssueStateForm.apply)
get("/:owner/:repository/issues")(referrersOnly {
searchIssues("all", _)
})
@@ -124,29 +128,11 @@ trait IssuesControllerBase extends ControllerBase {
})
post("/:owner/:repository/issue_comments/new", commentForm)(readableUsersOnly { (form, repository) =>
val owner = repository.owner
val name = repository.name
val userName = context.loginAccount.get.userName
handleComment(form.issueId, Some(form.content), repository)
})
getIssue(owner, name, form.issueId.toString).map { issue =>
val action = if(isEditable(owner, name, issue.openedUserName)){
params.get("action") filter { action =>
updateClosed(owner, name, form.issueId, if(action == "close") true else false) > 0
}
} else None
val commentId = createComment(owner, name, userName, form.issueId, form.content, action)
// record activity
recordCommentIssueActivity(owner, name, userName, issue.issueId, form.content)
action match {
case Some("reopen") => recordReopenIssueActivity(owner, name, userName, issue.issueId, issue.title)
case Some("close") => recordCloseIssueActivity(owner, name, userName, issue.issueId, issue.title)
case _ =>
}
redirect("/%s/%s/issues/%d#comment-%d".format(owner, name, form.issueId, commentId))
}
post("/:owner/:repository/issue_comments/state", issueStateForm)(readableUsersOnly { (form, repository) =>
handleComment(form.issueId, form.content, repository)
})
ajaxPost("/:owner/:repository/issue_comments/edit/:id", commentForm)(readableUsersOnly { (form, repository) =>
@@ -172,7 +158,7 @@ trait IssuesControllerBase extends ControllerBase {
org.json4s.jackson.Serialization.write(
Map("title" -> x.title,
"content" -> view.Markdown.toHtml(x.content getOrElse "No description given.",
repository, false, true, true)
repository, false, true)
))
}
} else Unauthorized
@@ -189,7 +175,7 @@ trait IssuesControllerBase extends ControllerBase {
contentType = formats("json")
org.json4s.jackson.Serialization.write(
Map("content" -> view.Markdown.toHtml(x.content,
repository, false, true, true)
repository, false, true)
))
}
} else Unauthorized
@@ -222,9 +208,85 @@ trait IssuesControllerBase extends ControllerBase {
Ok("updated")
})
post("/:owner/:repository/issues/batchedit/state")(collaboratorsOnly { repository =>
val owner = repository.owner
val name = repository.name
val userName = context.loginAccount.get.userName
params.get("value") collect {
case s if s == "close" => (s.capitalize, Some(s), true)
case s if s == "reopen" => (s.capitalize, Some(s), false)
} map { case (content, action, closed) =>
params("checked").split(',') foreach { issueId =>
createComment(owner, name, userName, issueId.toInt, content, action)
updateClosed(owner, name, issueId.toInt, closed)
}
redirect("/%s/%s/issues".format(owner, name))
} getOrElse NotFound
})
post("/:owner/:repository/issues/batchedit/label")(collaboratorsOnly { repository =>
val owner = repository.owner
val name = repository.name
params.get("value").map(_.toInt) map { labelId =>
params("checked").split(',') foreach { issueId =>
getIssueLabel(owner, name, issueId.toInt, labelId) getOrElse {
registerIssueLabel(owner, name, issueId.toInt, labelId)
}
}
redirect("/%s/%s/issues".format(owner, name))
} getOrElse NotFound
})
post("/:owner/:repository/issues/batchedit/assign")(collaboratorsOnly { repository =>
params("checked").split(',') foreach { issueId =>
updateAssignedUserName(repository.owner, repository.name, issueId.toInt,
params.get("value") filter (_.trim != ""))
}
redirect("/%s/%s/issues".format(repository.owner, repository.name))
})
post("/:owner/:repository/issues/batchedit/milestone")(collaboratorsOnly { repository =>
params("checked").split(',') foreach { issueId =>
updateMilestoneId(repository.owner, repository.name, issueId.toInt,
params.get("value") collect { case x if x.trim != "" => x.toInt })
}
redirect("/%s/%s/issues".format(repository.owner, repository.name))
})
private def isEditable(owner: String, repository: String, author: String)(implicit context: app.Context): Boolean =
hasWritePermission(owner, repository, context.loginAccount) || author == context.loginAccount.get.userName
private def handleComment(issueId: Int, content: Option[String], repository: RepositoryService.RepositoryInfo) = {
val owner = repository.owner
val name = repository.name
val userName = context.loginAccount.get.userName
getIssue(owner, name, issueId.toString) map { issue =>
val (action, recordActivity) =
params.get("action")
.filter(_ => isEditable(owner, name, issue.openedUserName))
.collect {
case s if s == "close" => true -> (Some(s) -> Some(recordCloseIssueActivity _))
case s if s == "reopen" => false -> (Some(s) -> Some(recordReopenIssueActivity _))
}
.map { case (closed, t) =>
updateClosed(owner, name, issueId, closed)
t
}
.getOrElse(None -> None)
val commentId = createComment(owner, name, userName, issueId, content.getOrElse(action.get.capitalize), action)
// record activity
content foreach ( recordCommentIssueActivity(owner, name, userName, issueId, _) )
recordActivity foreach ( _ (owner, name, userName, issueId, issue.title) )
redirect("/%s/%s/issues/%d#comment-%d".format(owner, name, issueId, commentId))
} getOrElse NotFound
}
private def searchIssues(filter: String, repository: RepositoryService.RepositoryInfo) = {
val owner = repository.owner
val repoName = repository.name
@@ -248,8 +310,9 @@ trait IssuesControllerBase extends ControllerBase {
issues.html.list(
searchIssue(owner, repoName, condition, filter, userName, (page - 1) * IssueLimit, IssueLimit),
page,
getLabels(owner, repoName),
(getCollaborators(owner, repoName) :+ owner).sorted,
getMilestones(owner, repoName).filter(_.closedDate.isEmpty),
getLabels(owner, repoName),
countIssue(owner, repoName, condition.copy(state = "open"), filter, userName),
countIssue(owner, repoName, condition.copy(state = "closed"), filter, userName),
countIssue(owner, repoName, condition, "all", None),

View File

@@ -24,7 +24,7 @@ trait LabelsControllerBase extends ControllerBase {
post("/:owner/:repository/issues/label/new", newForm)(collaboratorsOnly { (form, repository) =>
createLabel(repository.owner, repository.name, form.labelName, form.color.substring(1))
redirect("/%s/%s/issues".format(repository.owner, repository.name))
redirect(s"/${repository.owner}/${repository.name}/issues")
})
ajaxGet("/:owner/:repository/issues/label/edit")(collaboratorsOnly { repository =>
@@ -53,9 +53,9 @@ trait LabelsControllerBase extends ControllerBase {
private def labelName: Constraint = new Constraint(){
def validate(name: String, value: String): Option[String] =
if(!value.matches("^[^,]+$")){
Some("%s contains invalid character.".format(name))
Some(s"${name} contains invalid character.")
} else if(value.startsWith("_") || value.startsWith("-")){
Some("%s starts with invalid character.".format(name))
Some(s"${name} starts with invalid character.")
} else {
None
}

View File

@@ -35,7 +35,7 @@ trait MilestonesControllerBase extends ControllerBase {
post("/:owner/:repository/issues/milestones/new", milestoneForm)(collaboratorsOnly { (form, repository) =>
createMilestone(repository.owner, repository.name, form.title, form.description, form.dueDate)
redirect("/%s/%s/issues/milestones".format(repository.owner, repository.name))
redirect(s"/${repository.owner}/${repository.name}/issues/milestones")
})
get("/:owner/:repository/issues/milestones/:milestoneId/edit")(collaboratorsOnly { repository =>
@@ -45,28 +45,28 @@ trait MilestonesControllerBase extends ControllerBase {
post("/:owner/:repository/issues/milestones/:milestoneId/edit", milestoneForm)(collaboratorsOnly { (form, repository) =>
getMilestone(repository.owner, repository.name, params("milestoneId").toInt).map { milestone =>
updateMilestone(milestone.copy(title = form.title, description = form.description, dueDate = form.dueDate))
redirect("/%s/%s/issues/milestones".format(repository.owner, repository.name))
redirect(s"/${repository.owner}/${repository.name}/issues/milestones")
} getOrElse NotFound
})
get("/:owner/:repository/issues/milestones/:milestoneId/close")(collaboratorsOnly { repository =>
getMilestone(repository.owner, repository.name, params("milestoneId").toInt).map { milestone =>
closeMilestone(milestone)
redirect("/%s/%s/issues/milestones".format(repository.owner, repository.name))
redirect(s"/${repository.owner}/${repository.name}/issues/milestones")
} getOrElse NotFound
})
get("/:owner/:repository/issues/milestones/:milestoneId/open")(collaboratorsOnly { repository =>
getMilestone(repository.owner, repository.name, params("milestoneId").toInt).map { milestone =>
openMilestone(milestone)
redirect("/%s/%s/issues/milestones".format(repository.owner, repository.name))
redirect(s"/${repository.owner}/${repository.name}/issues/milestones")
} getOrElse NotFound
})
get("/:owner/:repository/issues/milestones/:milestoneId/delete")(collaboratorsOnly { repository =>
getMilestone(repository.owner, repository.name, params("milestoneId").toInt).map { milestone =>
deleteMilestone(repository.owner, repository.name, milestone.milestoneId)
redirect("/%s/%s/issues/milestones".format(repository.owner, repository.name))
redirect(s"/${repository.owner}/${repository.name}/issues/milestones")
} getOrElse NotFound
})

View File

@@ -31,7 +31,7 @@ trait RepositorySettingsControllerBase extends ControllerBase with FlashMapSuppo
* Redirect to the Options page.
*/
get("/:owner/:repository/settings")(ownerOnly { repository =>
redirect("/%s/%s/settings/options".format(repository.owner, repository.name))
redirect(s"/${repository.owner}/${repository.name}/settings/options")
})
/**
@@ -47,7 +47,7 @@ trait RepositorySettingsControllerBase extends ControllerBase with FlashMapSuppo
post("/:owner/:repository/settings/options", optionsForm)(ownerOnly { (form, repository) =>
saveRepositoryOptions(repository.owner, repository.name, form.description, form.defaultBranch, form.isPrivate)
flash += "info" -> "Repository settings has been updated."
redirect("/%s/%s/settings/options".format(repository.owner, repository.name))
redirect(s"/${repository.owner}/${repository.name}/settings/options")
})
/**
@@ -70,7 +70,7 @@ trait RepositorySettingsControllerBase extends ControllerBase with FlashMapSuppo
*/
post("/:owner/:repository/settings/collaborators/add", collaboratorForm)(ownerOnly { (form, repository) =>
addCollaborator(repository.owner, repository.name, form.userName)
redirect("/%s/%s/settings/collaborators".format(repository.owner, repository.name))
redirect(s"/${repository.owner}/${repository.name}/settings/collaborators")
})
/**
@@ -78,7 +78,7 @@ trait RepositorySettingsControllerBase extends ControllerBase with FlashMapSuppo
*/
get("/:owner/:repository/settings/collaborators/remove")(ownerOnly { repository =>
removeCollaborator(repository.owner, repository.name, params("name"))
redirect("/%s/%s/settings/collaborators".format(repository.owner, repository.name))
redirect(s"/${repository.owner}/${repository.name}/settings/collaborators")
})
/**
@@ -98,7 +98,7 @@ trait RepositorySettingsControllerBase extends ControllerBase with FlashMapSuppo
FileUtils.deleteDirectory(getWikiRepositoryDir(repository.owner, repository.name))
FileUtils.deleteDirectory(getTemporaryDir(repository.owner, repository.name))
redirect("/%s".format(repository.owner))
redirect(s"/${repository.owner}")
})
/**

View File

@@ -27,8 +27,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
contentType = "text/html"
view.helpers.markdown(params("content"), repository,
params("enableWikiLink").toBoolean,
params("enableCommitLink").toBoolean,
params("enableIssueLink").toBoolean)
params("enableRefsLink").toBoolean)
})
/**
@@ -58,13 +57,14 @@ trait RepositoryViewerControllerBase extends ControllerBase {
get("/:owner/:repository/commits/:branch")(referrersOnly { repository =>
val branchName = params("branch")
val page = params.getOrElse("page", "1").toInt
JGitUtil.withGit(getRepositoryDir(repository.owner, repository.name)){ git =>
val (logs, hasNext) = JGitUtil.getCommitLog(git, branchName, page, 30)
repo.html.commits(Nil, branchName, repository, logs.splitWith{ (commit1, commit2) =>
view.helpers.date(commit1.time) == view.helpers.date(commit2.time)
}, page, hasNext)
JGitUtil.getCommitLog(git, branchName, page, 30) match {
case Right((logs, hasNext)) =>
repo.html.commits(Nil, branchName, repository, logs.splitWith{ (commit1, commit2) =>
view.helpers.date(commit1.time) == view.helpers.date(commit2.time)
}, page, hasNext)
case Left(_) => NotFound
}
}
})
@@ -77,12 +77,14 @@ trait RepositoryViewerControllerBase extends ControllerBase {
val page = params.getOrElse("page", "1").toInt
JGitUtil.withGit(getRepositoryDir(repository.owner, repository.name)){ git =>
val (logs, hasNext) = JGitUtil.getCommitLog(git, branchName, page, 30, path)
repo.html.commits(path.split("/").toList, branchName, repository,
logs.splitWith{ (commit1, commit2) =>
view.helpers.date(commit1.time) == view.helpers.date(commit2.time)
}, page, hasNext)
JGitUtil.getCommitLog(git, branchName, page, 30, path) match {
case Right((logs, hasNext)) =>
repo.html.commits(path.split("/").toList, branchName, repository,
logs.splitWith{ (commit1, commit2) =>
view.helpers.date(commit1.time) == view.helpers.date(commit2.time)
}, page, hasNext)
case Left(_) => NotFound
}
}
})
@@ -214,27 +216,23 @@ trait RepositoryViewerControllerBase extends ControllerBase {
repo.html.guide(repository)
} else {
JGitUtil.withGit(getRepositoryDir(repository.owner, repository.name)){ git =>
val revisions = Seq(if(revstr.isEmpty) repository.repository.defaultBranch else revstr, repository.branchList.head)
// get specified commit
val (revCommit, revision) = try {
val revision = if(revstr.isEmpty) repository.repository.defaultBranch else revstr
(JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(revision)), revision)
} catch {
case e: NullPointerException => {
val revision = repository.branchList.head
(JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(revision)), revision)
}
}
// get files
val files = JGitUtil.getFileList(git, revision, path)
// process README.md
val readme = files.find(_.name == "README.md").map { file =>
new String(JGitUtil.getContent(Git.open(getRepositoryDir(repository.owner, repository.name)), file.id, true).get, "UTF-8")
}
revisions.map { rev => (git.getRepository.resolve(rev), rev)}.find(_._1 != null).map { case (objectId, revision) =>
val revCommit = JGitUtil.getRevCommitFromId(git, objectId)
repo.html.files(revision, repository,
if(path == ".") Nil else path.split("/").toList, // current path
new JGitUtil.CommitInfo(revCommit), // latest commit
files, readme)
// get files
val files = JGitUtil.getFileList(git, revision, path)
// process README.md
val readme = files.find(_.name == "README.md").map { file =>
new String(JGitUtil.getContent(Git.open(getRepositoryDir(repository.owner, repository.name)), file.id, true).get, "UTF-8")
}
repo.html.files(revision, repository,
if(path == ".") Nil else path.split("/").toList, // current path
new JGitUtil.CommitInfo(revCommit), // latest commit
files, readme)
} getOrElse NotFound
}
}
}

View File

@@ -1,7 +1,7 @@
package app
import service._
import util.{CollaboratorsAuthenticator, ReferrerAuthenticator, JGitUtil}
import util.{CollaboratorsAuthenticator, ReferrerAuthenticator, JGitUtil, StringUtil}
import util.Directory._
import jp.sf.amateras.scalatra.forms._
@@ -16,14 +16,14 @@ trait WikiControllerBase extends ControllerBase {
case class WikiPageEditForm(pageName: String, content: String, message: Option[String], currentPageName: String)
val newForm = mapping(
"pageName" -> trim(label("Page name" , text(required, maxlength(40), identifier, unique))),
"pageName" -> trim(label("Page name" , text(required, maxlength(40), pagename, unique))),
"content" -> trim(label("Content" , text(required))),
"message" -> trim(label("Message" , optional(text()))),
"currentPageName" -> trim(label("Current page name" , text()))
)(WikiPageEditForm.apply)
val editForm = mapping(
"pageName" -> trim(label("Page name" , text(required, maxlength(40), identifier))),
"pageName" -> trim(label("Page name" , text(required, maxlength(40), pagename))),
"content" -> trim(label("Content" , text(required))),
"message" -> trim(label("Message" , optional(text()))),
"currentPageName" -> trim(label("Current page name" , text(required)))
@@ -32,27 +32,30 @@ trait WikiControllerBase extends ControllerBase {
get("/:owner/:repository/wiki")(referrersOnly { repository =>
getWikiPage(repository.owner, repository.name, "Home").map { page =>
wiki.html.page("Home", page, repository, hasWritePermission(repository.owner, repository.name, context.loginAccount))
} getOrElse redirect("/%s/%s/wiki/Home/_edit".format(repository.owner, repository.name))
} getOrElse redirect(s"/${repository.owner}/${repository.name}/wiki/Home/_edit")
})
get("/:owner/:repository/wiki/:page")(referrersOnly { repository =>
val pageName = params("page")
val pageName = StringUtil.urlDecode(params("page"))
getWikiPage(repository.owner, repository.name, pageName).map { page =>
wiki.html.page(pageName, page, repository, hasWritePermission(repository.owner, repository.name, context.loginAccount))
} getOrElse redirect("/%s/%s/wiki/%s/_edit".format(repository.owner, repository.name, pageName)) // TODO URLEncode
} getOrElse redirect(s"/${repository.owner}/${repository.name}/wiki/${pageName}/_edit") // TODO URLEncode
})
get("/:owner/:repository/wiki/:page/_history")(referrersOnly { repository =>
val pageName = params("page")
val pageName = StringUtil.urlDecode(params("page"))
JGitUtil.withGit(getWikiRepositoryDir(repository.owner, repository.name)){ git =>
wiki.html.history(Some(pageName), JGitUtil.getCommitLog(git, "master", path = pageName + ".md")._1, repository)
JGitUtil.getCommitLog(git, "master", path = pageName + ".md") match {
case Right((logs, hasNext)) => wiki.html.history(Some(pageName), logs, repository)
case Left(_) => NotFound
}
}
})
get("/:owner/:repository/wiki/:page/_compare/:commitId")(referrersOnly { repository =>
val pageName = params("page")
val pageName = StringUtil.urlDecode(params("page"))
val commitId = params("commitId").split("\\.\\.\\.")
JGitUtil.withGit(getWikiRepositoryDir(repository.owner, repository.name)){ git =>
@@ -69,7 +72,7 @@ trait WikiControllerBase extends ControllerBase {
})
get("/:owner/:repository/wiki/:page/_edit")(collaboratorsOnly { repository =>
val pageName = params("page")
val pageName = StringUtil.urlDecode(params("page"))
wiki.html.edit(pageName, getWikiPage(repository.owner, repository.name, pageName), repository)
})
@@ -82,7 +85,7 @@ trait WikiControllerBase extends ControllerBase {
updateLastActivityDate(repository.owner, repository.name)
recordEditWikiPageActivity(repository.owner, repository.name, loginAccount.userName, form.pageName)
redirect("/%s/%s/wiki/%s".format(repository.owner, repository.name, form.pageName))
redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(form.pageName)}")
})
get("/:owner/:repository/wiki/_new")(collaboratorsOnly {
@@ -98,16 +101,16 @@ trait WikiControllerBase extends ControllerBase {
updateLastActivityDate(repository.owner, repository.name)
recordCreateWikiPageActivity(repository.owner, repository.name, loginAccount.userName, form.pageName)
redirect("/%s/%s/wiki/%s".format(repository.owner, repository.name, form.pageName))
redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(form.pageName)}")
})
get("/:owner/:repository/wiki/:page/_delete")(collaboratorsOnly { repository =>
val pageName = params("page")
val pageName = StringUtil.urlDecode(params("page"))
deleteWikiPage(repository.owner, repository.name, pageName, context.loginAccount.get.userName, "Delete %s".format(pageName))
deleteWikiPage(repository.owner, repository.name, pageName, context.loginAccount.get.userName, s"Delete ${pageName}")
updateLastActivityDate(repository.owner, repository.name)
redirect("/%s/%s/wiki".format(repository.owner, repository.name))
redirect(s"/${repository.owner}/${repository.name}/wiki")
})
get("/:owner/:repository/wiki/_pages")(referrersOnly { repository =>
@@ -117,7 +120,10 @@ trait WikiControllerBase extends ControllerBase {
get("/:owner/:repository/wiki/_history")(referrersOnly { repository =>
JGitUtil.withGit(getWikiRepositoryDir(repository.owner, repository.name)){ git =>
wiki.html.history(None, JGitUtil.getCommitLog(git, "master")._1, repository)
JGitUtil.getCommitLog(git, "master") match {
case Right((logs, hasNext)) => wiki.html.history(None, logs, repository)
case Left(_) => NotFound
}
}
})
@@ -133,4 +139,16 @@ trait WikiControllerBase extends ControllerBase {
getWikiPageList(params("owner"), params("repository")).find(_ == value).map(_ => "Page already exists.")
}
private def pagename: Constraint = new Constraint(){
def validate(name: String, value: String): Option[String] =
if(value.exists("\\/:*?\"<>|".contains(_))){
Some(s"${name} contains invalid character.")
} else if(value.startsWith("_") || value.startsWith("-")){
Some(s"${name} starts with invalid character.")
} else {
None
}
}
}