diff --git a/sbt.bat b/sbt.bat index 6949ebb..9a0b378 100644 --- a/sbt.bat +++ b/sbt.bat @@ -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" %* diff --git a/src/main/scala/app/AccountController.scala b/src/main/scala/app/AccountController.scala index acf066f..48b649b 100644 --- a/src/main/scala/app/AccountController.scala +++ b/src/main/scala/app/AccountController.scala @@ -58,7 +58,7 @@ 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 } diff --git a/src/main/scala/app/DashboardController.scala b/src/main/scala/app/DashboardController.scala index 9a2fcb9..81f0b6e 100644 --- a/src/main/scala/app/DashboardController.scala +++ b/src/main/scala/app/DashboardController.scala @@ -32,11 +32,11 @@ else IssueSearchCondition(request) session.put(sessionKey, condition) - + val userName = context.loginAccount.get.userName val repositories = getUserRepositories(userName, baseUrl).map(repo => repo.owner -> repo.name) val filterUser = Map(filter -> userName) - val page = IssueSearchCondition.page(request) + val page = IssueSearchCondition.page(request) // dashboard.html.issues( issues.html.listparts( @@ -54,4 +54,4 @@ } -} \ No newline at end of file +} diff --git a/src/main/scala/app/IndexController.scala b/src/main/scala/app/IndexController.scala index 5612f9b..f827492 100644 --- a/src/main/scala/app/IndexController.scala +++ b/src/main/scala/app/IndexController.scala @@ -16,19 +16,22 @@ 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) + ) }) diff --git a/src/main/scala/app/RepositoryViewerController.scala b/src/main/scala/app/RepositoryViewerController.scala index 43cb126..3a510c8 100644 --- a/src/main/scala/app/RepositoryViewerController.scala +++ b/src/main/scala/app/RepositoryViewerController.scala @@ -38,48 +38,28 @@ }) /** - * 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/.+?/", "") - val page = params.getOrElse("page", "1").toInt + 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 @@ /** * 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 - val raw = params.get("raw").getOrElse("false").toBoolean - val path = multiParams("splat").head //.replaceFirst("^tree/.+?/", "") + get("/:owner/:repository/blob/*")(referrersOnly { repository => + val (id, path) = splitPath(repository, multiParams("splat").head) + val raw = params.get("raw").getOrElse("false").toBoolean JGitUtil.withGit(getRepositoryDir(repository.owner, repository.name)){ git => val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id)) @@ -202,7 +181,17 @@ BadRequest } }) - + + 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. * diff --git a/src/main/scala/service/RepositoryService.scala b/src/main/scala/service/RepositoryService.scala index b8c7596..ce86ffd 100644 --- a/src/main/scala/service/RepositoryService.scala +++ b/src/main/scala/service/RepositoryService.scala @@ -54,39 +54,6 @@ 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. * * @param userName the user name of the repository owner @@ -101,29 +68,46 @@ } /** - * 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) + } } /** diff --git a/src/main/scala/util/JGitUtil.scala b/src/main/scala/util/JGitUtil.scala index f42c68d..f54b9c0 100644 --- a/src/main/scala/util/JGitUtil.scala +++ b/src/main/scala/util/JGitUtil.scala @@ -348,51 +348,11 @@ * @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 } /** diff --git a/src/main/scala/view/AvatarImageProvider.scala b/src/main/scala/view/AvatarImageProvider.scala index bd1703d..28cf7f3 100644 --- a/src/main/scala/view/AvatarImageProvider.scala +++ b/src/main/scala/view/AvatarImageProvider.scala @@ -12,8 +12,13 @@ */ 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) => - s"""http://www.gravatar.com/avatar/${StringUtil.md5(account.mailAddress)}?s=${size}""" + + 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}""" diff --git a/src/main/twirl/index.scala.html b/src/main/twirl/index.scala.html index c15f057..d62da6f 100644 --- a/src/main/twirl/index.scala.html +++ b/src/main/twirl/index.scala.html @@ -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 @@ No repositories } else { - @userRepositories.map { repositoryName => + @userRepositories.map { repository => - @repositoryName + + @if(repository.owner == loginAccount.get.userName){ + @repository.name + } else { + @repository.owner/@repository.name + } + } } @@ -43,12 +49,12 @@ Recent updated repositories - @if(repositories.isEmpty){ + @if(recentRepositories.isEmpty){ No repositories } else { - @repositories.map { repository => + @recentRepositories.map { repository => @repository.owner/@repository.name diff --git a/src/main/twirl/repo/tab.scala.html b/src/main/twirl/repo/tab.scala.html index 01b2ada..0587e86 100644 --- a/src/main/twirl/repo/tab.scala.html +++ b/src/main/twirl/repo/tab.scala.html @@ -26,9 +26,9 @@ } - Files + Files Commits - Tags@if(repository.tags.length > 0){ @repository.tags.length} + Tags@if(repository.tags.length > 0){ @repository.tags.length}