(refs #74)Add web hook URL addition.

This commit is contained in:
takezoe
2013-09-06 02:32:51 +09:00
parent 35733cd82e
commit 4d1605ded2
4 changed files with 56 additions and 6 deletions

View File

@@ -8,11 +8,14 @@ import org.apache.commons.io.FileUtils
import org.scalatra.FlashMapSupport import org.scalatra.FlashMapSupport
class RepositorySettingsController extends RepositorySettingsControllerBase class RepositorySettingsController extends RepositorySettingsControllerBase
with RepositoryService with AccountService with OwnerAuthenticator with UsersAuthenticator with RepositoryService with AccountService with WebHookService
with OwnerAuthenticator with UsersAuthenticator
trait RepositorySettingsControllerBase extends ControllerBase with FlashMapSupport { trait RepositorySettingsControllerBase extends ControllerBase with FlashMapSupport {
self: RepositoryService with AccountService with OwnerAuthenticator with UsersAuthenticator => self: RepositoryService with AccountService with WebHookService
with OwnerAuthenticator with UsersAuthenticator =>
// for repository options
case class OptionsForm(description: Option[String], defaultBranch: String, isPrivate: Boolean) case class OptionsForm(description: Option[String], defaultBranch: String, isPrivate: Boolean)
val optionsForm = mapping( val optionsForm = mapping(
@@ -20,13 +23,21 @@ trait RepositorySettingsControllerBase extends ControllerBase with FlashMapSuppo
"defaultBranch" -> trim(label("Default Branch" , text(required, maxlength(100)))), "defaultBranch" -> trim(label("Default Branch" , text(required, maxlength(100)))),
"isPrivate" -> trim(label("Repository Type", boolean())) "isPrivate" -> trim(label("Repository Type", boolean()))
)(OptionsForm.apply) )(OptionsForm.apply)
// for collaborator addition
case class CollaboratorForm(userName: String) case class CollaboratorForm(userName: String)
val collaboratorForm = mapping( val collaboratorForm = mapping(
"userName" -> trim(label("Username", text(required, collaborator))) "userName" -> trim(label("Username", text(required, collaborator)))
)(CollaboratorForm.apply) )(CollaboratorForm.apply)
// for web hook url addition
case class WebHookForm(url: String)
val webHookForm = mapping(
"url" -> trim(label("url", text(required, webHook)))
)(WebHookForm.apply)
/** /**
* Redirect to the Options page. * Redirect to the Options page.
*/ */
@@ -92,7 +103,12 @@ trait RepositorySettingsControllerBase extends ControllerBase with FlashMapSuppo
* Display the web hook page. * Display the web hook page.
*/ */
get("/:owner/:repository/settings/hooks")(ownerOnly { repository => get("/:owner/:repository/settings/hooks")(ownerOnly { repository =>
settings.html.hooks(repository) settings.html.hooks(getWebHookURLs(repository.owner, repository.name), repository)
})
post("/:owner/:repository/settings/hooks/add", webHookForm)(ownerOnly { (form, repository) =>
addWebHookURL(repository.owner, repository.name, form.url)
redirect(s"/${repository.owner}/${repository.name}/settings/hooks")
}) })
/** /**
@@ -115,6 +131,16 @@ trait RepositorySettingsControllerBase extends ControllerBase with FlashMapSuppo
redirect(s"/${repository.owner}") redirect(s"/${repository.owner}")
}) })
/**
* Provides duplication check for web hook url.
*/
private def webHook: Constraint = new Constraint(){
override def validate(name: String, value: String): Option[String] = {
val paths = request.getRequestURI.split("/")
getWebHookURLs(paths(1), paths(2)).map(_.url).find(_ == value).map(_ => "URL had been registered already.")
}
}
/** /**
* Provides Constraint to validate the collaborator name. * Provides Constraint to validate the collaborator name.
*/ */

View File

@@ -6,7 +6,7 @@ object WebHooks extends Table[WebHook]("WEB_HOOK") with BasicTemplate {
def url = column[String]("URL") def url = column[String]("URL")
def * = userName ~ repositoryName ~ url <> (WebHook, WebHook.unapply _) def * = userName ~ repositoryName ~ url <> (WebHook, WebHook.unapply _)
def byPrimaryKey(owner: String, repository: String) = byRepository(owner, repository) def byPrimaryKey(owner: String, repository: String, url: String) = byRepository(owner, repository) && (this.url is url.bind)
} }
case class WebHook( case class WebHook(

View File

@@ -0,0 +1,19 @@
package service
import scala.slick.driver.H2Driver.simple._
import Database.threadLocalSession
import model._
trait WebHookService {
def getWebHookURLs(owner: String, repository: String): List[WebHook] =
Query(WebHooks).filter(_.byRepository(owner, repository)).sortBy(_.url).list
def addWebHookURL(owner: String, repository: String, url :String): Unit =
WebHooks.insert(WebHook(owner, repository, url))
def deleteWebHookURL(owner: String, repository: String, url :String): Unit =
Query(WebHooks).filter(_.byPrimaryKey(owner, repository, url)).delete
}

View File

@@ -1,10 +1,15 @@
@(repository: service.RepositoryService.RepositoryInfo)(implicit context: app.Context) @(webHooks: List[model.WebHook], repository: service.RepositoryService.RepositoryInfo)(implicit context: app.Context)
@import context._ @import context._
@import view.helpers._ @import view.helpers._
@html.main("Settings", Some(repository)){ @html.main("Settings", Some(repository)){
@html.header("settings", repository) @html.header("settings", repository)
@menu("hooks", repository){ @menu("hooks", repository){
<h3>WebHook URLs</h3> <h3>WebHook URLs</h3>
<ul>
@webHooks.map { webHook =>
<li>@webHook.url <a href="#" class="remove">(remove)</a></li>
}
</ul>
<form method="POST" action="@url(repository)/settings/hooks/add" validate="true"> <form method="POST" action="@url(repository)/settings/hooks/add" validate="true">
<div> <div>
<span class="error" id="error-url"></span> <span class="error" id="error-url"></span>