Added support for CryptoPrice country codes
This commit is contained in:
parent
a18c15e172
commit
78a0df8a8e
4 changed files with 86 additions and 5 deletions
|
@ -12,6 +12,7 @@
|
||||||
<ID>LongParameterList:EntryLink.kt$EntryLink$( // Link's comments val comments: MutableList<EntryComment> = mutableListOf(), // Tags/categories val tags: MutableList<SyndCategory> = mutableListOf(), // Channel var channel: String, // Creation date var date: Date = Calendar.getInstance().time, // Link's URL var link: String, // Author's login var login: String = "", // Author's nickname var nick: String, // Link's title var title: String )</ID>
|
<ID>LongParameterList:EntryLink.kt$EntryLink$( // Link's comments val comments: MutableList<EntryComment> = mutableListOf(), // Tags/categories val tags: MutableList<SyndCategory> = mutableListOf(), // Channel var channel: String, // Creation date var date: Date = Calendar.getInstance().time, // Link's URL var link: String, // Author's login var login: String = "", // Author's nickname var nick: String, // Link's title var title: String )</ID>
|
||||||
<ID>LongParameterList:Twitter.kt$Twitter.Companion$( consumerKey: String?, consumerSecret: String?, token: String?, tokenSecret: String?, handle: String?, message: String, isDm: Boolean )</ID>
|
<ID>LongParameterList:Twitter.kt$Twitter.Companion$( consumerKey: String?, consumerSecret: String?, token: String?, tokenSecret: String?, handle: String?, message: String, isDm: Boolean )</ID>
|
||||||
<ID>MagicNumber:Comment.kt$Comment$3</ID>
|
<ID>MagicNumber:Comment.kt$Comment$3</ID>
|
||||||
|
<ID>MagicNumber:CryptoPrices.kt$CryptoPrices$10</ID>
|
||||||
<ID>MagicNumber:CurrencyConverter.kt$CurrencyConverter$11</ID>
|
<ID>MagicNumber:CurrencyConverter.kt$CurrencyConverter$11</ID>
|
||||||
<ID>MagicNumber:CurrencyConverter.kt$CurrencyConverter.Companion$3</ID>
|
<ID>MagicNumber:CurrencyConverter.kt$CurrencyConverter.Companion$3</ID>
|
||||||
<ID>MagicNumber:CurrencyConverter.kt$CurrencyConverter.Companion$4</ID>
|
<ID>MagicNumber:CurrencyConverter.kt$CurrencyConverter.Companion$4</ID>
|
||||||
|
|
|
@ -35,7 +35,10 @@ import net.thauvin.erik.crypto.CryptoException
|
||||||
import net.thauvin.erik.crypto.CryptoPrice
|
import net.thauvin.erik.crypto.CryptoPrice
|
||||||
import net.thauvin.erik.crypto.CryptoPrice.Companion.spotPrice
|
import net.thauvin.erik.crypto.CryptoPrice.Companion.spotPrice
|
||||||
import net.thauvin.erik.mobibot.Utils.helpFormat
|
import net.thauvin.erik.mobibot.Utils.helpFormat
|
||||||
|
import net.thauvin.erik.mobibot.Utils.sendList
|
||||||
import net.thauvin.erik.mobibot.Utils.sendMessage
|
import net.thauvin.erik.mobibot.Utils.sendMessage
|
||||||
|
import net.thauvin.erik.mobibot.Utils.today
|
||||||
|
import org.json.JSONObject
|
||||||
import org.pircbotx.hooks.types.GenericMessageEvent
|
import org.pircbotx.hooks.types.GenericMessageEvent
|
||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
@ -48,13 +51,32 @@ class CryptoPrices : ThreadedModule() {
|
||||||
private val logger: Logger = LoggerFactory.getLogger(CryptoPrices::class.java)
|
private val logger: Logger = LoggerFactory.getLogger(CryptoPrices::class.java)
|
||||||
|
|
||||||
override val name = "CryptoPrices"
|
override val name = "CryptoPrices"
|
||||||
|
override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent) {
|
||||||
|
synchronized(this) {
|
||||||
|
if (pubDate != today()) {
|
||||||
|
CODES.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.commandResponse(channel, cmd, args, event)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the cryptocurrency market price from [Coinbase](https://developers.coinbase.com/api/v2#get-spot-price).
|
* Returns the cryptocurrency market price from [Coinbase](https://developers.coinbase.com/api/v2#get-spot-price).
|
||||||
*/
|
*/
|
||||||
override fun run(channel: String, cmd: String, args: String, event: GenericMessageEvent) {
|
override fun run(channel: String, cmd: String, args: String, event: GenericMessageEvent) {
|
||||||
|
if (CODES.isEmpty()) {
|
||||||
|
try {
|
||||||
|
loadCodes()
|
||||||
|
} catch (e: ModuleException) {
|
||||||
|
if (logger.isWarnEnabled) logger.warn(e.debugMessage, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val debugMessage = "crypto($cmd $args)"
|
val debugMessage = "crypto($cmd $args)"
|
||||||
if (args.matches("\\w+( [a-zA-Z]{3}+)?".toRegex())) {
|
if (args == CURRENCY_CODES_KEYWORD) {
|
||||||
|
event.sendMessage("The supported currency codes are:")
|
||||||
|
event.sendList(ArrayList(CODES.keys), 10, isIndent = true)
|
||||||
|
} else if (args.matches("\\w+( [a-zA-Z]{3}+)?".toRegex())) {
|
||||||
try {
|
try {
|
||||||
val price = currentPrice(args.split(' '))
|
val price = currentPrice(args.split(' '))
|
||||||
val amount = try {
|
val amount = try {
|
||||||
|
@ -62,7 +84,7 @@ class CryptoPrices : ThreadedModule() {
|
||||||
} catch (ignore: IllegalArgumentException) {
|
} catch (ignore: IllegalArgumentException) {
|
||||||
price.amount
|
price.amount
|
||||||
}
|
}
|
||||||
event.respond("${price.base} current price is $amount [${price.currency}]")
|
event.respond("${price.base} current price is $amount [${CODES[price.currency]}]")
|
||||||
} catch (e: CryptoException) {
|
} catch (e: CryptoException) {
|
||||||
if (logger.isWarnEnabled) logger.warn("$debugMessage => ${e.statusCode}", e)
|
if (logger.isWarnEnabled) logger.warn("$debugMessage => ${e.statusCode}", e)
|
||||||
e.message?.let {
|
e.message?.let {
|
||||||
|
@ -82,6 +104,15 @@ class CryptoPrices : ThreadedModule() {
|
||||||
// Crypto command
|
// Crypto command
|
||||||
private const val CRYPTO_CMD = "crypto"
|
private const val CRYPTO_CMD = "crypto"
|
||||||
|
|
||||||
|
// Currency codes
|
||||||
|
private val CODES: MutableMap<String, String> = mutableMapOf()
|
||||||
|
|
||||||
|
// Currency codes keyword
|
||||||
|
private const val CURRENCY_CODES_KEYWORD = "codes"
|
||||||
|
|
||||||
|
// Last currency table retrieval date
|
||||||
|
private var pubDate = ""
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get current market price.
|
* Get current market price.
|
||||||
*/
|
*/
|
||||||
|
@ -92,6 +123,38 @@ class CryptoPrices : ThreadedModule() {
|
||||||
else
|
else
|
||||||
spotPrice(args[0])
|
spotPrice(args[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For testing purposes.
|
||||||
|
*/
|
||||||
|
fun getCurrencyName(code: String): String? {
|
||||||
|
return CODES[code]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the country ISO codes.
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
@Throws(ModuleException::class)
|
||||||
|
fun loadCodes() {
|
||||||
|
if (CODES.isEmpty()) {
|
||||||
|
try {
|
||||||
|
val json = JSONObject(CryptoPrice.apiCall(listOf("currencies")))
|
||||||
|
val data = json.getJSONArray("data")
|
||||||
|
for (i in 0 until data.length()) {
|
||||||
|
val d = data.getJSONObject(i)
|
||||||
|
CODES[d.getString("id")] = d.getString("name")
|
||||||
|
}
|
||||||
|
pubDate = today()
|
||||||
|
} catch (e: CryptoException) {
|
||||||
|
throw ModuleException(
|
||||||
|
"loadCodes(): CE",
|
||||||
|
"An error has occurred while retrieving the currency table.",
|
||||||
|
e
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -103,6 +166,8 @@ class CryptoPrices : ThreadedModule() {
|
||||||
add(helpFormat("%c $CRYPTO_CMD BTC"))
|
add(helpFormat("%c $CRYPTO_CMD BTC"))
|
||||||
add(helpFormat("%c $CRYPTO_CMD ETH EUR"))
|
add(helpFormat("%c $CRYPTO_CMD ETH EUR"))
|
||||||
add(helpFormat("%c $CRYPTO_CMD ETH2 GPB"))
|
add(helpFormat("%c $CRYPTO_CMD ETH2 GPB"))
|
||||||
|
add("To list the supported currency codes:")
|
||||||
|
add(helpFormat("%c $CRYPTO_CMD $CURRENCY_CODES_KEYWORD"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,12 +38,21 @@ import assertk.assertions.isGreaterThan
|
||||||
import assertk.assertions.prop
|
import assertk.assertions.prop
|
||||||
import net.thauvin.erik.crypto.CryptoPrice
|
import net.thauvin.erik.crypto.CryptoPrice
|
||||||
import net.thauvin.erik.mobibot.modules.CryptoPrices.Companion.currentPrice
|
import net.thauvin.erik.mobibot.modules.CryptoPrices.Companion.currentPrice
|
||||||
|
import net.thauvin.erik.mobibot.modules.CryptoPrices.Companion.getCurrencyName
|
||||||
|
import net.thauvin.erik.mobibot.modules.CryptoPrices.Companion.loadCodes
|
||||||
|
import org.testng.annotations.BeforeClass
|
||||||
import org.testng.annotations.Test
|
import org.testng.annotations.Test
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `CryptoPricesTest` class.
|
* The `CryptoPricesTest` class.
|
||||||
*/
|
*/
|
||||||
class CryptoPricesTest {
|
class CryptoPricesTest {
|
||||||
|
@BeforeClass
|
||||||
|
@Throws(ModuleException::class)
|
||||||
|
fun before() {
|
||||||
|
loadCodes()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Throws(ModuleException::class)
|
@Throws(ModuleException::class)
|
||||||
fun testMarketPrice() {
|
fun testMarketPrice() {
|
||||||
|
@ -61,4 +70,10 @@ class CryptoPricesTest {
|
||||||
prop(CryptoPrice::amount).transform { it.signum() }.isGreaterThan(0)
|
prop(CryptoPrice::amount).transform { it.signum() }.isGreaterThan(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testGetCurrencyName() {
|
||||||
|
assertThat(getCurrencyName("USD")).isEqualTo("US Dollar")
|
||||||
|
assertThat(getCurrencyName("EUR")).isEqualTo("Euro")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#Generated by the Semver Plugin for Gradle
|
#Generated by the Semver Plugin for Gradle
|
||||||
#Sun Jul 10 23:07:38 PDT 2022
|
#Mon Jul 11 07:36:52 PDT 2022
|
||||||
version.buildmeta=315
|
version.buildmeta=324
|
||||||
version.major=0
|
version.major=0
|
||||||
version.minor=8
|
version.minor=8
|
||||||
version.patch=0
|
version.patch=0
|
||||||
version.prerelease=rc
|
version.prerelease=rc
|
||||||
version.project=mobibot
|
version.project=mobibot
|
||||||
version.semver=0.8.0-rc+315
|
version.semver=0.8.0-rc+324
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue