(refs #3)Start work for repository search.

This commit is contained in:
takezoe
2013-07-17 03:24:47 +09:00
parent cb591925ea
commit 79ec96343f
3 changed files with 105 additions and 5 deletions

View File

@@ -1,12 +1,27 @@
package app
import util._
import util.Directory._
import service._
import jp.sf.amateras.scalatra.forms._
import org.eclipse.jgit.api.Git
import org.apache.commons.io.FileUtils
class IndexController extends IndexControllerBase
with RepositoryService with AccountService with SystemSettingsService with ActivityService
with ReferrerAuthenticator
trait IndexControllerBase extends ControllerBase { self: RepositoryService
with SystemSettingsService with ActivityService =>
with SystemSettingsService with ActivityService
with ReferrerAuthenticator =>
val searchForm = mapping(
"query" -> trim(text(required)), // TODO optional?
"owner" -> trim(text(required)),
"repository" -> trim(text(required))
)(SearchForm.apply)
case class SearchForm(query: String, owner: String, repository: String)
get("/"){
val loginAccount = context.loginAccount
@@ -18,4 +33,60 @@ trait IndexControllerBase extends ControllerBase { self: RepositoryService
)
}
post("/search", searchForm){ form =>
redirect(s"${form.owner}/${form.repository}/search?q=${StringUtil.urlEncode(form.query)}")
}
// TODO readable only
get("/:owner/:repository/search")(referrersOnly { repository =>
val owner = params("owner")
val name = params("repository")
val query = params("q")
val target = params.getOrElse("type", "Code")
target.toLowerCase match {
case "issue" => {
// TODO search issue
}
case _ => {
JGitUtil.withGit(getRepositoryDir(owner, name)){ git =>
// TODO search code
val dir = new java.io.File(getTemporaryDir(owner, name), "search")
if(!dir.exists){
val git = Git
.cloneRepository.setDirectory(dir)
.setURI(getRepositoryDir(owner, name).toURI.toString)
.setBranch(repository.repository.defaultBranch)
.call
git.getRepository.close
} else {
val git = Git.open(dir)
git.pull.call
if(git.getRepository.getBranch != repository.repository.defaultBranch){
git.checkout.setName(repository.repository.defaultBranch).call
}
git.getRepository.close
}
search.html.code(searchDirectory(query, dir).map { file =>
FileSearchResult(
file.getAbsolutePath.substring(dir.getAbsolutePath.length + 1).replace('\\', '/'),
new java.util.Date(file.lastModified)
)
}, query, repository)
}
}
}
})
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
}
}
}
case class FileSearchResult(path: String, lastModified: java.util.Date)

View File

@@ -29,7 +29,7 @@
<script src="@assets/zclip/ZeroClipboard.min.js"></script>
</head>
<body>
<form action="@path/search" method="GET">
<form id="search" action="@path/search" method="POST">
<div class="navbar">
<div class="navbar-inner">
<div class="container">
@@ -41,8 +41,14 @@
<a class="brand" href="@path/">GitBucket</a>
<div class="nav-collapse collapse pull-right">
@repository.map { repository =>
@if(loginAccount.isDefined){
<input type="text" name="query" style="width: 300px; margin-top: 0px; margin-bottom: 0px;" placeholder="Search this repository"/>
} else {
<input type="text" name="query" style="width: 300px; margin-top: 5px; margin-bottom: 0px;" placeholder="Search this repository"/>
}
<input type="hidden" name="owner" value="@repository.owner"/>
<input type="hidden" name="repository" value="@repository.name"/>
}
@if(loginAccount.isDefined){
<a href="@url(loginAccount.get.userName)" class="username menu">@avatar(loginAccount.get.userName, 20) @loginAccount.get.userName</a>
<a href="@path/new" class="menu" data-toggle="tooltip" data-placement="bottom" title="Create a new repo"><i class="icon-plus"></i></a>
@@ -65,5 +71,12 @@
<div class="container body">
@body
</div>
<script>
$(function(){
$('#search').submit(function(){
return $.trim($(this).find('input[name=query]').val()) != '';
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,16 @@
@(files: List[app.FileSearchResult], query: String, repository: service.RepositoryService.RepositoryInfo)(implicit context: app.Context)
@import context._
@import view.helpers._
@html.main("Search Results", Some(repository)){
@if(files.isEmpty){
<h4>We couldn't find any code matching '@query'</h4>
} else {
<h4>We've found @files.size code @plural(files.size, "result")</h4>
}
@files.map { file =>
<div>
<div><a href="@url(repository)/blob/@repository.repository.defaultBranch/@file.path">@file.path</a></div>
<div class="muted">@datetime(file.lastModified)</div>
</div>
}
}