Compare commits

...

1 Commits

Author SHA1 Message Date
Naoki Takezoe
9cc3a0d36e Optimize Get-Contents API 2021-11-05 20:21:39 +09:00
2 changed files with 26 additions and 24 deletions

View File

@@ -3,7 +3,7 @@ import gitbucket.core.api.{ApiCommit, ApiContents, ApiError, CreateAFile, JsonFo
import gitbucket.core.controller.ControllerBase import gitbucket.core.controller.ControllerBase
import gitbucket.core.service.{RepositoryCommitFileService, RepositoryService} import gitbucket.core.service.{RepositoryCommitFileService, RepositoryService}
import gitbucket.core.util.Directory.getRepositoryDir import gitbucket.core.util.Directory.getRepositoryDir
import gitbucket.core.util.JGitUtil.{CommitInfo, FileInfo, getContentFromId, getFileList} import gitbucket.core.util.JGitUtil.{CommitInfo, FileInfo, getContentFromId, getFileList, getSummaryMessage}
import gitbucket.core.util._ import gitbucket.core.util._
import gitbucket.core.view.helpers.{isRenderable, renderMarkup} import gitbucket.core.view.helpers.{isRenderable, renderMarkup}
import gitbucket.core.util.Implicits._ import gitbucket.core.util.Implicits._
@@ -49,19 +49,21 @@ trait ApiRepositoryContentsControllerBase extends ControllerBase {
getContents(repository, multiParams("splat").head, params.getOrElse("ref", repository.repository.defaultBranch)) getContents(repository, multiParams("splat").head, params.getOrElse("ref", repository.repository.defaultBranch))
}) })
private def getFileInfo(git: Git, revision: String, pathStr: String, ignoreCase: Boolean): Option[FileInfo] = { private def getFileInfo(git: Git, revision: String, pathStr: String): Option[FileInfo] = {
val (dirName, fileName) = pathStr.lastIndexOf('/') match { val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(revision))
case -1 => getPathObjectId(git, pathStr, revCommit).map { objectId =>
(".", pathStr) FileInfo(
case n => id = objectId,
(pathStr.take(n), pathStr.drop(n + 1)) isDirectory = false,
} name = pathStr.split("/").last,
if (ignoreCase) { path = pathStr.split("/").dropRight(1).mkString("/"),
getFileList(git, revision, dirName, maxFiles = context.settings.repositoryViewer.maxFiles) message = getSummaryMessage(revCommit.getFullMessage, revCommit.getShortMessage),
.find(_.name.toLowerCase.equals(fileName.toLowerCase)) commitId = revCommit.getName,
} else { time = revCommit.getAuthorIdent.getWhen,
getFileList(git, revision, dirName, maxFiles = context.settings.repositoryViewer.maxFiles) author = revCommit.getAuthorIdent.getName,
.find(_.name.equals(fileName)) mailAddress = revCommit.getAuthorIdent.getEmailAddress,
linkUrl = None
)
} }
} }
@@ -74,16 +76,17 @@ trait ApiRepositoryContentsControllerBase extends ControllerBase {
Using.resource(Git.open(getRepositoryDir(params("owner"), params("repository")))) { git => Using.resource(Git.open(getRepositoryDir(params("owner"), params("repository")))) { git =>
val fileList = getFileList(git, refStr, path, maxFiles = context.settings.repositoryViewer.maxFiles) val fileList = getFileList(git, refStr, path, maxFiles = context.settings.repositoryViewer.maxFiles)
if (fileList.isEmpty) { // file or NotFound if (fileList.isEmpty) { // file or NotFound
getFileInfo(git, refStr, path, ignoreCase) val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(refStr))
.flatMap { f => getPathObjectId(git, path, revCommit)
.flatMap { objectId =>
val largeFile = params.get("large_file").exists(s => s.equals("true")) val largeFile = params.get("large_file").exists(s => s.equals("true"))
val content = getContentFromId(git, f.id, largeFile) val content = getContentFromId(git, objectId, largeFile)
request.getHeader("Accept") match { request.getHeader("Accept") match {
case "application/vnd.github.v3.raw" => { case "application/vnd.github.v3.raw" => {
contentType = "application/vnd.github.v3.raw" contentType = "application/vnd.github.v3.raw"
content content
} }
case "application/vnd.github.v3.html" if isRenderable(f.name) => { case "application/vnd.github.v3.html" if isRenderable(path) => {
contentType = "application/vnd.github.v3.html" contentType = "application/vnd.github.v3.html"
content.map { c => content.map { c =>
List( List(
@@ -114,11 +117,12 @@ trait ApiRepositoryContentsControllerBase extends ControllerBase {
} }
} }
case _ => case _ =>
Some(JsonFormat(ApiContents(f, RepositoryName(repository), content))) getFileInfo(git, refStr, path).map { f =>
JsonFormat(ApiContents(f, RepositoryName(repository), content))
}
} }
} }
.getOrElse(NotFound()) .getOrElse(NotFound())
} else { // directory } else { // directory
JsonFormat(fileList.map { f => JsonFormat(fileList.map { f =>
ApiContents(f, RepositoryName(repository), None) ApiContents(f, RepositoryName(repository), None)
@@ -148,9 +152,7 @@ trait ApiRepositoryContentsControllerBase extends ControllerBase {
val path = paths.take(paths.size - 1).toList.mkString("/") val path = paths.take(paths.size - 1).toList.mkString("/")
Using.resource(Git.open(getRepositoryDir(params("owner"), params("repository")))) { Using.resource(Git.open(getRepositoryDir(params("owner"), params("repository")))) {
git => git =>
val fileInfo = getFileInfo(git, commit, path, false) getFileInfo(git, commit, path) match {
fileInfo match {
case Some(f) if !data.sha.contains(f.id.getName) => case Some(f) if !data.sha.contains(f.id.getName) =>
ApiError( ApiError(
"The blob SHA is not matched.", "The blob SHA is not matched.",

View File

@@ -512,7 +512,7 @@ object JGitUtil {
/** /**
* Returns the first line of the commit message. * Returns the first line of the commit message.
*/ */
private def getSummaryMessage(fullMessage: String, shortMessage: String): String = { def getSummaryMessage(fullMessage: String, shortMessage: String): String = {
val i = fullMessage.trim.indexOf('\n') val i = fullMessage.trim.indexOf('\n')
val firstLine = if (i >= 0) fullMessage.trim.substring(0, i).trim else fullMessage val firstLine = if (i >= 0) fullMessage.trim.substring(0, i).trim else fullMessage
if (firstLine.length > shortMessage.length) shortMessage else firstLine if (firstLine.length > shortMessage.length) shortMessage else firstLine