Plugin manager stuff

This commit is contained in:
ekardnam 2019-07-08 14:50:35 +02:00
parent 59511fd829
commit 11cef30d8e
9 changed files with 140 additions and 36 deletions

View file

@ -10,6 +10,5 @@ libraryDependencies ++= Seq(
libraryDependencies ++= Seq(
"net.debasishg" %% "redisclient" % "3.10"
)
libraryDependencies += "com.bot4s" %% "telegram-core" % "4.2.0-RC1"
mainClass := Some("Runner")
mainClass := Some("org.congressodeiradicali.karlmarx.Runner")

View file

@ -22,6 +22,7 @@ import com.bot4s.telegram.api.declarative.{Command, Commands}
import com.bot4s.telegram.clients.ScalajHttpClient
import com.bot4s.telegram.future.{Polling, TelegramBot}
import com.bot4s.telegram.models.{Message, User}
import org.congressodeiradicali.karlmarx.coreplugins.{BanPlugin, EchoPlugin, PluginManagerPlugin}
import slogging.{LogLevel, LoggerConfig, PrintLoggerFactory}
import scala.concurrent.Future
@ -42,6 +43,12 @@ class Bot(val token: String) extends TelegramBot
var plugins: List[Plugin] = List[Plugin](new PluginManagerPlugin(localizer, this))
def getPluginManager() : PluginManagerPlugin = plugins.head.asInstanceOf[PluginManagerPlugin]
// load core plugins
getPluginManager().managePlugin(new BanPlugin(localizer, this))
getPluginManager().managePlugin(new EchoPlugin(localizer, this))
def runAgainst(handlerPair: Plugin#HandlerPair, botUser: Option[User], cmd: Command): Boolean = {
handlerPair._1
.to(botUser.flatMap(_.username)) // Apply filter to bot username

View file

@ -1,12 +0,0 @@
package org.congressodeiradicali.karlmarx
import com.bot4s.telegram.api.declarative.{CommandFilterMagnet, CommandImplicits}
import com.bot4s.telegram.models.Message
import scala.concurrent.{ExecutionContext, Future, blocking}
class EchoPlugin(localizer: Localizer, bot: Bot) extends Plugin with CommandImplicits {
override var handlers: Map[CommandFilterMagnet, Handler] = Map {
stringToCommandFilter("echo") -> { msg => Future { msg.text }(ExecutionContext.global) }
}
}

View file

@ -9,5 +9,16 @@ trait Plugin {
type Handler = Message => Future[Option[String]]
type HandlerPair = (CommandFilterMagnet, Handler)
val name: String
val description: String
val license: String
val author: String
/**
* A string that identifies the plugin
* used for loading and unloading it with bot commands
*/
val identifier: String
var handlers: Map[CommandFilterMagnet, Handler]
}

View file

@ -1,20 +0,0 @@
package org.congressodeiradicali.karlmarx
import com.bot4s.telegram.api.declarative.{CommandFilterMagnet, CommandImplicits}
import scala.concurrent.{ExecutionContext, Future}
class PluginManagerPlugin(localizer: Localizer, bot: Bot) extends Plugin with CommandImplicits {
override var handlers: Map[CommandFilterMagnet, Handler] = Map {
stringToCommandFilter("enable") -> { msg =>
val response = msg.text.map {
case "echo" => Some(new EchoPlugin(localizer, bot))
case "ban" => Some(new BanPlugin(localizer, bot))
case _ => None
}.map {
case Some(plugin) => bot.plugins :+= plugin; "Added."
}
Future { response }(ExecutionContext.global)
}
}
}

View file

@ -1,10 +1,17 @@
package org.congressodeiradicali.karlmarx
package org.congressodeiradicali.karlmarx.coreplugins
import com.bot4s.telegram.api.declarative.{CommandFilterMagnet, CommandImplicits}
import org.congressodeiradicali.karlmarx._
import scala.concurrent.{ExecutionContext, Future}
import scala.util.{Failure, Success}
class BanPlugin(localizer: Localizer, bot: Bot) extends Plugin with CommandImplicits {
class BanPlugin(localizer: Localizer, bot: Bot) extends CorePlugin with CommandImplicits {
override val name: String = "Ban Plugin"
override val description: String = "Ban users and unban them"
override val identifier: String = "ban"
override var handlers: Map[CommandFilterMagnet, Handler] = Map {
stringToCommandFilter("ban") -> { msg =>

View file

@ -0,0 +1,10 @@
package org.congressodeiradicali.karlmarx.coreplugins
import org.congressodeiradicali.karlmarx.Plugin
trait CorePlugin extends Plugin {
override val license = "GNU AGPL"
override val author = "Congresso dei Radicali"
}

View file

@ -0,0 +1,18 @@
package org.congressodeiradicali.karlmarx.coreplugins
import com.bot4s.telegram.api.declarative.{CommandFilterMagnet, CommandImplicits}
import org.congressodeiradicali.karlmarx.{Bot, Localizer}
import scala.concurrent.{ExecutionContext, Future}
class EchoPlugin(localizer: Localizer, bot: Bot) extends CorePlugin with CommandImplicits {
override val name: String = "Echo Plugin"
override val description: String = "An echoing plugin"
override val identifier: String = "echo"
override var handlers: Map[CommandFilterMagnet, Handler] = Map {
stringToCommandFilter("echo") -> { msg => Future { msg.text }(ExecutionContext.global) }
}
}

View file

@ -0,0 +1,84 @@
package org.congressodeiradicali.karlmarx.coreplugins
import com.bot4s.telegram.api.declarative.{CommandFilterMagnet, CommandImplicits}
import com.bot4s.telegram.models.Message
import org.congressodeiradicali.karlmarx.{Bot, Localizer, Plugin}
import scala.concurrent.{ExecutionContext, Future}
class PluginManagerPlugin(localizer: Localizer, bot: Bot) extends CorePlugin with CommandImplicits {
override val name = "Plugin Manager"
override val description = "Manages other plugins"
override val identifier = "pluginmanager"
var managedPlugins: Map[String, Plugin] = Map()
var pluginStatus: Map[String, Boolean] = Map()
def managePlugin(plugin: Plugin) = {
managedPlugins += (plugin.identifier -> plugin)
pluginStatus += (plugin.identifier -> false)
}
def enableByIdentifier(id: String) : Boolean = managedPlugins.get(id).fold {
false
} { plugin =>
bot.plugins :+= plugin
pluginStatus = pluginStatus.updated(plugin.identifier, true)
true
}
def disableByIdentifier(id: String) : Boolean = managedPlugins.get(id).fold { /*checks if the plugin is managed*/
false
} { plugin =>
bot.plugins = bot.plugins.filter { _.identifier != plugin.identifier }
pluginStatus = pluginStatus.updated(plugin.identifier, false)
true
}
override var handlers: Map[CommandFilterMagnet, Handler] = Map {
stringToCommandFilter("enable") -> { msg : Message =>
val response = msg.text.fold {
"Enter a plugin name"
} { text =>
if (enableByIdentifier(text)) {
"Enabled!"
} else {
"Plugin not found"
}
}
Future { Some(response) }(ExecutionContext.global)
}
stringToCommandFilter("disable") -> { msg : Message =>
val response = msg.text.fold {
"Enter a plugin name"
} { text =>
if (disableByIdentifier(text)) {
"Disabled!"
} else {
"Plugin not found"
}
}
Future { Some(response) }(ExecutionContext.global)
}
stringToCommandFilter("status") -> { _ =>
var response = ""
pluginStatus.foreach { pair =>
response += managedPlugins.get(pair._1).fold {
// ignore and do the rest
""
} { plugin =>
s"${plugin.name}. Status: ${if (pair._2) "UP" else "DOWN"}"
}
}
Future { Some(response) }(ExecutionContext.global)
}
}
}