Utils functions improvements.

This commit is contained in:
Erik C. Thauvin 2021-05-14 20:57:25 -07:00
parent 790bd3159e
commit 2e1c6e7732
22 changed files with 221 additions and 225 deletions

View file

@ -36,11 +36,11 @@ import net.thauvin.erik.mobibot.PinboardUtils.deletePin
import net.thauvin.erik.mobibot.PinboardUtils.updatePin import net.thauvin.erik.mobibot.PinboardUtils.updatePin
import net.thauvin.erik.mobibot.Utils.buildCmdSyntax import net.thauvin.erik.mobibot.Utils.buildCmdSyntax
import net.thauvin.erik.mobibot.Utils.colorize import net.thauvin.erik.mobibot.Utils.colorize
import net.thauvin.erik.mobibot.Utils.ensureDir
import net.thauvin.erik.mobibot.Utils.getIntProperty import net.thauvin.erik.mobibot.Utils.getIntProperty
import net.thauvin.erik.mobibot.Utils.helpFormat import net.thauvin.erik.mobibot.Utils.helpFormat
import net.thauvin.erik.mobibot.Utils.isoLocalDate
import net.thauvin.erik.mobibot.Utils.today import net.thauvin.erik.mobibot.Utils.today
import net.thauvin.erik.mobibot.Utils.toIsoLocalDate
import net.thauvin.erik.mobibot.Utils.toDir
import net.thauvin.erik.mobibot.commands.AddLog import net.thauvin.erik.mobibot.commands.AddLog
import net.thauvin.erik.mobibot.commands.ChannelFeed import net.thauvin.erik.mobibot.commands.ChannelFeed
import net.thauvin.erik.mobibot.commands.Cycle import net.thauvin.erik.mobibot.commands.Cycle
@ -546,7 +546,7 @@ class Mobibot(nickname: String, channel: String, logsDirPath: String, p: Propert
} }
commandLine.hasOption(Constants.VERSION_ARG[0]) -> { commandLine.hasOption(Constants.VERSION_ARG[0]) -> {
// Output the version // Output the version
println("${ReleaseInfo.PROJECT} ${ReleaseInfo.VERSION} (${isoLocalDate(ReleaseInfo.BUILDDATE)})") println("${ReleaseInfo.PROJECT} ${ReleaseInfo.VERSION} (${ReleaseInfo.BUILDDATE.toIsoLocalDate()})")
println(ReleaseInfo.WEBSITE) println(ReleaseInfo.WEBSITE)
} }
else -> { else -> {
@ -567,7 +567,7 @@ class Mobibot(nickname: String, channel: String, logsDirPath: String, p: Propert
} }
val nickname = p.getProperty("nick", Mobibot::class.java.name.lowercase()) val nickname = p.getProperty("nick", Mobibot::class.java.name.lowercase())
val channel = p.getProperty("channel") val channel = p.getProperty("channel")
val logsDir = ensureDir(p.getProperty("logs", "."), false) val logsDir = p.getProperty("logs", ".").toDir()
// Redirect stdout and stderr // Redirect stdout and stderr
if (!commandLine.hasOption(Constants.DEBUG_ARG[0])) { if (!commandLine.hasOption(Constants.DEBUG_ARG[0])) {
@ -637,7 +637,7 @@ class Mobibot(nickname: String, channel: String, logsDirPath: String, p: Propert
// Set the URLs // Set the URLs
weblogUrl = p.getProperty("weblog", "") weblogUrl = p.getProperty("weblog", "")
backlogsUrl = ensureDir(p.getProperty("backlogs", weblogUrl), true) backlogsUrl = p.getProperty("backlogs", weblogUrl).toDir(true)
// Load the current entries and backlogs, if any // Load the current entries and backlogs, if any
try { try {

View file

@ -87,7 +87,7 @@ object Utils {
* Capitalize a string. * Capitalize a string.
*/ */
@JvmStatic @JvmStatic
fun capitalize(s: String?): String? = s?.replaceFirstChar { it.uppercase() } fun String.capitalise(): String = this.replaceFirstChar { it.uppercase() }
/** /**
* Colorize a string. * Colorize a string.
@ -115,30 +115,6 @@ object Utils {
@JvmStatic @JvmStatic
fun encodeUrl(s: String): String = URLEncoder.encode(s, StandardCharsets.UTF_8) fun encodeUrl(s: String): String = URLEncoder.encode(s, StandardCharsets.UTF_8)
/**
* Ensures that the given location (File/URL) has a trailing slash (`/`) to indicate a directory.
*/
@JvmStatic
fun ensureDir(location: String, isUrl: Boolean): String {
return if (location.isNotEmpty()) {
if (isUrl) {
if (location[location.length - 1] == '/') {
location
} else {
"$location/"
}
} else {
if (location[location.length - 1] == File.separatorChar) {
location
} else {
location + File.separatorChar
}
}
} else {
location
}
}
/** /**
* Returns a property as an int. * Returns a property as an int.
*/ */
@ -166,46 +142,27 @@ object Utils {
return (if (isIndent) " " else "").plus(if (isBold) bold(help) else help) return (if (isIndent) " " else "").plus(if (isBold) bold(help) else help)
} }
/**
* Returns the specified date as an ISO local date string.
*/
@JvmStatic
fun isoLocalDate(date: Date): String {
return isoLocalDate(LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()))
}
/**
* Returns the specified date as an ISO local date string.
*/
@JvmStatic
fun isoLocalDate(date: LocalDateTime): String = date.format(DateTimeFormatter.ISO_LOCAL_DATE)
/** /**
* Obfuscates the given string. * Obfuscates the given string.
*/ */
@JvmStatic @JvmStatic
fun obfuscate(s: String): String { fun String.obfuscate(): String {
return if (s.isNotBlank()) { return if (this.isNotBlank()) {
StringUtils.repeat('x', s.length) StringUtils.repeat('x', this.length)
} else s } else this
} }
/** /**
* Returns the plural form of a word, if count > 1. * Returns the plural form of a word, if count > 1.
*/ */
@JvmStatic fun String.plural(count: Int, plural: String): String = this.plural(count.toLong(), plural)
fun plural(count: Int, word: String, plural: String): String = plural(count.toLong(), word, plural)
/** /**
* Returns the plural form of a word, if count > 1. * Returns the plural form of a word, if count > 1.
*/ */
@JvmStatic @JvmStatic
fun plural(count: Long, word: String, plural: String): String { fun String.plural(count: Long, plural: String): String {
return if (count > 1) { return if (count > 1) plural else this
plural
} else {
word
}
} }
/** /**
@ -224,7 +181,55 @@ object Utils {
* Returns today's date. * Returns today's date.
*/ */
@JvmStatic @JvmStatic
fun today(): String = isoLocalDate(LocalDateTime.now()) fun today(): String = LocalDateTime.now().toIsoLocalDate()
/**
* Ensures that the given location (File/URL) has a trailing slash (`/`) to indicate a directory.
*/
@JvmStatic
fun String.toDir(isUrl: Boolean = false) : String {
return if (isUrl) {
if (this.last() == '/') {
this
} else {
"$this/"
}
} else {
if (this.last() == File.separatorChar) {
this
} else {
this + File.separatorChar
}
}
}
/**
* Returns the specified date as an ISO local date string.
*/
@JvmStatic
fun Date.toIsoLocalDate(): String {
return LocalDateTime.ofInstant(this.toInstant(), ZoneId.systemDefault()).toIsoLocalDate()
}
/**
* Returns the specified date as an ISO local date string.
*/
@JvmStatic
fun LocalDateTime.toIsoLocalDate(): String = this.format(DateTimeFormatter.ISO_LOCAL_DATE)
/**
* Returns the specified date formatted as `yyyy-MM-dd HH:mm`.
*/
@JvmStatic
fun Date.toUtcDateTime(): String {
return LocalDateTime.ofInstant(this.toInstant(), ZoneId.systemDefault()).toUtcDateTime()
}
/**
* Returns the specified date formatted as `yyyy-MM-dd HH:mm`.
*/
@JvmStatic
fun LocalDateTime.toUtcDateTime(): String = this.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))
/** /**
* Converts XML/XHTML entities to plain text. * Converts XML/XHTML entities to plain text.
@ -254,21 +259,21 @@ object Utils {
) )
with(info) { with(info) {
if (years > 0) { if (years > 0) {
append(years).append(plural(years, " year ", " years ")) append(years).append(" year ".plural(years, " years "))
} }
if (months > 0) { if (months > 0) {
append(weeks).append(plural(months, " month ", " months ")) append(weeks).append(" month ".plural(months, " months "))
} }
if (weeks > 0) { if (weeks > 0) {
append(weeks).append(plural(weeks, " week ", " weeks ")) append(weeks).append(" week ".plural(weeks, " weeks "))
} }
if (days > 0) { if (days > 0) {
append(days).append(plural(days, " day ", " days ")) append(days).append(" day ".plural(days, " days "))
} }
if (hours > 0) { if (hours > 0) {
append(hours).append(plural(hours, " hour ", " hours ")) append(hours).append(" hour ".plural(hours, " hours "))
} }
append(minutes).append(plural(minutes, " minute", " minutes")) append(minutes).append(" minute ".plural(minutes, " minutes"))
return toString() return toString()
} }
} }
@ -282,20 +287,4 @@ object Utils {
BufferedReader(InputStreamReader(url.openStream(), StandardCharsets.UTF_8)) BufferedReader(InputStreamReader(url.openStream(), StandardCharsets.UTF_8))
.use { reader -> return reader.lines().collect(Collectors.joining(System.lineSeparator())) } .use { reader -> return reader.lines().collect(Collectors.joining(System.lineSeparator())) }
} }
/**
* Returns the specified date formatted as `yyyy-MM-dd HH:mm`.
*/
@JvmStatic
fun utcDateTime(date: Date): String {
return utcDateTime(LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()))
}
/**
* Returns the specified date formatted as `yyyy-MM-dd HH:mm`.
*/
@JvmStatic
fun utcDateTime(date: LocalDateTime?): String {
return date?.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")) ?: ""
}
} }

