diff --git a/src/main/scala/app/IndexController.scala b/src/main/scala/app/IndexController.scala index 427c11f..d67b340 100644 --- a/src/main/scala/app/IndexController.scala +++ b/src/main/scala/app/IndexController.scala @@ -4,7 +4,6 @@ import util.Directory._ import service._ import jp.sf.amateras.scalatra.forms._ -import org.apache.commons.io.FileUtils import org.eclipse.jgit.treewalk.TreeWalk import org.eclipse.jgit.revwalk.RevWalk import scala.collection.mutable.ListBuffer @@ -19,7 +18,7 @@ with ReferrerAuthenticator => val searchForm = mapping( - "query" -> trim(text(required)), // TODO optional? + "query" -> trim(text(required)), "owner" -> trim(text(required)), "repository" -> trim(text(required)) )(SearchForm.apply) @@ -40,33 +39,25 @@ redirect(s"${form.owner}/${form.repository}/search?q=${StringUtil.urlEncode(form.query)}") } - // TODO readable only get("/:owner/:repository/search")(referrersOnly { repository => val query = params("q") val target = params.getOrElse("type", "Code") target.toLowerCase match { 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) => - val lowerText = content.toLowerCase - val indices = lowerQueries.map { lowerQuery => - lowerText.indexOf(lowerQuery) - } - val highlightText = 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("|") + ")", - "$1") - } else content.split("\n").take(5).mkString("\n") - - IssueSearchResult(issue.issueId, issue.title, issue.openedUserName, issue.registeredDate, commentCount, highlightText) + 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") @@ -75,23 +66,17 @@ treeWalk.setRecursive(true) treeWalk.addTree(revCommit.getTree) - val lowerQueries = query.toLowerCase.split("[ \\t ]+") + 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 text = new String(bytes, "UTF-8") val lowerText = text.toLowerCase - val indices = lowerQueries.map { lowerQuery => - lowerText.indexOf(lowerQuery) - } + val indices = lowerQueries.map(lowerText.indexOf _) if(!indices.exists(_ < 0)){ - val lineNumber = text.substring(0, indices.min).split("\n").size - 1 - val highlightText = StringUtil.escapeHtml(text.split("\n").drop(lineNumber).take(5).mkString("\n")) - .replaceAll("(?i)(" + lowerQueries.map("\\Q" + _ + "\\E").mkString("|") + ")", - "$1") - list.append((treeWalk.getPathString, highlightText)) + list.append((treeWalk.getPathString, getHighlightText(text, query))) } } } @@ -110,11 +95,18 @@ } }) - private def searchDirectory(query: String, dir: java.io.File, matched: List[java.io.File] = Nil): List[java.io.File] = { - dir.listFiles.toList.flatMap { - case file if(file.isDirectory && file.getName != ".git") => searchDirectory(query, file, matched) - case file if(file.isFile && FileUtils.readFileToString(file).contains(query)) => matched :+ file - case _ => matched + 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("|") + ")", + "$1") + } else { + content.split("\n").take(5).mkString("\n") } } diff --git a/src/main/scala/service/IssuesService.scala b/src/main/scala/service/IssuesService.scala index 037089e..b4490d9 100644 --- a/src/main/scala/service/IssuesService.scala +++ b/src/main/scala/service/IssuesService.scala @@ -9,6 +9,7 @@ import util.StringUtil._ import util.Implicits._ import scala.concurrent.duration.durationToPair +import util.StringUtil trait IssuesService { import IssuesService._ @@ -236,7 +237,7 @@ .update (closed, currentDate) 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 => lowerQueries.map { query => diff --git a/src/main/scala/util/StringUtil.scala b/src/main/scala/util/StringUtil.scala index d2aedb9..bad0ada 100644 --- a/src/main/scala/util/StringUtil.scala +++ b/src/main/scala/util/StringUtil.scala @@ -20,6 +20,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 = value.replace("&", "&").replace("<", "<").replace(">", ">").replace("\"", """)