From 2b2d04683541b0661945f7b6e37e7e34f13473c0 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Tue, 6 Dec 2022 15:38:14 -0800 Subject: [PATCH 1/3] Fixed Mastodon auto-post --- src/main/kotlin/net/thauvin/erik/mobibot/modules/Mastodon.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Mastodon.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Mastodon.kt index 858676e..41de68e 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Mastodon.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Mastodon.kt @@ -52,7 +52,6 @@ class Mastodon : SocialModule() { get() = properties[HANDLE_PROP] override val isAutoPost: Boolean - get() = isEnabled && properties[Twitter.AUTO_POST_PROP].toBoolean() override val isValidProperties: Boolean get() { From e510a77af1c9d2b11c2f4fe0afbeb404aa4c0a25 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Wed, 7 Dec 2022 11:50:19 -0800 Subject: [PATCH 2/3] Added tags to Mastodon post --- config/detekt/baseline.xml | 1 + .../kotlin/net/thauvin/erik/mobibot/Addons.kt | 4 +-- .../net/thauvin/erik/mobibot/Pinboard.kt | 21 ++++++------ .../thauvin/erik/mobibot/commands/Ignore.kt | 2 +- .../erik/mobibot/commands/links/Comment.kt | 8 ++--- .../mobibot/commands/links/LinksManager.kt | 18 +++++------ .../erik/mobibot/commands/links/Posting.kt | 16 +++++----- .../erik/mobibot/commands/links/Tags.kt | 4 +-- .../erik/mobibot/commands/links/View.kt | 4 +-- .../erik/mobibot/entries/EntriesUtils.kt | 16 +++++----- .../thauvin/erik/mobibot/entries/EntryLink.kt | 20 ++++-------- .../erik/mobibot/entries/FeedsManager.kt | 2 +- .../erik/mobibot/modules/AbstractModule.kt | 2 +- .../thauvin/erik/mobibot/modules/Mastodon.kt | 17 +++++----- .../thauvin/erik/mobibot/modules/Twitter.kt | 10 ++---- .../erik/mobibot/entries/EntriesUtilsTest.kt | 32 +++++++++---------- .../erik/mobibot/entries/EntryLinkTest.kt | 19 +++++++---- version.properties | 6 ++-- 18 files changed, 99 insertions(+), 103 deletions(-) diff --git a/config/detekt/baseline.xml b/config/detekt/baseline.xml index d0fbcc9..33a9f22 100644 --- a/config/detekt/baseline.xml +++ b/config/detekt/baseline.xml @@ -86,6 +86,7 @@ ThrowsCount:WolframAlpha.kt$WolframAlpha.Companion$@JvmStatic @Throws(ModuleException::class) fun queryWolfram(query: String, units: String = IMPERIAL, appId: String?): String TooGenericExceptionCaught:StockQuote.kt$StockQuote.Companion$e: NullPointerException TooGenericExceptionCaught:Weather2.kt$Weather2.Companion$e: NullPointerException + TooManyFunctions:EntryLink.kt$EntryLink : Serializable TooManyFunctions:Mobibot.kt$Mobibot : ListenerAdapter TooManyFunctions:Tell.kt$Tell : AbstractCommand diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/Addons.kt b/src/main/kotlin/net/thauvin/erik/mobibot/Addons.kt index db5fb25..8720e95 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/Addons.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/Addons.kt @@ -46,8 +46,8 @@ import java.util.Properties */ class Addons(private val props: Properties) { private val logger: Logger = LoggerFactory.getLogger(Addons::class.java) - private val disabledModules = props.getProperty("disabled-modules", "").split(LinksManager.TAG_MATCH.toRegex()) - private val disableCommands = props.getProperty("disabled-commands", "").split(LinksManager.TAG_MATCH.toRegex()) + private val disabledModules = props.getProperty("disabled-modules", "").split(LinksManager.TAG_MATCH) + private val disableCommands = props.getProperty("disabled-commands", "").split(LinksManager.TAG_MATCH) val commands: MutableList = mutableListOf() val modules: MutableList = mutableListOf() diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/Pinboard.kt b/src/main/kotlin/net/thauvin/erik/mobibot/Pinboard.kt index 9d46188..ee9b020 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/Pinboard.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/Pinboard.kt @@ -55,13 +55,9 @@ class Pinboard { if (poster.apiToken.isNotBlank()) { runBlocking { launch { - poster.addPin( - entry.link, - entry.title, - entry.postedBy(ircServer), - entry.pinboardTags, - entry.date.toTimestamp() - ) + with(entry) { + poster.addPin(link, title, postedBy(ircServer), formatTags(), date.toTimestamp()) + } } } } @@ -98,7 +94,7 @@ class Pinboard { if (oldUrl != link) { poster.deletePin(oldUrl) } - poster.addPin(link, title, entry.postedBy(ircServer), pinboardTags, date.toTimestamp()) + poster.addPin(link, title, postedBy(ircServer), formatTags(), date.toTimestamp()) } } } @@ -106,7 +102,7 @@ class Pinboard { } /** - * Format a date to a UTC timestamp. + * Formats a date to a UTC timestamp. */ private fun Date.toTimestamp(): String { return ZonedDateTime.ofInstant( @@ -115,6 +111,13 @@ class Pinboard { ).format(DateTimeFormatter.ISO_INSTANT) } + /** + * Formats the tags for pinboard. + */ + private fun EntryLink.formatTags(): String { + return nick + formatTags(",", ",") + } + /** * Returns the pinboard.in extended attribution line. */ diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/commands/Ignore.kt b/src/main/kotlin/net/thauvin/erik/mobibot/commands/Ignore.kt index 7306cea..5d03cb8 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/commands/Ignore.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/commands/Ignore.kt @@ -141,7 +141,7 @@ class Ignore : AbstractCommand() { override fun setProperty(key: String, value: String) { super.setProperty(key, value) if (IGNORE_PROP == key) { - ignored.addAll(value.split(LinksManager.TAG_MATCH.toRegex())) + ignored.addAll(value.split(LinksManager.TAG_MATCH) } } diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/Comment.kt b/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/Comment.kt index e60955a..5a09836 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/Comment.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/Comment.kt @@ -38,7 +38,7 @@ import net.thauvin.erik.mobibot.Utils.helpFormat import net.thauvin.erik.mobibot.Utils.isChannelOp import net.thauvin.erik.mobibot.Utils.sendMessage import net.thauvin.erik.mobibot.commands.AbstractCommand -import net.thauvin.erik.mobibot.entries.EntriesUtils.buildComment +import net.thauvin.erik.mobibot.entries.EntriesUtils.printComment import net.thauvin.erik.mobibot.entries.EntriesUtils.toLinkLabel import net.thauvin.erik.mobibot.entries.EntryLink import org.pircbotx.hooks.types.GenericMessageEvent @@ -111,7 +111,7 @@ class Comment : AbstractCommand() { if (event.isChannelOp(channel) && cmd.length > 1) { val comment = entry.getComment(commentIndex) comment.nick = cmd.substring(1) - event.sendMessage(buildComment(entryIndex, commentIndex, comment)) + event.sendMessage(printComment(entryIndex, commentIndex, comment)) LinksManager.entries.save() } else { event.sendMessage("Please ask a channel op to change the author of this comment for you.") @@ -142,11 +142,11 @@ class Comment : AbstractCommand() { event: GenericMessageEvent ) { entry.setComment(commentIndex, cmd, event.user.nick) - event.sendMessage(buildComment(entryIndex, commentIndex, entry.getComment(commentIndex))) + event.sendMessage(printComment(entryIndex, commentIndex, entry.getComment(commentIndex))) LinksManager.entries.save() } private fun showComment(entry: EntryLink, entryIndex: Int, commentIndex: Int, event: GenericMessageEvent) { - event.sendMessage(buildComment(entryIndex, commentIndex, entry.getComment(commentIndex))) + event.sendMessage(printComment(entryIndex, commentIndex, entry.getComment(commentIndex))) } } diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/LinksManager.kt b/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/LinksManager.kt index d0c9769..af6adf4 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/LinksManager.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/LinksManager.kt @@ -42,7 +42,7 @@ import net.thauvin.erik.mobibot.Utils.today import net.thauvin.erik.mobibot.commands.AbstractCommand import net.thauvin.erik.mobibot.commands.Ignore.Companion.isNotIgnored import net.thauvin.erik.mobibot.entries.Entries -import net.thauvin.erik.mobibot.entries.EntriesUtils.buildLink +import net.thauvin.erik.mobibot.entries.EntriesUtils.printLink import net.thauvin.erik.mobibot.entries.EntriesUtils.toLinkLabel import net.thauvin.erik.mobibot.entries.EntryLink import net.thauvin.erik.mobibot.social.SocialManager @@ -65,10 +65,10 @@ class LinksManager : AbstractCommand() { } companion object { - const val LINK_MATCH = "^[hH][tT][tT][pP](|[sS])://.*" + val LINK_MATCH = "^[hH][tT][tT][pP](|[sS])://.*".toRegex() const val KEYWORDS_PROP = "tags-keywords" const val TAGS_PROP = "tags" - const val TAG_MATCH = ", *| +" + val TAG_MATCH = ", *| +".toRegex() /** * Entries array @@ -116,7 +116,7 @@ class LinksManager : AbstractCommand() { val data = cmds[1].trim().split("${Tags.COMMAND}:", limit = 2) title = data[0].trim() if (data.size > 1) { - tags.addAll(data[1].split(TAG_MATCH.toRegex())) + tags.addAll(data[1].split(TAG_MATCH)) } } @@ -136,7 +136,7 @@ class LinksManager : AbstractCommand() { val entry = EntryLink(link, title, sender, login, channel, tags) entries.links.add(entry) val index = entries.links.lastIndexOf(entry) - event.sendMessage(buildLink(index, entry)) + event.sendMessage(printLink(index, entry)) pinboard.addPin(event.bot().serverHostname, entry) @@ -156,7 +156,7 @@ class LinksManager : AbstractCommand() { override fun helpResponse(channel: String, topic: String, event: GenericMessageEvent): Boolean = false override fun matches(message: String): Boolean { - return message.matches(LINK_MATCH.toRegex()) + return message.matches(LINK_MATCH) } internal fun fetchTitle(link: String): String { @@ -179,7 +179,7 @@ class LinksManager : AbstractCommand() { return try { val match = entries.links.single { it.link == link } event.sendMessage( - "Duplicate".bold() + " >> " + buildLink(entries.links.indexOf(match), match) + "Duplicate".bold() + " >> " + printLink(entries.links.indexOf(match), match) ) true } catch (ignore: NoSuchElementException) { @@ -200,9 +200,9 @@ class LinksManager : AbstractCommand() { override fun setProperty(key: String, value: String) { super.setProperty(key, value) if (KEYWORDS_PROP == key) { - keywords.addAll(value.split(TAG_MATCH.toRegex())) + keywords.addAll(value.split(TAG_MATCH)) } else if (TAGS_PROP == key) { - defaultTags.addAll(value.split(TAG_MATCH.toRegex())) + defaultTags.addAll(value.split(TAG_MATCH)) } } } diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/Posting.kt b/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/Posting.kt index a0224b9..9368d37 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/Posting.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/Posting.kt @@ -94,7 +94,7 @@ class Posting : AbstractCommand() { val entry: EntryLink = entries.links[entryIndex] val commentIndex = entry.addComment(cmd, event.user.nick) val comment = entry.getComment(commentIndex) - event.sendMessage(EntriesUtils.buildComment(entryIndex, commentIndex, comment)) + event.sendMessage(EntriesUtils.printComment(entryIndex, commentIndex, comment)) entries.save() } @@ -103,7 +103,7 @@ class Posting : AbstractCommand() { val entry: EntryLink = entries.links[entryIndex] entry.title = cmd.substring(1).trim() LinksManager.pinboard.updatePin(event.bot().serverHostname, entry.link, entry) - event.sendMessage(EntriesUtils.buildLink(entryIndex, entry)) + event.sendMessage(EntriesUtils.printLink(entryIndex, entry)) entries.save() } } @@ -112,11 +112,11 @@ class Posting : AbstractCommand() { val entry: EntryLink = entries.links[entryIndex] if (entry.login == event.user.login || event.isChannelOp(channel)) { val link = cmd.substring(1) - if (link.matches(LinksManager.LINK_MATCH.toRegex())) { + if (link.matches(LinksManager.LINK_MATCH)) { val oldLink = entry.link entry.link = link LinksManager.pinboard.updatePin(event.bot().serverHostname, oldLink, entry) - event.sendMessage(EntriesUtils.buildLink(entryIndex, entry)) + event.sendMessage(EntriesUtils.printLink(entryIndex, entry)) entries.save() } } @@ -128,7 +128,7 @@ class Posting : AbstractCommand() { val entry: EntryLink = entries.links[index] entry.nick = cmd.substring(1) LinksManager.pinboard.updatePin(event.bot().serverHostname, entry.link, entry) - event.sendMessage(EntriesUtils.buildLink(index, entry)) + event.sendMessage(EntriesUtils.printLink(index, entry)) entries.save() } } else { @@ -151,14 +151,14 @@ class Posting : AbstractCommand() { private fun showEntry(index: Int, event: GenericMessageEvent) { val entry: EntryLink = entries.links[index] - event.sendMessage(EntriesUtils.buildLink(index, entry)) + event.sendMessage(EntriesUtils.printLink(index, entry)) if (entry.tags.isNotEmpty()) { - event.sendMessage(EntriesUtils.buildTags(index, entry)) + event.sendMessage(EntriesUtils.printTags(index, entry)) } if (entry.comments.isNotEmpty()) { val comments = entry.comments for (i in comments.indices) { - event.sendMessage(EntriesUtils.buildComment(index, i, comments[i])) + event.sendMessage(EntriesUtils.printComment(index, i, comments[i])) } } } diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/Tags.kt b/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/Tags.kt index 8146e88..785e3a0 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/Tags.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/Tags.kt @@ -67,14 +67,14 @@ class Tags : AbstractCommand() { if (entry.login == event.user.login || event.isChannelOp(channel)) { entry.setTags(cmd) LinksManager.pinboard.updatePin(event.bot().serverHostname, entry.link, entry) - event.sendMessage(EntriesUtils.buildTags(index, entry)) + event.sendMessage(EntriesUtils.printTags(index, entry)) LinksManager.entries.save() } else { event.sendMessage("Please ask a channel op to change the tags for you.") } } else { if (entry.tags.isNotEmpty()) { - event.sendMessage(EntriesUtils.buildTags(index, entry)) + event.sendMessage(EntriesUtils.printTags(index, entry)) } else { event.sendMessage("The entry has no tags. Why don't add some?") } diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/View.kt b/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/View.kt index ee817a0..008ccad 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/View.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/View.kt @@ -97,11 +97,11 @@ class View : AbstractCommand() { entry = entries.links[index] if (query.isNotBlank()) { if (entry.matches(query)) { - event.sendMessage(EntriesUtils.buildLink(index, entry, true)) + event.sendMessage(EntriesUtils.printLink(index, entry, true)) sent++ } } else { - event.sendMessage(EntriesUtils.buildLink(index, entry, true)) + event.sendMessage(EntriesUtils.printLink(index, entry, true)) sent++ } index++ diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/entries/EntriesUtils.kt b/src/main/kotlin/net/thauvin/erik/mobibot/entries/EntriesUtils.kt index 2b96dac..ac2c259 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/entries/EntriesUtils.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/entries/EntriesUtils.kt @@ -40,18 +40,18 @@ import net.thauvin.erik.mobibot.Utils.green */ object EntriesUtils { /** - * Builds an entry's comment for display on the channel. + * Prints an entry's comment for display on the channel. */ @JvmStatic - fun buildComment(entryIndex: Int, commentIndex: Int, comment: EntryComment): String = + fun printComment(entryIndex: Int, commentIndex: Int, comment: EntryComment): String = ("${entryIndex.toLinkLabel()}.${commentIndex + 1}: [${comment.nick}] ${comment.comment}") /** - * Builds an entry's link for display on the channel. + * Prints an entry's link for display on the channel. */ @JvmStatic @JvmOverloads - fun buildLink(entryIndex: Int, entry: EntryLink, isView: Boolean = false): String { + fun printLink(entryIndex: Int, entry: EntryLink, isView: Boolean = false): String { val buff = StringBuilder().append(entryIndex.toLinkLabel()).append(": ") .append('[').append(entry.nick).append(']') if (isView && entry.comments.isNotEmpty()) { @@ -70,14 +70,14 @@ object EntriesUtils { } /** - * Build an entry's tags/categories for display on the channel. + * Prints an entry's tags/categories for display on the channel. e.g. L1T: tag1, tag2 */ @JvmStatic - fun buildTags(entryIndex: Int, entry: EntryLink): String = - entryIndex.toLinkLabel() + "${Constants.TAG_CMD}: " + entry.pinboardTags.replace(",", ", ") + fun printTags(entryIndex: Int, entry: EntryLink): String = + entryIndex.toLinkLabel() + "${Constants.TAG_CMD}: " + entry.formatTags(", ") /** - * Build link label based on its index. e.g: L1 + * Builds link label based on its index. e.g: L1 */ @JvmStatic fun Int.toLinkLabel(): String = Constants.LINK_CMD + (this + 1) diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/entries/EntryLink.kt b/src/main/kotlin/net/thauvin/erik/mobibot/entries/EntryLink.kt index b70fa9d..59f4e73 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/entries/EntryLink.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/entries/EntryLink.kt @@ -127,24 +127,18 @@ class EntryLink( return comments.remove(entryComment) } + /** + * Formats the tags. + */ + fun formatTags(sep: String, prefix: String = "") : String { + return tags.joinToString(separator = sep, prefix = prefix){it.name} + } + /** * Returns a comment. */ fun getComment(index: Int): EntryComment = comments[index] - /** - * Returns the tags formatted for pinboard.in - */ - val pinboardTags: String - get() { - val pinboardTags = StringBuilder(nick) - for (tag in tags) { - pinboardTags.append(',') - pinboardTags.append(tag.name) - } - return pinboardTags.toString() - } - /** * Returns true if a string is contained in the link, title, or nick. */ diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/entries/FeedsManager.kt b/src/main/kotlin/net/thauvin/erik/mobibot/entries/FeedsManager.kt index 32ba16d..1ae2690 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/entries/FeedsManager.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/entries/FeedsManager.kt @@ -160,7 +160,7 @@ class FeedsManager private constructor() { item.description = SyndContentImpl().apply { value = buff.toString() } item.title = title item.publishedDate = date - item.author = "${channel.substring(1)}@${entries.ircServer} ($nick)" + item.author = "${channel.removePrefix("#")}@${entries.ircServer} ($nick)" item.categories = tags items.add(item) } 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 83eafcf..61e2eaf 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/AbstractModule.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/AbstractModule.kt @@ -113,7 +113,7 @@ abstract class AbstractModule { */ open val isValidProperties: Boolean get() { - for (s in propertyKeys) { + for (s in properties.keys) { if (properties[s].isNullOrBlank()) { return false } diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Mastodon.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Mastodon.kt index 41de68e..b355fdc 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Mastodon.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Mastodon.kt @@ -52,22 +52,21 @@ class Mastodon : SocialModule() { get() = properties[HANDLE_PROP] override val isAutoPost: Boolean + get() = isEnabled && properties[AUTO_POST_PROP].toBoolean() override val isValidProperties: Boolean - get() { - for (s in propertyKeys) { - if (AUTO_POST_PROP != s && HANDLE_PROP != s && properties[s].isNullOrBlank()) { - return false - } - } - return true - } + get() = !(properties[INSTANCE_PROP].isNullOrBlank() || properties[ACCESS_TOKEN_PROP].isNullOrBlank()) /** * Formats the entry for posting. */ override fun formatEntry(entry: EntryLink): String { - return "${entry.title} via ${entry.nick} on ${entry.channel}\n\n${entry.link}" + return "${entry.title} (via ${entry.nick} on ${entry.channel})${formatTags(entry)}\n\n${entry.link}" + } + + private fun formatTags(entry: EntryLink): String { + return entry.tags.filter { !it.name.equals(entry.channel.removePrefix("#"), true) } + .joinToString(separator = " ", prefix = "\n\n") { "#${it.name}" } } /** 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 91cca2a..2253494 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Twitter.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Twitter.kt @@ -49,14 +49,8 @@ class Twitter : SocialModule() { get() = isEnabled && properties[AUTO_POST_PROP].toBoolean() override val isValidProperties: Boolean - get() { - for (s in propertyKeys) { - if (AUTO_POST_PROP != s && HANDLE_PROP != s && properties[s].isNullOrBlank()) { - return false - } - } - return true - } + get() = !(properties[CONSUMER_KEY_PROP].isNullOrBlank() || properties[CONSUMER_SECRET_PROP].isNullOrBlank() + || properties[TOKEN_PROP].isNullOrBlank() || properties[TOKEN_SECRET_PROP].isNullOrBlank()) /** * Formats the entry for posting. diff --git a/src/test/kotlin/net/thauvin/erik/mobibot/entries/EntriesUtilsTest.kt b/src/test/kotlin/net/thauvin/erik/mobibot/entries/EntriesUtilsTest.kt index 0de9d5e..23ba01e 100644 --- a/src/test/kotlin/net/thauvin/erik/mobibot/entries/EntriesUtilsTest.kt +++ b/src/test/kotlin/net/thauvin/erik/mobibot/entries/EntriesUtilsTest.kt @@ -36,9 +36,9 @@ import assertk.assertThat import assertk.assertions.contains import assertk.assertions.isEqualTo import net.thauvin.erik.mobibot.Constants -import net.thauvin.erik.mobibot.entries.EntriesUtils.buildComment -import net.thauvin.erik.mobibot.entries.EntriesUtils.buildLink -import net.thauvin.erik.mobibot.entries.EntriesUtils.buildTags +import net.thauvin.erik.mobibot.entries.EntriesUtils.printComment +import net.thauvin.erik.mobibot.entries.EntriesUtils.printLink +import net.thauvin.erik.mobibot.entries.EntriesUtils.printTags import net.thauvin.erik.mobibot.entries.EntriesUtils.toLinkLabel import org.testng.annotations.Test @@ -60,33 +60,33 @@ class EntriesUtilsTest { } @Test(groups = ["entries"]) - fun buildLinkLabelTest() { - assertThat(1.toLinkLabel()).isEqualTo("${Constants.LINK_CMD}2") + fun printCommentTest() { + assertThat(printComment(0, 0, comment)).isEqualTo("${Constants.LINK_CMD}1.1: [nick] comment") } @Test(groups = ["entries"]) - fun buildCommentTest() { - assertThat(buildComment(0, 0, comment)).isEqualTo("${Constants.LINK_CMD}1.1: [nick] comment") - } - - @Test(groups = ["entries"]) - fun buildLinkTest() { + fun printLinkTest() { for (i in links.indices) { assertThat( - buildLink(i - 1, links[i]), "link $i" + printLink(i - 1, links[i]), "link $i" ).isEqualTo("L$i: [Skynx$i] \u0002Mobitopia$i\u0002 ( \u000303https://www.mobitopia.org/$i\u000F )") } assertThat(links.first().addComment(comment), "addComment()").isEqualTo(0) - assertThat(buildLink(0, links.first(), isView = true), "buildLink(isView=true)").contains("[+1]") + assertThat(printLink(0, links.first(), isView = true), "printLink(isView=true)").contains("[+1]") } @Test(groups = ["entries"]) - fun buildTagsTest() { + fun printTagsTest() { for (i in links.indices) { assertThat( - buildTags(i - 1, links[i]), "tag $i" - ).isEqualTo("L${i}T: Skynx$i, tag1, tag2, tag3, tag4, tag5") + printTags(i - 1, links[i]), "tag $i" + ).isEqualTo("L${i}T: tag1, tag2, tag3, tag4, tag5") } } + + @Test(groups = ["entries"]) + fun toLinkLabelTest() { + assertThat(1.toLinkLabel()).isEqualTo("${Constants.LINK_CMD}2") + } } diff --git a/src/test/kotlin/net/thauvin/erik/mobibot/entries/EntryLinkTest.kt b/src/test/kotlin/net/thauvin/erik/mobibot/entries/EntryLinkTest.kt index 5c9ef99..b36d167 100644 --- a/src/test/kotlin/net/thauvin/erik/mobibot/entries/EntryLinkTest.kt +++ b/src/test/kotlin/net/thauvin/erik/mobibot/entries/EntryLinkTest.kt @@ -40,6 +40,7 @@ import assertk.assertions.isFalse import assertk.assertions.isTrue import assertk.assertions.prop import assertk.assertions.size +import assertk.assertions.startsWith import com.rometools.rome.feed.synd.SyndCategory import com.rometools.rome.feed.synd.SyndCategoryImpl import org.testng.annotations.Test @@ -94,13 +95,11 @@ class EntryLinkTest { @Test(groups = ["entries"]) fun testConstructor() { - val tag = "test" - val tags = listOf(SyndCategoryImpl().apply { name = tag }) + val tags = listOf(SyndCategoryImpl().apply { name = "tag1" }, SyndCategoryImpl().apply { name = "tag2" }) val link = EntryLink("link", "title", "nick", "channel", Date(), tags) assertThat(link, "link").all { prop(EntryLink::tags).size().isEqualTo(tags.size) - prop(EntryLink::tags).index(0).prop(SyndCategory::getName).isEqualTo(tag) - prop(EntryLink::pinboardTags).isEqualTo("nick,$tag") + prop(EntryLink::tags).index(0).prop(SyndCategory::getName).isEqualTo("tag1") } } @@ -122,11 +121,17 @@ class EntryLinkTest { assertThat(tag.name, "tag.name($i)").isEqualTo("tag${i + 1}") } assertThat(entryLink::tags).size().isEqualTo(5) - entryLink.setTags("-tag5") + entryLink.setTags("-tag5, tag4") entryLink.setTags("+mobitopia") - entryLink.setTags("tag4") entryLink.setTags("-mobitopia") - assertThat(entryLink::pinboardTags).isEqualTo(entryLink.nick + ",tag1,tag2,tag3,tag4,mobitopia") + assertThat( + entryLink.formatTags(","), + "formatTags(',')" + ).isEqualTo("tag1,tag2,tag3,tag4,mobitopia") + entryLink.setTags("-tag4 tag5") + assertThat( + entryLink.formatTags(" ", ","), "formatTag(' ',',')" + ).isEqualTo(",tag1 tag2 tag3 mobitopia tag5") val size = entryLink.tags.size entryLink.setTags("") assertThat(entryLink.tags, "setTags('')").size().isEqualTo(size) diff --git a/version.properties b/version.properties index d91b88d..edb9391 100644 --- a/version.properties +++ b/version.properties @@ -1,9 +1,9 @@ #Generated by the Semver Plugin for Gradle -#Mon Dec 05 21:57:24 PST 2022 -version.buildmeta=814 +#Wed Dec 07 02:53:01 PST 2022 +version.buildmeta=857 version.major=0 version.minor=8 version.patch=0 version.prerelease=rc version.project=mobibot -version.semver=0.8.0-rc+814 +version.semver=0.8.0-rc+857 From 0fba4445f891c017323dde10d276bdc68dc0d03a Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Wed, 7 Dec 2022 12:08:15 -0800 Subject: [PATCH 3/3] Removed unnecessary threading (ThreadedModule, etc.) --- config/detekt/baseline.xml | 4 +- .../net/thauvin/erik/mobibot/FeedReader.kt | 2 +- .../net/thauvin/erik/mobibot/Mobibot.kt | 20 +++---- .../net/thauvin/erik/mobibot/Pinboard.kt | 32 +++------- .../erik/mobibot/commands/ChannelFeed.kt | 8 +-- .../thauvin/erik/mobibot/commands/Cycle.kt | 11 ++-- .../thauvin/erik/mobibot/commands/Ignore.kt | 2 +- .../thauvin/erik/mobibot/commands/Users.kt | 10 +--- .../erik/mobibot/commands/tell/TellMessage.kt | 2 +- .../thauvin/erik/mobibot/modules/ChatGpt.kt | 4 +- .../erik/mobibot/modules/CryptoPrices.kt | 4 +- .../erik/mobibot/modules/CurrencyConverter.kt | 4 +- .../erik/mobibot/modules/GoogleSearch.kt | 4 +- .../net/thauvin/erik/mobibot/modules/Joke.kt | 18 +----- .../thauvin/erik/mobibot/modules/Mastodon.kt | 2 +- .../erik/mobibot/modules/StockQuote.kt | 4 +- .../erik/mobibot/modules/ThreadedModule.kt | 58 ------------------- .../thauvin/erik/mobibot/modules/Twitter.kt | 2 +- .../thauvin/erik/mobibot/modules/Weather2.kt | 4 +- .../erik/mobibot/modules/WolframAlpha.kt | 4 +- .../erik/mobibot/social/SocialManager.kt | 4 +- .../erik/mobibot/social/SocialModule.kt | 44 ++++++-------- .../erik/mobibot/entries/EntryLinkTest.kt | 1 - version.properties | 6 +- 24 files changed, 73 insertions(+), 181 deletions(-) delete mode 100644 src/main/kotlin/net/thauvin/erik/mobibot/modules/ThreadedModule.kt diff --git a/config/detekt/baseline.xml b/config/detekt/baseline.xml index 33a9f22..19b4dbd 100644 --- a/config/detekt/baseline.xml +++ b/config/detekt/baseline.xml @@ -54,7 +54,7 @@ NestedBlockDepth:EntryLink.kt$EntryLink$private fun setTags(tags: List<String?>) NestedBlockDepth:FeedsManager.kt$FeedsManager.Companion$@JvmStatic @Throws(IOException::class, FeedException::class) fun loadFeed(entries: Entries, currentFile: String = currentXml): String NestedBlockDepth:FeedsManager.kt$FeedsManager.Companion$@JvmStatic fun saveFeed(entries: Entries, currentFile: String = currentXml) - NestedBlockDepth:GoogleSearch.kt$GoogleSearch$override fun run(channel: String, cmd: String, args: String, event: GenericMessageEvent) + NestedBlockDepth:GoogleSearch.kt$GoogleSearch$override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) NestedBlockDepth:GoogleSearch.kt$GoogleSearch.Companion$@JvmStatic @Throws(ModuleException::class) fun searchGoogle( query: String, apiKey: String?, cseKey: String?, quotaUser: String = ReleaseInfo.PROJECT ): List<Message> NestedBlockDepth:LinksManager.kt$LinksManager$override fun commandResponse(channel: String, args: String, event: GenericMessageEvent) NestedBlockDepth:Lookup.kt$Lookup$override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) @@ -66,7 +66,7 @@ NestedBlockDepth:TwitterOAuth.kt$TwitterOAuth$@JvmStatic fun main(args: Array<String>) NestedBlockDepth:Utils.kt$Utils$@JvmStatic fun loadData(file: String, default: Any, logger: Logger, description: String): Any NestedBlockDepth:Utils.kt$Utils$@JvmStatic fun saveData(file: String, data: Any, logger: Logger, description: String) - NestedBlockDepth:Weather2.kt$Weather2$override fun run(channel: String, cmd: String, args: String, event: GenericMessageEvent) + NestedBlockDepth:Weather2.kt$Weather2$override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) NestedBlockDepth:Weather2.kt$Weather2.Companion$@JvmStatic @Throws(ModuleException::class) fun getWeather(query: String, apiKey: String?): List<Message> PrintStackTrace:TwitterOAuth.kt$TwitterOAuth$ioe PrintStackTrace:TwitterOAuth.kt$TwitterOAuth$te diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/FeedReader.kt b/src/main/kotlin/net/thauvin/erik/mobibot/FeedReader.kt index eb00137..fc43dbc 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/FeedReader.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/FeedReader.kt @@ -65,7 +65,7 @@ class FeedReader(private val url: String, val event: GenericMessageEvent) : Runn event.sendMessage("An error has occurred while parsing the feed: ${e.message}") } catch (e: IOException) { if (logger.isWarnEnabled) logger.warn("Unable to fetch the feed at $url", e) - event.sendMessage("An error has occurred while fetching the feed: ${e.message}") + event.sendMessage("An IO error has occurred while fetching the feed: ${e.message}") } } diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/Mobibot.kt b/src/main/kotlin/net/thauvin/erik/mobibot/Mobibot.kt index bae8403..fcd2d08 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/Mobibot.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/Mobibot.kt @@ -176,7 +176,7 @@ class Mobibot(nickname: String, val channel: String, logsDirPath: String, p: Pro override fun onDisconnect(event: DisconnectEvent?) { event?.let { with(event.getBot()) { - LinksManager.socialManager.notification("$nick disconnected from irc://$serverHostname") + LinksManager.socialManager.notification("$nick disconnected from $serverHostname") seen.add(userChannelDao.getChannel(channel).users) } } @@ -202,7 +202,7 @@ class Mobibot(nickname: String, val channel: String, logsDirPath: String, p: Pro with(event.getBot()) { if (user.nick == nick) { LinksManager.socialManager.notification( - "$nick has joined ${event.channel.name} on irc://$serverHostname" + "$nick has joined ${event.channel.name} on $serverHostname" ) seen.add(userChannelDao.getChannel(channel).users) } else { @@ -215,12 +215,10 @@ class Mobibot(nickname: String, val channel: String, logsDirPath: String, p: Pro override fun onMessage(event: MessageEvent?) { event?.user?.let { user -> - val sender = user.nick - val message = event.message tell.send(event) - if (message.matches("(?i)${Pattern.quote(event.bot().nick)}:.*".toRegex())) { // mobibot: - if (logger.isTraceEnabled) logger.trace(">>> $sender: $message") - val cmds = message.substring(message.indexOf(':') + 1).trim().split(" ".toRegex(), 2) + if (event.message.matches("(?i)${Pattern.quote(event.bot().nick)}:.*".toRegex())) { // mobibot: + if (logger.isTraceEnabled) logger.trace(">>> ${user.nick}: ${event.message}") + val cmds = event.message.substring(event.bot().nick.length + 1).trim().split(" ".toRegex(), 2) val cmd = cmds[0].lowercase() val args = cmds.lastOrEmpty().trim() if (cmd.startsWith(Constants.HELP_CMD)) { // mobibot: help @@ -230,10 +228,10 @@ class Mobibot(nickname: String, val channel: String, logsDirPath: String, p: Pro addons.exec(channel, cmd, args, event) } } else if (addons.match(channel, event)) { // Links, e.g.: https://www.example.com/ or L1: , etc. - if (logger.isTraceEnabled) logger.trace(">>> $sender: $message") + if (logger.isTraceEnabled) logger.trace(">>> ${user.nick}: ${event.message}") } - storeRecap(sender, message, false) - seen.add(sender) + storeRecap(user.nick, event.message, false) + seen.add(user.nick) } } @@ -252,7 +250,7 @@ class Mobibot(nickname: String, val channel: String, logsDirPath: String, p: Pro with(event.getBot()) { if (user.nick == nick) { LinksManager.socialManager.notification( - "$nick has left ${event.channel.name} on irc://$serverHostname" + "$nick has left ${event.channel.name} on $serverHostname" ) seen.add(userChannelDao.getChannel(channel).users) } else { diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/Pinboard.kt b/src/main/kotlin/net/thauvin/erik/mobibot/Pinboard.kt index ee9b020..1bc719b 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/Pinboard.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/Pinboard.kt @@ -32,8 +32,6 @@ package net.thauvin.erik.mobibot -import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking import net.thauvin.erik.mobibot.entries.EntryLink import net.thauvin.erik.pinboard.PinboardPoster import java.time.ZoneId @@ -53,12 +51,8 @@ class Pinboard { */ fun addPin(ircServer: String, entry: EntryLink) { if (poster.apiToken.isNotBlank()) { - runBlocking { - launch { - with(entry) { - poster.addPin(link, title, postedBy(ircServer), formatTags(), date.toTimestamp()) - } - } + with(entry) { + poster.addPin(link, title, postedBy(ircServer), formatTags(), date.toTimestamp()) } } } @@ -75,12 +69,9 @@ class Pinboard { */ fun deletePin(entry: EntryLink) { if (poster.apiToken.isNotBlank()) { - runBlocking { - launch { - poster.deletePin(entry.link) - } - } + poster.deletePin(entry.link) } + } /** @@ -88,15 +79,11 @@ class Pinboard { */ fun updatePin(ircServer: String, oldUrl: String, entry: EntryLink) { if (poster.apiToken.isNotBlank()) { - runBlocking { - launch { - with(entry) { - if (oldUrl != link) { - poster.deletePin(oldUrl) - } - poster.addPin(link, title, postedBy(ircServer), formatTags(), date.toTimestamp()) - } + with(entry) { + if (oldUrl != link) { + poster.deletePin(oldUrl) } + poster.addPin(link, title, postedBy(ircServer), formatTags(), date.toTimestamp()) } } } @@ -106,8 +93,7 @@ class Pinboard { */ private fun Date.toTimestamp(): String { return ZonedDateTime.ofInstant( - toInstant().truncatedTo(ChronoUnit.SECONDS), - ZoneId.systemDefault() + toInstant().truncatedTo(ChronoUnit.SECONDS), ZoneId.systemDefault() ).format(DateTimeFormatter.ISO_INSTANT) } diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/commands/ChannelFeed.kt b/src/main/kotlin/net/thauvin/erik/mobibot/commands/ChannelFeed.kt index 3cc1b1a..8412af0 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/commands/ChannelFeed.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/commands/ChannelFeed.kt @@ -32,8 +32,6 @@ package net.thauvin.erik.mobibot.commands -import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking import net.thauvin.erik.mobibot.FeedReader import net.thauvin.erik.mobibot.Utils.helpFormat import org.pircbotx.hooks.types.GenericMessageEvent @@ -55,11 +53,7 @@ class ChannelFeed(channel: String) : AbstractCommand() { override fun commandResponse(channel: String, args: String, event: GenericMessageEvent) { if (isEnabled()) { - runBlocking { - launch { - properties[FEED_PROP]?.let { FeedReader(it, event).run() } - } - } + properties[FEED_PROP]?.let { FeedReader(it, event).run() } } } diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/commands/Cycle.kt b/src/main/kotlin/net/thauvin/erik/mobibot/commands/Cycle.kt index 20a49d2..31a9c65 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/commands/Cycle.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/commands/Cycle.kt @@ -33,6 +33,7 @@ package net.thauvin.erik.mobibot.commands import kotlinx.coroutines.delay +import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import net.thauvin.erik.mobibot.Utils.bot import net.thauvin.erik.mobibot.Utils.helpFormat @@ -51,10 +52,12 @@ class Cycle : AbstractCommand() { with(event.bot()) { if (event.isChannelOp(channel)) { runBlocking { - sendIRC().message(channel, "${event.user.nick} asked me to leave. I'll be back!") - userChannelDao.getChannel(channel).send().part() - delay(wait * 1000L) - sendIRC().joinChannel(channel) + launch { + sendIRC().message(channel, "${event.user.nick} asked me to leave. I'll be back!") + userChannelDao.getChannel(channel).send().part() + delay(wait * 1000L) + sendIRC().joinChannel(channel) + } } } else { helpResponse(channel, args, event) diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/commands/Ignore.kt b/src/main/kotlin/net/thauvin/erik/mobibot/commands/Ignore.kt index 5d03cb8..f47f057 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/commands/Ignore.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/commands/Ignore.kt @@ -141,7 +141,7 @@ class Ignore : AbstractCommand() { override fun setProperty(key: String, value: String) { super.setProperty(key, value) if (IGNORE_PROP == key) { - ignored.addAll(value.split(LinksManager.TAG_MATCH) + ignored.addAll(value.split(LinksManager.TAG_MATCH)) } } diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/commands/Users.kt b/src/main/kotlin/net/thauvin/erik/mobibot/commands/Users.kt index fddb9be..66c4ebf 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/commands/Users.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/commands/Users.kt @@ -45,15 +45,7 @@ class Users : AbstractCommand() { override val isVisible = true override fun commandResponse(channel: String, args: String, event: GenericMessageEvent) { - val nicks = mutableListOf() val ch = event.bot().userChannelDao.getChannel(channel) - ch.users.forEach { - if (it.channelsOpIn.contains(ch)) { - nicks.add("@${it.nick}") - } else { - nicks.add(it.nick) - } - } - event.sendList(nicks, 8) + event.sendList(ch.users.map { if (it.channelsOpIn.contains(ch)) "@${it.nick}" else it.nick }, 8) } } diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/commands/tell/TellMessage.kt b/src/main/kotlin/net/thauvin/erik/mobibot/commands/tell/TellMessage.kt index a504c92..7d8aaed 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/commands/tell/TellMessage.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/commands/tell/TellMessage.kt @@ -37,7 +37,7 @@ import java.time.LocalDateTime import java.time.format.DateTimeFormatter /** - * The `TellMessage` class. + * Tell Message. */ class TellMessage( /** diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt.kt index 40021e3..c464928 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt.kt @@ -46,12 +46,12 @@ import java.net.http.HttpClient import java.net.http.HttpRequest import java.net.http.HttpResponse -class ChatGpt : ThreadedModule() { +class ChatGpt : AbstractModule() { private val logger: Logger = LoggerFactory.getLogger(ChatGpt::class.java) override val name = "ChatGPT" - override fun run(channel: String, cmd: String, args: String, event: GenericMessageEvent) { + override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) { if (args.isNotBlank()) { try { event.sendMessage( 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 7f9e4b7..66a33ae 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/CryptoPrices.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/CryptoPrices.kt @@ -46,7 +46,7 @@ import java.io.IOException /** * The Cryptocurrency Prices module. */ -class CryptoPrices : ThreadedModule() { +class CryptoPrices : AbstractModule() { private val logger: Logger = LoggerFactory.getLogger(CryptoPrices::class.java) override val name = "CryptoPrices" @@ -55,7 +55,7 @@ class CryptoPrices : ThreadedModule() { * Returns the cryptocurrency market price from * [Coinbase](https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices#get-spot-price). */ - override fun run(channel: String, cmd: String, args: String, event: GenericMessageEvent) { + override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) { if (CURRENCIES.isEmpty()) { try { loadCurrencies() 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 712aedf..3d0bf0a 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/CurrencyConverter.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/CurrencyConverter.kt @@ -52,7 +52,7 @@ import java.util.TreeMap /** * The CurrencyConverter module. */ -class CurrencyConverter : ThreadedModule() { +class CurrencyConverter : AbstractModule() { private val logger: Logger = LoggerFactory.getLogger(CurrencyConverter::class.java) override val name = "CurrencyConverter" @@ -71,7 +71,7 @@ class CurrencyConverter : ThreadedModule() { /** * Converts the specified currencies. */ - override fun run(channel: String, cmd: String, args: String, event: GenericMessageEvent) { + override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) { reload() if (SYMBOLS.isEmpty()) { 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 7499ec8..76451db 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/GoogleSearch.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/GoogleSearch.kt @@ -54,7 +54,7 @@ import java.net.URL /** * The GoogleSearch module. */ -class GoogleSearch : ThreadedModule() { +class GoogleSearch : AbstractModule() { private val logger: Logger = LoggerFactory.getLogger(GoogleSearch::class.java) override val name = "GoogleSearch" @@ -62,7 +62,7 @@ class GoogleSearch : ThreadedModule() { /** * Searches Google. */ - override fun run(channel: String, cmd: String, args: String, event: GenericMessageEvent) { + override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) { if (args.isNotBlank()) { try { val results = searchGoogle( 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 e85a914..202dc68 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Joke.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Joke.kt @@ -31,8 +31,6 @@ */ package net.thauvin.erik.mobibot.modules -import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking import net.thauvin.erik.jokeapi.exceptions.HttpErrorException import net.thauvin.erik.jokeapi.exceptions.JokeException import net.thauvin.erik.jokeapi.getJoke @@ -52,21 +50,15 @@ import java.io.IOException /** * The Joke module. */ -class Joke : ThreadedModule() { +class Joke : AbstractModule() { 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) } - } - } - /** * Returns a random joke from [JokeAPI](https://v2.jokeapi.dev/). */ - override fun run(channel: String, cmd: String, args: String, event: GenericMessageEvent) { + override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) { with(event.bot()) { try { randomJoke().forEach { @@ -92,12 +84,8 @@ class Joke : ThreadedModule() { @Throws(ModuleException::class) fun randomJoke(): List { return try { - val messages = mutableListOf() val joke = getJoke(safe = true, type = Type.SINGLE, splitNewLine = true) - joke.joke.forEach { - messages.add(PublicMessage(it, Colors.CYAN)) - } - messages + joke.joke.map { PublicMessage(it, Colors.CYAN) } } catch (e: JokeException) { throw ModuleException("randomJoke(): ${e.additionalInfo}", e.message, e) } catch (e: HttpErrorException) { diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Mastodon.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Mastodon.kt index b355fdc..ae805cd 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Mastodon.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Mastodon.kt @@ -93,7 +93,7 @@ class Mastodon : SocialModule() { private const val MASTODON_CMD = "mastodon" /** - * Toots on Mastodon. + * Post on Mastodon. */ @JvmStatic @Throws(ModuleException::class) 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 4c2859f..ffca08b 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/StockQuote.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/StockQuote.kt @@ -52,7 +52,7 @@ import java.net.URL /** * The StockQuote module. */ -class StockQuote : ThreadedModule() { +class StockQuote : AbstractModule() { private val logger: Logger = LoggerFactory.getLogger(StockQuote::class.java) override val name = "StockQuote" @@ -60,7 +60,7 @@ class StockQuote : ThreadedModule() { /** * Returns the specified stock quote from Alpha Vantage. */ - override fun run(channel: String, cmd: String, args: String, event: GenericMessageEvent) { + override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) { if (args.isNotBlank()) { try { val messages = getQuote(args, properties[ALPHAVANTAGE_API_KEY_PROP]) diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/ThreadedModule.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/ThreadedModule.kt deleted file mode 100644 index 269b24d..0000000 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/ThreadedModule.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * ThreadedModule.kt - * - * Copyright (c) 2004-2022, Erik C. Thauvin (erik@thauvin.net) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of this project nor the names of its contributors may be - * used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.thauvin.erik.mobibot.modules - -import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking -import org.pircbotx.hooks.types.GenericMessageEvent - -/** - * The `ThreadedModule` class. - */ -abstract class ThreadedModule : AbstractModule() { - override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) { - if (isEnabled && event.message.isNotEmpty()) { - runBlocking { - launch { - run(channel, cmd, args, event) - } - } - } else { - helpResponse(event) - } - } - - /** - * Runs the thread. - */ - abstract fun run(channel: String, cmd: String, args: String, event: GenericMessageEvent) -} 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 2253494..28f9cde 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Twitter.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Twitter.kt @@ -88,7 +88,7 @@ class Twitter : SocialModule() { private const val TWITTER_CMD = "twitter" /** - * Tweets on Twitter. + * Post on Twitter. */ @JvmStatic @Throws(ModuleException::class) 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 8dcdc15..5c5ae67 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Weather2.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Weather2.kt @@ -54,7 +54,7 @@ import kotlin.math.roundToInt /** * The `Weather2` module. */ -class Weather2 : ThreadedModule() { +class Weather2 : AbstractModule() { private val logger: Logger = LoggerFactory.getLogger(Weather2::class.java) override val name = "Weather" @@ -62,7 +62,7 @@ class Weather2 : ThreadedModule() { /** * Fetches the weather data from a specific city. */ - override fun run(channel: String, cmd: String, args: String, event: GenericMessageEvent) { + override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) { if (args.isNotBlank()) { try { val messages = getWeather(args, properties[OWM_API_KEY_PROP]) diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/WolframAlpha.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/WolframAlpha.kt index 1d5abd3..56d3a3d 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/WolframAlpha.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/WolframAlpha.kt @@ -43,7 +43,7 @@ import org.slf4j.LoggerFactory import java.io.IOException import java.net.URL -class WolframAlpha : ThreadedModule() { +class WolframAlpha : AbstractModule() { private val logger: Logger = LoggerFactory.getLogger(WolframAlpha::class.java) override val name = "WolframAlpha" @@ -56,7 +56,7 @@ class WolframAlpha : ThreadedModule() { } } - override fun run(channel: String, cmd: String, args: String, event: GenericMessageEvent) { + override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) { if (args.isNotBlank()) { try { val query = args.trim().split("units=", limit = 2, ignoreCase = true) diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/social/SocialManager.kt b/src/main/kotlin/net/thauvin/erik/mobibot/social/SocialManager.kt index c991140..f3a86fe 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/social/SocialManager.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/social/SocialManager.kt @@ -110,8 +110,8 @@ class SocialManager { */ fun shutdown() { timer.cancel() - for (index in entries) { - postEntry(index) + entries.forEach { + postEntry(it) } } } diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/social/SocialModule.kt b/src/main/kotlin/net/thauvin/erik/mobibot/social/SocialModule.kt index c15dd55..e31ccdc 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/social/SocialModule.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/social/SocialModule.kt @@ -32,18 +32,16 @@ package net.thauvin.erik.mobibot.social -import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking import net.thauvin.erik.mobibot.commands.links.LinksManager import net.thauvin.erik.mobibot.entries.EntriesUtils.toLinkLabel import net.thauvin.erik.mobibot.entries.EntryLink +import net.thauvin.erik.mobibot.modules.AbstractModule import net.thauvin.erik.mobibot.modules.ModuleException -import net.thauvin.erik.mobibot.modules.ThreadedModule import org.pircbotx.hooks.types.GenericMessageEvent import org.slf4j.Logger import org.slf4j.LoggerFactory -abstract class SocialModule : ThreadedModule() { +abstract class SocialModule : AbstractModule() { private val logger: Logger = LoggerFactory.getLogger(SocialManager::class.java) abstract val handle: String? @@ -56,15 +54,11 @@ abstract class SocialModule : ThreadedModule() { */ fun notification(msg: String) { if (isEnabled && !handle.isNullOrBlank()) { - runBlocking { - launch { - try { - post(message = msg, isDm = true) - if (logger.isDebugEnabled) logger.debug("Notified $handle on $name: $msg") - } catch (e: ModuleException) { - if (logger.isWarnEnabled) logger.warn("Failed to notify $handle on $name: $msg", e) - } - } + try { + post(message = msg, isDm = true) + if (logger.isDebugEnabled) logger.debug("Notified $handle on $name: $msg") + } catch (e: ModuleException) { + if (logger.isWarnEnabled) logger.warn("Failed to notify $handle on $name: $msg", e) } } } @@ -76,25 +70,21 @@ abstract class SocialModule : ThreadedModule() { */ fun postEntry(index: Int) { if (isAutoPost && LinksManager.entries.links.size >= index) { - runBlocking { - launch { - try { - if (logger.isDebugEnabled) { - logger.debug("Posting {} to $name.", index.toLinkLabel()) - } - post(message = formatEntry(LinksManager.entries.links[index]), isDm = false) - } catch (e: ModuleException) { - if (logger.isWarnEnabled) logger.warn( - "Failed to post entry ${index.toLinkLabel()} on $name.", - e - ) - } + try { + if (logger.isDebugEnabled) { + logger.debug("Posting {} to $name.", index.toLinkLabel()) } + post(message = formatEntry(LinksManager.entries.links[index]), isDm = false) + } catch (e: ModuleException) { + if (logger.isWarnEnabled) logger.warn( + "Failed to post entry ${index.toLinkLabel()} on $name.", + e + ) } } } - override fun run(channel: String, cmd: String, args: String, event: GenericMessageEvent) { + override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) { try { event.respond(post("$args (by ${event.user.nick} on $channel)", false)) } catch (e: ModuleException) { diff --git a/src/test/kotlin/net/thauvin/erik/mobibot/entries/EntryLinkTest.kt b/src/test/kotlin/net/thauvin/erik/mobibot/entries/EntryLinkTest.kt index b36d167..8c1a862 100644 --- a/src/test/kotlin/net/thauvin/erik/mobibot/entries/EntryLinkTest.kt +++ b/src/test/kotlin/net/thauvin/erik/mobibot/entries/EntryLinkTest.kt @@ -40,7 +40,6 @@ import assertk.assertions.isFalse import assertk.assertions.isTrue import assertk.assertions.prop import assertk.assertions.size -import assertk.assertions.startsWith import com.rometools.rome.feed.synd.SyndCategory import com.rometools.rome.feed.synd.SyndCategoryImpl import org.testng.annotations.Test diff --git a/version.properties b/version.properties index edb9391..4eb40f3 100644 --- a/version.properties +++ b/version.properties @@ -1,9 +1,9 @@ #Generated by the Semver Plugin for Gradle -#Wed Dec 07 02:53:01 PST 2022 -version.buildmeta=857 +#Sat Dec 10 10:16:56 PST 2022 +version.buildmeta=874 version.major=0 version.minor=8 version.patch=0 version.prerelease=rc version.project=mobibot -version.semver=0.8.0-rc+857 +version.semver=0.8.0-rc+874