diff --git a/src/main/scala/org/congressodeiradicali/karlmarx/Bot.scala b/src/main/scala/org/congressodeiradicali/karlmarx/Bot.scala
index 3ca4261..6e89a31 100644
--- a/src/main/scala/org/congressodeiradicali/karlmarx/Bot.scala
+++ b/src/main/scala/org/congressodeiradicali/karlmarx/Bot.scala
@@ -17,6 +17,8 @@
package org.congressodeiradicali.karlmarx
+import java.io.File
+
import com.bot4s.telegram.api.RequestHandler
import com.bot4s.telegram.api.declarative.{Command, Commands}
import com.bot4s.telegram.clients.ScalajHttpClient
@@ -52,6 +54,21 @@ class Bot(val token: String) extends TelegramBot
plugin(new SetPlugin(this))
)
+ // Load external plugins
+
+ val pluginLoader: PluginLoader = new JARPluginLoader()
+
+ private def loadExternalPlugins = {
+ val d = new File("plugins")
+ if (d.exists && d.isDirectory) {
+ d.listFiles().filter(_.isFile).map(pluginLoader.loadFromFile)
+ }
+ }
+
+ loadExternalPlugins
+
+ ////////////////////////
+
// Future[Option[T]] is just two wrappers; remove the inner, useless one
def collapseFutureOption[T](arg: Future[Option[T]]): Future[T] = arg.flatMap {
case Some(x) => Future(x)
diff --git a/src/main/scala/org/congressodeiradicali/karlmarx/JARPluginLoader.scala b/src/main/scala/org/congressodeiradicali/karlmarx/JARPluginLoader.scala
new file mode 100644
index 0000000..8ac225e
--- /dev/null
+++ b/src/main/scala/org/congressodeiradicali/karlmarx/JARPluginLoader.scala
@@ -0,0 +1,65 @@
+/*
+ This file is part of karl-marx.
+
+ karl-marx is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ karl-marx is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with karl-marx. If not, see .
+ */
+
+package org.congressodeiradicali.karlmarx
+
+import java.io.File
+import java.net.URL
+import java.util.Properties
+import java.util.jar.JarFile
+
+import scala.reflect.internal.util.ScalaClassLoader.URLClassLoader
+import scala.util.{Failure, Success, Try}
+
+class JARPluginLoader extends PluginLoader {
+
+ final val MANIFEST_LOCATION = "plugin-manifest.properties"
+ // manifest structure is
+ // package=some.package
+ // class=PluginClassName
+
+
+ override def loadFromFile(file: File): Try[Plugin] = {
+ val jarFile = new JarFile(file)
+ val manifestInputStream = jarFile.getInputStream(jarFile.getEntry(MANIFEST_LOCATION))
+
+ val props = new Properties()
+ props.load(manifestInputStream)
+
+ manifestInputStream.close()
+
+ val `package` = props.getProperty("package")
+ val `class` = props.getProperty("class")
+
+ val fullClassName = s"${`package`}.${`class`}"
+
+ try {
+ val url = file.toURI.toURL
+ val jarUrl = s"jar:${url.toString}!/"
+ val urls = Seq[URL](new URL(jarUrl))
+ val ucl = new URLClassLoader(urls, null)
+
+ // TODO deprecation
+ val plugin = Class.forName(fullClassName, true, ucl).newInstance().asInstanceOf[Plugin]
+ Success(plugin)
+ } catch {
+ case e: Throwable => Failure(e)
+ }
+
+ }
+
+}
diff --git a/src/main/scala/org/congressodeiradicali/karlmarx/Localizer.scala b/src/main/scala/org/congressodeiradicali/karlmarx/Localizer.scala
index 3b83637..5e8604a 100644
--- a/src/main/scala/org/congressodeiradicali/karlmarx/Localizer.scala
+++ b/src/main/scala/org/congressodeiradicali/karlmarx/Localizer.scala
@@ -33,7 +33,6 @@ object Locales {
(LocalizableString.BAN_UNAUTHORIZED, "Only an administrator can ban users"),
(LocalizableString.BAN_SUCCESSFUL, "User was banned successfully"),
- (LocalizableString.BAN_FAILED, "Cannot ban, something went wrong"),
(LocalizableString.BAN_FAILED_INVALID_USER, "Cannot ban, invalid user"),
(LocalizableString.BAN_FAILED_BAN_ADMIN, "Cannot ban an admin user"),
(LocalizableString.BAN_FAILED_REPLY, "Please reply to a message to ban someone"),
@@ -49,7 +48,6 @@ object Locales {
(LocalizableString.BAN_UNAUTHORIZED, "Solo un amministratore può bannare gli utenti"),
(LocalizableString.BAN_SUCCESSFUL, "Utente bannato con successo"),
- (LocalizableString.BAN_FAILED, "Non sono riuscito a bannare, qualcosa è andato storto"),
(LocalizableString.BAN_FAILED_INVALID_USER, "Impossibile bannare, utente non valido"),
(LocalizableString.BAN_FAILED_BAN_ADMIN, "Non puoi bannare un admin"),
(LocalizableString.BAN_FAILED_REPLY, "Rispondi a un messaggio per bannare qualcuno"),
diff --git a/src/main/scala/org/congressodeiradicali/karlmarx/PluginLoader.scala b/src/main/scala/org/congressodeiradicali/karlmarx/PluginLoader.scala
new file mode 100644
index 0000000..9cb613a
--- /dev/null
+++ b/src/main/scala/org/congressodeiradicali/karlmarx/PluginLoader.scala
@@ -0,0 +1,28 @@
+/*
+ This file is part of karl-marx.
+
+ karl-marx is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ karl-marx is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with karl-marx. If not, see .
+ */
+
+package org.congressodeiradicali.karlmarx
+
+import java.io.File
+
+import scala.util.Try
+
+trait PluginLoader {
+
+ def loadFromFile(file: File): Try[Plugin]
+
+}
diff --git a/src/main/scala/org/congressodeiradicali/karlmarx/coreplugins/BanPlugin.scala b/src/main/scala/org/congressodeiradicali/karlmarx/coreplugins/BanPlugin.scala
index 076d72c..f2ad0b5 100644
--- a/src/main/scala/org/congressodeiradicali/karlmarx/coreplugins/BanPlugin.scala
+++ b/src/main/scala/org/congressodeiradicali/karlmarx/coreplugins/BanPlugin.scala
@@ -18,11 +18,9 @@
package org.congressodeiradicali.karlmarx.coreplugins
import com.bot4s.telegram.api.declarative.{CommandFilterMagnet, CommandImplicits}
-import org.congressodeiradicali.karlmarx.LocalizableString.LocalizableString
import org.congressodeiradicali.karlmarx._
import scala.concurrent.Future
-import scala.util.{Failure, Success}
class BanPlugin(bot: Bot) extends CorePlugin with CommandImplicits {
@@ -32,33 +30,25 @@ class BanPlugin(bot: Bot) extends CorePlugin with CommandImplicits {
override val identifier: String = "ban"
override var commandHandlers: Map[CommandFilterMagnet, CommandHandler] = Map {
- stringToCommandFilter("ban") -> { (msg, argv) =>
+ stringToCommandFilter("ban") -> { (msg, _) =>
- var futureLocalizedString: Future[LocalizableString] = null
-
- if (argv.length > 0) {
-
- } else {
- futureLocalizedString = msg.replyToMessage.fold {
- Future { LocalizableString.BAN_FAILED_REPLY }
- } { reply =>
- reply.from.fold {
- Future { LocalizableString.BAN_FAILED_INVALID_USER }
- } { user =>
- bot.requestBotUser(user, msg.chat).map { target =>
- if (target.isAdmin || target.isCreator)
- LocalizableString.BAN_FAILED_BAN_ADMIN
- else {
- target.ban()
- LocalizableString.BAN_SUCCESSFUL
- }
+ val futureLocalizedString = msg.replyToMessage.fold {
+ Future { LocalizableString.BAN_FAILED_REPLY }
+ } { reply =>
+ reply.from.fold {
+ Future { LocalizableString.BAN_FAILED_INVALID_USER }
+ } { user =>
+ bot.requestBotUser(user, msg.chat).map { target =>
+ if (target.isAdmin || target.isCreator)
+ LocalizableString.BAN_FAILED_BAN_ADMIN
+ else {
+ target.ban()
+ LocalizableString.BAN_SUCCESSFUL
}
}
}
-
}
-
futureLocalizedString.map { s => Some(bot.localize(s)) }
}
}
diff --git a/src/main/scala/org/congressodeiradicali/karlmarx/coreplugins/PluginManagerPlugin.scala b/src/main/scala/org/congressodeiradicali/karlmarx/coreplugins/PluginManagerPlugin.scala
index 0370d40..56d742c 100644
--- a/src/main/scala/org/congressodeiradicali/karlmarx/coreplugins/PluginManagerPlugin.scala
+++ b/src/main/scala/org/congressodeiradicali/karlmarx/coreplugins/PluginManagerPlugin.scala
@@ -71,7 +71,7 @@ class PluginManagerPlugin(bot: Bot) extends CorePlugin with CommandImplicits {
Some(
bot.plugins.values.map { plugin =>
s"${plugin.identifier}: ${plugin.name}. ${plugin.description}. License: ${plugin.license}. Author: ${plugin.author}"
- }.mkString("\n")
+ }.mkString("\n\n")
)
}
},