Reworked the URL reader to include the code and body text when an error is returned.
This commit is contained in:
parent
2a2ab39b5f
commit
951fdaa5f7
13 changed files with 84 additions and 40 deletions
|
@ -41,11 +41,10 @@ import org.pircbotx.hooks.types.GenericMessageEvent
|
|||
import org.slf4j.Logger
|
||||
import java.io.BufferedInputStream
|
||||
import java.io.BufferedOutputStream
|
||||
import java.io.BufferedReader
|
||||
import java.io.IOException
|
||||
import java.io.InputStreamReader
|
||||
import java.io.ObjectInputStream
|
||||
import java.io.ObjectOutputStream
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.URL
|
||||
import java.net.URLEncoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
@ -56,7 +55,6 @@ import java.time.ZoneId
|
|||
import java.time.format.DateTimeFormatter
|
||||
import java.util.Date
|
||||
import java.util.Properties
|
||||
import java.util.stream.Collectors
|
||||
import kotlin.io.path.exists
|
||||
import kotlin.io.path.fileSize
|
||||
|
||||
|
@ -186,6 +184,12 @@ object Utils {
|
|||
return event.bot().userChannelDao.getChannel(channel).isOp(event.user)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if a HTTP status code indicates a successful response.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun Int.isHttpSuccess() = this in 200..399
|
||||
|
||||
/**
|
||||
* Returns the last item of a list of strings or empty if none.
|
||||
*/
|
||||
|
@ -402,8 +406,21 @@ object Utils {
|
|||
*/
|
||||
@JvmStatic
|
||||
@Throws(IOException::class)
|
||||
fun URL.reader(): String {
|
||||
BufferedReader(InputStreamReader(this.openStream(), StandardCharsets.UTF_8))
|
||||
.use { reader -> return reader.lines().collect(Collectors.joining(System.lineSeparator())) }
|
||||
fun URL.reader(): UrlReaderResponse {
|
||||
val connection = this.openConnection() as HttpURLConnection
|
||||
connection.setRequestProperty(
|
||||
"User-Agent",
|
||||
"Mozilla/5.0 (Linux x86_64; rv:104.0) Gecko/20100101 Firefox/104.0"
|
||||
)
|
||||
return if (connection.responseCode.isHttpSuccess()) {
|
||||
UrlReaderResponse(connection.responseCode, connection.inputStream.bufferedReader().readText())
|
||||
} else {
|
||||
UrlReaderResponse(connection.responseCode, connection.errorStream.bufferedReader().readText())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds the [URL.reader] response code and body text.
|
||||
*/
|
||||
data class UrlReaderResponse(val responseCode: Int, val body: String)
|
||||
}
|
||||
|
|
|
@ -80,11 +80,11 @@ class CryptoPrices : ThreadedModule() {
|
|||
} catch (e: CryptoException) {
|
||||
if (logger.isWarnEnabled) logger.warn("$debugMessage => ${e.statusCode}", e)
|
||||
e.message?.let {
|
||||
event.sendMessage(it)
|
||||
event.respond(it)
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
if (logger.isErrorEnabled) logger.error(debugMessage, e)
|
||||
event.sendMessage("An IO error has occurred while retrieving the cryptocurrency market price.")
|
||||
event.respond("An IO error has occurred while retrieving the cryptocurrency market price.")
|
||||
}
|
||||
} else {
|
||||
helpResponse(event)
|
||||
|
|
|
@ -143,7 +143,7 @@ class CurrencyConverter : ThreadedModule() {
|
|||
try {
|
||||
val amt = cmds[0].replace(",", "")
|
||||
val url = URL("https://api.exchangerate.host/convert?from=$to&to=$from&amount=$amt")
|
||||
val json = JSONObject(url.reader())
|
||||
val json = JSONObject(url.reader().body)
|
||||
|
||||
if (json.getBoolean("success")) {
|
||||
PublicMessage(
|
||||
|
@ -170,7 +170,7 @@ class CurrencyConverter : ThreadedModule() {
|
|||
fun loadSymbols() {
|
||||
try {
|
||||
val url = URL("https://api.exchangerate.host/symbols")
|
||||
val json = JSONObject(url.reader())
|
||||
val json = JSONObject(url.reader().body)
|
||||
if (json.getBoolean("success")) {
|
||||
val symbols = json.getJSONObject("symbols")
|
||||
for (key in symbols.keys()) {
|
||||
|
|
|
@ -76,7 +76,7 @@ class GoogleSearch : ThreadedModule() {
|
|||
} catch (e: ModuleException) {
|
||||
if (logger.isWarnEnabled) logger.warn(e.debugMessage, e)
|
||||
e.message?.let {
|
||||
event.sendMessage(it)
|
||||
event.respond(it)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -118,7 +118,7 @@ class GoogleSearch : ThreadedModule() {
|
|||
"https://www.googleapis.com/customsearch/v1?key=$apiKey&cx=$cseKey" +
|
||||
""aUser=${quotaUser}&q=${query.encodeUrl()}&filter=1&num=5&alt=json"
|
||||
)
|
||||
val json = JSONObject(url.reader())
|
||||
val json = JSONObject(url.reader().body)
|
||||
if (json.has("items")) {
|
||||
val ja = json.getJSONArray("items")
|
||||
for (i in 0 until ja.length()) {
|
||||
|
@ -126,6 +126,10 @@ class GoogleSearch : ThreadedModule() {
|
|||
results.add(NoticeMessage(j.getString("title").unescapeXml()))
|
||||
results.add(NoticeMessage(helpFormat(j.getString("link"), false), Colors.DARK_GREEN))
|
||||
}
|
||||
} else if (json.has("error")) {
|
||||
val error = json.getJSONObject("error")
|
||||
val message = error.getString("message")
|
||||
throw ModuleException("searchGoogle($query): ${error.getInt("code")} : $message", message)
|
||||
} else {
|
||||
results.add(ErrorMessage("No results found.", Colors.RED))
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ class StockQuote : ThreadedModule() {
|
|||
} catch (e: ModuleException) {
|
||||
if (logger.isWarnEnabled) logger.warn(e.debugMessage, e)
|
||||
e.message?.let {
|
||||
event.sendMessage(it)
|
||||
event.respond(it)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -147,7 +147,7 @@ class StockQuote : ThreadedModule() {
|
|||
response = URL(
|
||||
"${ALPHAVANTAGE_URL}SYMBOL_SEARCH&keywords=" + symbol.encodeUrl() + "&apikey="
|
||||
+ apiKey.encodeUrl()
|
||||
).reader()
|
||||
).reader().body
|
||||
var json = getJsonResponse(response, debugMessage)
|
||||
val symbols = json.getJSONArray("bestMatches")
|
||||
if (symbols.isEmpty) {
|
||||
|
@ -160,7 +160,7 @@ class StockQuote : ThreadedModule() {
|
|||
"${ALPHAVANTAGE_URL}GLOBAL_QUOTE&symbol="
|
||||
+ symbolInfo.getString("1. symbol").encodeUrl() + "&apikey="
|
||||
+ apiKey.encodeUrl()
|
||||
).reader()
|
||||
).reader().body
|
||||
json = getJsonResponse(response, debugMessage)
|
||||
val quote = json.getJSONObject("Global Quote")
|
||||
if (quote.isEmpty) {
|
||||
|
|
|
@ -34,6 +34,7 @@ package net.thauvin.erik.mobibot.modules
|
|||
|
||||
import net.thauvin.erik.mobibot.Utils
|
||||
import net.thauvin.erik.mobibot.Utils.encodeUrl
|
||||
import net.thauvin.erik.mobibot.Utils.isHttpSuccess
|
||||
import net.thauvin.erik.mobibot.Utils.reader
|
||||
import net.thauvin.erik.mobibot.Utils.sendMessage
|
||||
import org.pircbotx.hooks.types.GenericMessageEvent
|
||||
|
@ -68,13 +69,13 @@ class WolframAlpha : ThreadedModule() {
|
|||
} else {
|
||||
getUnits(properties[WOLFRAM_UNITS_PROP])
|
||||
},
|
||||
apiKey = properties[WOLFRAM_API_KEY_PROP]
|
||||
appId = properties[WOLFRAM_APPID_KEY]
|
||||
)
|
||||
)
|
||||
} catch (e: ModuleException) {
|
||||
if (logger.isWarnEnabled) logger.warn(e.debugMessage, e)
|
||||
e.message?.let {
|
||||
event.sendMessage(it)
|
||||
event.respond(it)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -86,7 +87,7 @@ class WolframAlpha : ThreadedModule() {
|
|||
/**
|
||||
* The Wolfram Alpha API Key property.
|
||||
*/
|
||||
const val WOLFRAM_API_KEY_PROP = "wolfram-api-key"
|
||||
const val WOLFRAM_APPID_KEY = "wolfram-appid"
|
||||
|
||||
/**
|
||||
* The Wolfram units properties
|
||||
|
@ -103,14 +104,23 @@ class WolframAlpha : ThreadedModule() {
|
|||
|
||||
@JvmStatic
|
||||
@Throws(ModuleException::class)
|
||||
fun queryWolfram(query: String, units: String = IMPERIAL, apiKey: String?): String {
|
||||
if (!apiKey.isNullOrEmpty()) {
|
||||
fun queryWolfram(query: String, units: String = IMPERIAL, appId: String?): String {
|
||||
if (!appId.isNullOrEmpty()) {
|
||||
try {
|
||||
return URL("${API_URL}${apiKey}&units=${units}&i=" + query.encodeUrl()).reader()
|
||||
val urlReader = URL("${API_URL}${appId}&units=${units}&i=" + query.encodeUrl()).reader()
|
||||
if (urlReader.responseCode.isHttpSuccess()) {
|
||||
return urlReader.body
|
||||
} else {
|
||||
throw ModuleException(
|
||||
"wolfram($query): ${urlReader.responseCode} : ${urlReader.body} ",
|
||||
urlReader.body.ifEmpty {
|
||||
"Looks like Wolfram Alpha isn't able to answer that. (${urlReader.responseCode})"
|
||||
}
|
||||
)
|
||||
}
|
||||
} catch (ioe: IOException) {
|
||||
throw ModuleException(
|
||||
"wolfram($query): IOE",
|
||||
"Looks like Wolfram Alpha isn't able to answer that.",
|
||||
"wolfram($query): IOE", "An IO Error occurred while querying Wolfram Alpha.", ioe
|
||||
)
|
||||
}
|
||||
} else {
|
||||
|
@ -128,6 +138,6 @@ class WolframAlpha : ThreadedModule() {
|
|||
add(Utils.helpFormat("%c $WOLFRAM_CMD days until christmas"))
|
||||
add(Utils.helpFormat("%c $WOLFRAM_CMD distance earth moon units=metric"))
|
||||
}
|
||||
initProperties(WOLFRAM_API_KEY_PROP, WOLFRAM_UNITS_PROP)
|
||||
initProperties(WOLFRAM_APPID_KEY, WOLFRAM_UNITS_PROP)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue