Add paginator and separate search code in controller to service.

This commit is contained in:
takezoe
2013-07-19 20:24:31 +09:00
parent f4a5e18c69
commit 54280d5572
4 changed files with 140 additions and 120 deletions

View File

@@ -1,21 +1,16 @@
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
import model.Issue
class IndexController extends IndexControllerBase
with RepositoryService with AccountService with SystemSettingsService with ActivityService with IssuesService
with RepositoryService with AccountService with SystemSettingsService with ActivityService
with RepositorySearchService with IssuesService
with ReferrerAuthenticator
trait IndexControllerBase extends ControllerBase { self: RepositoryService
with SystemSettingsService with ActivityService with IssuesService
with SystemSettingsService with ActivityService with RepositorySearchService
with ReferrerAuthenticator =>
val searchForm = mapping(
@@ -41,7 +36,6 @@ trait IndexControllerBase extends ControllerBase { self: RepositoryService
}
get("/:owner/:repository/search")(referrersOnly { repository =>
import RepositorySearch._
val query = params("q").trim
val target = params.getOrElse("type", "code")
val page = try {
@@ -51,114 +45,17 @@ trait IndexControllerBase extends ControllerBase { self: RepositoryService
case e: NumberFormatException => 1
}
val SearchResult(files, issues) = searchRepository(repository.owner, repository.name, query)
target.toLowerCase match {
case "issue" =>
search.html.issues(issues.map { case (issue, commentCount, content) =>
IssueSearchResult(
issue.issueId,
issue.title,
issue.openedUserName,
issue.registeredDate,
commentCount,
getHighlightText(content, query)._1)
}, files.size, query, page, repository)
case _ =>
JGitUtil.withGit(getRepositoryDir(repository.owner, repository.name)){ git =>
val commits = JGitUtil.getLatestCommitFromPaths(git, files.toList.map(_._1), "HEAD")
case "issue" => search.html.issues(
searchIssues(repository.owner, repository.name, query),
countFiles(repository.owner, repository.name, query),
query, page, repository)
search.html.code(files.toList.map { case (path, text) =>
val (highlightText, lineNumber) = getHighlightText(text, query)
FileSearchResult(
path,
commits(path).getCommitterIdent.getWhen,
highlightText,
lineNumber)
}, issues.size, query, page, repository)
}
case _ => search.html.code(
searchFiles(repository.owner, repository.name, query),
countIssues(repository.owner, repository.name, query),
query, page, repository)
}
})
case class SearchResult(
files: List[(String, String)],
issues: List[(Issue, Int, String)]
)
def searchRepository(owner: String, repository: String, query: String): SearchResult = {
val issues = if(query.isEmpty) Nil else searchIssuesByKeyword(owner, repository, query)
val files = if(query.isEmpty) Nil else searchRepositoryFiles(owner, repository, query)
SearchResult(files, issues)
}
private def searchRepositoryFiles(owner: String, repository: String, query: String): List[(String, String)] = {
JGitUtil.withGit(getRepositoryDir(owner, repository)){ 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 keywords = 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 = keywords.map(lowerText.indexOf _)
if(!indices.exists(_ < 0)){
list.append((treeWalk.getPathString, text))
}
}
}
}
}
treeWalk.release
revWalk.release
list.toList
}
}
private def getHighlightText(content: String, query: String): (String, Int) = {
val keywords = StringUtil.splitWords(query.toLowerCase)
val lowerText = content.toLowerCase
val indices = keywords.map(lowerText.indexOf _)
if(!indices.exists(_ < 0)){
val lineNumber = content.substring(0, indices.min).split("\n").size - 1
val highlightText = StringUtil.escapeHtml(content.split("\n").drop(lineNumber).take(5).mkString("\n"))
.replaceAll("(?i)(" + keywords.map("\\Q" + _ + "\\E").mkString("|") + ")",
"<span style=\"background-color: #ffff88;;\">$1</span>")
(highlightText, lineNumber + 1)
} else {
(content.split("\n").take(5).mkString("\n"), 1)
}
}
}
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,
highlightLineNumber: Int)
object RepositorySearch extends IssuesService {
val CodeLimit = 10
val IssueLimit = 10
}