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.Geo
import cn.rtast.fancybot.entity.weather.Weather import cn.rtast.fancybot.entity.weather.Weather
import cn.rtast.fancybot.util.Http 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.entity.GroupMessage
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OBMessage import cn.rtast.rob.util.ob.OBMessage
import java.awt.Color
import java.awt.Font
import java.awt.image.BufferedImage
class WeatherCommand : BaseCommand() { class WeatherCommand : BaseCommand() {
override val commandNames = listOf("/weather", "/天气") 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>) { override suspend fun executeGroup(listener: OBMessage, message: GroupMessage, args: List<String>) {
if (args.isEmpty()) { if (args.isEmpty()) {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
@@ -39,16 +72,8 @@ class WeatherCommand : BaseCommand() {
mapOf("location" to lookupLocation.id, "key" to configManager.qweatherKey) mapOf("location" to lookupLocation.id, "key" to configManager.qweatherKey)
) )
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addAt(message.sender.userId) .addReply(message.messageId)
.addNewLine() .addImage(this.createWeatherCard(weather, lookupLocation), true)
.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(",")}")
.build() .build()
listener.sendGroupMessage(message.groupId, msg) listener.sendGroupMessage(message.groupId, msg)
} catch (_: NullPointerException) { } catch (_: NullPointerException) {
@@ -34,8 +34,8 @@ object BVParseCommand {
private const val USER_STAT_URL = "https://api.bilibili.com/x/relation/stat" private const val USER_STAT_URL = "https://api.bilibili.com/x/relation/stat"
private const val CANVAS_WIDTH = 1000 private const val CANVAS_WIDTH = 1000
private const val CANVAS_HEIGHT = 600 private const val CANVAS_HEIGHT = 600
private val titleFont = Font("Serif", Font.ITALIC, 40).deriveFont(Font.ITALIC) private val titleFont = Font("Serif", Font.ITALIC, 40)
private val numberFont = Font("Serif", Font.ITALIC, 25).deriveFont(Font.ITALIC) private val numberFont = Font("Serif", Font.ITALIC, 25)
private val twoTwoLogo = ImageIO.read(Resources.loadFromResources("bili/22-coin.png")) private val twoTwoLogo = ImageIO.read(Resources.loadFromResources("bili/22-coin.png"))
private val likeIcon = ImageIO.read(Resources.loadFromResources("bili/like.png")) private val likeIcon = ImageIO.read(Resources.loadFromResources("bili/like.png"))
private val coinIcon = ImageIO.read(Resources.loadFromResources("bili/coin.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 starIcon = ImageIO.read(Resources.loadFromResources("github/star.png"))
private val issueIcon = ImageIO.read(Resources.loadFromResources("github/issue.png")) private val issueIcon = ImageIO.read(Resources.loadFromResources("github/issue.png"))
private val forkIcon = ImageIO.read(Resources.loadFromResources("github/fork.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 customFont = Font("Serif", Font.ITALIC, 50).deriveFont(Font.BOLD)
private val titleCustomFont = Font("Serif", Font.ITALIC, 75).deriveFont(Font.ITALIC).deriveFont(Font.BOLD) private val titleCustomFont = Font("Serif", Font.ITALIC, 75).deriveFont(Font.BOLD)
private val descriptionCustomFont = Font("Serif", Font.ITALIC, 40).deriveFont(Font.ITALIC).deriveFont(Font.BOLD) private val descriptionCustomFont = Font("Serif", Font.ITALIC, 40).deriveFont(Font.BOLD)
private val languageColors = mapOf( private val languageColors = mapOf(
"Kotlin" to Color(169, 123, 255), "Kotlin" to Color(169, 123, 255),
@@ -14,7 +14,8 @@ data class Weather(
data class Now( data class Now(
val temp: String, val temp: String,
val text: String, val text: String,
val windDir: String val windDir: String,
val icon: String,
) )
data class Refer( data class Refer(
@@ -20,7 +20,7 @@ fun Graphics2D.drawCustomImage(
y: Int, y: Int,
maxWidth: Double, maxWidth: Double,
maxHeight: Double, maxHeight: Double,
clip: Boolean clip: Boolean = false
) { ) {
val originalWidth = image.getWidth(null) val originalWidth = image.getWidth(null)
val originalHeight = image.getHeight(null) val originalHeight = image.getHeight(null)
@@ -61,4 +61,13 @@ fun BufferedImage.toByteArray(): ByteArray {
ImageIO.write(this, "png", outputStream) ImageIO.write(this, "png", outputStream)
return outputStream.toByteArray() 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 { fun loadFromResources(filename: String): InputStream {
return this::class.java.classLoader.getResourceAsStream(filename) 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() }
}
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB