diff --git a/src/main/scala/ScalatraBootstrap.scala b/src/main/scala/ScalatraBootstrap.scala index af98e21..b8b523c 100644 --- a/src/main/scala/ScalatraBootstrap.scala +++ b/src/main/scala/ScalatraBootstrap.scala @@ -4,8 +4,9 @@ class ScalatraBootstrap extends LifeCycle { override def init(context: ServletContext) { - context.mount(new CreateRepositoryServlet, "/new") - context.mount(new RepositoryViewerServlet, "/*") + context.mount(new CreateRepositoryController, "/new") + context.mount(new WikiController, "/*") + context.mount(new RepositoryViewerController, "/*") context.addListener(new ServletContextListener(){ def contextInitialized(e: ServletContextEvent): Unit = { diff --git a/src/main/scala/app/CreateRepositoryController.scala b/src/main/scala/app/CreateRepositoryController.scala new file mode 100644 index 0000000..43cecfa --- /dev/null +++ b/src/main/scala/app/CreateRepositoryController.scala @@ -0,0 +1,83 @@ +package app + +import util.Directory._ +import org.scalatra._ +import java.io.File +import org.eclipse.jgit.api.Git +import org.eclipse.jgit.lib._ +import org.apache.commons.io._ +import jp.sf.amateras.scalatra.forms._ + +/** + * Creates new repository. + */ +class CreateRepositoryController extends ControllerBase { + + case class RepositoryCreationForm(name: String, description: String) + + val form = mapping( + "name" -> trim(label("Repository name", text(required, maxlength(40), repository))), + "description" -> trim(label("Description" , text())) + )(RepositoryCreationForm.apply) + + /** + * Show the new repository form. + */ + get("/") { + html.newrepo() + } + + /** + * Create new repository. + */ + post("/", form) { form => + val gitdir = getRepositoryDir(LoginUser, form.name) + val repository = new RepositoryBuilder().setGitDir(gitdir).setBare.build + + repository.create + + val config = repository.getConfig + config.setBoolean("http", null, "receivepack", true) + config.save + + val tmpdir = getInitRepositoryDir(LoginUser, form.name) + try { + // Clone the repository + Git.cloneRepository.setURI(gitdir.toURI.toString).setDirectory(tmpdir).call + + // Create README.md + FileUtils.writeStringToFile(new File(tmpdir, "README.md"), if(form.description.nonEmpty){ + form.name + "\n===============\n\n" + form.description + } else { + form.name + "\n===============\n" + }, "UTF-8") + + val git = Git.open(tmpdir) + git.add.addFilepattern("README.md").call + git.commit.setMessage("Initial commit").call + git.push.call + + } finally { + FileUtils.deleteDirectory(tmpdir) + } + + // redirect to the repository + redirect("/%s/%s".format(LoginUser, form.name)) + } + + /** + * Constraint for the repository name. + */ + def repository: Constraint = new Constraint(){ + def validate(name: String, value: String): Option[String] = { + if(!value.matches("^[a-z0-9\\-_]+$")){ + Some("Repository name contains invalid character.") + } else if(getRepositories(LoginUser).contains(value)){ + Some("Repository already exists.") + } else { + None + } + } + } + +} \ No newline at end of file diff --git a/src/main/scala/app/CreateRepositoryServlet.scala b/src/main/scala/app/CreateRepositoryServlet.scala deleted file mode 100644 index 42fede5..0000000 --- a/src/main/scala/app/CreateRepositoryServlet.scala +++ /dev/null @@ -1,83 +0,0 @@ -package app - -import util.Directory._ -import org.scalatra._ -import java.io.File -import org.eclipse.jgit.api.Git -import org.eclipse.jgit.lib._ -import org.apache.commons.io._ -import jp.sf.amateras.scalatra.forms._ - -/** - * Creates new repository. - */ -class CreateRepositoryServlet extends ServletBase { - - case class RepositoryCreationForm(name: String, description: String) - - val form = mapping( - "name" -> trim(label("Repository name", text(required, maxlength(40), repository))), - "description" -> trim(label("Description" , text())) - )(RepositoryCreationForm.apply) - - /** - * Show the new repository form. - */ - get("/") { - html.newrepo() - } - - /** - * Create new repository. - */ - post("/", form) { form => - val gitdir = getRepositoryDir(LoginUser, form.name) - val repository = new RepositoryBuilder().setGitDir(gitdir).setBare.build - - repository.create - - val config = repository.getConfig - config.setBoolean("http", null, "receivepack", true) - config.save - - val tmpdir = getInitRepositoryDir(LoginUser, form.name) - try { - // Clone the repository - Git.cloneRepository.setURI(gitdir.toURI.toString).setDirectory(tmpdir).call - - // Create README.md - FileUtils.writeStringToFile(new File(tmpdir, "README.md"), if(form.description.nonEmpty){ - form.name + "\n===============\n\n" + form.description - } else { - form.name + "\n===============\n" - }, "UTF-8") - - val git = Git.open(tmpdir) - git.add.addFilepattern("README.md").call - git.commit.setMessage("Initial commit").call - git.push.call - - } finally { - FileUtils.deleteDirectory(tmpdir) - } - - // redirect to the repository - redirect("/%s/%s".format(LoginUser, form.name)) - } - - /** - * Constraint for the repository name. - */ - def repository: Constraint = new Constraint(){ - def validate(name: String, value: String): Option[String] = { - if(!value.matches("^[a-z0-9\\-_]+$")){ - Some("Repository name contains invalid character.") - } else if(getRepositories(LoginUser).contains(value)){ - Some("Repository already exists.") - } else { - None - } - } - } - -} \ No newline at end of file diff --git a/src/main/scala/app/RepositoryViewerController.scala b/src/main/scala/app/RepositoryViewerController.scala new file mode 100644 index 0000000..23ead73 --- /dev/null +++ b/src/main/scala/app/RepositoryViewerController.scala @@ -0,0 +1,237 @@ +package app + +import util.Directory._ +import util.Implicits._ +import util.{JGitUtil, FileTypeUtil} +import org.scalatra._ +import java.io.File +import java.util.Date +import org.eclipse.jgit.api.Git +import org.eclipse.jgit.lib._ +import org.apache.commons.io.FileUtils +import org.eclipse.jgit.treewalk._ +import org.eclipse.jgit.revwalk.RevCommit +import org.eclipse.jgit.diff.DiffEntry.ChangeType +import org.eclipse.jgit.revwalk.RevWalk + +// TODO Should models move to other package? +/** + * The repository data. + * + * @param owner the user name of the repository owner + * @param repository the repository name + * @param url the repository URL + * @param branchList the list of branch names + * @param tags the list of tags + */ +case class RepositoryInfo(owner: String, name: String, url: String, branchList: List[String], tags: List[String]) + +/** + * The file data for the file list of the repository viewer. + * + * @param id the object id + * @param isDirectory whether is it directory + * @param name the file (or directory) name + * @param time the last modified time + * @param message the last commit message + * @param committer the last committer name + */ +case class FileInfo(id: ObjectId, isDirectory: Boolean, name: String, time: Date, message: String, committer: String) + +/** + * The commit data. + * + * @param id the commit id + * @param time the commit time + * @param committer the commiter name + * @param message the commit message + */ +case class CommitInfo(id: String, time: Date, committer: String, message: String){ + def this(rev: org.eclipse.jgit.revwalk.RevCommit) = + this(rev.getName, rev.getCommitterIdent.getWhen, rev.getCommitterIdent.getName, rev.getFullMessage) +} + +case class DiffInfo(changeType: ChangeType, oldPath: String, newPath: String, oldContent: Option[String], newContent: Option[String]) + +/** + * The file content data for the file content view of the repository viewer. + * + * @param viewType "image", "large" or "other" + * @param content the string content + */ +case class ContentInfo(viewType: String, content: Option[String]) + +/** + * The repository viewer. + */ +class RepositoryViewerController extends ControllerBase { + + /** + * Displays user information. + */ + get("/:owner") { + val owner = params("owner") + + html.user(owner, getRepositories(owner).map(JGitUtil.getRepositoryInfo(owner, _, servletContext))) + } + + /** + * Displays the file list of the repository root and the default branch. + */ + get("/:owner/:repository") { + val owner = params("owner") + val repository = params("repository") + + fileList(owner, repository) + } + + /** + * Displays the file list of the repository root and the specified branch. + */ + get("/:owner/:repository/tree/:id") { + val owner = params("owner") + val repository = params("repository") + + fileList(owner, repository, params("id")) + } + + /** + * Displays the file list of the specified path and branch. + */ + get("/:owner/:repository/tree/:id/*") { + val owner = params("owner") + val repository = params("repository") + + fileList(owner, repository, params("id"), multiParams("splat").head) + } + + /** + * Displays the commit list of the specified branch. + */ + get("/:owner/:repository/commits/:branch"){ + val owner = params("owner") + val repository = params("repository") + val branchName = params("branch") + val page = params.getOrElse("page", "1").toInt + + val (logs, hasNext) = JGitUtil.getCommitLog(Git.open(getRepositoryDir(owner, repository)), branchName, page) + + html.commits(branchName, JGitUtil.getRepositoryInfo(owner, repository, servletContext), + logs.splitWith{ (commit1, commit2) => + view.helpers.date(commit1.time) == view.helpers.date(commit2.time) + }, page, hasNext) + } + + /** + * Displays the file content of the specified branch or commit. + */ + get("/:owner/:repository/blob/:id/*"){ + val owner = params("owner") + val repository = params("repository") + val id = params("id") // branch name or commit id + val raw = params.get("raw").getOrElse("false").toBoolean + val path = multiParams("splat").head.replaceFirst("^tree/.+?/", "") + val repositoryInfo = JGitUtil.getRepositoryInfo(owner, repository, servletContext) + + val git = Git.open(getRepositoryDir(owner, repository)) + val commitId = git.getRepository.resolve(id) + + val revWalk = new RevWalk(git.getRepository) + val revCommit = revWalk.parseCommit(commitId) + revWalk.dispose + + @scala.annotation.tailrec + def getPathObjectId(path: String, walk: TreeWalk): ObjectId = walk.next match { + case true if(walk.getPathString == path) => walk.getObjectId(0) + case true => getPathObjectId(path, walk) + } + + val treeWalk = new TreeWalk(git.getRepository) + treeWalk.addTree(revCommit.getTree) + treeWalk.setRecursive(true) + val objectId = getPathObjectId(path, treeWalk) + treeWalk.release + + if(raw){ + // Download + contentType = "application/octet-stream" + JGitUtil.getContent(git, objectId, false) + + } else { + // Viewer + val large = FileTypeUtil.isLarge(git.getRepository.getObjectDatabase.open(objectId).getSize) + val viewer = if(FileTypeUtil.isImage(path)) "image" else if(large) "large" else "text" + val content = ContentInfo(viewer, if(viewer == "text") JGitUtil.getContent(git, objectId, false).map(new String(_, "UTF-8")) else None) + + html.blob(id, repositoryInfo, path.split("/").toList, content, new CommitInfo(revCommit)) + } + } + + /** + * Displays details of the specified commit. + */ + get("/:owner/:repository/commit/:id"){ + val owner = params("owner") + val repository = params("repository") + val id = params("id") + + val git = Git.open(getRepositoryDir(owner, repository)) + + val revWalk = new RevWalk(git.getRepository) + val objectId = git.getRepository.resolve(id) + val revCommit = revWalk.parseCommit(objectId) + revWalk.dispose + + html.commit(id, new CommitInfo(revCommit), JGitUtil.getRepositoryInfo(owner, repository, servletContext), JGitUtil.getDiffs(git, id)) + } + + /** + * Provides HTML of the file list. + * + * @param owner the repository owner + * @param repository the repository name + * @param rev the branch name or commit id(optional) + * @param path the directory path (optional) + * @return HTML of the file list + */ + private def fileList(owner: String, repository: String, revstr: String = "", path: String = ".") = { + val revision = if(revstr.isEmpty){ + Git.open(getRepositoryDir(owner, repository)).getRepository.getBranch + } else { + revstr + } + + val git = Git.open(getRepositoryDir(owner, repository)) + + // get latest commit + val revWalk = new RevWalk(git.getRepository) + val objectId = git.getRepository.resolve(revision) + val revCommit = revWalk.parseCommit(objectId) + revWalk.dispose + + val files = JGitUtil.getFileList(git, revision, path) + + // process README.md + val readme = files.find(_.name == "README.md").map { file => + import org.pegdown._ + val git = Git.open(getRepositoryDir(owner, repository)) + new PegDownProcessor().markdownToHtml(new String(git.getRepository.open(file.id).getBytes, "UTF-8")) + } + + html.files( + // current branch + revision, + // repository + JGitUtil.getRepositoryInfo(owner, repository, servletContext), + // current path + if(path == ".") Nil else path.split("/").toList, + // latest commit + new CommitInfo(revCommit), + // file list + files, + // readme + readme + ) + } + +} \ No newline at end of file diff --git a/src/main/scala/app/RepositoryViewerServlet.scala b/src/main/scala/app/RepositoryViewerServlet.scala deleted file mode 100644 index 6bff314..0000000 --- a/src/main/scala/app/RepositoryViewerServlet.scala +++ /dev/null @@ -1,237 +0,0 @@ -package app - -import util.Directory._ -import util.Implicits._ -import util.{JGitUtil, FileTypeUtil} -import org.scalatra._ -import java.io.File -import java.util.Date -import org.eclipse.jgit.api.Git -import org.eclipse.jgit.lib._ -import org.apache.commons.io.FileUtils -import org.eclipse.jgit.treewalk._ -import org.eclipse.jgit.revwalk.RevCommit -import org.eclipse.jgit.diff.DiffEntry.ChangeType -import org.eclipse.jgit.revwalk.RevWalk - -// TODO Should models move to other package? -/** - * The repository data. - * - * @param owner the user name of the repository owner - * @param repository the repository name - * @param url the repository URL - * @param branchList the list of branch names - * @param tags the list of tags - */ -case class RepositoryInfo(owner: String, name: String, url: String, branchList: List[String], tags: List[String]) - -/** - * The file data for the file list of the repository viewer. - * - * @param id the object id - * @param isDirectory whether is it directory - * @param name the file (or directory) name - * @param time the last modified time - * @param message the last commit message - * @param committer the last committer name - */ -case class FileInfo(id: ObjectId, isDirectory: Boolean, name: String, time: Date, message: String, committer: String) - -/** - * The commit data. - * - * @param id the commit id - * @param time the commit time - * @param committer the commiter name - * @param message the commit message - */ -case class CommitInfo(id: String, time: Date, committer: String, message: String){ - def this(rev: org.eclipse.jgit.revwalk.RevCommit) = - this(rev.getName, rev.getCommitterIdent.getWhen, rev.getCommitterIdent.getName, rev.getFullMessage) -} - -case class DiffInfo(changeType: ChangeType, oldPath: String, newPath: String, oldContent: Option[String], newContent: Option[String]) - -/** - * The file content data for the file content view of the repository viewer. - * - * @param viewType "image", "large" or "other" - * @param content the string content - */ -case class ContentInfo(viewType: String, content: Option[String]) - -/** - * The repository viewer. - */ -class RepositoryViewerServlet extends ServletBase { - - /** - * Displays user information. - */ - get("/:owner") { - val owner = params("owner") - - html.user(owner, getRepositories(owner).map(JGitUtil.getRepositoryInfo(owner, _, servletContext))) - } - - /** - * Displays the file list of the repository root and the default branch. - */ - get("/:owner/:repository") { - val owner = params("owner") - val repository = params("repository") - - fileList(owner, repository) - } - - /** - * Displays the file list of the repository root and the specified branch. - */ - get("/:owner/:repository/tree/:id") { - val owner = params("owner") - val repository = params("repository") - - fileList(owner, repository, params("id")) - } - - /** - * Displays the file list of the specified path and branch. - */ - get("/:owner/:repository/tree/:id/*") { - val owner = params("owner") - val repository = params("repository") - - fileList(owner, repository, params("id"), multiParams("splat").head) - } - - /** - * Displays the commit list of the specified branch. - */ - get("/:owner/:repository/commits/:branch"){ - val owner = params("owner") - val repository = params("repository") - val branchName = params("branch") - val page = params.getOrElse("page", "1").toInt - - val (logs, hasNext) = JGitUtil.getCommitLog(Git.open(getRepositoryDir(owner, repository)), branchName, page) - - html.commits(branchName, JGitUtil.getRepositoryInfo(owner, repository, servletContext), - logs.splitWith{ (commit1, commit2) => - view.helpers.date(commit1.time) == view.helpers.date(commit2.time) - }, page, hasNext) - } - - /** - * Displays the file content of the specified branch or commit. - */ - get("/:owner/:repository/blob/:id/*"){ - val owner = params("owner") - val repository = params("repository") - val id = params("id") // branch name or commit id - val raw = params.get("raw").getOrElse("false").toBoolean - val path = multiParams("splat").head.replaceFirst("^tree/.+?/", "") - val repositoryInfo = JGitUtil.getRepositoryInfo(owner, repository, servletContext) - - val git = Git.open(getRepositoryDir(owner, repository)) - val commitId = git.getRepository.resolve(id) - - val revWalk = new RevWalk(git.getRepository) - val revCommit = revWalk.parseCommit(commitId) - revWalk.dispose - - @scala.annotation.tailrec - def getPathObjectId(path: String, walk: TreeWalk): ObjectId = walk.next match { - case true if(walk.getPathString == path) => walk.getObjectId(0) - case true => getPathObjectId(path, walk) - } - - val treeWalk = new TreeWalk(git.getRepository) - treeWalk.addTree(revCommit.getTree) - treeWalk.setRecursive(true) - val objectId = getPathObjectId(path, treeWalk) - treeWalk.release - - if(raw){ - // Download - contentType = "application/octet-stream" - JGitUtil.getContent(git, objectId, false) - - } else { - // Viewer - val large = FileTypeUtil.isLarge(git.getRepository.getObjectDatabase.open(objectId).getSize) - val viewer = if(FileTypeUtil.isImage(path)) "image" else if(large) "large" else "text" - val content = ContentInfo(viewer, if(viewer == "text") JGitUtil.getContent(git, objectId, false).map(new String(_, "UTF-8")) else None) - - html.blob(id, repositoryInfo, path.split("/").toList, content, new CommitInfo(revCommit)) - } - } - - /** - * Displays details of the specified commit. - */ - get("/:owner/:repository/commit/:id"){ - val owner = params("owner") - val repository = params("repository") - val id = params("id") - - val git = Git.open(getRepositoryDir(owner, repository)) - - val revWalk = new RevWalk(git.getRepository) - val objectId = git.getRepository.resolve(id) - val revCommit = revWalk.parseCommit(objectId) - revWalk.dispose - - html.commit(id, new CommitInfo(revCommit), JGitUtil.getRepositoryInfo(owner, repository, servletContext), JGitUtil.getDiffs(git, id)) - } - - /** - * Provides HTML of the file list. - * - * @param owner the repository owner - * @param repository the repository name - * @param rev the branch name or commit id(optional) - * @param path the directory path (optional) - * @return HTML of the file list - */ - private def fileList(owner: String, repository: String, revstr: String = "", path: String = ".") = { - val revision = if(revstr.isEmpty){ - Git.open(getRepositoryDir(owner, repository)).getRepository.getBranch - } else { - revstr - } - - val git = Git.open(getRepositoryDir(owner, repository)) - - // get latest commit - val revWalk = new RevWalk(git.getRepository) - val objectId = git.getRepository.resolve(revision) - val revCommit = revWalk.parseCommit(objectId) - revWalk.dispose - - val files = JGitUtil.getFileList(git, revision, path) - - // process README.md - val readme = files.find(_.name == "README.md").map { file => - import org.pegdown._ - val git = Git.open(getRepositoryDir(owner, repository)) - new PegDownProcessor().markdownToHtml(new String(git.getRepository.open(file.id).getBytes, "UTF-8")) - } - - html.files( - // current branch - revision, - // repository - JGitUtil.getRepositoryInfo(owner, repository, servletContext), - // current path - if(path == ".") Nil else path.split("/").toList, - // latest commit - new CommitInfo(revCommit), - // file list - files, - // readme - readme - ) - } - -} \ No newline at end of file diff --git a/src/main/scala/app/ServletBase.scala b/src/main/scala/app/ServletBase.scala index fed9331..61f4383 100644 --- a/src/main/scala/app/ServletBase.scala +++ b/src/main/scala/app/ServletBase.scala @@ -9,7 +9,7 @@ /** * Provides generic features for ScalatraServlet implementations. */ -abstract class ServletBase extends ScalatraServlet with ClientSideValidationFormSupport with JacksonJsonSupport { +abstract class ControllerBase extends ScalatraFilter with ClientSideValidationFormSupport with JacksonJsonSupport { implicit val jsonFormats = DefaultFormats diff --git a/src/main/scala/app/UsersController.scala b/src/main/scala/app/UsersController.scala new file mode 100644 index 0000000..ddd5c95 --- /dev/null +++ b/src/main/scala/app/UsersController.scala @@ -0,0 +1,9 @@ +package app + +class UsersController extends ControllerBase { + + get("/"){ + + } + +} \ No newline at end of file diff --git a/src/main/scala/app/UsersServlet.scala b/src/main/scala/app/UsersServlet.scala deleted file mode 100644 index e28c14e..0000000 --- a/src/main/scala/app/UsersServlet.scala +++ /dev/null @@ -1,9 +0,0 @@ -package app - -class UsersServlet extends ServletBase { - - get("/"){ - - } - -} \ No newline at end of file diff --git a/src/main/scala/app/WikiController.scala b/src/main/scala/app/WikiController.scala new file mode 100644 index 0000000..e31a1ee --- /dev/null +++ b/src/main/scala/app/WikiController.scala @@ -0,0 +1,14 @@ +package app + +import util.{WikiUtil, JGitUtil} + +class WikiController extends ControllerBase { + + get("/:owner/:repository/wiki"){ + val owner = params("owner") + val repository = params("repository") + + html.wiki(WikiUtil.getPage(owner, repository, "Home"), JGitUtil.getRepositoryInfo(owner, repository, servletContext)) + } + +} \ No newline at end of file diff --git a/src/main/scala/util/WikiUtil.scala b/src/main/scala/util/WikiUtil.scala index 6daf794..5620687 100644 --- a/src/main/scala/util/WikiUtil.scala +++ b/src/main/scala/util/WikiUtil.scala @@ -1,77 +1,97 @@ -package util - -import java.io.File -import java.util.Date -import org.eclipse.jgit.api.Git -import org.apache.commons.io.FileUtils - -object WikiUtil { - - /** - * The model for wiki page. - * - * @param name the page name +package util + +import java.io.File +import java.util.Date +import org.eclipse.jgit.api.Git +import org.apache.commons.io.FileUtils +import org.eclipse.jgit.lib.RepositoryBuilder + +object WikiUtil { + + /** + * The model for wiki page. + * + * @param name the page name * @param content the page content - */ - case class WikiPageInfo(name: String, content: String) - - /** - * The model for wiki page history. - * - * @param name the page name - * @param committer the committer the committer - * @param message the commit message + */ + case class WikiPageInfo(name: String, content: String) + + /** + * The model for wiki page history. + * + * @param name the page name + * @param committer the committer the committer + * @param message the commit message * @param date the commit date - */ - case class WikiPageHistoryInfo(name: String, committer: String, message: String, date: Date) - - /** + */ + case class WikiPageHistoryInfo(name: String, committer: String, message: String, date: Date) + + /** * Returns the directory of the wiki repository. - */ - def getWikiRepositoryDir(owner: String, repository: String): File = - new File("%s/%s/%s-wiki.git".format(Directory.RepositoryHome, owner, repository)) - - /** + */ + def getWikiRepositoryDir(owner: String, repository: String): File = + new File("%s/%s/%s-wiki.git".format(Directory.RepositoryHome, owner, repository)) + + /** * 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)) - - - /** + */ + def getWikiWorkDir(owner: String, repository: String): File = + new File("%s/tmp/%s/%s-wiki".format(Directory.RepositoryHome, owner, repository)) + + // TODO synchronized? + def createWikiRepository(owner: String, repository: String): Unit = { + val dir = getWikiRepositoryDir(owner, repository) + if(!dir.exists){ + val repo = new RepositoryBuilder().setGitDir(dir).setBare.build + repo.create + } + } + + /** * Returns the wiki page. - */ - def getPage(owner: String, repository: String, pageName: String): Option[WikiPageInfo] = { - val git = Git.open(getWikiRepositoryDir(owner, repository)) - JGitUtil.getFileList(git, "master", ".").find(_.name == pageName).map { file => - WikiPageInfo(file.name, new String(git.getRepository.open(file.id).getBytes, "UTF-8")) - } - } - - // TODO - //def getPageHistory(owner: String, repository: String, pageName: String): List[WikiPageHistoryInfo] - - // TODO synchronized - /** - * Save the wiki page. - */ - def savePage(owner: String, repository: String, pageName: String, content: String, committer: String, message: String): Unit = { - val workDir = getWikiWorkDir(owner, repository) - - // clone - if(!workDir.exists){ - Git.cloneRepository.setURI(getWikiRepositoryDir(owner, repository).toURI.toString).setDirectory(workDir).call - } - - // write as file - val file = new File(workDir, pageName + ".md") - FileUtils.writeStringToFile(file, content, "UTF-8") - - // commit and push - val cloned = Git.open(workDir) - cloned.add.addFilepattern(file.getName).call - cloned.commit.setAuthor(committer, committer + "@devnull").setMessage(message).call - cloned.push.call - } - + */ + def getPage(owner: String, repository: String, pageName: String): Option[WikiPageInfo] = { + createWikiRepository(owner, repository) + val git = Git.open(getWikiRepositoryDir(owner, repository)) + try { + JGitUtil.getFileList(git, "master", ".").find(_.name == pageName).map { file => + WikiPageInfo(file.name, new String(git.getRepository.open(file.id).getBytes, "UTF-8")) + } + } catch { + // TODO no commit, but it should not judge by exception. + case e: NullPointerException => None + } + } + + // TODO + // def getPageList(owner: String, repository: String): List[WikiPageHistoryInfo] + + // TODO + //def getPageHistory(owner: String, repository: String, pageName: String): List[WikiPageHistoryInfo] + + // TODO synchronized + /** + * Save the wiki page. + */ + def savePage(owner: String, repository: String, pageName: String, content: String, committer: String, message: String): Unit = { + createWikiRepository(owner, repository) + + val workDir = getWikiWorkDir(owner, repository) + + // clone + if(!workDir.exists){ + Git.cloneRepository.setURI(getWikiRepositoryDir(owner, repository).toURI.toString).setDirectory(workDir).call + } + + // write as file + val file = new File(workDir, pageName + ".md") + FileUtils.writeStringToFile(file, content, "UTF-8") + + // commit and push + val cloned = Git.open(workDir) + cloned.add.addFilepattern(file.getName).call + cloned.commit.setAuthor(committer, committer + "@devnull").setMessage(message).call + cloned.push.call + } + } \ No newline at end of file diff --git a/src/main/twirl/blob.scala.html b/src/main/twirl/blob.scala.html index 1ce5d21..5bf9e06 100644 --- a/src/main/twirl/blob.scala.html +++ b/src/main/twirl/blob.scala.html @@ -2,7 +2,7 @@ @import context._ @import view.helpers @main(repository.owner+"/"+repository.name) { - @header(branch, repository) + @header("code", repository) @navtab(branch, repository, "files")
@repository.name / diff --git a/src/main/twirl/commit.scala.html b/src/main/twirl/commit.scala.html index c2ac5fc..6feef66 100644 --- a/src/main/twirl/commit.scala.html +++ b/src/main/twirl/commit.scala.html @@ -1,115 +1,115 @@ -@(branch: String, commit: app.CommitInfo, repository: app.RepositoryInfo, diffs: Seq[app.DiffInfo])(implicit context: app.Context) -@import context._ -@import view.helpers -@import org.eclipse.jgit.diff.DiffEntry.ChangeType -@main(helpers.cut(commit.message, 20)){ - @header(branch, repository) - @navtab(branch, repository, "commits") - - - - - - - -
-
@helpers.format(commit.message)
-
@branch
-
- @commit.committer @helpers.datetime(commit.time) -
- commit @commit.id -
-
- - @diffs.zipWithIndex.map { case (diff, i) => - - - - - - - - -
- @if(diff.changeType == ChangeType.COPY || diff.changeType == ChangeType.RENAME){ - @diff.oldPath -> @diff.newPath - } - @if(diff.changeType == ChangeType.ADD || diff.changeType == ChangeType.DELETE || diff.changeType == ChangeType.MODIFY){ - @diff.newPath - } - -
- @if(diff.newContent != None || diff.oldContent != None){ -
- - - } else { - Too big file not shown - } -
- } -} - - - - - + + + + \ No newline at end of file diff --git a/src/main/twirl/commits.scala.html b/src/main/twirl/commits.scala.html index a855595..5d2d032 100644 --- a/src/main/twirl/commits.scala.html +++ b/src/main/twirl/commits.scala.html @@ -2,7 +2,7 @@ @import context._ @import view.helpers @main(repository.owner+"/"+repository.name) { - @header(branch, repository) + @header("code", repository) @navtab(branch, repository, "commits")
@repository.name / Commit History diff --git a/src/main/twirl/files.scala.html b/src/main/twirl/files.scala.html index 8b6abec..786d1d9 100644 --- a/src/main/twirl/files.scala.html +++ b/src/main/twirl/files.scala.html @@ -2,7 +2,7 @@ @import context._ @import view.helpers @main(repository.owner+"/"+repository.name) { - @header(branch, repository) + @header("code", repository) @navtab(branch, repository, "files")
@repository.name / diff --git a/src/main/twirl/header.scala.html b/src/main/twirl/header.scala.html index e6a534b..a88f1d0 100644 --- a/src/main/twirl/header.scala.html +++ b/src/main/twirl/header.scala.html @@ -1,4 +1,4 @@ -@(branch: String, repository: app.RepositoryInfo)(implicit context: app.Context) +@(active: String, repository: app.RepositoryInfo)(implicit context: app.Context) @import context._
@repository.owner / @repository.name @@ -6,10 +6,10 @@ diff --git a/src/main/twirl/wiki.scala.html b/src/main/twirl/wiki.scala.html new file mode 100644 index 0000000..f138263 --- /dev/null +++ b/src/main/twirl/wiki.scala.html @@ -0,0 +1,11 @@ +@(page: Option[util.WikiUtil.WikiPageInfo], repository: app.RepositoryInfo)(implicit context: app.Context) +@main("Wiki"){ + @header("wiki", repository) + + xxxx +} \ No newline at end of file