mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-02 03:26:06 +01:00
119 lines
4.4 KiB
Scala
119 lines
4.4 KiB
Scala
package app
|
|
|
|
import util._
|
|
import util.Directory._
|
|
import service._
|
|
import jp.sf.amateras.scalatra.forms._
|
|
import org.eclipse.jgit.treewalk.TreeWalk
|
|
import org.eclipse.jgit.revwalk.RevWalk
|
|
import scala.collection.mutable.ListBuffer
|
|
import org.eclipse.jgit.lib.FileMode
|
|
|
|
class IndexController extends IndexControllerBase
|
|
with RepositoryService with AccountService with SystemSettingsService with ActivityService with IssuesService
|
|
with ReferrerAuthenticator
|
|
|
|
trait IndexControllerBase extends ControllerBase { self: RepositoryService
|
|
with SystemSettingsService with ActivityService with IssuesService
|
|
with ReferrerAuthenticator =>
|
|
|
|
val searchForm = mapping(
|
|
"query" -> trim(text(required)),
|
|
"owner" -> trim(text(required)),
|
|
"repository" -> trim(text(required))
|
|
)(SearchForm.apply)
|
|
|
|
case class SearchForm(query: String, owner: String, repository: String)
|
|
|
|
get("/"){
|
|
val loginAccount = context.loginAccount
|
|
|
|
html.index(getRecentActivities(),
|
|
getAccessibleRepositories(loginAccount, baseUrl),
|
|
loadSystemSettings(),
|
|
loginAccount.map{ account => getRepositoryNamesOfUser(account.userName) }.getOrElse(Nil)
|
|
)
|
|
}
|
|
|
|
post("/search", searchForm){ form =>
|
|
redirect(s"${form.owner}/${form.repository}/search?q=${StringUtil.urlEncode(form.query)}")
|
|
}
|
|
|
|
get("/:owner/:repository/search")(referrersOnly { repository =>
|
|
val query = params("q")
|
|
val target = params.getOrElse("type", "code")
|
|
|
|
target.toLowerCase match {
|
|
case "issue" => {
|
|
search.html.issues(queryIssues(repository.owner, repository.name, query).map { case (issue, commentCount, content) =>
|
|
IssueSearchResult(
|
|
issue.issueId,
|
|
issue.title,
|
|
issue.openedUserName,
|
|
issue.registeredDate,
|
|
commentCount,
|
|
getHighlightText(content, query))
|
|
}, query, repository)
|
|
|
|
}
|
|
case _ => {
|
|
// TODO move to JGitUtil?
|
|
JGitUtil.withGit(getRepositoryDir(repository.owner, repository.name)){ git =>
|
|
val revWalk = new RevWalk(git.getRepository)
|
|
val objectId = git.getRepository.resolve("HEAD")
|
|
val revCommit = revWalk.parseCommit(objectId)
|
|
val treeWalk = new TreeWalk(git.getRepository)
|
|
treeWalk.setRecursive(true)
|
|
treeWalk.addTree(revCommit.getTree)
|
|
|
|
val lowerQueries = StringUtil.splitWords(query.toLowerCase)
|
|
val list = new ListBuffer[(String, String)]
|
|
while (treeWalk.next()) {
|
|
if(treeWalk.getFileMode(0) != FileMode.TREE){
|
|
JGitUtil.getContent(git, treeWalk.getObjectId(0), false).foreach { bytes =>
|
|
if(FileUtil.isText(bytes)){
|
|
val text = new String(bytes, "UTF-8")
|
|
val lowerText = text.toLowerCase
|
|
val indices = lowerQueries.map(lowerText.indexOf _)
|
|
if(!indices.exists(_ < 0)){
|
|
list.append((treeWalk.getPathString, getHighlightText(text, query)))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
treeWalk.release
|
|
revWalk.release
|
|
|
|
val commits = JGitUtil.getLatestCommitFromPaths(git, list.toList.map(_._1), "HEAD")
|
|
|
|
search.html.code(list.toList.map { case (path, highlightText) =>
|
|
FileSearchResult(path, commits(path).getCommitterIdent.getWhen, highlightText)
|
|
}, query, repository)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
private def getHighlightText(content: String, query: String): String = {
|
|
val lowerQueries = StringUtil.splitWords(query.toLowerCase)
|
|
val lowerText = content.toLowerCase
|
|
val indices = lowerQueries.map(lowerText.indexOf _)
|
|
|
|
if(!indices.exists(_ < 0)){
|
|
val lineNumber = content.substring(0, indices.min).split("\n").size - 1
|
|
StringUtil.escapeHtml(content.split("\n").drop(lineNumber).take(5).mkString("\n"))
|
|
.replaceAll("(?i)(" + lowerQueries.map("\\Q" + _ + "\\E").mkString("|") + ")",
|
|
"<span style=\"background-color: yellow;\">$1</span>")
|
|
} else {
|
|
content.split("\n").take(5).mkString("\n")
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
case class IssueSearchResult(issueId: Int, title: String, openedUserName: String, registeredDate: java.util.Date,
|
|
commentCount: Int, highlightText: String)
|
|
|
|
case class FileSearchResult(path: String, lastModified: java.util.Date, highlightText: String) |