Conflicts:
	src/main/scala/app/DashboardController.scala
This commit is contained in:
shimamoto
2013-07-30 10:51:44 +09:00
10 changed files with 90 additions and 143 deletions

View File

@@ -1,2 +1,2 @@
set SCRIPT_DIR=%~dp0
java -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256m -Xmx512M -Xss2M -jar "%SCRIPT_DIR%\sbt-launch-0.12.3.jar" %*
java -Dhttp.proxyHost=proxy.intellilink.co.jp -Dhttp.proxyPort=8080 -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256m -Xmx512M -Xss2M -jar "%SCRIPT_DIR%\sbt-launch-0.12.3.jar" %*

View File

@@ -58,7 +58,7 @@ trait AccountControllerBase extends AccountManagementControllerBase with FlashMa
case _ =>
_root_.account.html.repositories(account,
if(account.isGroupAccount) Nil else getGroupsByUserName(userName),
getVisibleRepositories(userName, baseUrl, context.loginAccount.map(_.userName)))
getVisibleRepositories(context.loginAccount, baseUrl, Some(userName)))
}
} getOrElse NotFound
}

View File

@@ -16,19 +16,22 @@ trait IndexControllerBase extends ControllerBase {
val loginAccount = context.loginAccount
html.index(getRecentActivities(),
getAccessibleRepositories(loginAccount, baseUrl),
getVisibleRepositories(loginAccount, baseUrl),
loadSystemSettings(),
loginAccount.map{ account => getRepositoryNamesOfUser(account.userName) }.getOrElse(Nil)
loginAccount.map{ account => getUserRepositories(account.userName, baseUrl) }.getOrElse(Nil)
)
}
/**
* JSON API for collaborator completion.
*
* TODO Move to other controller?
*/
// TODO Move to other controller?
get("/_user/proposals")(usersOnly {
contentType = formats("json")
org.json4s.jackson.Serialization.write(Map("options" -> getAllUsers.filter(!_.isGroupAccount).map(_.userName).toArray))
org.json4s.jackson.Serialization.write(
Map("options" -> getAllUsers.filter(!_.isGroupAccount).map(_.userName).toArray)
)
})

View File

