diff --git a/src/main/scala/app/ControllerBase.scala b/src/main/scala/app/ControllerBase.scala index 82ea872..2c885b1 100644 --- a/src/main/scala/app/ControllerBase.scala +++ b/src/main/scala/app/ControllerBase.scala @@ -11,8 +11,7 @@ import org.apache.commons.io.FileUtils import model.Account import service.{SystemSettingsService, AccountService} -import javax.servlet.http.{HttpServletResponse, HttpSession, HttpServletRequest} -import java.text.SimpleDateFormat +import javax.servlet.http.{HttpServletResponse, HttpServletRequest} import javax.servlet.{FilterChain, ServletResponse, ServletRequest} import org.scalatra.i18n._ @@ -164,7 +163,7 @@ /** * Base trait for controllers which manages account information. */ -trait AccountManagementControllerBase extends ControllerBase with FileUploadControllerBase { +trait AccountManagementControllerBase extends ControllerBase { self: AccountService => protected def updateImage(userName: String, fileId: Option[String], clearImage: Boolean): Unit = @@ -175,9 +174,9 @@ } } else { fileId.map { fileId => - val filename = "avatar." + FileUtil.getExtension(getUploadedFilename(fileId).get) + val filename = "avatar." + FileUtil.getExtension(session.getAndRemove(Keys.Session.Upload(fileId)).get) FileUtils.moveFile( - getTemporaryFile(fileId), + new java.io.File(getTemporaryDir(session.getId), fileId), new java.io.File(getUserUploadDir(userName), filename) ) updateAvatarImage(userName, Some(filename)) @@ -197,28 +196,3 @@ } } - -/** - * Base trait for controllers which needs file uploading feature. - */ -trait FileUploadControllerBase { - - def generateFileId: String = - new SimpleDateFormat("yyyyMMddHHmmSSsss").format(new java.util.Date(System.currentTimeMillis)) - - def TemporaryDir(implicit session: HttpSession): java.io.File = - new java.io.File(GitBucketHome, s"tmp/_upload/${session.getId}") - - def getTemporaryFile(fileId: String)(implicit session: HttpSession): java.io.File = - new java.io.File(TemporaryDir, fileId) - - // def removeTemporaryFile(fileId: String)(implicit session: HttpSession): Unit = - // getTemporaryFile(fileId).delete() - - def removeTemporaryFiles()(implicit session: HttpSession): Unit = - FileUtils.deleteDirectory(TemporaryDir) - - def getUploadedFilename(fileId: String)(implicit session: HttpSession): Option[String] = - session.getAndRemove[String](Keys.Session.Upload(fileId)) - -} \ No newline at end of file diff --git a/src/main/scala/app/FileUploadController.scala b/src/main/scala/app/FileUploadController.scala index 9950b48..970da6e 100644 --- a/src/main/scala/app/FileUploadController.scala +++ b/src/main/scala/app/FileUploadController.scala @@ -1,31 +1,40 @@ package app -import _root_.util.{Keys, FileUtil} +import util.{Keys, FileUtil} import util.ControlUtil._ +import util.Directory._ import org.scalatra._ -import org.scalatra.servlet.{MultipartConfig, FileUploadSupport} +import org.scalatra.servlet.{MultipartConfig, FileUploadSupport, FileItem} import org.apache.commons.io.FileUtils /** * Provides Ajax based file upload functionality. * - * This servlet saves uploaded file as temporary file and returns the unique id. - * You can get uploaded file using [[app.FileUploadControllerBase#getTemporaryFile()]] with this id. + * This servlet saves uploaded file. */ -class FileUploadController extends ScalatraServlet with FileUploadSupport with FileUploadControllerBase { +class FileUploadController extends ScalatraServlet with FileUploadSupport { configureMultipartHandling(MultipartConfig(maxFileSize = Some(3 * 1024 * 1024))) post("/image"){ - fileParams.get("file") match { - case Some(file) if(FileUtil.isImage(file.name)) => defining(generateFileId){ fileId => - FileUtils.writeByteArrayToFile(getTemporaryFile(fileId), file.get) - session += Keys.Session.Upload(fileId) -> file.name - Ok(fileId) - } - case None => BadRequest + execute { (file, fileId) => + FileUtils.writeByteArrayToFile(new java.io.File(getTemporaryDir(session.getId), fileId), file.get) + session += Keys.Session.Upload(fileId) -> file.name } } -} + post("/image/:owner/:repository"){ + } + + private def execute(f: (FileItem, String) => Unit) = fileParams.get("file") match { + case Some(file) if(FileUtil.isImage(file.name)) => + defining(FileUtil.generateFileId){ fileId => + f(file, fileId) + + Ok(fileId) + } + case _ => BadRequest + } + +} diff --git a/src/main/scala/servlet/SessionCleanupListener.scala b/src/main/scala/servlet/SessionCleanupListener.scala index 87ce1d1..ee4ea7b 100644 --- a/src/main/scala/servlet/SessionCleanupListener.scala +++ b/src/main/scala/servlet/SessionCleanupListener.scala @@ -1,15 +1,16 @@ package servlet import javax.servlet.http.{HttpSessionEvent, HttpSessionListener} -import app.FileUploadControllerBase +import org.apache.commons.io.FileUtils +import util.Directory._ /** * Removes session associated temporary files when session is destroyed. */ -class SessionCleanupListener extends HttpSessionListener with FileUploadControllerBase { +class SessionCleanupListener extends HttpSessionListener { def sessionCreated(se: HttpSessionEvent): Unit = {} - def sessionDestroyed(se: HttpSessionEvent): Unit = removeTemporaryFiles()(se.getSession) + def sessionDestroyed(se: HttpSessionEvent): Unit = FileUtils.deleteDirectory(getTemporaryDir(se.getSession.getId)) } diff --git a/src/main/scala/util/Directory.scala b/src/main/scala/util/Directory.scala index d37577a..1d15f1a 100644 --- a/src/main/scala/util/Directory.scala +++ b/src/main/scala/util/Directory.scala @@ -29,24 +29,10 @@ }).getAbsolutePath val GitBucketConf = new File(GitBucketHome, "gitbucket.conf") - + val RepositoryHome = s"${GitBucketHome}/repositories" val DatabaseHome = s"${GitBucketHome}/data" - - /** - * Repository names of the specified user. - */ - def getRepositories(owner: String): List[String] = - defining(new File(s"${RepositoryHome}/${owner}")){ dir => - if(dir.exists){ - dir.listFiles.filter { file => - file.isDirectory && !file.getName.endsWith(".wiki.git") - }.map(_.getName.replaceFirst("\\.git$", "")).toList - } else { - Nil - } - } /** * Substance directory of the repository. @@ -55,11 +41,23 @@ new File(s"${RepositoryHome}/${owner}/${repository}.git") /** + * Directory for files which are attached to issue. + */ + def getAttachedDir(owner: String, repository: String): File = + new File(s"${RepositoryHome}/${owner}/${repository}/issues") + + /** * Directory for uploaded files by the specified user. */ def getUserUploadDir(userName: String): File = new File(s"${GitBucketHome}/data/${userName}/files") /** + * Root of temporary directories for the upload file. + */ + def getTemporaryDir(sessionId: String): File = + new File(s"${GitBucketHome}/tmp/_upload/${sessionId}") + + /** * Root of temporary directories for the specified repository. */ def getTemporaryDir(owner: String, repository: String): File = diff --git a/src/main/scala/util/FileUtil.scala b/src/main/scala/util/FileUtil.scala index e4c052f..e0978d3 100644 --- a/src/main/scala/util/FileUtil.scala +++ b/src/main/scala/util/FileUtil.scala @@ -4,6 +4,7 @@ import java.net.URLConnection import java.io.File import util.ControlUtil._ +import scala.util.Random object FileUtil { @@ -26,28 +27,12 @@ } def isImage(name: String): Boolean = getMimeType(name).startsWith("image/") - + def isLarge(size: Long): Boolean = (size > 1024 * 1000) - + def isText(content: Array[Byte]): Boolean = !content.contains(0) -// def createZipFile(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) -// } -// } -// } -// -// using(new ZipArchiveOutputStream(dest)){ out => -// addDirectoryToZip(out, dir, dir.getName) -// } -// } + def generateFileId: String = System.currentTimeMillis + Random.alphanumeric.take(10).mkString def getFileName(path: String): String = defining(path.lastIndexOf('/')){ i => if(i >= 0) path.substring(i + 1) else path