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.Utils.buildCmdSyntax
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.helpFormat
import net.thauvin.erik.mobibot.Utils.isoLocalDate
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.ChannelFeed
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]) -> {
// Output the version
println("${ReleaseInfo.PROJECT} ${ReleaseInfo.VERSION} (${isoLocalDate(ReleaseInfo.BUILDDATE)})")
println("${ReleaseInfo.PROJECT} ${ReleaseInfo.VERSION} (${ReleaseInfo.BUILDDATE.toIsoLocalDate()})")
println(ReleaseInfo.WEBSITE)
}
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 channel = p.getProperty("channel")
val logsDir = ensureDir(p.getProperty("logs", "."), false)
val logsDir = p.getProperty("logs", ".").toDir()
// Redirect stdout and stderr
if (!commandLine.hasOption(Constants.DEBUG_ARG[0])) {
@ -637,7 +637,7 @@ class Mobibot(nickname: String, channel: String, logsDirPath: String, p: Propert
// Set the URLs
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
try {

View file

@ -87,7 +87,7 @@ object Utils {
* Capitalize a string.
*/
@JvmStatic
fun capitalize(s: String?): String? = s?.replaceFirstChar { it.uppercase() }
fun String.capitalise(): String = this.replaceFirstChar { it.uppercase() }
/**
* Colorize a string.
@ -115,30 +115,6 @@ object Utils {
@JvmStatic
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.
*/
@ -166,46 +142,27 @@ object Utils {
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.
*/
@JvmStatic
fun obfuscate(s: String): String {
return if (s.isNotBlank()) {
StringUtils.repeat('x', s.length)
} else s
fun String.obfuscate(): String {
return if (this.isNotBlank()) {
StringUtils.repeat('x', this.length)
} else this
}
/**
* Returns the plural form of a word, if count > 1.
*/
@JvmStatic
fun plural(count: Int, word: String, plural: String): String = plural(count.toLong(), word, plural)
fun String.plural(count: Int, plural: String): String = this.plural(count.toLong(), plural)
/**
* Returns the plural form of a word, if count > 1.
*/
@JvmStatic
fun plural(count: Long, word: String, plural: String): String {
return if (count > 1) {
plural
} else {
word
}
fun String.plural(count: Long, plural: String): String {
return if (count > 1) plural else this
}
/**
@ -224,7 +181,55 @@ object Utils {
* Returns today's date.
*/
@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.
@ -254,21 +259,21 @@ object Utils {
)
with(info) {
if (years > 0) {
append(years).append(plural(years, " year ", " years "))
append(years).append(" year ".plural(years, " years "))
}
if (months > 0) {
append(weeks).append(plural(months, " month ", " months "))
append(weeks).append(" month ".plural(months, " months "))
}
if (weeks > 0) {
append(weeks).append(plural(weeks, " week ", " weeks "))
append(weeks).append(" week ".plural(weeks, " weeks "))
}
if (days > 0) {
append(days).append(plural(days, " day ", " days "))
append(days).append(" day ".plural(days, " days "))
}
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()
}
}
@ -282,20 +287,4 @@ object Utils {
BufferedReader(InputStreamReader(url.openStream(), StandardCharsets.UTF_8))
.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
import net.thauvin.erik.mobibot.Mobibot
import net.thauvin.erik.mobibot.Utils
import net.thauvin.erik.mobibot.Utils.buildCmdSyntax
import java.util.concurrent.ConcurrentHashMap
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 {
if (!this.isOp || this.isOp == isOp) {
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
}

View file

@ -33,7 +33,9 @@
package net.thauvin.erik.mobibot.commands
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
class Ignore(bot: Mobibot) : AbstractCommand(bot) {
@ -46,17 +48,17 @@ class Ignore(bot: Mobibot) : AbstractCommand(bot) {
override val name = IGNORE_CMD
override val help = listOf(
"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:",
Utils.helpFormat("%c $name"),
helpFormat("%c $name"),
"To toggle your ignore status:",
Utils.helpFormat("%c $name $me")
helpFormat("%c $name $me")
)
private val helpOp = listOf(
"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:",
Utils.helpFormat("%c $name <nick> [<nick> ...]")
helpFormat("%c $name <nick> [<nick> ...]")
)
override val isOp = false
@ -98,7 +100,7 @@ class Ignore(bot: Mobibot) : AbstractCommand(bot) {
): Boolean {
return if (isOp) {
for (h in helpOp) {
bot.send(sender, Utils.buildCmdSyntax(h, bot.nick, isPrivate), isPrivate)
bot.send(sender, buildCmdSyntax(h, bot.nick, isPrivate), isPrivate)
}
true
} else {
@ -143,7 +145,7 @@ class Ignore(bot: Mobibot) : AbstractCommand(bot) {
@Suppress("MagicNumber")
bot.sendList(sender, ignored.sorted(), 8, isPrivate, isIndent = true)
} 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.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.helpFormat
import net.thauvin.erik.mobibot.Utils.uptime
@ -42,8 +42,8 @@ import java.lang.management.ManagementFactory
class Info(bot: Mobibot?) : AbstractCommand(bot!!) {
private val allVersions = listOf(
capitalize(ReleaseInfo.PROJECT) + " ${ReleaseInfo.VERSION} (" + green(ReleaseInfo.WEBSITE) + ')',
"Written by ${ReleaseInfo.AUTHOR} (" + green(ReleaseInfo.AUTHOR_URL) + ')'
"${ReleaseInfo.PROJECT.capitalise()} ${ReleaseInfo.VERSION} (${green(ReleaseInfo.WEBSITE)})",
"Written by ${ReleaseInfo.AUTHOR} (${green(ReleaseInfo.AUTHOR_URL)})"
)
override val name = "info"
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
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.LocalDateTime
@ -41,7 +42,7 @@ class Recap(bot: Mobibot) : AbstractCommand(bot) {
override val name = "recap"
override val help = listOf(
"To list the last 10 public channel messages:",
Utils.helpFormat("%c $name")
helpFormat("%c $name")
)
override val isOp = false
override val isPublic = true
@ -57,7 +58,7 @@ class Recap(bot: Mobibot) : AbstractCommand(bot) {
@JvmStatic
fun storeRecap(sender: String, message: String, isAction: Boolean) {
recaps.add(
Utils.utcDateTime(LocalDateTime.now(Clock.systemUTC()))
LocalDateTime.now(Clock.systemUTC()).toUtcDateTime()
+ " - $sender" + (if (isAction) " " else ": ") + message
)
@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.ReleaseInfo
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) {
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")
+ " (" + System.getProperty("os.arch") + ')',
"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.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.Ignore
import net.thauvin.erik.mobibot.entries.EntriesMgr
@ -72,7 +74,7 @@ class LinksMgr(bot: Mobibot) : AbstractCommand(bot) {
val history = mutableListOf<String>()
@JvmStatic
var startDate: String = Utils.today()
var startDate: String = today()
private set
/**
@ -88,9 +90,9 @@ class LinksMgr(bot: Mobibot) : AbstractCommand(bot) {
@JvmStatic
fun startup(current: String, backlogs: String, channel: String) {
startDate = EntriesMgr.loadEntries(current, channel, entries)
if (Utils.today() != startDate) {
if (today() != startDate) {
entries.clear()
startDate = Utils.today()
startDate = today()
}
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,
Utils.helpFormat("${EntriesUtils.buildLinkCmd(index)}:|This is the title"),
helpFormat("${EntriesUtils.buildLinkCmd(index)}:|This is the title"),
isPrivate
)
}
@ -183,7 +185,7 @@ class LinksMgr(bot: Mobibot) : AbstractCommand(bot) {
for (i in entries.indices) {
if (link == entries[i].link) {
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
}
}
@ -201,10 +203,10 @@ class LinksMgr(bot: Mobibot) : AbstractCommand(bot) {
}
private fun saveDayBackup(bot: Mobibot): Boolean {
if (Utils.today() != startDate) {
if (today() != startDate) {
saveEntries(bot, true)
entries.clear()
startDate = Utils.today()
startDate = today()
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.plural
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.links.View
@ -117,21 +117,16 @@ class Tell(bot: Mobibot) : AbstractCommand(bot) {
*/
override val name = "tell"
override val help: List<String>
get() = listOf(
override val help = listOf(
"To send a message to someone when they join the channel:",
helpFormat("%c $name <nick> <message>"),
"To view queued and sent messages:",
helpFormat("%c $name ${View.VIEW_CMD}"),
"Messages are kept for " + bold(maxDays)
+ plural(maxDays, " day.", " days.")
"Messages are kept for ${bold(maxDays)}" + " day.".plural(maxDays, " days.")
)
override val isOp: Boolean
get() = false
override val isPublic: Boolean
get() = isEnabled()
override val isVisible: Boolean
get() = isEnabled()
override val isOp: Boolean = false
override val isPublic: Boolean = isEnabled()
override val isVisible: Boolean = isEnabled()
override fun commandResponse(
sender: String,
@ -232,8 +227,8 @@ class Tell(bot: Mobibot) : AbstractCommand(bot) {
&& !message.isNotified) {
bot.send(
nickname,
"Your message ${reverseColor("[ID " + message.id + ']')} was sent to " +
"${bold(message.recipient)} on ${utcDateTime(message.receptionDate)}",
"Your message ${reverseColor("[ID " + message.id + ']')} was sent to "
+ "${bold(message.recipient)} on ${message.receptionDate.toUtcDateTime()}",
true
)
message.isNotified = true
@ -248,9 +243,7 @@ class Tell(bot: Mobibot) : AbstractCommand(bot) {
*
* @return The size.
*/
fun size(): Int {
return messages.size
}
fun size(): Int = messages.size
// View all messages.
private fun viewAll(sender: String, isPrivate: Boolean) {
@ -281,7 +274,7 @@ class Tell(bot: Mobibot) : AbstractCommand(bot) {
bot.send(
sender,
bold(message.sender) + ARROW + bold(message.recipient)
+ " [" + utcDateTime(message.receptionDate) + ", ID: "
+ " [${message.receptionDate.toUtcDateTime()}, ID: "
+ bold(message.id) + ", DELIVERED]",
isPrivate
)
@ -289,7 +282,7 @@ class Tell(bot: Mobibot) : AbstractCommand(bot) {
bot.send(
sender,
bold(message.sender) + ARROW + bold(message.recipient)
+ " [" + utcDateTime(message.queued) + ", ID: "
+ " [${message.queued.toUtcDateTime()}, ID: "
+ bold(message.id) + ", QUEUED]",
isPrivate
)
@ -312,11 +305,7 @@ class Tell(bot: Mobibot) : AbstractCommand(bot) {
),
isPrivate
)
bot.send(
sender,
"Messages are kept for ${bold(maxDays)}${plural(maxDays, " day.", " days.")}",
isPrivate
)
bot.send(sender, help.last(), isPrivate)
}
}

View file

@ -40,7 +40,7 @@ import com.rometools.rome.io.FeedException
import com.rometools.rome.io.SyndFeedInput
import com.rometools.rome.io.SyndFeedOutput
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.InputStreamReader
import java.io.OutputStreamWriter
@ -146,7 +146,7 @@ object EntriesMgr {
Files.newInputStream(Paths.get(file)), StandardCharsets.UTF_8
).use { reader ->
val feed = input.build(reader)
today = isoLocalDate(feed.publishedDate)
today = feed.publishedDate.toIsoLocalDate()
val items = feed.entries
var entry: EntryLink
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.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.Message
import net.thauvin.erik.mobibot.msg.PublicMessage
@ -56,7 +59,7 @@ class CurrencyConverter(bot: Mobibot) : ThreadedModule(bot) {
isPrivate: Boolean
) {
synchronized(this) {
if (pubDate != Utils.today()) {
if (pubDate != today()) {
EXCHANGE_RATES.clear()
}
}
@ -85,7 +88,7 @@ class CurrencyConverter(bot: Mobibot) : ThreadedModule(bot) {
helpResponse(sender, isPrivate)
}
} 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")
sendList(sender, currencyRates(), 3, isPrivate, isIndent = true)
} else {
@ -109,16 +112,16 @@ class CurrencyConverter(bot: Mobibot) : ThreadedModule(bot) {
send(sender, "To convert from one currency to another:", isPrivate)
send(
sender,
Utils.helpFormat(
Utils.buildCmdSyntax("%c $CURRENCY_CMD 100 USD to EUR", nick, isPrivateMsgEnabled)
helpFormat(
buildCmdSyntax("%c $CURRENCY_CMD 100 USD to EUR", nick, isPrivateMsgEnabled)
),
isPrivate
)
send(sender, "For a listing of current rates:", isPrivate)
send(
sender,
Utils.helpFormat(
Utils.buildCmdSyntax("%c $CURRENCY_CMD $CURRENCY_RATES_KEYWORD", nick, isPrivateMsgEnabled)
helpFormat(
buildCmdSyntax("%c $CURRENCY_CMD $CURRENCY_RATES_KEYWORD", nick, isPrivateMsgEnabled)
),
isPrivate
)

View file

@ -32,7 +32,11 @@
package net.thauvin.erik.mobibot.modules
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.NoticeMessage
import org.jibble.pircbot.Colors
@ -86,21 +90,21 @@ class GoogleSearch(bot: Mobibot) : ThreadedModule(bot) {
@Throws(ModuleException::class)
fun searchGoogle(query: String, apiKey: String?, cseKey: String?): List<Message> {
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()) {
val results = mutableListOf<Message>()
try {
val url = URL(
"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")
for (i in 0 until ja.length()) {
val j = ja.getJSONObject(i)
results.add(NoticeMessage(Utils.unescapeXml(j.getString("title"))))
results.add(NoticeMessage(Utils.helpFormat(j.getString("link"), false), Colors.DARK_GREEN))
results.add(NoticeMessage(unescapeXml(j.getString("title"))))
results.add(NoticeMessage(helpFormat(j.getString("link"), false), Colors.DARK_GREEN))
}
} catch (e: IOException) {
throw ModuleException("searchGoogle($query)", "An IO error has occurred searching Google.", e)
@ -117,7 +121,7 @@ class GoogleSearch(bot: Mobibot) : ThreadedModule(bot) {
init {
commands.add(GOOGLE_CMD)
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)
}
}

View file

@ -32,7 +32,9 @@
package net.thauvin.erik.mobibot.modules
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.PublicMessage
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) {
try {
bot.send(Utils.cyan(randomJoke().msg))
bot.send(cyan(randomJoke().msg))
} catch (e: ModuleException) {
if (bot.logger.isWarnEnabled) bot.logger.warn(e.debugMessage, e)
bot.send(sender, e.message, isPrivate)
@ -81,7 +83,7 @@ class Joke(bot: Mobibot) : ThreadedModule(bot) {
fun randomJoke(): Message {
return try {
val url = URL(JOKE_URL)
val json = JSONObject(Utils.urlReader(url))
val json = JSONObject(urlReader(url))
PublicMessage(
json.getJSONObject("value")["joke"].toString().replace("\\'", "'")
.replace("\\\"", "\"")
@ -97,6 +99,6 @@ class Joke(bot: Mobibot) : ThreadedModule(bot) {
init {
commands.add(JOKE_CMD)
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.)
*/
fun getSanitizedMessage(vararg sanitize: String): String {
val obfuscate = sanitize.map { obfuscate(it) }.toTypedArray()
val obfuscate = sanitize.map { it.obfuscate() }.toTypedArray()
return when {
cause != null -> {
cause.javaClass.name + ": " + StringUtils.replaceEach(cause.message, sanitize, obfuscate)

View file

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

View file

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

View file

@ -36,7 +36,10 @@ import net.aksingh.owmjapis.core.OWM
import net.aksingh.owmjapis.core.OWM.Country
import net.aksingh.owmjapis.model.CurrentWeather
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.Message
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> {
if (apiKey.isNullOrBlank()) {
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)
@ -151,7 +154,7 @@ class Weather2(bot: Mobibot) : ThreadedModule(bot) {
for (w in list) {
if (w != null) {
condition.append(' ')
.append(Utils.capitalize(w.getDescription()))
.append(w.getDescription().capitalise())
.append('.')
}
}
@ -167,7 +170,7 @@ class Weather2(bot: Mobibot) : ThreadedModule(bot) {
messages.add(
NoticeMessage(
"https://openweathermap.org/find?q="
+ Utils.encodeUrl("$city,${country.uppercase()}"),
+ encodeUrl("$city,${country.uppercase()}"),
Colors.GREEN
)
)
@ -197,10 +200,10 @@ class Weather2(bot: Mobibot) : ThreadedModule(bot) {
init {
commands.add(WEATHER_CMD)
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(Utils.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(helpFormat("%c $WEATHER_CMD paris, fr"))
help.add("The default ISO 3166 country code is ${bold("US")}. Zip codes supported in most countries.")
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 response: String = if (tz != null) {
if (BEATS_KEYWORD == tz) {
"The current Internet Time is: " + bold(internetTime() + ' ' + BEATS_KEYWORD)
"The current Internet Time is: ${bold(internetTime())} $BEATS_KEYWORD"
} else {
(ZonedDateTime.now()
.withZoneSameInstant(ZoneId.of(tz))
@ -215,7 +215,7 @@ class WorldTime(bot: Mobibot) : AbstractModule(bot) {
init {
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(helpFormat("%c $TIME_CMD"))
commands.add(TIME_CMD)