Ver código fonte

Using futures for command handlers

ekardnam 4 anos atrás
pai
commit
ac827cebf6

+ 23 - 19
src/main/scala/org/congressodeiradicali/karlmarx/BanPlugin.scala

@@ -1,8 +1,7 @@
 package org.congressodeiradicali.karlmarx
-import com.bot4s.telegram.api.declarative.CommandFilterMagnet
 import com.bot4s.telegram.models.Message
 
-import scala.util.{Failure, Success}
+import scala.concurrent.{ExecutionContext, Future, blocking}
 
 class BanPlugin(localizer: Localizer, bot: Bot) extends Plugin {
   // override var handlers: Map[CommandFilterMagnet, Handler] = ...
@@ -12,24 +11,29 @@ class BanPlugin(localizer: Localizer, bot: Bot) extends Plugin {
     user.syncAfterInit{user => user.canBanUsers}{_ => false}
   }
 
-  onCommand("ban", { msg =>
-    val text = msg.replyToMessage.fold {
-      LocalizableString.BAN_FAILED_REPLY
-    } { message =>
-      message.from.fold {
-        LocalizableString.BAN_FAILED_INVALID_USER
-      } { u =>
-        val user = new BotUser(u, message.chat, bot)
-        user.init() map {
-          case Success(_) if user.isAdmin => LocalizableString.BAN_FAILED_BAN_ADMIN
-          case Success(_) => {
-            user.ban()
-            LocalizableString.BAN_SUCCESSFUL
+  onCommand("ban") { implicit msg =>
+    Future {
+      val text = msg.replyToMessage.fold {
+        LocalizableString.BAN_FAILED_REPLY
+      } { message =>
+        message.from.fold {
+          LocalizableString.BAN_FAILED_INVALID_USER
+        } { u =>
+          val user = new BotUser(u, message.chat, bot)
+          blocking {
+            user syncAfterInit { botuser =>
+              if (botuser.isAdmin || botuser.isCreator) {
+                LocalizableString.BAN_FAILED_BAN_ADMIN
+              } else {
+                user.ban()
+                LocalizableString.BAN_SUCCESSFUL
+              }
+            } { _ => LocalizableString.BAN_FAILED }
           }
-          case Failure(_) => LocalizableString.BAN_FAILED
         }
       }
-    }
-    Some(localizer.getString(text))
-  })
+
+      Some(localizer.getString(text))
+    }(ExecutionContext.global)
+  }
 }

+ 8 - 2
src/main/scala/org/congressodeiradicali/karlmarx/Bot.scala

@@ -74,12 +74,18 @@ class Bot(val token: String) extends TelegramBot
   }
 
   onExtMessage { case (message, botUser) =>
+
     using(command) { cmd =>
       val promises = plugins
         .flatMap(_.handlers)
         .filter(runAgainst(_, botUser, cmd)) // Filter handlers that match the command
-        .flatMap(_._2(message)) // Run the handler
-        .map(reply(_)(message).void) // Send replies
+        .map(_._2(message)) // Run the handler
+        .map {
+          _.map {
+            case Some(s) => reply(s)(message).void
+          }
+        } // Send replies
+
       Future.sequence(promises).flatMap(_ => Future{unit}) // Discard the content
     }(message)
   }

+ 7 - 3
src/main/scala/org/congressodeiradicali/karlmarx/Plugin.scala

@@ -1,13 +1,17 @@
 package org.congressodeiradicali.karlmarx
 
-import com.bot4s.telegram.api.declarative.{Action, CommandFilterMagnet}
+import com.bot4s.telegram.api.declarative.CommandFilterMagnet
 import com.bot4s.telegram.models.Message
 
+import scala.concurrent.Future
+
 trait Plugin {
-  type Handler = Message => Option[String]
+  type Handler = Message => Future[Option[String]]
   type HandlerPair = (CommandFilterMagnet, Handler)
+
   var handlers: Map[CommandFilterMagnet, Handler]
-  def onCommand(filter: CommandFilterMagnet, action: Handler): Unit = {
+
+  def onCommand(filter: CommandFilterMagnet)(action: Handler): Unit = {
     val pair: HandlerPair = (filter, action)
     handlers += pair
   }