(refs #3)Cleanup

This commit is contained in:
takezoe
2013-07-17 16:59:38 +09:00
parent 512e59193d
commit 7f0aff8c03
3 changed files with 29 additions and 34 deletions

View File

@@ -4,7 +4,6 @@ import util._
import util.Directory._ import util.Directory._
import service._ import service._
import jp.sf.amateras.scalatra.forms._ import jp.sf.amateras.scalatra.forms._
import org.apache.commons.io.FileUtils
import org.eclipse.jgit.treewalk.TreeWalk import org.eclipse.jgit.treewalk.TreeWalk
import org.eclipse.jgit.revwalk.RevWalk import org.eclipse.jgit.revwalk.RevWalk
import scala.collection.mutable.ListBuffer import scala.collection.mutable.ListBuffer
@@ -19,7 +18,7 @@ trait IndexControllerBase extends ControllerBase { self: RepositoryService
with ReferrerAuthenticator => with ReferrerAuthenticator =>
val searchForm = mapping( val searchForm = mapping(
"query" -> trim(text(required)), // TODO optional? "query" -> trim(text(required)),
"owner" -> trim(text(required)), "owner" -> trim(text(required)),
"repository" -> trim(text(required)) "repository" -> trim(text(required))
)(SearchForm.apply) )(SearchForm.apply)
@@ -40,33 +39,25 @@ trait IndexControllerBase extends ControllerBase { self: RepositoryService
redirect(s"${form.owner}/${form.repository}/search?q=${StringUtil.urlEncode(form.query)}") redirect(s"${form.owner}/${form.repository}/search?q=${StringUtil.urlEncode(form.query)}")
} }
// TODO readable only
get("/:owner/:repository/search")(referrersOnly { repository => get("/:owner/:repository/search")(referrersOnly { repository =>
val query = params("q") val query = params("q")
val target = params.getOrElse("type", "Code") val target = params.getOrElse("type", "Code")
target.toLowerCase match { target.toLowerCase match {
case "issue" => { case "issue" => {
// TODO search issue
val lowerQueries = query.toLowerCase.split("[ \\t ]+")
search.html.issues(queryIssues(repository.owner, repository.name, query).map { case (issue, commentCount, content) => search.html.issues(queryIssues(repository.owner, repository.name, query).map { case (issue, commentCount, content) =>
val lowerText = content.toLowerCase IssueSearchResult(
val indices = lowerQueries.map { lowerQuery => issue.issueId,
lowerText.indexOf(lowerQuery) issue.title,
} issue.openedUserName,
val highlightText = if(!indices.exists(_ < 0)){ issue.registeredDate,
val lineNumber = content.substring(0, indices.min).split("\n").size - 1 commentCount,
StringUtil.escapeHtml(content.split("\n").drop(lineNumber).take(5).mkString("\n")) getHighlightText(content, query))
.replaceAll("(?i)(" + lowerQueries.map("\\Q" + _ + "\\E").mkString("|") + ")",
"<span style=\"background-color: yellow;\">$1</span>")
} else content.split("\n").take(5).mkString("\n")
IssueSearchResult(issue.issueId, issue.title, issue.openedUserName, issue.registeredDate, commentCount, highlightText)
}, query, repository) }, query, repository)
} }
case _ => { case _ => {
// TODO move to JGitUtil?
JGitUtil.withGit(getRepositoryDir(repository.owner, repository.name)){ git => JGitUtil.withGit(getRepositoryDir(repository.owner, repository.name)){ git =>
val revWalk = new RevWalk(git.getRepository) val revWalk = new RevWalk(git.getRepository)
val objectId = git.getRepository.resolve("HEAD") val objectId = git.getRepository.resolve("HEAD")
@@ -75,23 +66,17 @@ trait IndexControllerBase extends ControllerBase { self: RepositoryService
treeWalk.setRecursive(true) treeWalk.setRecursive(true)
treeWalk.addTree(revCommit.getTree) treeWalk.addTree(revCommit.getTree)
val lowerQueries = query.toLowerCase.split("[ \\t ]+") val lowerQueries = StringUtil.splitWords(query.toLowerCase)
val list = new ListBuffer[(String, String)] val list = new ListBuffer[(String, String)]
while (treeWalk.next()) { while (treeWalk.next()) {
if(treeWalk.getFileMode(0) != FileMode.TREE){ if(treeWalk.getFileMode(0) != FileMode.TREE){
JGitUtil.getContent(git, treeWalk.getObjectId(0), false).foreach { bytes => JGitUtil.getContent(git, treeWalk.getObjectId(0), false).foreach { bytes =>
if(FileUtil.isText(bytes)){ if(FileUtil.isText(bytes)){
val text = new String(bytes, "UTF-8") val text = new String(bytes, "UTF-8")
val lowerText = text.toLowerCase val lowerText = text.toLowerCase
val indices = lowerQueries.map { lowerQuery => val indices = lowerQueries.map(lowerText.indexOf _)
lowerText.indexOf(lowerQuery)
}
if(!indices.exists(_ < 0)){ if(!indices.exists(_ < 0)){
val lineNumber = text.substring(0, indices.min).split("\n").size - 1 list.append((treeWalk.getPathString, getHighlightText(text, query)))
val highlightText = StringUtil.escapeHtml(text.split("\n").drop(lineNumber).take(5).mkString("\n"))
.replaceAll("(?i)(" + lowerQueries.map("\\Q" + _ + "\\E").mkString("|") + ")",
"<span style=\"background-color: yellow;\">$1</span>")
list.append((treeWalk.getPathString, highlightText))
} }
} }
} }
@@ -110,11 +95,18 @@ trait IndexControllerBase extends ControllerBase { self: RepositoryService
} }
}) })
private def searchDirectory(query: String, dir: java.io.File, matched: List[java.io.File] = Nil): List[java.io.File] = { private def getHighlightText(content: String, query: String): String = {
dir.listFiles.toList.flatMap { val lowerQueries = StringUtil.splitWords(query.toLowerCase)
case file if(file.isDirectory && file.getName != ".git") => searchDirectory(query, file, matched) val lowerText = content.toLowerCase
case file if(file.isFile && FileUtils.readFileToString(file).contains(query)) => matched :+ file val indices = lowerQueries.map(lowerText.indexOf _)
case _ => matched
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")
} }
} }

View File

@@ -9,6 +9,7 @@ import model._
import util.StringUtil._ import util.StringUtil._
import util.Implicits._ import util.Implicits._
import scala.concurrent.duration.durationToPair import scala.concurrent.duration.durationToPair
import util.StringUtil
trait IssuesService { trait IssuesService {
import IssuesService._ import IssuesService._
@@ -236,7 +237,7 @@ trait IssuesService {
.update (closed, currentDate) .update (closed, currentDate)
def queryIssues(owner: String, repository: String, query: String): List[(Issue, Int, String)] = { def queryIssues(owner: String, repository: String, query: String): List[(Issue, Int, String)] = {
val lowerQueries = query.toLowerCase.split("[ \\t ]+") val lowerQueries = StringUtil.splitWords(query.toLowerCase)
val issues = Query(Issues).filter { t => val issues = Query(Issues).filter { t =>
lowerQueries.map { query => lowerQueries.map { query =>

View File

@@ -20,6 +20,8 @@ object StringUtil {
def urlDecode(value: String): String = URLDecoder.decode(value, "UTF-8") def urlDecode(value: String): String = URLDecoder.decode(value, "UTF-8")
def splitWords(value: String): Array[String] = value.split("[ \\t ]+]")
def escapeHtml(value: String): String = def escapeHtml(value: String): String =
value.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;").replace("\"", "&quot;") value.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;").replace("\"", "&quot;")