diff --git a/build.gradle b/build.gradle
index 143d5f1..f62606e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,6 @@
plugins {
id 'application'
- id 'com.github.ben-manes.versions' version '0.40.0'
+ id 'com.github.ben-manes.versions' version '0.41.0'
id 'idea'
id 'io.gitlab.arturbosch.detekt' version '1.19.0'
id 'java'
@@ -78,7 +78,7 @@ dependencies {
testImplementation 'com.willowtreeapps.assertk:assertk-jvm:0.25'
// testImplementation 'org.mockito.kotlin:mockito-kotlin:4.0.0'
// testImplementation "org.mockito:mockito-core:4.0.0"
- testImplementation 'org.testng:testng:7.4.0'
+ testImplementation 'org.testng:testng:7.5'
}
test {
diff --git a/config/detekt/baseline.xml b/config/detekt/baseline.xml
index 7f49882..5f0626e 100644
--- a/config/detekt/baseline.xml
+++ b/config/detekt/baseline.xml
@@ -42,7 +42,8 @@
MagicNumber:WorldTime.kt$WorldTime.Companion$3600
MagicNumber:WorldTime.kt$WorldTime.Companion$60
MagicNumber:WorldTime.kt$WorldTime.Companion$86.4
- NestedBlockDepth:Addons.kt$Addons$ fun add(command: AbstractCommand, props: Properties)
+ NestedBlockDepth:Addons.kt$Addons$ fun add(command: AbstractCommand)
+ NestedBlockDepth:Addons.kt$Addons$ fun add(module: AbstractModule)
NestedBlockDepth:Comment.kt$Comment$override fun commandResponse(channel: String, args: String, event: GenericMessageEvent)
NestedBlockDepth:CurrencyConverter.kt$CurrencyConverter.Companion$ @JvmStatic fun convertCurrency(query: String): Message
NestedBlockDepth:EntryLink.kt$EntryLink$ private fun setTags(tags: List<String?>)
diff --git a/properties/mobibot.properties b/properties/mobibot.properties
index 67326f3..28f5a8d 100644
--- a/properties/mobibot.properties
+++ b/properties/mobibot.properties
@@ -1,5 +1,5 @@
channel=#mobitopia
-server=irc.freenode.net
+server=irc.libera.chat
#port=6667
login=mobibot
nick=mobibot
@@ -24,6 +24,9 @@ backlogs=http://www.mobitopia.org/mobibot/logs
tell-max-days=5
tell-max-size=50
+#disabled-commands=die, ignore
+#disabled-modules=dice, joke
+
#
# Credentials for: http://pinboard.in/
#
diff --git a/src/main/java/net/thauvin/erik/mobibot/modules/War.java b/src/main/java/net/thauvin/erik/mobibot/modules/War.java
index 16102b4..5565ecb 100644
--- a/src/main/java/net/thauvin/erik/mobibot/modules/War.java
+++ b/src/main/java/net/thauvin/erik/mobibot/modules/War.java
@@ -75,6 +75,12 @@ public final class War extends AbstractModule {
help.add(Utils.helpFormat("%c " + WAR_CMD));
}
+ @NotNull
+ @Override
+ public String getName() {
+ return "War";
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/Addons.kt b/src/main/kotlin/net/thauvin/erik/mobibot/Addons.kt
index e530ae8..4e95ad0 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/Addons.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/Addons.kt
@@ -31,7 +31,9 @@
*/
package net.thauvin.erik.mobibot
+import net.thauvin.erik.mobibot.Utils.notContains
import net.thauvin.erik.mobibot.commands.AbstractCommand
+import net.thauvin.erik.mobibot.commands.links.LinksMgr
import net.thauvin.erik.mobibot.modules.AbstractModule
import org.pircbotx.hooks.events.PrivateMessageEvent
import org.pircbotx.hooks.types.GenericMessageEvent
@@ -40,7 +42,10 @@ import java.util.Properties
/**
* Modules and Commands addons.
*/
-class Addons {
+class Addons(private val props: Properties) {
+ private val disabledModules = props.getProperty("disabled-modules", "").split(LinksMgr.TAG_MATCH.toRegex())
+ private val disableCommands = props.getProperty("disabled-commands", "").split(LinksMgr.TAG_MATCH.toRegex())
+
val commands: MutableList = mutableListOf()
val modules: MutableList = mutableListOf()
val modulesNames: MutableList = mutableListOf()
@@ -50,18 +55,20 @@ class Addons {
/**
* Add a module with properties.
*/
- fun add(module: AbstractModule, props: Properties) {
+ fun add(module: AbstractModule) {
with(module) {
- if (hasProperties()) {
- propertyKeys.forEach {
- setProperty(it, props.getProperty(it, ""))
+ if (disabledModules.notContains(name, true)) {
+ if (hasProperties()) {
+ propertyKeys.forEach {
+ setProperty(it, props.getProperty(it, ""))
+ }
}
- }
- if (isEnabled) {
- modules.add(this)
- modulesNames.add(javaClass.simpleName)
- names.addAll(commands)
+ if (isEnabled) {
+ modules.add(this)
+ modulesNames.add(name)
+ names.addAll(commands)
+ }
}
}
}
@@ -69,20 +76,22 @@ class Addons {
/**
* Add a command with properties.
*/
- fun add(command: AbstractCommand, props: Properties) {
+ fun add(command: AbstractCommand) {
with(command) {
- if (properties.isNotEmpty()) {
- properties.keys.forEach {
- setProperty(it, props.getProperty(it, ""))
+ if (disableCommands.notContains(name, true)) {
+ if (properties.isNotEmpty()) {
+ properties.keys.forEach {
+ setProperty(it, props.getProperty(it, ""))
+ }
}
- }
- if (isEnabled()) {
- commands.add(this)
- if (isVisible) {
- if (isOpOnly) {
- ops.add(name)
- } else {
- names.add(name)
+ if (isEnabled()) {
+ commands.add(this)
+ if (isVisible) {
+ if (isOpOnly) {
+ ops.add(name)
+ } else {
+ names.add(name)
+ }
}
}
}
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/Mobibot.kt b/src/main/kotlin/net/thauvin/erik/mobibot/Mobibot.kt
index ef6f842..02467d6 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/Mobibot.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/Mobibot.kt
@@ -112,7 +112,7 @@ class Mobibot(nickname: String, val channel: String, logsDirPath: String, p: Pro
private val config: Configuration
// Commands and Modules
- private val addons = Addons()
+ private val addons: Addons
// Tell module
private val tell: Tell
@@ -391,46 +391,48 @@ class Mobibot(nickname: String, val channel: String, logsDirPath: String, p: Pro
pinboard.setApiToken(p.getProperty("pinboard-api-token", ""))
}
+ addons = Addons(p)
+
// Load the commands
- addons.add(ChannelFeed(channel.removePrefix("#")), p)
- addons.add(Comment(), p)
- addons.add(Cycle(), p)
- addons.add(Die(), p)
- addons.add(Ignore(), p)
- addons.add(LinksMgr(), p)
- addons.add(Me(), p)
- addons.add(Msg(), p)
- addons.add(Nick(), p)
- addons.add(Posting(), p)
- addons.add(Recap(), p)
- addons.add(Say(), p)
- addons.add(Tags(), p)
+ addons.add(ChannelFeed(channel.removePrefix("#")))
+ addons.add(Comment())
+ addons.add(Cycle())
+ addons.add(Die())
+ addons.add(Ignore())
+ addons.add(LinksMgr())
+ addons.add(Me())
+ addons.add(Msg())
+ addons.add(Nick())
+ addons.add(Posting())
+ addons.add(Recap())
+ addons.add(Say())
+ addons.add(Tags())
// Tell command
tell = Tell("${logsDirPath}${nickname}.ser")
- addons.add(tell, p)
+ addons.add(tell)
- addons.add(LinksMgr.twitter, p)
- addons.add(Users(), p)
- addons.add(Versions(), p)
- addons.add(View(), p)
+ addons.add(LinksMgr.twitter)
+ addons.add(Users())
+ addons.add(Versions())
+ addons.add(View())
// Load the modules
- addons.add(Calc(), p)
- addons.add(CryptoPrices(), p)
- addons.add(CurrencyConverter(), p)
- addons.add(Dice(), p)
- addons.add(GoogleSearch(), p)
- addons.add(Info(tell), p)
- addons.add(Joke(), p)
- addons.add(Lookup(), p)
- addons.add(Modules(addons.modulesNames), p)
- addons.add(Ping(), p)
- addons.add(RockPaperScissors(), p)
- addons.add(StockQuote(), p)
- addons.add(Weather2(), p)
- addons.add(WorldTime(), p)
- addons.add(War(), p)
+ addons.add(Calc())
+ addons.add(CryptoPrices())
+ addons.add(CurrencyConverter())
+ addons.add(Dice())
+ addons.add(GoogleSearch())
+ addons.add(Info(tell))
+ addons.add(Joke())
+ addons.add(Lookup())
+ addons.add(Modules(addons.modulesNames))
+ addons.add(Ping())
+ addons.add(RockPaperScissors())
+ addons.add(StockQuote())
+ addons.add(Weather2())
+ addons.add(WorldTime())
+ addons.add(War())
// Sort the addons
addons.sort()
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/Utils.kt b/src/main/kotlin/net/thauvin/erik/mobibot/Utils.kt
index 38fafa7..b68ee47 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/Utils.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/Utils.kt
@@ -180,7 +180,7 @@ object Utils {
}
/**
- * Return the last item of a list of strings or empty if none.
+ * Returns the last item of a list of strings or empty if none.
*/
@JvmStatic
fun List.lastOrEmpty(): String {
@@ -190,6 +190,12 @@ object Utils {
""
}
+ /**
+ * Returns {@code true} if the list does not contain the given string.
+ */
+ @JvmStatic
+ fun List.notContains(text: String, ignoreCase: Boolean = false) = this.none { it.equals(text, ignoreCase) }
+
/**
* Obfuscates the given string.
*/
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/AbstractModule.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/AbstractModule.kt
index dd5d3d5..25e7c9d 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/AbstractModule.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/AbstractModule.kt
@@ -41,6 +41,11 @@ import org.pircbotx.hooks.types.GenericMessageEvent
* The `Module` abstract class.
*/
abstract class AbstractModule {
+ /**
+ * The module name.
+ */
+ abstract val name: String
+
/**
* The module's commands, if any.
*/
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Calc.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Calc.kt
index 29c0805..76f3786 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Calc.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Calc.kt
@@ -46,6 +46,8 @@ import java.text.DecimalFormat
class Calc : AbstractModule() {
private val logger: Logger = LoggerFactory.getLogger(Calc::class.java)
+ override val name = "Calc"
+
override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) {
if (args.isNotBlank()) {
try {
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/CryptoPrices.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/CryptoPrices.kt
index 57e3dc4..8cb3396 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/CryptoPrices.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/CryptoPrices.kt
@@ -47,6 +47,8 @@ import java.io.IOException
class CryptoPrices : ThreadedModule() {
private val logger: Logger = LoggerFactory.getLogger(CryptoPrices::class.java)
+ override val name = "CryptoPrices"
+
/**
* Returns the cryptocurrency market price from [Coinbase](https://developers.coinbase.com/api/v2#get-spot-price).
*/
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/CurrencyConverter.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/CurrencyConverter.kt
index 275e99c..f6de896 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/CurrencyConverter.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/CurrencyConverter.kt
@@ -59,6 +59,8 @@ import javax.xml.XMLConstants
class CurrencyConverter : ThreadedModule() {
private val logger: Logger = LoggerFactory.getLogger(CurrencyConverter::class.java)
+ override val name = "CurrencyConverter"
+
override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) {
synchronized(this) {
if (pubDate != today()) {
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Dice.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Dice.kt
index 667a0b0..9e7725d 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Dice.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Dice.kt
@@ -40,6 +40,8 @@ import org.pircbotx.hooks.types.GenericMessageEvent
* The Dice module.
*/
class Dice : AbstractModule() {
+ override val name = "Dice"
+
override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) {
val botRoll = roll()
val roll = roll()
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/GoogleSearch.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/GoogleSearch.kt
index a0658bc..6adffdd 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/GoogleSearch.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/GoogleSearch.kt
@@ -55,6 +55,8 @@ import java.net.URL
class GoogleSearch : ThreadedModule() {
private val logger: Logger = LoggerFactory.getLogger(GoogleSearch::class.java)
+ override val name = "GoogleSearch"
+
/**
* Searches Google.
*/
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Joke.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Joke.kt
index ff5c030..6922698 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Joke.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Joke.kt
@@ -54,6 +54,8 @@ import java.net.URL
class Joke : ThreadedModule() {
private val logger: Logger = LoggerFactory.getLogger(Joke::class.java)
+ override val name = "Joke"
+
override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) {
runBlocking {
launch { run(channel, cmd, args, event) }
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Lookup.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Lookup.kt
index f6ae628..90a0316 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Lookup.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Lookup.kt
@@ -48,6 +48,8 @@ import java.net.UnknownHostException
class Lookup : AbstractModule() {
private val logger: Logger = LoggerFactory.getLogger(Lookup::class.java)
+ override val name = "Lookup"
+
override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) {
if (args.matches("(\\S.)+(\\S)+".toRegex())) {
try {
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Ping.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Ping.kt
index b4876de..0818120 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Ping.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Ping.kt
@@ -39,9 +39,8 @@ import org.pircbotx.hooks.types.GenericMessageEvent
* The Ping module.
*/
class Ping : AbstractModule() {
- /**
- * {@inheritDoc}
- */
+ override val name = "Ping"
+
override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) {
event.bot().sendIRC().action(channel, randomPing())
}
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/RockPaperScissors.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/RockPaperScissors.kt
index 95eb5e2..c092548 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/RockPaperScissors.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/RockPaperScissors.kt
@@ -42,6 +42,8 @@ import org.pircbotx.hooks.types.GenericMessageEvent
* Simple module example in Kotlin.
*/
class RockPaperScissors : AbstractModule() {
+ override val name = "RockPaperScissors"
+
init {
with(commands) {
add(Hands.ROCK.name.lowercase())
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/StockQuote.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/StockQuote.kt
index 240ea0e..63d358c 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/StockQuote.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/StockQuote.kt
@@ -55,6 +55,8 @@ import java.net.URL
class StockQuote : ThreadedModule() {
private val logger: Logger = LoggerFactory.getLogger(StockQuote::class.java)
+ override val name = "StockQuote"
+
/**
* Returns the specified stock quote from Alpha Vantage.
*/
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Twitter.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Twitter.kt
index 61fbd1b..74f0ba0 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Twitter.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Twitter.kt
@@ -57,6 +57,8 @@ class Twitter : ThreadedModule() {
// Twitter auto-posts.
private val entries: MutableSet = HashSet()
+ override val name = "Twitter"
+
/**
* Add an entry to be posted on Twitter.
*/
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Weather2.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Weather2.kt
index bdc5de9..96ae93e 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Weather2.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Weather2.kt
@@ -57,6 +57,8 @@ import kotlin.math.roundToInt
class Weather2 : ThreadedModule() {
private val logger: Logger = LoggerFactory.getLogger(Weather2::class.java)
+ override val name = "Weather"
+
/**
* Fetches the weather data from a specific city.
*/
diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/WorldTime.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/WorldTime.kt
index 7160d15..fc0edf6 100644
--- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/WorldTime.kt
+++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/WorldTime.kt
@@ -45,6 +45,8 @@ import java.time.temporal.ChronoField
* The WorldTime module.
*/
class WorldTime : AbstractModule() {
+ override val name = "WorldTime"
+
companion object {
/**
* Beats (Internet Time) keyword
diff --git a/src/test/kotlin/net/thauvin/erik/mobibot/AddonsTest.kt b/src/test/kotlin/net/thauvin/erik/mobibot/AddonsTest.kt
index 33cca2e..54346a9 100644
--- a/src/test/kotlin/net/thauvin/erik/mobibot/AddonsTest.kt
+++ b/src/test/kotlin/net/thauvin/erik/mobibot/AddonsTest.kt
@@ -41,35 +41,43 @@ import net.thauvin.erik.mobibot.commands.Die
import net.thauvin.erik.mobibot.commands.Ignore
import net.thauvin.erik.mobibot.commands.links.Comment
import net.thauvin.erik.mobibot.commands.links.View
+import net.thauvin.erik.mobibot.modules.Dice
import net.thauvin.erik.mobibot.modules.Joke
+import net.thauvin.erik.mobibot.modules.Lookup
import net.thauvin.erik.mobibot.modules.RockPaperScissors
import net.thauvin.erik.mobibot.modules.Twitter
+import net.thauvin.erik.mobibot.modules.War
import org.testng.annotations.Test
import java.util.Properties
class AddonsTest {
- private val addons = Addons()
+ private val p = Properties().apply {
+ put("disabled-modules", "war,dice Lookup")
+ put("disabled-commands", "View | comment")
+ }
+ private val addons = Addons(p)
@Test
fun addTest() {
- val p = Properties()
-
// Modules
- addons.add(Joke(), p)
- addons.add(RockPaperScissors(), p)
- addons.add(Twitter(), p) // no properties, disabled.
+ addons.add(Joke())
+ addons.add(RockPaperScissors())
+ addons.add(Twitter()) // no properties, disabled.
+ addons.add(War())
+ addons.add(Dice())
+ addons.add(Lookup())
assertThat(addons.modules.size, "modules = 2").isEqualTo(2)
-
assertThat(addons.modulesNames, "module names").containsExactly("Joke", "RockPaperScissors")
// Commands
- addons.add(View(), p)
- addons.add(Comment(), p)
- addons.add(Cycle(), p)
- addons.add(Die(), p) // invisible
- addons.add(ChannelFeed("channel"), p) // no properties, disabled
- addons.add(Ignore(), p.apply { put(Ignore.IGNORE_PROP, "nick") })
- assertThat(addons.commands.size, "commands = 4").isEqualTo(5)
+ addons.add(View())
+ addons.add(Comment())
+ addons.add(Cycle())
+ addons.add(Die()) // invisible
+ addons.add(ChannelFeed("channel")) // no properties, disabled
+ p[Ignore.IGNORE_PROP] = "nick"
+ addons.add(Ignore())
+ assertThat(addons.commands.size, "commands = 3").isEqualTo(3)
assertThat(addons.ops, "ops").containsExactly("cycle")
@@ -78,8 +86,6 @@ class AddonsTest {
"rock",
"paper",
"scissors",
- "view",
- "comment",
"ignore"
)
}
diff --git a/version.properties b/version.properties
index 41eca0f..4aea8d8 100644
--- a/version.properties
+++ b/version.properties
@@ -1,9 +1,9 @@
#Generated by the Semver Plugin for Gradle
-#Sat Jan 01 06:34:39 PST 2022
-version.buildmeta=2428
+#Sat Jan 08 23:07:31 PST 2022
+version.buildmeta=2440
version.major=0
version.minor=8
version.patch=0
version.prerelease=beta
version.project=mobibot
-version.semver=0.8.0-beta+2428
+version.semver=0.8.0-beta+2440