View file

@ -33,7 +33,7 @@
package net.thauvin.erik.mobibot.commands package net.thauvin.erik.mobibot.commands
import net.thauvin.erik.mobibot.Mobibot import net.thauvin.erik.mobibot.Mobibot
import net.thauvin.erik.mobibot.Utils import net.thauvin.erik.mobibot.Utils.buildCmdSyntax
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
abstract class AbstractCommand(val bot: Mobibot) { abstract class AbstractCommand(val bot: Mobibot) {
@ -56,7 +56,7 @@ abstract class AbstractCommand(val bot: Mobibot) {
open fun helpResponse(command: String, sender: String, isOp: Boolean, isPrivate: Boolean): Boolean { open fun helpResponse(command: String, sender: String, isOp: Boolean, isPrivate: Boolean): Boolean {
if (!this.isOp || this.isOp == isOp) { if (!this.isOp || this.isOp == isOp) {
for (h in help) { for (h in help) {
bot.send(sender, Utils.buildCmdSyntax(h, bot.nick, isPrivate), isPrivate) bot.send(sender, buildCmdSyntax(h, bot.nick, isPrivate), isPrivate)
} }
return true return true
} }

View file

@ -33,7 +33,9 @@
package net.thauvin.erik.mobibot.commands package net.thauvin.erik.mobibot.commands
import net.thauvin.erik.mobibot.Mobibot import net.thauvin.erik.mobibot.Mobibot
import net.thauvin.erik.mobibot.Utils import net.thauvin.erik.mobibot.Utils.bold
import net.thauvin.erik.mobibot.Utils.buildCmdSyntax
import net.thauvin.erik.mobibot.Utils.helpFormat
import net.thauvin.erik.mobibot.commands.links.LinksMgr import net.thauvin.erik.mobibot.commands.links.LinksMgr
class Ignore(bot: Mobibot) : AbstractCommand(bot) { class Ignore(bot: Mobibot) : AbstractCommand(bot) {
@ -46,17 +48,17 @@ class Ignore(bot: Mobibot) : AbstractCommand(bot) {
override val name = IGNORE_CMD override val name = IGNORE_CMD
override val help = listOf( override val help = listOf(
"To ignore a link posted to the channel:", "To ignore a link posted to the channel:",
Utils.helpFormat("https://www.foo.bar %n"), helpFormat("https://www.foo.bar %n"),
"To check your ignore status:", "To check your ignore status:",
Utils.helpFormat("%c $name"), helpFormat("%c $name"),
"To toggle your ignore status:", "To toggle your ignore status:",
Utils.helpFormat("%c $name $me") helpFormat("%c $name $me")
) )
private val helpOp = listOf( private val helpOp = listOf(
"To ignore a link posted to the channel:", "To ignore a link posted to the channel:",
Utils.helpFormat("https://www.foo.bar " + Utils.bold("%n"), false), helpFormat("https://www.foo.bar " + bold("%n"), false),
"To add/remove nicks from the ignored list:", "To add/remove nicks from the ignored list:",
Utils.helpFormat("%c $name <nick> [<nick> ...]") helpFormat("%c $name <nick> [<nick> ...]")
) )
override val isOp = false override val isOp = false
@ -98,7 +100,7 @@ class Ignore(bot: Mobibot) : AbstractCommand(bot) {
): Boolean { ): Boolean {
return if (isOp) { return if (isOp) {
for (h in helpOp) { for (h in helpOp) {
bot.send(sender, Utils.buildCmdSyntax(h, bot.nick, isPrivate), isPrivate) bot.send(sender, buildCmdSyntax(h, bot.nick, isPrivate), isPrivate)
} }
true true
} else { } else {
@ -143,7 +145,7 @@ class Ignore(bot: Mobibot) : AbstractCommand(bot) {
@Suppress("MagicNumber") @Suppress("MagicNumber")
bot.sendList(sender, ignored.sorted(), 8, isPrivate, isIndent = true) bot.sendList(sender, ignored.sorted(), 8, isPrivate, isIndent = true)
} else { } else {
bot.send(sender, "No one is currently ${Utils.bold("ignored")}.", isPrivate) bot.send(sender, "No one is currently ${bold("ignored")}.", isPrivate)
} }
} }

View file

@ -33,7 +33,7 @@ package net.thauvin.erik.mobibot.commands
import net.thauvin.erik.mobibot.Mobibot import net.thauvin.erik.mobibot.Mobibot
import net.thauvin.erik.mobibot.ReleaseInfo import net.thauvin.erik.mobibot.ReleaseInfo
import net.thauvin.erik.mobibot.Utils.capitalize import net.thauvin.erik.mobibot.Utils.capitalise
import net.thauvin.erik.mobibot.Utils.green import net.thauvin.erik.mobibot.Utils.green
import net.thauvin.erik.mobibot.Utils.helpFormat import net.thauvin.erik.mobibot.Utils.helpFormat
import net.thauvin.erik.mobibot.Utils.uptime import net.thauvin.erik.mobibot.Utils.uptime
@ -42,8 +42,8 @@ import java.lang.management.ManagementFactory
class Info(bot: Mobibot?) : AbstractCommand(bot!!) { class Info(bot: Mobibot?) : AbstractCommand(bot!!) {
private val allVersions = listOf( private val allVersions = listOf(
capitalize(ReleaseInfo.PROJECT) + " ${ReleaseInfo.VERSION} (" + green(ReleaseInfo.WEBSITE) + ')', "${ReleaseInfo.PROJECT.capitalise()} ${ReleaseInfo.VERSION} (${green(ReleaseInfo.WEBSITE)})",
"Written by ${ReleaseInfo.AUTHOR} (" + green(ReleaseInfo.AUTHOR_URL) + ')' "Written by ${ReleaseInfo.AUTHOR} (${green(ReleaseInfo.AUTHOR_URL)})"
) )
override val name = "info" override val name = "info"
override val help = listOf("To view information about the bot:", helpFormat("%c $name")) override val help = listOf("To view information about the bot:", helpFormat("%c $name"))

View file

@ -33,7 +33,8 @@
package net.thauvin.erik.mobibot.commands package net.thauvin.erik.mobibot.commands
import net.thauvin.erik.mobibot.Mobibot import net.thauvin.erik.mobibot.Mobibot
import net.thauvin.erik.mobibot.Utils import net.thauvin.erik.mobibot.Utils.toUtcDateTime
import net.thauvin.erik.mobibot.Utils.helpFormat
import java.time.Clock import java.time.Clock
import java.time.LocalDateTime import java.time.LocalDateTime
@ -41,7 +42,7 @@ class Recap(bot: Mobibot) : AbstractCommand(bot) {
override val name = "recap" override val name = "recap"
override val help = listOf( override val help = listOf(
"To list the last 10 public channel messages:", "To list the last 10 public channel messages:",
Utils.helpFormat("%c $name") helpFormat("%c $name")
) )
override val isOp = false override val isOp = false
override val isPublic = true override val isPublic = true
@ -57,7 +58,7 @@ class Recap(bot: Mobibot) : AbstractCommand(bot) {
@JvmStatic @JvmStatic
fun storeRecap(sender: String, message: String, isAction: Boolean) { fun storeRecap(sender: String, message: String, isAction: Boolean) {
recaps.add( recaps.add(
Utils.utcDateTime(LocalDateTime.now(Clock.systemUTC())) LocalDateTime.now(Clock.systemUTC()).toUtcDateTime()
+ " - $sender" + (if (isAction) " " else ": ") + message + " - $sender" + (if (isAction) " " else ": ") + message
) )
@Suppress("MagicNumber") @Suppress("MagicNumber")

View file

@ -34,11 +34,11 @@ package net.thauvin.erik.mobibot.commands
import net.thauvin.erik.mobibot.Mobibot import net.thauvin.erik.mobibot.Mobibot
import net.thauvin.erik.mobibot.ReleaseInfo import net.thauvin.erik.mobibot.ReleaseInfo
import net.thauvin.erik.mobibot.Utils.helpFormat import net.thauvin.erik.mobibot.Utils.helpFormat
import net.thauvin.erik.mobibot.Utils.isoLocalDate import net.thauvin.erik.mobibot.Utils.toIsoLocalDate
class Versions(bot: Mobibot) : AbstractCommand(bot) { class Versions(bot: Mobibot) : AbstractCommand(bot) {
private val allVersions = listOf( private val allVersions = listOf(
"Version: ${ReleaseInfo.VERSION} (" + isoLocalDate(ReleaseInfo.BUILDDATE) + ')', "Version: ${ReleaseInfo.VERSION} (${ReleaseInfo.BUILDDATE.toIsoLocalDate()})",
"Platform: " + System.getProperty("os.name") + ' ' + System.getProperty("os.version") "Platform: " + System.getProperty("os.name") + ' ' + System.getProperty("os.version")
+ " (" + System.getProperty("os.arch") + ')', + " (" + System.getProperty("os.arch") + ')',
"Runtime: " + System.getProperty("java.runtime.name") + ' ' + System.getProperty("java.runtime.version") "Runtime: " + System.getProperty("java.runtime.name") + ' ' + System.getProperty("java.runtime.version")

View file

@ -34,7 +34,9 @@ package net.thauvin.erik.mobibot.commands.links
import net.thauvin.erik.mobibot.Constants import net.thauvin.erik.mobibot.Constants
import net.thauvin.erik.mobibot.Mobibot import net.thauvin.erik.mobibot.Mobibot
import net.thauvin.erik.mobibot.Utils import net.thauvin.erik.mobibot.Utils.bold
import net.thauvin.erik.mobibot.Utils.helpFormat
import net.thauvin.erik.mobibot.Utils.today
import net.thauvin.erik.mobibot.commands.AbstractCommand import net.thauvin.erik.mobibot.commands.AbstractCommand
import net.thauvin.erik.mobibot.commands.Ignore import net.thauvin.erik.mobibot.commands.Ignore
import net.thauvin.erik.mobibot.entries.EntriesMgr import net.thauvin.erik.mobibot.entries.EntriesMgr
@ -72,7 +74,7 @@ class LinksMgr(bot: Mobibot) : AbstractCommand(bot) {
val history = mutableListOf<String>() val history = mutableListOf<String>()
@JvmStatic @JvmStatic
var startDate: String = Utils.today() var startDate: String = today()
private set private set
/** /**
@ -88,9 +90,9 @@ class LinksMgr(bot: Mobibot) : AbstractCommand(bot) {
@JvmStatic @JvmStatic
fun startup(current: String, backlogs: String, channel: String) { fun startup(current: String, backlogs: String, channel: String) {
startDate = EntriesMgr.loadEntries(current, channel, entries) startDate = EntriesMgr.loadEntries(current, channel, entries)
if (Utils.today() != startDate) { if (today() != startDate) {
entries.clear() entries.clear()
startDate = Utils.today() startDate = today()
} }
EntriesMgr.loadBacklogs(backlogs, history) EntriesMgr.loadBacklogs(backlogs, history)
} }
@ -144,7 +146,7 @@ class LinksMgr(bot: Mobibot) : AbstractCommand(bot) {
bot.send(sender, "Please specify a title, by typing:", isPrivate) bot.send(sender, "Please specify a title, by typing:", isPrivate)
bot.send( bot.send(
sender, sender,
Utils.helpFormat("${EntriesUtils.buildLinkCmd(index)}:|This is the title"), helpFormat("${EntriesUtils.buildLinkCmd(index)}:|This is the title"),
isPrivate isPrivate
) )
} }
@ -183,7 +185,7 @@ class LinksMgr(bot: Mobibot) : AbstractCommand(bot) {
for (i in entries.indices) { for (i in entries.indices) {
if (link == entries[i].link) { if (link == entries[i].link) {
val entry: EntryLink = entries[i] val entry: EntryLink = entries[i]
bot.send(sender, Utils.bold("Duplicate") + " >> " + EntriesUtils.buildLink(i, entry), isPrivate) bot.send(sender, bold("Duplicate") + " >> " + EntriesUtils.buildLink(i, entry), isPrivate)
return true return true
} }
} }
@ -201,10 +203,10 @@ class LinksMgr(bot: Mobibot) : AbstractCommand(bot) {
} }
private fun saveDayBackup(bot: Mobibot): Boolean { private fun saveDayBackup(bot: Mobibot): Boolean {
if (Utils.today() != startDate) { if (today() != startDate) {
saveEntries(bot, true) saveEntries(bot, true)
entries.clear() entries.clear()
startDate = Utils.today() startDate = today()
return true return true
} }

View file

@ -38,7 +38,7 @@ import net.thauvin.erik.mobibot.Utils.getIntProperty
import net.thauvin.erik.mobibot.Utils.helpFormat import net.thauvin.erik.mobibot.Utils.helpFormat
import net.thauvin.erik.mobibot.Utils.plural import net.thauvin.erik.mobibot.Utils.plural
import net.thauvin.erik.mobibot.Utils.reverseColor import net.thauvin.erik.mobibot.Utils.reverseColor
import net.thauvin.erik.mobibot.Utils.utcDateTime import net.thauvin.erik.mobibot.Utils.toUtcDateTime
import net.thauvin.erik.mobibot.commands.AbstractCommand import net.thauvin.erik.mobibot.commands.AbstractCommand
import net.thauvin.erik.mobibot.commands.links.View import net.thauvin.erik.mobibot.commands.links.View
@ -117,21 +117,16 @@ class Tell(bot: Mobibot) : AbstractCommand(bot) {
*/ */
override val name = "tell" override val name = "tell"
override val help: List<String> override val help = listOf(
get() = listOf(
"To send a message to someone when they join the channel:", "To send a message to someone when they join the channel:",
helpFormat("%c $name <nick> <message>"), helpFormat("%c $name <nick> <message>"),
"To view queued and sent messages:", "To view queued and sent messages:",
helpFormat("%c $name ${View.VIEW_CMD}"), helpFormat("%c $name ${View.VIEW_CMD}"),
"Messages are kept for " + bold(maxDays) "Messages are kept for ${bold(maxDays)}" + " day.".plural(maxDays, " days.")
+ plural(maxDays, " day.", " days.")
) )
override val isOp: Boolean override val isOp: Boolean = false
get() = false override val isPublic: Boolean = isEnabled()
override val isPublic: Boolean override val isVisible: Boolean = isEnabled()
get() = isEnabled()
override val isVisible: Boolean
get() = isEnabled()
override fun commandResponse( override fun commandResponse(
sender: String, sender: String,
@ -232,8 +227,8 @@ class Tell(bot: Mobibot) : AbstractCommand(bot) {
&& !message.isNotified) { && !message.isNotified) {
bot.send( bot.send(
nickname, nickname,
"Your message ${reverseColor("[ID " + message.id + ']')} was sent to " + "Your message ${reverseColor("[ID " + message.id + ']')} was sent to "
"${bold(message.recipient)} on ${utcDateTime(message.receptionDate)}", + "${bold(message.recipient)} on ${message.receptionDate.toUtcDateTime()}",
true true
) )
message.isNotified = true message.isNotified = true
@ -248,9 +243,7 @@ class Tell(bot: Mobibot) : AbstractCommand(bot) {
* *
* @return The size. * @return The size.
*/ */
fun size(): Int { fun size(): Int = messages.size
return messages.size
}
// View all messages. // View all messages.
private fun viewAll(sender: String, isPrivate: Boolean) { private fun viewAll(sender: String, isPrivate: Boolean) {
@ -281,7 +274,7 @@ class Tell(bot: Mobibot) : AbstractCommand(bot) {
bot.send( bot.send(
sender, sender,
bold(message.sender) + ARROW + bold(message.recipient) bold(message.sender) + ARROW + bold(message.recipient)
+ " [" + utcDateTime(message.receptionDate) + ", ID: " + " [${message.receptionDate.toUtcDateTime()}, ID: "
+ bold(message.id) + ", DELIVERED]", + bold(message.id) + ", DELIVERED]",
isPrivate isPrivate
) )
@ -289,7 +282,7 @@ class Tell(bot: Mobibot) : AbstractCommand(bot) {
bot.send( bot.send(
sender, sender,
bold(message.sender) + ARROW + bold(message.recipient) bold(message.sender) + ARROW + bold(message.recipient)
+ " [" + utcDateTime(message.queued) + ", ID: " + " [${message.queued.toUtcDateTime()}, ID: "
+ bold(message.id) + ", QUEUED]", + bold(message.id) + ", QUEUED]",
isPrivate isPrivate
) )
@ -312,11 +305,7 @@ class Tell(bot: Mobibot) : AbstractCommand(bot) {
), ),
isPrivate isPrivate
) )
bot.send( bot.send(sender, help.last(), isPrivate)
sender,
"Messages are kept for ${bold(maxDays)}${plural(maxDays, " day.", " days.")}",
isPrivate
)
} }
} }

View file

@ -40,7 +40,7 @@ import com.rometools.rome.io.FeedException
import com.rometools.rome.io.SyndFeedInput import com.rometools.rome.io.SyndFeedInput
import com.rometools.rome.io.SyndFeedOutput import com.rometools.rome.io.SyndFeedOutput
import net.thauvin.erik.mobibot.Mobibot import net.thauvin.erik.mobibot.Mobibot
import net.thauvin.erik.mobibot.Utils.isoLocalDate import net.thauvin.erik.mobibot.Utils.toIsoLocalDate
import java.io.IOException import java.io.IOException
import java.io.InputStreamReader import java.io.InputStreamReader
import java.io.OutputStreamWriter import java.io.OutputStreamWriter
@ -146,7 +146,7 @@ object EntriesMgr {
Files.newInputStream(Paths.get(file)), StandardCharsets.UTF_8 Files.newInputStream(Paths.get(file)), StandardCharsets.UTF_8
).use { reader -> ).use { reader ->
val feed = input.build(reader) val feed = input.build(reader)
today = isoLocalDate(feed.publishedDate) today = feed.publishedDate.toIsoLocalDate()
val items = feed.entries val items = feed.entries
var entry: EntryLink var entry: EntryLink
for (i in items.indices.reversed()) { for (i in items.indices.reversed()) {

View file

@ -33,7 +33,10 @@ package net.thauvin.erik.mobibot.modules
import net.thauvin.erik.mobibot.Constants import net.thauvin.erik.mobibot.Constants
import net.thauvin.erik.mobibot.Mobibot import net.thauvin.erik.mobibot.Mobibot
import net.thauvin.erik.mobibot.Utils import net.thauvin.erik.mobibot.Utils.bold
import net.thauvin.erik.mobibot.Utils.buildCmdSyntax
import net.thauvin.erik.mobibot.Utils.helpFormat
import net.thauvin.erik.mobibot.Utils.today
import net.thauvin.erik.mobibot.msg.ErrorMessage import net.thauvin.erik.mobibot.msg.ErrorMessage
import net.thauvin.erik.mobibot.msg.Message import net.thauvin.erik.mobibot.msg.Message
import net.thauvin.erik.mobibot.msg.PublicMessage import net.thauvin.erik.mobibot.msg.PublicMessage
@ -56,7 +59,7 @@ class CurrencyConverter(bot: Mobibot) : ThreadedModule(bot) {
isPrivate: Boolean isPrivate: Boolean
) { ) {
synchronized(this) { synchronized(this) {
if (pubDate != Utils.today()) { if (pubDate != today()) {
EXCHANGE_RATES.clear() EXCHANGE_RATES.clear()
} }
} }
@ -85,7 +88,7 @@ class CurrencyConverter(bot: Mobibot) : ThreadedModule(bot) {
helpResponse(sender, isPrivate) helpResponse(sender, isPrivate)
} }
} else if (args.contains(CURRENCY_RATES_KEYWORD)) { } else if (args.contains(CURRENCY_RATES_KEYWORD)) {
send(sender, "The currency rates for ${Utils.bold(pubDate)} are:", isPrivate) send(sender, "The currency rates for ${bold(pubDate)} are:", isPrivate)
@Suppress("MagicNumber") @Suppress("MagicNumber")
sendList(sender, currencyRates(), 3, isPrivate, isIndent = true) sendList(sender, currencyRates(), 3, isPrivate, isIndent = true)
} else { } else {
@ -109,16 +112,16 @@ class CurrencyConverter(bot: Mobibot) : ThreadedModule(bot) {
send(sender, "To convert from one currency to another:", isPrivate) send(sender, "To convert from one currency to another:", isPrivate)
send( send(
sender, sender,
Utils.helpFormat( helpFormat(
Utils.buildCmdSyntax("%c $CURRENCY_CMD 100 USD to EUR", nick, isPrivateMsgEnabled) buildCmdSyntax("%c $CURRENCY_CMD 100 USD to EUR", nick, isPrivateMsgEnabled)
), ),
isPrivate isPrivate
) )
send(sender, "For a listing of current rates:", isPrivate) send(sender, "For a listing of current rates:", isPrivate)
send( send(
sender, sender,
Utils.helpFormat( helpFormat(
Utils.buildCmdSyntax("%c $CURRENCY_CMD $CURRENCY_RATES_KEYWORD", nick, isPrivateMsgEnabled) buildCmdSyntax("%c $CURRENCY_CMD $CURRENCY_RATES_KEYWORD", nick, isPrivateMsgEnabled)
), ),
isPrivate isPrivate
) )

View file

@ -32,7 +32,11 @@
package net.thauvin.erik.mobibot.modules package net.thauvin.erik.mobibot.modules
import net.thauvin.erik.mobibot.Mobibot import net.thauvin.erik.mobibot.Mobibot
import net.thauvin.erik.mobibot.Utils import net.thauvin.erik.mobibot.Utils.capitalise
import net.thauvin.erik.mobibot.Utils.encodeUrl
import net.thauvin.erik.mobibot.Utils.helpFormat
import net.thauvin.erik.mobibot.Utils.urlReader
import net.thauvin.erik.mobibot.Utils.unescapeXml
import net.thauvin.erik.mobibot.msg.Message import net.thauvin.erik.mobibot.msg.Message
import net.thauvin.erik.mobibot.msg.NoticeMessage import net.thauvin.erik.mobibot.msg.NoticeMessage
import org.jibble.pircbot.Colors import org.jibble.pircbot.Colors
@ -86,21 +90,21 @@ class GoogleSearch(bot: Mobibot) : ThreadedModule(bot) {
@Throws(ModuleException::class) @Throws(ModuleException::class)
fun searchGoogle(query: String, apiKey: String?, cseKey: String?): List<Message> { fun searchGoogle(query: String, apiKey: String?, cseKey: String?): List<Message> {
if (apiKey.isNullOrBlank() || cseKey.isNullOrBlank()) { if (apiKey.isNullOrBlank() || cseKey.isNullOrBlank()) {
throw ModuleException("${Utils.capitalize(GOOGLE_CMD)} is disabled. The API keys are missing.") throw ModuleException("${GOOGLE_CMD.capitalise()} is disabled. The API keys are missing.")
} }
return if (query.isNotBlank()) { return if (query.isNotBlank()) {
val results = mutableListOf<Message>() val results = mutableListOf<Message>()
try { try {
val url = URL( val url = URL(
"https://www.googleapis.com/customsearch/v1?key=$apiKey&cx=$cseKey" + "https://www.googleapis.com/customsearch/v1?key=$apiKey&cx=$cseKey" +
"&q=${Utils.encodeUrl(query)}&filter=1&num=5&alt=json" "&q=${encodeUrl(query)}&filter=1&num=5&alt=json"
) )
val json = JSONObject(Utils.urlReader(url)) val json = JSONObject(urlReader(url))
val ja = json.getJSONArray("items") val ja = json.getJSONArray("items")
for (i in 0 until ja.length()) { for (i in 0 until ja.length()) {
val j = ja.getJSONObject(i) val j = ja.getJSONObject(i)
results.add(NoticeMessage(Utils.unescapeXml(j.getString("title")))) results.add(NoticeMessage(unescapeXml(j.getString("title"))))
results.add(NoticeMessage(Utils.helpFormat(j.getString("link"), false), Colors.DARK_GREEN)) results.add(NoticeMessage(helpFormat(j.getString("link"), false), Colors.DARK_GREEN))
} }
} catch (e: IOException) { } catch (e: IOException) {
throw ModuleException("searchGoogle($query)", "An IO error has occurred searching Google.", e) throw ModuleException("searchGoogle($query)", "An IO error has occurred searching Google.", e)
@ -117,7 +121,7 @@ class GoogleSearch(bot: Mobibot) : ThreadedModule(bot) {
init { init {
commands.add(GOOGLE_CMD) commands.add(GOOGLE_CMD)
help.add("To search Google:") help.add("To search Google:")
help.add(Utils.helpFormat("%c $GOOGLE_CMD <query>")) help.add(helpFormat("%c $GOOGLE_CMD <query>"))
initProperties(GOOGLE_API_KEY_PROP, GOOGLE_CSE_KEY_PROP) initProperties(GOOGLE_API_KEY_PROP, GOOGLE_CSE_KEY_PROP)
} }
} }

View file

@ -32,7 +32,9 @@
package net.thauvin.erik.mobibot.modules package net.thauvin.erik.mobibot.modules
import net.thauvin.erik.mobibot.Mobibot import net.thauvin.erik.mobibot.Mobibot
import net.thauvin.erik.mobibot.Utils import net.thauvin.erik.mobibot.Utils.cyan
import net.thauvin.erik.mobibot.Utils.helpFormat
import net.thauvin.erik.mobibot.Utils.urlReader
import net.thauvin.erik.mobibot.msg.Message import net.thauvin.erik.mobibot.msg.Message
import net.thauvin.erik.mobibot.msg.PublicMessage import net.thauvin.erik.mobibot.msg.PublicMessage
import org.json.JSONException import org.json.JSONException
@ -58,7 +60,7 @@ class Joke(bot: Mobibot) : ThreadedModule(bot) {
*/ */
override fun run(sender: String, cmd: String, args: String, isPrivate: Boolean) { override fun run(sender: String, cmd: String, args: String, isPrivate: Boolean) {
try { try {
bot.send(Utils.cyan(randomJoke().msg)) bot.send(cyan(randomJoke().msg))
} catch (e: ModuleException) { } catch (e: ModuleException) {
if (bot.logger.isWarnEnabled) bot.logger.warn(e.debugMessage, e) if (bot.logger.isWarnEnabled) bot.logger.warn(e.debugMessage, e)
bot.send(sender, e.message, isPrivate) bot.send(sender, e.message, isPrivate)
@ -81,7 +83,7 @@ class Joke(bot: Mobibot) : ThreadedModule(bot) {
fun randomJoke(): Message { fun randomJoke(): Message {
return try { return try {
val url = URL(JOKE_URL) val url = URL(JOKE_URL)
val json = JSONObject(Utils.urlReader(url)) val json = JSONObject(urlReader(url))
PublicMessage( PublicMessage(
json.getJSONObject("value")["joke"].toString().replace("\\'", "'") json.getJSONObject("value")["joke"].toString().replace("\\'", "'")
.replace("\\\"", "\"") .replace("\\\"", "\"")
@ -97,6 +99,6 @@ class Joke(bot: Mobibot) : ThreadedModule(bot) {
init { init {
commands.add(JOKE_CMD) commands.add(JOKE_CMD)
help.add("To retrieve a random joke:") help.add("To retrieve a random joke:")
help.add(Utils.helpFormat("%c $JOKE_CMD")) help.add(helpFormat("%c $JOKE_CMD"))
} }
} }

View file

@ -68,7 +68,7 @@ class ModuleException : Exception {
* Return the sanitized message (e.g. remove API keys, etc.) * Return the sanitized message (e.g. remove API keys, etc.)
*/ */
fun getSanitizedMessage(vararg sanitize: String): String { fun getSanitizedMessage(vararg sanitize: String): String {
val obfuscate = sanitize.map { obfuscate(it) }.toTypedArray() val obfuscate = sanitize.map { it.obfuscate() }.toTypedArray()
return when { return when {
cause != null -> { cause != null -> {
cause.javaClass.name + ": " + StringUtils.replaceEach(cause.message, sanitize, obfuscate) cause.javaClass.name + ": " + StringUtils.replaceEach(cause.message, sanitize, obfuscate)

View file

@ -33,7 +33,10 @@
package net.thauvin.erik.mobibot.modules package net.thauvin.erik.mobibot.modules
import net.thauvin.erik.mobibot.Mobibot import net.thauvin.erik.mobibot.Mobibot
import net.thauvin.erik.mobibot.Utils import net.thauvin.erik.mobibot.Utils.bold
import net.thauvin.erik.mobibot.Utils.green
import net.thauvin.erik.mobibot.Utils.helpFormat
import net.thauvin.erik.mobibot.Utils.red
import kotlin.random.Random import kotlin.random.Random
@ -51,7 +54,7 @@ class RockPaperScissors(bot: Mobibot) : AbstractModule(bot) {
with(help) { with(help) {
add("To play Rock Paper Scissors:") add("To play Rock Paper Scissors:")
add( add(
Utils.helpFormat( helpFormat(
"%c ${Hands.ROCK.name.lowercase()} | ${Hands.PAPER.name.lowercase()}" "%c ${Hands.ROCK.name.lowercase()} | ${Hands.PAPER.name.lowercase()}"
+ " | ${Hands.SCISSORS.name.lowercase()}" + " | ${Hands.SCISSORS.name.lowercase()}"
) )
@ -99,15 +102,15 @@ class RockPaperScissors(bot: Mobibot) : AbstractModule(bot) {
with(bot) { with(bot) {
when { when {
hand == botHand -> { hand == botHand -> {
send("${Utils.green(hand.name)} vs. ${Utils.green(botHand.name)}") send("${green(hand.name)} vs. ${green(botHand.name)}")
action("tied.") action("tied.")
} }
hand.beats(botHand) -> { hand.beats(botHand) -> {
send("${Utils.green(hand.name)} ${Utils.bold(hand.action)} ${Utils.red(botHand.name)}") send("${green(hand.name)} ${bold(hand.action)} ${red(botHand.name)}")
action("lost.") action("lost.")
} }
else -> { else -> {
send("${Utils.green(botHand.name)} ${Utils.bold(botHand.action)} ${Utils.red(hand.name)}") send("${green(botHand.name)} ${bold(botHand.action)} ${red(hand.name)}")
action("wins.") action("wins.")
} }
} }

View file

@ -32,7 +32,11 @@
package net.thauvin.erik.mobibot.modules package net.thauvin.erik.mobibot.modules
import net.thauvin.erik.mobibot.Mobibot import net.thauvin.erik.mobibot.Mobibot
import net.thauvin.erik.mobibot.Utils import net.thauvin.erik.mobibot.Utils.capitalise
import net.thauvin.erik.mobibot.Utils.encodeUrl
import net.thauvin.erik.mobibot.Utils.helpFormat
import net.thauvin.erik.mobibot.Utils.unescapeXml
import net.thauvin.erik.mobibot.Utils.urlReader
import net.thauvin.erik.mobibot.msg.ErrorMessage import net.thauvin.erik.mobibot.msg.ErrorMessage
import net.thauvin.erik.mobibot.msg.Message import net.thauvin.erik.mobibot.msg.Message
import net.thauvin.erik.mobibot.msg.NoticeMessage import net.thauvin.erik.mobibot.msg.NoticeMessage
@ -91,7 +95,7 @@ class StockQuote(bot: Mobibot) : ThreadedModule(bot) {
try { try {
val info = json.getString("Information") val info = json.getString("Information")
if (info.isNotEmpty()) { if (info.isNotEmpty()) {
throw ModuleException(debugMessage, Utils.unescapeXml(info)) throw ModuleException(debugMessage, unescapeXml(info))
} }
} catch (ignore: JSONException) { } catch (ignore: JSONException) {
// Do nothing // Do nothing
@ -99,11 +103,11 @@ class StockQuote(bot: Mobibot) : ThreadedModule(bot) {
try { try {
var error = json.getString("Note") var error = json.getString("Note")
if (error.isNotEmpty()) { if (error.isNotEmpty()) {
throw ModuleException(debugMessage, Utils.unescapeXml(error)) throw ModuleException(debugMessage, unescapeXml(error))
} }
error = json.getString("Error Message") error = json.getString("Error Message")
if (error.isNotEmpty()) { if (error.isNotEmpty()) {
throw ModuleException(debugMessage, Utils.unescapeXml(error)) throw ModuleException(debugMessage, unescapeXml(error))
} }
} catch (ignore: JSONException) { } catch (ignore: JSONException) {
// Do nothing // Do nothing
@ -122,7 +126,7 @@ class StockQuote(bot: Mobibot) : ThreadedModule(bot) {
fun getQuote(symbol: String, apiKey: String?): List<Message> { fun getQuote(symbol: String, apiKey: String?): List<Message> {
if (apiKey.isNullOrBlank()) { if (apiKey.isNullOrBlank()) {
throw ModuleException( throw ModuleException(
"${Utils.capitalize(STOCK_CMD)} is disabled. The API key is missing." "${STOCK_CMD.capitalise()} is disabled. The API key is missing."
) )
} }
return if (symbol.isNotBlank()) { return if (symbol.isNotBlank()) {
@ -132,10 +136,10 @@ class StockQuote(bot: Mobibot) : ThreadedModule(bot) {
try { try {
with(messages) { with(messages) {
// Search for symbol/keywords // Search for symbol/keywords
response = Utils.urlReader( response = urlReader(
URL( URL(
"${ALPHAVANTAGE_URL}SYMBOL_SEARCH&keywords=" + Utils.encodeUrl(symbol) "${ALPHAVANTAGE_URL}SYMBOL_SEARCH&keywords=" + encodeUrl(symbol)
+ "&apikey=" + Utils.encodeUrl(apiKey) + "&apikey=" + encodeUrl(apiKey)
) )
) )
var json = getJsonResponse(response, debugMessage) var json = getJsonResponse(response, debugMessage)
@ -146,11 +150,11 @@ class StockQuote(bot: Mobibot) : ThreadedModule(bot) {
val symbolInfo = symbols.getJSONObject(0) val symbolInfo = symbols.getJSONObject(0)
// Get quote for symbol // Get quote for symbol
response = Utils.urlReader( response = urlReader(
URL( URL(
"${ALPHAVANTAGE_URL}GLOBAL_QUOTE&symbol=" "${ALPHAVANTAGE_URL}GLOBAL_QUOTE&symbol="
+ Utils.encodeUrl(symbolInfo.getString("1. symbol")) + encodeUrl(symbolInfo.getString("1. symbol"))
+ "&apikey=" + Utils.encodeUrl(apiKey) + "&apikey=" + encodeUrl(apiKey)
) )
) )
json = getJsonResponse(response, debugMessage) json = getJsonResponse(response, debugMessage)
@ -161,34 +165,28 @@ class StockQuote(bot: Mobibot) : ThreadedModule(bot) {
} }
add( add(
PublicMessage( PublicMessage(
"Symbol: " + Utils.unescapeXml(quote.getString("01. symbol")) "Symbol: " + unescapeXml(quote.getString("01. symbol"))
+ " [" + Utils.unescapeXml(symbolInfo.getString("2. name")) + ']' + " [" + unescapeXml(symbolInfo.getString("2. name")) + ']'
) )
) )
add(PublicMessage(" Price: " + Utils.unescapeXml(quote.getString("05. price")))) add(PublicMessage(" Price: " + unescapeXml(quote.getString("05. price"))))
add( add(
PublicMessage( PublicMessage(
" Previous: " + Utils.unescapeXml(quote.getString("08. previous close")) " Previous: " + unescapeXml(quote.getString("08. previous close"))
) )
) )
add(NoticeMessage(" Open: " + Utils.unescapeXml(quote.getString("02. open")))) add(NoticeMessage(" Open: " + unescapeXml(quote.getString("02. open"))))
add(NoticeMessage(" High: " + Utils.unescapeXml(quote.getString("03. high")))) add(NoticeMessage(" High: " + unescapeXml(quote.getString("03. high"))))
add(NoticeMessage(" Low: " + Utils.unescapeXml(quote.getString("04. low")))) add(NoticeMessage(" Low: " + unescapeXml(quote.getString("04. low"))))
add( add(NoticeMessage(" Volume: " + unescapeXml(quote.getString("06. volume"))))
NoticeMessage( add(NoticeMessage(
" Volume: " + Utils.unescapeXml(quote.getString("06. volume")) " Latest: " + unescapeXml(quote.getString("07. latest trading day"))
) )
) )
add( add(
NoticeMessage( NoticeMessage(
" Latest: " " Change: " + unescapeXml(quote.getString("09. change")) + " ["
+ Utils.unescapeXml(quote.getString("07. latest trading day")) + unescapeXml(quote.getString("10. change percent")) + ']'
)
)
add(
NoticeMessage(
" Change: " + Utils.unescapeXml(quote.getString("09. change")) + " ["
+ Utils.unescapeXml(quote.getString("10. change percent")) + ']'
) )
) )
} }
@ -208,7 +206,7 @@ class StockQuote(bot: Mobibot) : ThreadedModule(bot) {
init { init {
commands.add(STOCK_CMD) commands.add(STOCK_CMD)
help.add("To retrieve a stock quote:") help.add("To retrieve a stock quote:")
help.add(Utils.helpFormat("%c $STOCK_CMD <symbol|keywords>")) help.add(helpFormat("%c $STOCK_CMD <symbol|keywords>"))
initProperties(ALPHAVANTAGE_API_KEY_PROP) initProperties(ALPHAVANTAGE_API_KEY_PROP)
} }
} }

View file

@ -36,7 +36,10 @@ import net.aksingh.owmjapis.core.OWM
import net.aksingh.owmjapis.core.OWM.Country import net.aksingh.owmjapis.core.OWM.Country
import net.aksingh.owmjapis.model.CurrentWeather import net.aksingh.owmjapis.model.CurrentWeather
import net.thauvin.erik.mobibot.Mobibot import net.thauvin.erik.mobibot.Mobibot
import net.thauvin.erik.mobibot.Utils import net.thauvin.erik.mobibot.Utils.capitalise
import net.thauvin.erik.mobibot.Utils.bold
import net.thauvin.erik.mobibot.Utils.encodeUrl
import net.thauvin.erik.mobibot.Utils.helpFormat
import net.thauvin.erik.mobibot.msg.ErrorMessage import net.thauvin.erik.mobibot.msg.ErrorMessage
import net.thauvin.erik.mobibot.msg.Message import net.thauvin.erik.mobibot.msg.Message
import net.thauvin.erik.mobibot.msg.NoticeMessage import net.thauvin.erik.mobibot.msg.NoticeMessage
@ -102,7 +105,7 @@ class Weather2(bot: Mobibot) : ThreadedModule(bot) {
fun getWeather(query: String, apiKey: String?): List<Message> { fun getWeather(query: String, apiKey: String?): List<Message> {
if (apiKey.isNullOrBlank()) { if (apiKey.isNullOrBlank()) {
throw ModuleException( throw ModuleException(
"${Utils.capitalize(WEATHER_CMD)} is disabled. The API key is missing." "${WEATHER_CMD.capitalise()} is disabled. The API key is missing."
) )
} }
val owm = OWM(apiKey) val owm = OWM(apiKey)
@ -151,7 +154,7 @@ class Weather2(bot: Mobibot) : ThreadedModule(bot) {
for (w in list) { for (w in list) {
if (w != null) { if (w != null) {
condition.append(' ') condition.append(' ')
.append(Utils.capitalize(w.getDescription())) .append(w.getDescription().capitalise())
.append('.') .append('.')
} }
} }
@ -167,7 +170,7 @@ class Weather2(bot: Mobibot) : ThreadedModule(bot) {
messages.add( messages.add(
NoticeMessage( NoticeMessage(
"https://openweathermap.org/find?q=" "https://openweathermap.org/find?q="
+ Utils.encodeUrl("$city,${country.uppercase()}"), + encodeUrl("$city,${country.uppercase()}"),
Colors.GREEN Colors.GREEN
) )
) )
@ -197,10 +200,10 @@ class Weather2(bot: Mobibot) : ThreadedModule(bot) {
init { init {
commands.add(WEATHER_CMD) commands.add(WEATHER_CMD)
help.add("To display weather information:") help.add("To display weather information:")
help.add(Utils.helpFormat("%c $WEATHER_CMD <city> [, <country code>]")) help.add(helpFormat("%c $WEATHER_CMD <city> [, <country code>]"))
help.add("For example:") help.add("For example:")
help.add(Utils.helpFormat("%c $WEATHER_CMD paris, fr")) help.add(helpFormat("%c $WEATHER_CMD paris, fr"))
help.add("The default ISO 3166 country code is ${Utils.bold("US")}. Zip codes supported in most countries.") help.add("The default ISO 3166 country code is ${bold("US")}. Zip codes supported in most countries.")
initProperties(OWM_API_KEY_PROP) initProperties(OWM_API_KEY_PROP)
} }
} }

View file

@ -77,7 +77,7 @@ class WorldTime(bot: Mobibot) : AbstractModule(bot) {
val tz = COUNTRIES_MAP[(query.substring(query.indexOf(' ') + 1).trim()).uppercase()] val tz = COUNTRIES_MAP[(query.substring(query.indexOf(' ') + 1).trim()).uppercase()]
val response: String = if (tz != null) { val response: String = if (tz != null) {
if (BEATS_KEYWORD == tz) { if (BEATS_KEYWORD == tz) {
"The current Internet Time is: " + bold(internetTime() + ' ' + BEATS_KEYWORD) "The current Internet Time is: ${bold(internetTime())} $BEATS_KEYWORD"
} else { } else {
(ZonedDateTime.now() (ZonedDateTime.now()
.withZoneSameInstant(ZoneId.of(tz)) .withZoneSameInstant(ZoneId.of(tz))
@ -215,7 +215,7 @@ class WorldTime(bot: Mobibot) : AbstractModule(bot) {
init { init {
help.add("To display a country's current date/time:") help.add("To display a country's current date/time:")
help.add(helpFormat("%c $TIME_CMD") + " [<country code>]") help.add(helpFormat("%c $TIME_CMD [<country code>]"))
help.add("For a listing of the supported countries:") help.add("For a listing of the supported countries:")
help.add(helpFormat("%c $TIME_CMD")) help.add(helpFormat("%c $TIME_CMD"))
commands.add(TIME_CMD) commands.add(TIME_CMD)

View file

@ -35,18 +35,18 @@ import net.thauvin.erik.mobibot.Utils.bold
import net.thauvin.erik.mobibot.Utils.capitalize import net.thauvin.erik.mobibot.Utils.capitalize
import net.thauvin.erik.mobibot.Utils.colorize import net.thauvin.erik.mobibot.Utils.colorize
import net.thauvin.erik.mobibot.Utils.cyan import net.thauvin.erik.mobibot.Utils.cyan
import net.thauvin.erik.mobibot.Utils.ensureDir
import net.thauvin.erik.mobibot.Utils.getIntProperty import net.thauvin.erik.mobibot.Utils.getIntProperty
import net.thauvin.erik.mobibot.Utils.green import net.thauvin.erik.mobibot.Utils.green
import net.thauvin.erik.mobibot.Utils.isoLocalDate
import net.thauvin.erik.mobibot.Utils.obfuscate import net.thauvin.erik.mobibot.Utils.obfuscate
import net.thauvin.erik.mobibot.Utils.plural import net.thauvin.erik.mobibot.Utils.plural
import net.thauvin.erik.mobibot.Utils.reverseColor import net.thauvin.erik.mobibot.Utils.reverseColor
import net.thauvin.erik.mobibot.Utils.toDir
import net.thauvin.erik.mobibot.Utils.toIsoLocalDate
import net.thauvin.erik.mobibot.Utils.toUtcDateTime
import net.thauvin.erik.mobibot.Utils.today import net.thauvin.erik.mobibot.Utils.today
import net.thauvin.erik.mobibot.Utils.unescapeXml import net.thauvin.erik.mobibot.Utils.unescapeXml
import net.thauvin.erik.mobibot.Utils.uptime import net.thauvin.erik.mobibot.Utils.uptime
import net.thauvin.erik.mobibot.Utils.urlReader import net.thauvin.erik.mobibot.Utils.urlReader
import net.thauvin.erik.mobibot.Utils.utcDateTime
import org.apache.commons.lang3.StringUtils import org.apache.commons.lang3.StringUtils
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.jibble.pircbot.Colors import org.jibble.pircbot.Colors
@ -101,13 +101,6 @@ class UtilsTest {
assertThat(cyan(ascii)).isEqualTo(Colors.CYAN + ascii + Colors.NORMAL) assertThat(cyan(ascii)).isEqualTo(Colors.CYAN + ascii + Colors.NORMAL)
} }
@Test
fun testEnsureDir() {
assertThat(ensureDir("dir", false)).describedAs("ensureDir(dir, false)").isEqualTo("dir" + File.separatorChar)
assertThat(ensureDir("https://erik.thauvin.net", true)).describedAs("ensureDir(erik.thauvin.net, true)")
.isEqualTo("https://erik.thauvin.net/")
}
@Test @Test
fun testGetIntProperty() { fun testGetIntProperty() {
assertThat(getIntProperty("10", 1)).describedAs("getIntProperty(10, 1)").isEqualTo(10) assertThat(getIntProperty("10", 1)).describedAs("getIntProperty(10, 1)").isEqualTo(10)
@ -121,25 +114,25 @@ class UtilsTest {
@Test @Test
fun testIsoLocalDate() { fun testIsoLocalDate() {
assertThat(isoLocalDate(cal.time)).describedAs("isoLocalDate(date)").isEqualTo("1952-02-17") assertThat(cal.time.toIsoLocalDate()).describedAs("isoLocalDate(date)").isEqualTo("1952-02-17")
assertThat(isoLocalDate(localDateTime)).describedAs("isoLocalDate(localDate)").isEqualTo("1952-02-17") assertThat(localDateTime.toIsoLocalDate()).describedAs("isoLocalDate(localDate)").isEqualTo("1952-02-17")
} }
@Test @Test
fun testObfuscate() { fun testObfuscate() {
assertThat(obfuscate(ascii).length).describedAs("obfuscate is right length").isEqualTo(ascii.length) assertThat(ascii.obfuscate().length).describedAs("obfuscate is right length").isEqualTo(ascii.length)
assertThat(obfuscate(ascii)).describedAs("obfuscate()").isEqualTo(StringUtils.repeat("x", ascii.length)) assertThat(ascii.obfuscate()).describedAs("obfuscate()").isEqualTo(StringUtils.repeat("x", ascii.length))
assertThat(obfuscate(" ")).describedAs("obfuscate(blank)").isEqualTo(" ") assertThat(" ".obfuscate()).describedAs("obfuscate(blank)").isEqualTo(" ")
} }
@Test @Test
fun testPlural() { fun testPlural() {
val week = "week" val week = "week"
val weeks = "weeks" val weeks = "weeks"
assertThat(plural(-1, week, weeks)).describedAs("plural(-1)").isEqualTo(week) assertThat(week.plural(-1, weeks)).describedAs("plural(-1)").isEqualTo(week)
assertThat(plural(0, week, weeks)).describedAs("plural(0)").isEqualTo(week) assertThat(week.plural(0, weeks)).describedAs("plural(0)").isEqualTo(week)
assertThat(plural(1, week, weeks)).describedAs("plural(1)").isEqualTo(week) assertThat(week.plural(1, weeks)).describedAs("plural(1)").isEqualTo(week)
assertThat(plural(2, week, weeks)).describedAs("plural(2)").isEqualTo(weeks) assertThat(week.plural(2, weeks)).describedAs("plural(2)").isEqualTo(weeks)
} }
@Test @Test
@ -149,7 +142,14 @@ class UtilsTest {
@Test @Test
fun testToday() { fun testToday() {
assertThat(today()).isEqualTo(isoLocalDate(LocalDateTime.now())) assertThat(today()).isEqualTo(LocalDateTime.now().toIsoLocalDate())
}
@Test
fun testToDir() {
assertThat("dir".toDir(false)).describedAs("toDir(dir, false)").isEqualTo("dir" + File.separatorChar)
assertThat("https://erik.thauvin.net".toDir(true)).describedAs("toDir(erik.thauvin.net, true)")
.isEqualTo("https://erik.thauvin.net/")
} }
@Test @Test
@ -174,7 +174,7 @@ class UtilsTest {
@Test @Test
fun testUtcDateTime() { fun testUtcDateTime() {
assertThat(utcDateTime(cal.time)).describedAs("utcDateTime(date)").isEqualTo("1952-02-17 12:30") assertThat(cal.time.toUtcDateTime()).describedAs("utcDateTime(date)").isEqualTo("1952-02-17 12:30")
assertThat(utcDateTime(localDateTime)).describedAs("utcDateTime(localDate)").isEqualTo("1952-02-17 12:30") assertThat(localDateTime.toUtcDateTime()).describedAs("utcDateTime(localDate)").isEqualTo("1952-02-17 12:30")
} }
} }

View file

@ -32,7 +32,7 @@
package net.thauvin.erik.mobibot.modules package net.thauvin.erik.mobibot.modules
import net.objecthunter.exp4j.tokenizer.UnknownFunctionOrVariableException import net.objecthunter.exp4j.tokenizer.UnknownFunctionOrVariableException
import net.thauvin.erik.mobibot.Utils import net.thauvin.erik.mobibot.Utils.bold
import net.thauvin.erik.mobibot.modules.Calc.Companion.calculate import net.thauvin.erik.mobibot.modules.Calc.Companion.calculate
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy import org.assertj.core.api.Assertions.assertThatThrownBy
@ -44,10 +44,10 @@ import org.testng.annotations.Test
class CalcTest { class CalcTest {
@Test @Test
fun testCalculate() { fun testCalculate() {
assertThat(calculate("1 + 1")).describedAs("calculate(1+1)").isEqualTo("1+1 = %s", Utils.bold(2)) assertThat(calculate("1 + 1")).describedAs("calculate(1+1)").isEqualTo("1+1 = %s", bold(2))
assertThat(calculate("1 -3")).describedAs("calculate(1 -3)").isEqualTo("1-3 = %s", Utils.bold(-2)) assertThat(calculate("1 -3")).describedAs("calculate(1 -3)").isEqualTo("1-3 = %s", bold(-2))
assertThat(calculate("pi+π+e+φ")).describedAs("calculate(pi+π+e+φ)") assertThat(calculate("pi+π+e+φ")).describedAs("calculate(pi+π+e+φ)")
.isEqualTo("pi+π+e+φ = %s", Utils.bold("10.62")) .isEqualTo("pi+π+e+φ = %s", bold("10.62"))
assertThatThrownBy { calculate("one + one") }.describedAs("calculate(one+one)") assertThatThrownBy { calculate("one + one") }.describedAs("calculate(one+one)")
.isInstanceOf(UnknownFunctionOrVariableException::class.java) .isInstanceOf(UnknownFunctionOrVariableException::class.java)
} }

View file

@ -31,7 +31,7 @@
*/ */
package net.thauvin.erik.mobibot.modules package net.thauvin.erik.mobibot.modules
import net.thauvin.erik.mobibot.Utils import net.thauvin.erik.mobibot.Utils.bold
import net.thauvin.erik.mobibot.modules.WorldTime.Companion.time import net.thauvin.erik.mobibot.modules.WorldTime.Companion.time
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.testng.annotations.Test import org.testng.annotations.Test
@ -42,7 +42,7 @@ import org.testng.annotations.Test
class WordTimeTest { class WordTimeTest {
@Test @Test
fun testTime() { fun testTime() {
assertThat(time("PST").msg).describedAs("PST").endsWith(Utils.bold("Los Angeles")) assertThat(time("PST").msg).describedAs("PST").endsWith(bold("Los Angeles"))
assertThat(time("BLAH").isError).describedAs("BLAH").isTrue assertThat(time("BLAH").isError).describedAs("BLAH").isTrue
assertThat(time("BEATS").msg).describedAs("BEATS").contains("@") assertThat(time("BEATS").msg).describedAs("BEATS").contains("@")
} }

View file

@ -1,9 +1,9 @@
#Generated by the Semver Plugin for Gradle #Generated by the Semver Plugin for Gradle
#Thu May 13 21:34:31 PDT 2021 #Fri May 14 20:13:13 PDT 2021
version.buildmeta=771 version.buildmeta=782
version.major=0 version.major=0
version.minor=8 version.minor=8
version.patch=0 version.patch=0
version.prerelease=beta version.prerelease=beta
version.project=mobibot version.project=mobibot
version.semver=0.8.0-beta+771 version.semver=0.8.0-beta+782