@@ -37,49 +37,29 @@ trait RepositoryViewerControllerBase extends ControllerBase {
fileList(_)
})
/**
* Displays the file list of the repository root and the specified branch.
*/
get("/:owner/:repository/tree/:id")(referrersOnly {
fileList(_, params("id"))
})
/**
* Displays the file list of the specified path and branch.
*/
get("/:owner/:repository/tree/:id/*")(referrersOnly {
fileList(_, params("id"), multiParams("splat").head)
})
/**
* Displays the commit list of the specified branch.
*/
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 =>
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
}
get("/:owner/:repository/tree/*")(referrersOnly { repository =>
val (id, path) = splitPath(repository, multiParams("splat").head)
if(path.isEmpty){
fileList(repository, id)
} else {
fileList(repository, id, path)
}
})
/**
* Displays the commit list of the specified resource.
*/
get("/:owner/:repository/commits/:branch/*")(referrersOnly { repository =>
val branchName = params("branch")
val path = multiParams("splat").head //.replaceFirst("^tree/.+?/", "")
get("/:owner/:repository/commits/*")(referrersOnly { repository =>
val (branchName, path) = splitPath(repository, multiParams("splat").head)
val page = params.getOrElse("page", "1").toInt
JGitUtil.withGit(getRepositoryDir(repository.owner, repository.name)){ git =>
JGitUtil.getCommitLog(git, branchName, page, 30, path) match {
case Right((logs, hasNext)) =>
repo.html.commits(path.split("/").toList, branchName, repository,
repo.html.commits(if(path.isEmpty) Nil else path.split("/").toList, branchName, repository,
logs.splitWith{ (commit1, commit2) =>
view.helpers.date(commit1.time) == view.helpers.date(commit2.time)
}, page, hasNext)
@@ -91,10 +71,9 @@ trait RepositoryViewerControllerBase extends ControllerBase {
/**
* Displays the file content of the specified branch or commit.
*/
get("/:owner/:repository/blob/:id/*")(referrersOnly { repository =>
val id = params("id") // branch name or commit id
get("/:owner/:repository/blob/*")(referrersOnly { repository =>
val (id, path) = splitPath(repository, multiParams("splat").head)
val raw = params.get("raw").getOrElse("false").toBoolean
val path = multiParams("splat").head //.replaceFirst("^tree/.+?/", "")
JGitUtil.withGit(getRepositoryDir(repository.owner, repository.name)){ git =>
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))
@@ -203,6 +182,16 @@ trait RepositoryViewerControllerBase extends ControllerBase {
}
})
private def splitPath(repository: service.RepositoryService.RepositoryInfo, path: String): (String, String) = {
val id = repository.branchList.collectFirst {
case branch if(path == branch || path.startsWith(branch + "/")) => branch
} orElse repository.tags.collectFirst {
case tag if(path == tag.name || path.startsWith(tag.name + "/")) => tag.name
} orElse Some(path) get
(id, path.substring(id.length).replaceFirst("^/", ""))
}
/**
* Provides HTML of the file list.
*

View File

@@ -53,39 +53,6 @@ trait RepositoryService { self: AccountService =>
def getRepositoryNamesOfUser(userName: String): List[String] =
Query(Repositories) filter(_.userName is userName.bind) map (_.repositoryName) list
/**
* Returns the list of specified user's repositories information.
*
* @param userName the user name
* @param baseUrl the base url of this application
* @param loginUserName the logged in user name
* @return the list of repository information which is sorted in descending order of lastActivityDate.
*/
def getVisibleRepositories(userName: String, baseUrl: String, loginUserName: Option[String]): List[RepositoryInfo] = {
val q1 = Repositories
.filter { t => t.userName is userName.bind }
.map { r => r }
val q2 = Collaborators
.innerJoin(Repositories).on((t1, t2) => t1.byRepository(t2.userName, t2.repositoryName))
.filter{ case (t1, t2) => t1.collaboratorName is userName.bind}
.map { case (t1, t2) => t2 }
def visibleFor(t: Repositories.type, loginUserName: Option[String]) = {
loginUserName match {
case Some(x) => (t.isPrivate is false.bind) || (
(t.isPrivate is true.bind) && ((t.userName is x.bind) || (Collaborators.filter { c =>
c.byRepository(t.userName, t.repositoryName) && (c.collaboratorName is x.bind)
}.exists)))
case None => (t.isPrivate is false.bind)
}
}
q1.union(q2).filter(visibleFor(_, loginUserName)).sortBy(_.lastActivityDate desc).list map { repository =>
new RepositoryInfo(JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName, baseUrl), repository)
}
}
/**
* Returns the specified repository information.
*
@@ -101,29 +68,46 @@ trait RepositoryService { self: AccountService =>
}
/**
* Returns the list of accessible repositories information for the specified account user.
*
* @param account the account
* @param baseUrl the base url of this application
* @return the repository informations which is sorted in descending order of lastActivityDate.
* Returns the list of specified user's repositories.
* It contains own repositories and collaboration repositories.
*/
def getAccessibleRepositories(account: Option[Account], baseUrl: String): List[RepositoryInfo] = {
def newRepositoryInfo(repository: Repository): RepositoryInfo = {
def getUserRepositories(userName: String, baseUrl: String): List[RepositoryInfo] = {
Query(Repositories).filter { t1 =>
(t1.userName is userName.bind) ||
(Query(Collaborators).filter { t2 => t2.byRepository(t1.userName, t1.repositoryName) && (t2.collaboratorName is userName.bind)} exists)
}.sortBy(_.lastActivityDate desc).list.map{ repository =>
new RepositoryInfo(JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName, baseUrl), repository)
}
}
(account match {
/**
* Returns the list of visible repositories for the specified user.
* If repositoryUserName is given then filters results by repository owner.
*
* @param loginAccount the logged in account
* @param baseUrl the base url of this application
* @param repositoryUserName the repository owner (if None then returns all repositories which are visible for logged in user)
* @return the repository information which is sorted in descending order of lastActivityDate.
*/
def getVisibleRepositories(loginAccount: Option[Account], baseUrl: String, repositoryUserName: Option[String] = None): List[RepositoryInfo] = {
val query = loginAccount match {
// for Administrators
case Some(x) if(x.isAdmin) => Query(Repositories)
// for Normal Users
case Some(x) if(!x.isAdmin) =>
Query(Repositories) filter { t => (t.isPrivate is false.bind) ||
(Query(Collaborators).filter(t2 => t2.byRepository(t.userName, t.repositoryName) && (t2.collaboratorName is x.userName.bind)) exists)
(Query(Collaborators).filter { t2 => t2.byRepository(t.userName, t.repositoryName) && (t2.collaboratorName is x.userName.bind)} exists)
}
// for Guests
case None => Query(Repositories) filter(_.isPrivate is false.bind)
}).sortBy(_.lastActivityDate desc).list.map(newRepositoryInfo _)
}
val filtered = repositoryUserName.map { userName => query.filter(_.userName is userName.bind) } getOrElse query
filtered.sortBy(_.lastActivityDate desc).list.map{ repository =>
new RepositoryInfo(JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName, baseUrl), repository)
}
}
/**

View File

@@ -348,51 +348,11 @@ object JGitUtil {
* @return the list of latest commit
*/
def getLatestCommitFromPaths(git: Git, paths: List[String], revision: String): Map[String, RevCommit] = {
val map = new scala.collection.mutable.HashMap[String, RevCommit]
val revWalk = new RevWalk(git.getRepository)
revWalk.markStart(revWalk.parseCommit(git.getRepository.resolve(revision)))
//revWalk.sort(RevSort.REVERSE);
val i = revWalk.iterator
while(i.hasNext && map.size != paths.length){
val commit = i.next
if(commit.getParentCount == 0){
// Initial commit
val treeWalk = new TreeWalk(git.getRepository)
treeWalk.reset()
treeWalk.setRecursive(true)
treeWalk.addTree(commit.getTree)
while (treeWalk.next) {
paths.foreach { path =>
if(treeWalk.getPathString.startsWith(path) && !map.contains(path)){
map.put(path, commit)
}
}
}
treeWalk.release
} else {
(0 to commit.getParentCount - 1).foreach { i =>
val parent = revWalk.parseCommit(commit.getParent(i).getId())
val df = new DiffFormatter(DisabledOutputStream.INSTANCE)
df.setRepository(git.getRepository)
df.setDiffComparator(RawTextComparator.DEFAULT)
df.setDetectRenames(true)
val diffs = df.scan(parent.getTree(), commit.getTree)
diffs.asScala.foreach { diff =>
paths.foreach { path =>
if(diff.getChangeType != ChangeType.DELETE && diff.getNewPath.startsWith(path) && !map.contains(path)){
map.put(path, commit)
}
}
}
}
}
revWalk.release
}
map.toMap
val start = git.getRepository.resolve(revision)
paths.map { path =>
val commit = git.log.add(start).addPath(path).setMaxCount(1).call.iterator.next
(path, commit)
}.toMap
}
/**

View File

@@ -12,8 +12,13 @@ trait AvatarImageProvider { self: RequestCache =>
*/
protected def getAvatarImageHtml(userName: String, size: Int,
mailAddress: String = "", tooltip: Boolean = false)(implicit context: app.Context): Html = {
val src = getAccountByUserName(userName).collect { case account if(account.image.isEmpty) =>
val src = getAccountByUserName(userName).map { account =>
if(account.image.isEmpty){
s"""http://www.gravatar.com/avatar/${StringUtil.md5(account.mailAddress)}?s=${size}"""
} else {
s"""${context.path}/${userName}/_avatar"""
}
} getOrElse {
if(mailAddress.nonEmpty){
s"""http://www.gravatar.com/avatar/${StringUtil.md5(mailAddress)}?s=${size}"""

View File

@@ -1,7 +1,7 @@
@(activities: List[model.Activity],
repositories: List[service.RepositoryService.RepositoryInfo],
recentRepositories: List[service.RepositoryService.RepositoryInfo],
systemSettings: service.SystemSettingsService.SystemSettings,
userRepositories: List[String])(implicit context: app.Context)
userRepositories: List[service.RepositoryService.RepositoryInfo])(implicit context: app.Context)
@import context._
@import view.helpers._
@main("GitBucket"){
@@ -28,9 +28,15 @@
<td>No repositories</td>
</tr>
} else {
@userRepositories.map { repositoryName =>
@userRepositories.map { repository =>
<tr>
<td><a href="@path/@loginAccount.get.userName/@repositoryName"><strong>@repositoryName</strong></a></td>
<td>
@if(repository.owner == loginAccount.get.userName){
<a href="@url(repository)"><strong>@repository.name</strong></a>
} else {
<a href="@url(repository)">@repository.owner/<strong>@repository.name</strong></a>
}
</td>
</tr>
}
}
@@ -43,12 +49,12 @@
Recent updated repositories
</th>
</tr>
@if(repositories.isEmpty){
@if(recentRepositories.isEmpty){
<tr>
<td>No repositories</td>
</tr>
} else {
@repositories.map { repository =>
@recentRepositories.map { repository =>
<tr>
<td>
<a href="@url(repository)">@repository.owner/<strong>@repository.name</strong></a>

View File

@@ -26,9 +26,9 @@
</div>
</li>
}
<li@if(active=="files"){ class="active"}><a href="@url(repository)/tree/@id">Files</a></li>
<li@if(active=="files" ){ class="active"}><a href="@url(repository)/tree/@id">Files</a></li>
<li@if(active=="commits"){ class="active"}><a href="@url(repository)/commits/@id">Commits</a></li>
<li@if(active=="tags"){ class="active"}><a href="@url(repository)/tags">Tags@if(repository.tags.length > 0){ <span class="badge">@repository.tags.length</span>}</a></li>
<li@if(active=="tags" ){ class="active"}><a href="@url(repository)/tags">Tags@if(repository.tags.length > 0){ <span class="badge">@repository.tags.length</span>}</a></li>
<li class="pull-right">
<div class="input-append">
<input type="text" value="@repository.url" id="repository-url" readonly>