feat: add weather card response and clean up code

This commit is contained in:
2024-09-14 14:52:37 +08:00
parent cbde7e0554
commit 7998857853
77 files changed
+57 -17

No files matched your search

@@ -11,14 +11,47 @@ import cn.rtast.fancybot.configManager
import cn.rtast.fancybot.entity.weather.Geo
import cn.rtast.fancybot.entity.weather.Weather
import cn.rtast.fancybot.util.Http
import cn.rtast.fancybot.util.Resources
import cn.rtast.fancybot.util.drawCenteredText
import cn.rtast.fancybot.util.drawCustomImage
import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.fancybot.util.toBufferedImage
import cn.rtast.fancybot.util.toByteArray
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OBMessage
import java.awt.Color
import java.awt.Font
import java.awt.image.BufferedImage
class WeatherCommand : BaseCommand() {
override val commandNames = listOf("/weather", "/天气")
private val canvasWidth = 800
private val canvasHeight = 600
private val font = Font("Serif", Font.ITALIC, 60).deriveFont(Font.BOLD)
private val locationFont = Font("Serif", Font.ITALIC, 50)
private fun createWeatherCard(weather: Weather, geoResult: Geo.Location): String {
val emptyImage = BufferedImage(canvasWidth, canvasHeight, BufferedImage.TYPE_INT_RGB)
val g2d = emptyImage.createGraphics()
val weatherIcon = Resources.loadFromResourcesAsBytes("qweather/${weather.now.icon}.png")
?: Resources.loadFromResourcesAsBytes("qweather/100.png")!!
g2d.color = Color(209, 238, 238)
g2d.fillRect(0, 0, canvasWidth, canvasHeight)
g2d.drawCustomImage(weatherIcon.toBufferedImage(), canvasWidth / 2 - 230, canvasHeight / 2 - 80, 230.0, 230.0)
g2d.color = Color.BLACK
g2d.font = font
g2d.drawString("${weather.now.temp}", canvasWidth / 2, canvasHeight / 2 + 20)
g2d.drawString(weather.now.text, canvasWidth / 2, canvasHeight / 2 + 100)
g2d.font = locationFont
g2d.drawCenteredText("${geoResult.adm1}-${geoResult.adm2}-${geoResult.name}", canvasWidth / 2, 90)
g2d.color = Color(155, 48, 255)
g2d.drawCenteredText("数据来源: ${weather.refer.sources.joinToString(",")}", canvasWidth / 2, canvasHeight - 80)
return emptyImage.toByteArray().encodeToBase64()
}
override suspend fun executeGroup(listener: OBMessage, message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
val msg = MessageChain.Builder()
@@ -39,16 +72,8 @@ class WeatherCommand : BaseCommand() {
mapOf("location" to lookupLocation.id, "key" to configManager.qweatherKey)
)
val msg = MessageChain.Builder()
.addAt(message.sender.userId)
.addNewLine()
.addText("地区: ${lookupLocation.country}")
.addText("-${lookupLocation.adm1}")
.addText("-${lookupLocation.adm2}")
.addText("-${lookupLocation.name}")
.addNewLine()
.addText("温度: ${weather.now.temp} ℃ | ${weather.now.text}/${weather.now.windDir}")
.addNewLine()
.addText("数据来源: ${weather.refer.sources.joinToString(",")}")
.addReply(message.messageId)
.addImage(this.createWeatherCard(weather, lookupLocation), true)
.build()
listener.sendGroupMessage(message.groupId, msg)
} catch (_: NullPointerException) {
@@ -34,8 +34,8 @@ object BVParseCommand {
private const val USER_STAT_URL = "https://api.bilibili.com/x/relation/stat"
private const val CANVAS_WIDTH = 1000
private const val CANVAS_HEIGHT = 600
private val titleFont = Font("Serif", Font.ITALIC, 40).deriveFont(Font.ITALIC)
private val numberFont = Font("Serif", Font.ITALIC, 25).deriveFont(Font.ITALIC)
private val titleFont = Font("Serif", Font.ITALIC, 40)
private val numberFont = Font("Serif", Font.ITALIC, 25)
private val twoTwoLogo = ImageIO.read(Resources.loadFromResources("bili/22-coin.png"))
private val likeIcon = ImageIO.read(Resources.loadFromResources("bili/like.png"))
private val coinIcon = ImageIO.read(Resources.loadFromResources("bili/coin.png"))
@@ -34,9 +34,9 @@ object GitHubParseCommand {
private val starIcon = ImageIO.read(Resources.loadFromResources("github/star.png"))
private val issueIcon = ImageIO.read(Resources.loadFromResources("github/issue.png"))
private val forkIcon = ImageIO.read(Resources.loadFromResources("github/fork.png"))
private val customFont = Font("Serif", Font.ITALIC, 50).deriveFont(Font.ITALIC).deriveFont(Font.BOLD)
private val titleCustomFont = Font("Serif", Font.ITALIC, 75).deriveFont(Font.ITALIC).deriveFont(Font.BOLD)
private val descriptionCustomFont = Font("Serif", Font.ITALIC, 40).deriveFont(Font.ITALIC).deriveFont(Font.BOLD)
private val customFont = Font("Serif", Font.ITALIC, 50).deriveFont(Font.BOLD)
private val titleCustomFont = Font("Serif", Font.ITALIC, 75).deriveFont(Font.BOLD)
private val descriptionCustomFont = Font("Serif", Font.ITALIC, 40).deriveFont(Font.BOLD)
private val languageColors = mapOf(
"Kotlin" to Color(169, 123, 255),
@@ -14,7 +14,8 @@ data class Weather(
data class Now(
val temp: String,
val text: String,
val windDir: String
val windDir: String,
val icon: String,
)
data class Refer(
@@ -20,7 +20,7 @@ fun Graphics2D.drawCustomImage(
y: Int,
maxWidth: Double,
maxHeight: Double,
clip: Boolean
clip: Boolean = false
) {
val originalWidth = image.getWidth(null)
val originalHeight = image.getHeight(null)
@@ -61,4 +61,13 @@ fun BufferedImage.toByteArray(): ByteArray {
ImageIO.write(this, "png", outputStream)
return outputStream.toByteArray()
}
}
fun Graphics2D.drawCenteredText(text: String, x: Int, y: Int) {
val metrics = this.fontMetrics
val textWidth = metrics.stringWidth(text)
val textHeight = metrics.height
val drawX = x - textWidth / 2
val drawY = y + textHeight / 2
this.drawString(text, drawX, drawY)
}
@@ -13,4 +13,9 @@ object Resources {
fun loadFromResources(filename: String): InputStream {
return this::class.java.classLoader.getResourceAsStream(filename)
}
fun loadFromResourcesAsBytes(filename: String): ByteArray? {
val inputStream = this::class.java.classLoader.getResourceAsStream(filename)
return inputStream?.use { it.readBytes() }
}
}