mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-08 14:35:52 +01:00
(refs #32)Add plugin install tab
This commit is contained in:
@@ -67,12 +67,15 @@ object JavaScriptPlugin {
|
||||
|
||||
def define(id: String, author: String, url: String, description: String) = new JavaScriptPlugin(id, author, url, description)
|
||||
|
||||
def evaluateJavaScript(script: String): Any = {
|
||||
def evaluateJavaScript(script: String, vars: Map[String, Any] = Map.empty): Any = {
|
||||
val context = JsContext.enter()
|
||||
try {
|
||||
val scope = context.initStandardObjects()
|
||||
scope.put("PluginSystem", scope, PluginSystem)
|
||||
scope.put("JavaScriptPlugin", scope, this)
|
||||
vars.foreach { case (key, value) =>
|
||||
scope.put(key, scope, value)
|
||||
}
|
||||
val result = context.evaluateString(scope, script, "<cmd>", 1, null)
|
||||
result
|
||||
} finally {
|
||||
|
||||
@@ -5,6 +5,7 @@ import javax.servlet.http.{HttpServletResponse, HttpServletRequest}
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import util.Directory._
|
||||
import util.ControlUtil._
|
||||
import org.apache.commons.io.FileUtils
|
||||
|
||||
/**
|
||||
@@ -16,6 +17,7 @@ object PluginSystem {
|
||||
|
||||
private val initialized = new AtomicBoolean(false)
|
||||
private val pluginsMap = scala.collection.mutable.Map[String, Plugin]()
|
||||
private val repositoriesList = scala.collection.mutable.ListBuffer[PluginRepository]()
|
||||
|
||||
def install(plugin: Plugin): Unit = {
|
||||
pluginsMap.put(plugin.id, plugin)
|
||||
@@ -27,25 +29,46 @@ object PluginSystem {
|
||||
pluginsMap.remove(id)
|
||||
}
|
||||
|
||||
def repositories: List[PluginRepository] = repositoriesList.toList
|
||||
|
||||
/**
|
||||
* Initializes the plugin system. Load scripts from GITBUCKET_HOME/plugins.
|
||||
*/
|
||||
def init(): Unit = {
|
||||
if(initialized.compareAndSet(false, true)){
|
||||
// Load installed plugins
|
||||
val pluginDir = new java.io.File(PluginHome)
|
||||
if(pluginDir.exists && pluginDir.isDirectory){
|
||||
pluginDir.listFiles.filter(f => f.isDirectory && !f.getName.startsWith(".")).foreach { dir =>
|
||||
val file = new java.io.File(dir, "plugin.js")
|
||||
if(file.exists && file.isFile){
|
||||
val script = FileUtils.readFileToString(file, "UTF-8")
|
||||
try {
|
||||
JavaScriptPlugin.evaluateJavaScript(script)
|
||||
} catch {
|
||||
case e: Exception => logger.warn(s"Error in plugin loading for ${file.getAbsolutePath}", e)
|
||||
}
|
||||
}
|
||||
installPlugin(dir.getName)
|
||||
}
|
||||
}
|
||||
// Add default plugin repositories
|
||||
repositoriesList += PluginRepository("central", "https://github.com/takezoe/gitbucket_plugins.git")
|
||||
}
|
||||
}
|
||||
|
||||
def installPlugin(id: String): Unit = {
|
||||
val pluginDir = new java.io.File(PluginHome)
|
||||
val javaScriptFile = new java.io.File(pluginDir, id + "/plugin.js")
|
||||
|
||||
if(javaScriptFile.exists && javaScriptFile.isFile){
|
||||
val properties = new java.util.Properties()
|
||||
using(new java.io.FileInputStream(new java.io.File(pluginDir, id + "/plugin.properties"))){ in =>
|
||||
properties.load(in)
|
||||
}
|
||||
|
||||
val script = FileUtils.readFileToString(javaScriptFile, "UTF-8")
|
||||
try {
|
||||
JavaScriptPlugin.evaluateJavaScript(script, Map(
|
||||
"id" -> properties.getProperty("id"),
|
||||
"author" -> properties.getProperty("author"),
|
||||
"url" -> properties.getProperty("url"),
|
||||
"description" -> properties.getProperty("description")
|
||||
))
|
||||
} catch {
|
||||
case e: Exception => logger.warn(s"Error in plugin loading for ${javaScriptFile.getAbsolutePath}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +78,7 @@ object PluginSystem {
|
||||
def globalActions : List[Action] = pluginsMap.values.flatMap(_.globalActions).toList
|
||||
|
||||
// Case classes to hold plug-ins information internally in GitBucket
|
||||
case class PluginRepository(id: String, url: String)
|
||||
case class GlobalMenu(label: String, url: String, icon: String, condition: Context => Boolean)
|
||||
case class RepositoryMenu(label: String, name: String, url: String, icon: String, condition: Context => Boolean)
|
||||
case class Action(path: String, function: (HttpServletRequest, HttpServletResponse) => Any)
|
||||
|
||||
Reference in New Issue
Block a user