mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-07 22:15:51 +01:00
Merge branch 'master' of https://github.com/takezoe/gitbucket.git
Conflicts: src/main/scala/app/DashboardController.scala
This commit is contained in:
2
sbt.bat
2
sbt.bat
@@ -1,2 +1,2 @@
|
|||||||
set SCRIPT_DIR=%~dp0
|
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" %*
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ trait AccountControllerBase extends AccountManagementControllerBase with FlashMa
|
|||||||
case _ =>
|
case _ =>
|
||||||
_root_.account.html.repositories(account,
|
_root_.account.html.repositories(account,
|
||||||
if(account.isGroupAccount) Nil else getGroupsByUserName(userName),
|
if(account.isGroupAccount) Nil else getGroupsByUserName(userName),
|
||||||
getVisibleRepositories(userName, baseUrl, context.loginAccount.map(_.userName)))
|
getVisibleRepositories(context.loginAccount, baseUrl, Some(userName)))
|
||||||
}
|
}
|
||||||
} getOrElse NotFound
|
} getOrElse NotFound
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,19 +16,22 @@ trait IndexControllerBase extends ControllerBase {
|
|||||||
val loginAccount = context.loginAccount
|
val loginAccount = context.loginAccount
|
||||||
|
|
||||||
html.index(getRecentActivities(),
|
html.index(getRecentActivities(),
|
||||||
getAccessibleRepositories(loginAccount, baseUrl),
|
getVisibleRepositories(loginAccount, baseUrl),
|
||||||
loadSystemSettings(),
|
loadSystemSettings(),
|
||||||
loginAccount.map{ account => getRepositoryNamesOfUser(account.userName) }.getOrElse(Nil)
|
loginAccount.map{ account => getUserRepositories(account.userName, baseUrl) }.getOrElse(Nil)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSON API for collaborator completion.
|
* JSON API for collaborator completion.
|
||||||
|
*
|
||||||
|
* TODO Move to other controller?
|
||||||
*/
|
*/
|
||||||
// TODO Move to other controller?
|
|
||||||
get("/_user/proposals")(usersOnly {
|
get("/_user/proposals")(usersOnly {
|
||||||
contentType = formats("json")
|
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)
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -37,49 +37,29 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
fileList(_)
|
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.
|
* Displays the file list of the specified path and branch.
|
||||||
*/
|
*/
|
||||||
get("/:owner/:repository/tree/:id/*")(referrersOnly {
|
get("/:owner/:repository/tree/*")(referrersOnly { repository =>
|
||||||
fileList(_, params("id"), multiParams("splat").head)
|
val (id, path) = splitPath(repository, multiParams("splat").head)
|
||||||
})
|
if(path.isEmpty){
|
||||||
|
fileList(repository, id)
|
||||||
/**
|
} else {
|
||||||
* Displays the commit list of the specified branch.
|
fileList(repository, id, path)
|
||||||
*/
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays the commit list of the specified resource.
|
* Displays the commit list of the specified resource.
|
||||||
*/
|
*/
|
||||||
get("/:owner/:repository/commits/:branch/*")(referrersOnly { repository =>
|
get("/:owner/:repository/commits/*")(referrersOnly { repository =>
|
||||||
val branchName = params("branch")
|
val (branchName, path) = splitPath(repository, multiParams("splat").head)
|
||||||
val path = multiParams("splat").head //.replaceFirst("^tree/.+?/", "")
|
|
||||||
val page = params.getOrElse("page", "1").toInt
|
val page = params.getOrElse("page", "1").toInt
|
||||||
|
|
||||||
JGitUtil.withGit(getRepositoryDir(repository.owner, repository.name)){ git =>
|
JGitUtil.withGit(getRepositoryDir(repository.owner, repository.name)){ git =>
|
||||||
JGitUtil.getCommitLog(git, branchName, page, 30, path) match {
|
JGitUtil.getCommitLog(git, branchName, page, 30, path) match {
|
||||||
case Right((logs, hasNext)) =>
|
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) =>
|
logs.splitWith{ (commit1, commit2) =>
|
||||||
view.helpers.date(commit1.time) == view.helpers.date(commit2.time)
|
view.helpers.date(commit1.time) == view.helpers.date(commit2.time)
|
||||||
}, page, hasNext)
|
}, page, hasNext)
|
||||||
@@ -91,10 +71,9 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
/**
|
/**
|
||||||
* Displays the file content of the specified branch or commit.
|
* Displays the file content of the specified branch or commit.
|
||||||
*/
|
*/
|
||||||
get("/:owner/:repository/blob/:id/*")(referrersOnly { repository =>
|
get("/:owner/:repository/blob/*")(referrersOnly { repository =>
|
||||||
val id = params("id") // branch name or commit id
|
val (id, path) = splitPath(repository, multiParams("splat").head)
|
||||||
val raw = params.get("raw").getOrElse("false").toBoolean
|
val raw = params.get("raw").getOrElse("false").toBoolean
|
||||||
val path = multiParams("splat").head //.replaceFirst("^tree/.+?/", "")
|
|
||||||
|
|
||||||
JGitUtil.withGit(getRepositoryDir(repository.owner, repository.name)){ git =>
|
JGitUtil.withGit(getRepositoryDir(repository.owner, repository.name)){ git =>
|
||||||
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))
|
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.
|
* Provides HTML of the file list.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -53,39 +53,6 @@ trait RepositoryService { self: AccountService =>
|
|||||||
def getRepositoryNamesOfUser(userName: String): List[String] =
|
def getRepositoryNamesOfUser(userName: String): List[String] =
|
||||||
Query(Repositories) filter(_.userName is userName.bind) map (_.repositoryName) list
|
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.
|
* 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.
|
* Returns the list of specified user's repositories.
|
||||||
*
|
* It contains own repositories and collaboration repositories.
|
||||||
* @param account the account
|
|
||||||
* @param baseUrl the base url of this application
|
|
||||||
* @return the repository informations which is sorted in descending order of lastActivityDate.
|
|
||||||
*/
|
*/
|
||||||
def getAccessibleRepositories(account: Option[Account], baseUrl: String): List[RepositoryInfo] = {
|
def getUserRepositories(userName: String, baseUrl: String): List[RepositoryInfo] = {
|
||||||
|
Query(Repositories).filter { t1 =>
|
||||||
def newRepositoryInfo(repository: Repository): RepositoryInfo = {
|
(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)
|
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
|
// for Administrators
|
||||||
case Some(x) if(x.isAdmin) => Query(Repositories)
|
case Some(x) if(x.isAdmin) => Query(Repositories)
|
||||||
// for Normal Users
|
// for Normal Users
|
||||||
case Some(x) if(!x.isAdmin) =>
|
case Some(x) if(!x.isAdmin) =>
|
||||||
Query(Repositories) filter { t => (t.isPrivate is false.bind) ||
|
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
|
// for Guests
|
||||||
case None => Query(Repositories) filter(_.isPrivate is false.bind)
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -348,51 +348,11 @@ object JGitUtil {
|
|||||||
* @return the list of latest commit
|
* @return the list of latest commit
|
||||||
*/
|
*/
|
||||||
def getLatestCommitFromPaths(git: Git, paths: List[String], revision: String): Map[String, RevCommit] = {
|
def getLatestCommitFromPaths(git: Git, paths: List[String], revision: String): Map[String, RevCommit] = {
|
||||||
|
val start = git.getRepository.resolve(revision)
|
||||||
val map = new scala.collection.mutable.HashMap[String, RevCommit]
|
paths.map { path =>
|
||||||
|
val commit = git.log.add(start).addPath(path).setMaxCount(1).call.iterator.next
|
||||||
val revWalk = new RevWalk(git.getRepository)
|
(path, commit)
|
||||||
revWalk.markStart(revWalk.parseCommit(git.getRepository.resolve(revision)))
|
}.toMap
|
||||||
//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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,8 +12,13 @@ trait AvatarImageProvider { self: RequestCache =>
|
|||||||
*/
|
*/
|
||||||
protected def getAvatarImageHtml(userName: String, size: Int,
|
protected def getAvatarImageHtml(userName: String, size: Int,
|
||||||
mailAddress: String = "", tooltip: Boolean = false)(implicit context: app.Context): Html = {
|
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}"""
|
s"""http://www.gravatar.com/avatar/${StringUtil.md5(account.mailAddress)}?s=${size}"""
|
||||||
|
} else {
|
||||||
|
s"""${context.path}/${userName}/_avatar"""
|
||||||
|
}
|
||||||
} getOrElse {
|
} getOrElse {
|
||||||
if(mailAddress.nonEmpty){
|
if(mailAddress.nonEmpty){
|
||||||
s"""http://www.gravatar.com/avatar/${StringUtil.md5(mailAddress)}?s=${size}"""
|
s"""http://www.gravatar.com/avatar/${StringUtil.md5(mailAddress)}?s=${size}"""
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
@(activities: List[model.Activity],
|
@(activities: List[model.Activity],
|
||||||
repositories: List[service.RepositoryService.RepositoryInfo],
|
recentRepositories: List[service.RepositoryService.RepositoryInfo],
|
||||||
systemSettings: service.SystemSettingsService.SystemSettings,
|
systemSettings: service.SystemSettingsService.SystemSettings,
|
||||||
userRepositories: List[String])(implicit context: app.Context)
|
userRepositories: List[service.RepositoryService.RepositoryInfo])(implicit context: app.Context)
|
||||||
@import context._
|
@import context._
|
||||||
@import view.helpers._
|
@import view.helpers._
|
||||||
@main("GitBucket"){
|
@main("GitBucket"){
|
||||||
@@ -28,9 +28,15 @@
|
|||||||
<td>No repositories</td>
|
<td>No repositories</td>
|
||||||
</tr>
|
</tr>
|
||||||
} else {
|
} else {
|
||||||
@userRepositories.map { repositoryName =>
|
@userRepositories.map { repository =>
|
||||||
<tr>
|
<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>
|
</tr>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,12 +49,12 @@
|
|||||||
Recent updated repositories
|
Recent updated repositories
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
@if(repositories.isEmpty){
|
@if(recentRepositories.isEmpty){
|
||||||
<tr>
|
<tr>
|
||||||
<td>No repositories</td>
|
<td>No repositories</td>
|
||||||
</tr>
|
</tr>
|
||||||
} else {
|
} else {
|
||||||
@repositories.map { repository =>
|
@recentRepositories.map { repository =>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a href="@url(repository)">@repository.owner/<strong>@repository.name</strong></a>
|
<a href="@url(repository)">@repository.owner/<strong>@repository.name</strong></a>
|
||||||
|
|||||||
@@ -26,9 +26,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</li>
|
</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=="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">
|
<li class="pull-right">
|
||||||
<div class="input-append">
|
<div class="input-append">
|
||||||
<input type="text" value="@repository.url" id="repository-url" readonly>
|
<input type="text" value="@repository.url" id="repository-url" readonly>
|
||||||
|
|||||||
Reference in New Issue
Block a user