Implemented: Downloading tagged contents as zip file.

This commit is contained in:
takezoe
2013-05-05 04:34:39 +09:00
parent afef6f13c6
commit 1e7f7404dc
5 changed files with 82 additions and 6 deletions

View File

@@ -2,7 +2,7 @@ package app
import util.Directory._
import util.Implicits._
import util.{JGitUtil, FileTypeUtil}
import util.{JGitUtil, FileTypeUtil, CompressUtil}
import org.scalatra._
import java.io.File
import java.util.Date
@@ -216,6 +216,47 @@ class RepositoryViewerController extends ControllerBase {
repo.html.tags(JGitUtil.getRepositoryInfo(owner, repository, servletContext))
}
/**
* Download repository contents as an archive.
*/
get("/:owner/:repository/archive/:name"){
val owner = params("owner")
val repository = params("repository")
val name = params("name")
if(name.endsWith(".zip")){
val revision = name.replaceFirst("\\.zip$", "")
val workDir = getDownloadWorkDir(owner, repository, session.getId)
if(workDir.exists){
FileUtils.deleteDirectory(workDir)
}
workDir.mkdirs
// clone the repository
val cloneDir = new File(workDir, revision)
val git = Git.cloneRepository
.setURI(getRepositoryDir(owner, repository).toURI.toString)
.setDirectory(cloneDir)
.call
// checkout the specified revision
git.checkout.setName(revision).call
git.getRepository.close
// remove .git
FileUtils.deleteDirectory(new File(cloneDir, ".git"))
// create zip file
val zipFile = new File(workDir, (if(revision.length == 40) revision.substring(0, 10) else revision) + ".zip")
CompressUtil.zip(zipFile, cloneDir)
contentType = "application/octet-stream"
zipFile
} else {
BadRequest
}
}
/**
* Provides HTML of the file list.
*

View File

@@ -0,0 +1,32 @@
package util
import java.io.File
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
import org.apache.commons.io.FileUtils
import org.apache.commons.io.IOUtils
object CompressUtil {
def zip(dest: File, dir: File): Unit = {
def addDirectoryToZip(out: ZipArchiveOutputStream, dir: File, path: String): Unit = {
dir.listFiles.map { file =>
if(file.isFile){
out.putArchiveEntry(new ZipArchiveEntry(path + "/" + file.getName))
out.write(FileUtils.readFileToByteArray(file))
out.closeArchiveEntry
} else if(file.isDirectory){
addDirectoryToZip(out, file, path + "/" + file.getName)
}
}
}
val out = new ZipArchiveOutputStream(dest)
try {
addDirectoryToZip(out, dir, dir.getName)
} finally {
IOUtils.closeQuietly(out)
}
}
}

View File

@@ -33,6 +33,12 @@ object Directory {
def getRepositoryDir(owner: String, repository: String): File =
new File("%s/%s/%s.git".format(RepositoryHome, owner, repository))
/**
* Temporary directory which is used to create an archive to download repository contents.
*/
def getDownloadWorkDir(owner: String, repository: String, sessionId: String): File =
new File("%s/tmp/%s/%s/download/%s".format(GitBucketHome, owner, repository, sessionId))
/**
* Temporary directory which is used in the repository creation.
* GiyBucket generates initial repository contents in this directory and push them.

View File

@@ -44,7 +44,7 @@ object WikiUtil {
* Returns the directory of the wiki working directory which is cloned from the wiki repository.
*/
def getWikiWorkDir(owner: String, repository: String): File =
new File("%s/tmp/%s/%s.wiki".format(Directory.RepositoryHome, owner, repository))
new File("%s/tmp/%s/%s.wiki".format(Directory.GitBucketHome, owner, repository))
// TODO synchronized?
def createWikiRepository(owner: String, repository: String): Unit = {
@@ -81,9 +81,6 @@ object WikiUtil {
.sortBy(x => x)
}
// TODO
//def getPageHistory(owner: String, repository: String, pageName: String): List[WikiPageHistoryInfo]
// TODO synchronized
/**
* Save the wiki page.

View File

@@ -17,7 +17,7 @@
<td>@tag.name</td>
<td>@helpers.datetime(tag.time)</td>
<td><a href="@path/@repository.owner/@repository.name/tree/@tag.id">@tag.id.substring(0, 10)</a></td>
<td><a href="">ZIP</a></td>
<td><a href="@path/@repository.owner/@repository.name/archive/@(tag.name).zip">ZIP</a></td>
</tr>
}
</table>