feat: add compiler and format class dir
This commit is contained in:
23 files changed
+128
-68
No files matched your search
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2024 RTAkland
|
||||
* Author: RTAkland
|
||||
* Date: 2024/9/6
|
||||
*/
|
||||
|
||||
|
||||
package cn.rtast.fancybot.commands.misc
|
||||
|
||||
import cn.rtast.fancybot.entity.bili.BVID
|
||||
import cn.rtast.fancybot.util.Http
|
||||
import cn.rtast.fancybot.util.Resources
|
||||
import cn.rtast.fancybot.util.drawCustomImage
|
||||
import cn.rtast.fancybot.util.str.encodeToBase64
|
||||
import cn.rtast.fancybot.util.str.setTruncat
|
||||
import cn.rtast.rob.entity.GroupMessage
|
||||
import cn.rtast.rob.util.ob.MessageChain
|
||||
import cn.rtast.rob.util.ob.OBMessage
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import java.awt.Color
|
||||
import java.awt.Font
|
||||
import java.awt.RenderingHints
|
||||
import java.awt.image.BufferedImage
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.net.URI
|
||||
import javax.imageio.ImageIO
|
||||
|
||||
object BVParseCommand {
|
||||
|
||||
private const val CID_URL = "https://api.bilibili.com/x/web-interface/view"
|
||||
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 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"))
|
||||
private val viewIcon = ImageIO.read(Resources.loadFromResources("bili/view.png"))
|
||||
private val shareIcon = ImageIO.read(Resources.loadFromResources("bili/share.png"))
|
||||
private val favoriteIcon = ImageIO.read(Resources.loadFromResources("bili/favorite.png"))
|
||||
private val replyIcon = ImageIO.read(Resources.loadFromResources("bili/reply.png"))
|
||||
|
||||
private val tempOkHttpClient = OkHttpClient()
|
||||
|
||||
fun getShortUrlBVID(shortUrl: String): String {
|
||||
val request = Request.Builder().url(shortUrl.split(" ").last()).build()
|
||||
val redirectedUrl = tempOkHttpClient.newCall(request).execute()
|
||||
redirectedUrl.use {
|
||||
return it.request.url.toString().split("/")[4].split("?").first()
|
||||
}
|
||||
}
|
||||
|
||||
private fun Int.formatNumber(): String {
|
||||
return if (this >= 10000) {
|
||||
val result = this / 10000.0
|
||||
String.format("%.1f万", result)
|
||||
} else {
|
||||
this.toString()
|
||||
}
|
||||
}
|
||||
|
||||
private fun createResponseImage(
|
||||
title: String,
|
||||
author: String,
|
||||
authorFace: String,
|
||||
picUrl: String,
|
||||
reply: String,
|
||||
view: String,
|
||||
coin: String,
|
||||
share: String,
|
||||
like: String,
|
||||
favorite: String
|
||||
): String {
|
||||
val coverImage = ImageIO.read(URI(picUrl).toURL())
|
||||
val faceImage = ImageIO.read(URI(authorFace).toURL())
|
||||
val backgroundImage = BufferedImage(CANVAS_WIDTH, CANVAS_HEIGHT, BufferedImage.TYPE_INT_RGB)
|
||||
val g2d = backgroundImage.createGraphics()
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
|
||||
g2d.color = Color(43, 43, 43)
|
||||
g2d.fillRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT)
|
||||
// draw rect
|
||||
g2d.color = Color(102, 102, 102)
|
||||
g2d.fillRect(0, 0, CANVAS_WIDTH, 120)
|
||||
g2d.color = Color.WHITE
|
||||
// draw numbers
|
||||
g2d.font = numberFont
|
||||
g2d.drawString(like, 110, 200)
|
||||
g2d.drawString(coin, 110, 290)
|
||||
g2d.drawString(view, 110, 380)
|
||||
g2d.drawString(favorite, 300, 380)
|
||||
g2d.drawString(reply, 300, 290)
|
||||
g2d.drawString(share, 300, 200)
|
||||
// draw video title
|
||||
val truncatedText = setTruncat(title, g2d)
|
||||
g2d.font = titleFont
|
||||
g2d.drawString(truncatedText, 20, 70)
|
||||
// draw author name
|
||||
g2d.drawString(author, 40, 580)
|
||||
// draw icons
|
||||
g2d.drawCustomImage(favoriteIcon, 230, 340, 50.0, 50.0, false)
|
||||
g2d.drawCustomImage(replyIcon, 230, 250, 50.0, 50.0, false)
|
||||
g2d.drawCustomImage(shareIcon, 230, 160, 50.0, 50.0, false)
|
||||
g2d.drawCustomImage(viewIcon, 40, 340, 50.0, 50.0, false)
|
||||
g2d.drawCustomImage(coinIcon, 40, 250, 50.0, 50.0, false)
|
||||
g2d.drawCustomImage(likeIcon, 40, 160, 50.0, 50.0, false)
|
||||
// draw 22 logo
|
||||
g2d.drawCustomImage(twoTwoLogo, 800, 450, 90.0, 160.0, false)
|
||||
// draw author face
|
||||
g2d.drawCustomImage(faceImage, 40, 480, 60.0, 60.0, true)
|
||||
// draw cover image
|
||||
g2d.drawCustomImage(coverImage, 430, 140, 600.0, 300.0, true)
|
||||
g2d.dispose()
|
||||
val byteArrayOutputStream = ByteArrayOutputStream()
|
||||
ImageIO.write(backgroundImage, "png", byteArrayOutputStream)
|
||||
val imageBytes = byteArrayOutputStream.toByteArray()
|
||||
return imageBytes.encodeToBase64()
|
||||
}
|
||||
|
||||
suspend fun parse(listener: OBMessage, bvid: String, message: GroupMessage) {
|
||||
val videoInfo = Http.get<BVID>(CID_URL, mapOf("bvid" to bvid))
|
||||
val authorFace = videoInfo.data.owner.face
|
||||
val title = videoInfo.data.title
|
||||
val author = videoInfo.data.owner.name
|
||||
val coverPicUrl = videoInfo.data.pic
|
||||
val view = videoInfo.data.stat.view.formatNumber()
|
||||
val share = videoInfo.data.stat.share.formatNumber()
|
||||
val like = videoInfo.data.stat.like.formatNumber()
|
||||
val favorite = videoInfo.data.stat.favorite.formatNumber()
|
||||
val coin = videoInfo.data.stat.coin.formatNumber()
|
||||
val reply = videoInfo.data.stat.reply.formatNumber()
|
||||
val image = this.createResponseImage(
|
||||
title, author, authorFace,
|
||||
coverPicUrl, reply, view, coin,
|
||||
share, like, favorite
|
||||
)
|
||||
val msg = MessageChain.Builder()
|
||||
.addReply(message.messageId)
|
||||
.addImage(image, true)
|
||||
.build()
|
||||
listener.sendGroupMessage(message.groupId, msg)
|
||||
}
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2024 RTAkland
|
||||
* Author: RTAkland
|
||||
* Date: 2024/9/12
|
||||
*/
|
||||
|
||||
|
||||
package cn.rtast.fancybot.commands.misc
|
||||
|
||||
import cn.rtast.fancybot.configManager
|
||||
import cn.rtast.fancybot.entity.github.RepoInfo
|
||||
import cn.rtast.fancybot.util.Http
|
||||
import cn.rtast.fancybot.util.Resources
|
||||
import cn.rtast.fancybot.util.drawCustomImage
|
||||
import cn.rtast.fancybot.util.str.encodeToBase64
|
||||
import cn.rtast.fancybot.util.str.setTruncat
|
||||
import cn.rtast.rob.entity.GroupMessage
|
||||
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.RenderingHints
|
||||
import java.awt.image.BufferedImage
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.net.URI
|
||||
import javax.imageio.ImageIO
|
||||
|
||||
object GitHubParseCommand {
|
||||
|
||||
private const val REPO_INFO_API = "https://api.github.com/repos"
|
||||
private const val CANVAS_WIDTH = 1620
|
||||
private const val CANVAS_HEIGHT = 1000
|
||||
private val githubLogo = ImageIO.read(Resources.loadFromResources("github/favicon.png"))
|
||||
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, 50).deriveFont(Font.ITALIC).deriveFont(Font.BOLD)
|
||||
|
||||
private val languageColors = mapOf(
|
||||
"Kotlin" to Color(169, 123, 255),
|
||||
"Java" to Color(176, 114, 25),
|
||||
"Python" to Color(53, 114, 165),
|
||||
"JavaScript" to Color(241, 224, 90),
|
||||
"C++" to Color(243, 75, 125),
|
||||
"Go" to Color(0, 173, 216),
|
||||
"Ruby" to Color(112, 21, 22),
|
||||
"PHP" to Color(79, 93, 149),
|
||||
"TypeScript" to Color(43, 116, 137),
|
||||
"Swift" to Color(240, 81, 56),
|
||||
"Unknown" to Color(211, 211, 211)
|
||||
)
|
||||
|
||||
private fun Int.formatNumber(): String {
|
||||
return when {
|
||||
this >= 1_000_000 -> String.format("%.1fM", this / 1_000_000.0)
|
||||
this >= 10_000 -> String.format("%.1fk", this / 1_000.0)
|
||||
this >= 1_000 -> String.format("%dk", this / 1_000)
|
||||
else -> this.toString()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getLanguageColor(language: String): Color {
|
||||
return languageColors[language] ?: languageColors["Unknown"]!!
|
||||
}
|
||||
|
||||
private fun getRepoStat(username: String, repo: String): RepoInfo {
|
||||
return Http.get<RepoInfo>(
|
||||
"$REPO_INFO_API/$username/$repo",
|
||||
headers = mapOf("Authorization" to "Bearer ${configManager.githubKey}")
|
||||
)
|
||||
}
|
||||
|
||||
private fun createImage(repoStat: RepoInfo): String {
|
||||
val canvas = BufferedImage(CANVAS_WIDTH, CANVAS_HEIGHT, BufferedImage.TYPE_INT_RGB)
|
||||
val g2d = canvas.createGraphics()
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
|
||||
g2d.font = customFont
|
||||
g2d.color = Color.WHITE
|
||||
g2d.fillRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT)
|
||||
g2d.color = this.getLanguageColor(repoStat.language)
|
||||
g2d.fillRect(0, CANVAS_HEIGHT - 20, CANVAS_WIDTH, 20)
|
||||
g2d.drawCustomImage(githubLogo, 1300, 780, 100.0, 100.0, false) // draw github logo
|
||||
g2d.drawCustomImage(starIcon, 100, 730, 70.0, 70.0, false) // draw star icon
|
||||
g2d.drawCustomImage(issueIcon, 500, 730, 70.0, 70.0, false) // draw issue icon
|
||||
g2d.drawCustomImage(forkIcon, 900, 730, 70.0, 70.0, false) // draw fork icon
|
||||
g2d.color = Color(60, 60, 60)
|
||||
g2d.drawString("Stars", 160, 840)
|
||||
g2d.drawString("Issues", 560, 840)
|
||||
g2d.drawString("Forks", 960, 840)
|
||||
g2d.drawString(repoStat.starsCount.formatNumber(), 200, 780)
|
||||
g2d.drawString(repoStat.openIssueCount.formatNumber(), 600, 780)
|
||||
g2d.drawString(repoStat.forksCount.formatNumber(), 1000, 780)
|
||||
g2d.font = titleCustomFont
|
||||
val truncatedFullNameText = setTruncat(repoStat.fullName, g2d, 1000)
|
||||
g2d.drawString(truncatedFullNameText, 80, 280)
|
||||
g2d.font = descriptionCustomFont
|
||||
val truncatedDescription = setTruncat(repoStat.description, g2d, 1000)
|
||||
g2d.drawString(truncatedDescription, 20, 450)
|
||||
val avatarImage = ImageIO.read(URI(repoStat.owner.avatarUrl).toURL())
|
||||
g2d.drawCustomImage(avatarImage, 1200, 300, 300.0, 300.0, true)
|
||||
val byteArrayOutputStream = ByteArrayOutputStream()
|
||||
ImageIO.write(canvas, "png", byteArrayOutputStream)
|
||||
val imageBytes = byteArrayOutputStream.toByteArray()
|
||||
return imageBytes.encodeToBase64()
|
||||
}
|
||||
|
||||
suspend fun parse(listener: OBMessage, message: GroupMessage) {
|
||||
val path = message.rawMessage
|
||||
.replace(".git", "")
|
||||
.replace("https://github.com/", "")
|
||||
.replace("git@github.com:", "")
|
||||
.split("/")
|
||||
val user = path.first()
|
||||
val repo = path.last()
|
||||
val repoStat = this.getRepoStat(user, repo)
|
||||
val image = this.createImage(repoStat)
|
||||
val msg = MessageChain.Builder()
|
||||
.addReply(message.messageId)
|
||||
.addImage(image, true)
|
||||
.build()
|
||||
listener.sendGroupMessage(message.groupId, msg)
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2024 RTAkland
|
||||
* Author: RTAkland
|
||||
* Date: 2024/9/6
|
||||
*/
|
||||
|
||||
|
||||
package cn.rtast.fancybot.commands.misc
|
||||
|
||||
import cn.rtast.rob.entity.GetMessage
|
||||
import cn.rtast.rob.enums.ArrayMessageType
|
||||
import cn.rtast.rob.util.ob.MessageChain
|
||||
import cn.rtast.rob.util.ob.OBMessage
|
||||
|
||||
object ImageURLCommand {
|
||||
|
||||
suspend fun callback(listener: OBMessage, message: GetMessage) {
|
||||
val msg = MessageChain.Builder()
|
||||
.addReply(message.data.messageId)
|
||||
.addText("哈哈哈哈图片来咯~")
|
||||
.addNewLine()
|
||||
val image = message.data.message.find { it.type == ArrayMessageType.image }
|
||||
if (image == null) {
|
||||
val gif = message.data.message.find { it.type == ArrayMessageType.mface }!!
|
||||
msg.addText(gif.data.url!!)
|
||||
} else {
|
||||
msg.addText(image.data.file!!)
|
||||
|
||||
}
|
||||
listener.sendGroupMessage(message.data.groupId!!, msg.build())
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2024 RTAkland
|
||||
* Author: RTAkland
|
||||
* Date: 2024/9/8
|
||||
*/
|
||||
|
||||
|
||||
package cn.rtast.fancybot.commands.misc
|
||||
|
||||
import cn.rtast.fancybot.util.str.encodeToBase64
|
||||
import cn.rtast.rob.entity.GetMessage
|
||||
import cn.rtast.rob.enums.ArrayMessageType
|
||||
import cn.rtast.rob.util.ob.MessageChain
|
||||
import cn.rtast.rob.util.ob.OBMessage
|
||||
import com.madgag.gif.fmsware.AnimatedGifEncoder
|
||||
import com.madgag.gif.fmsware.GifDecoder
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.net.URI
|
||||
|
||||
object ReverseGIFCommand {
|
||||
|
||||
private fun reverseGif(gifUrl: String): String {
|
||||
val gifStream = URI(gifUrl).toURL().openStream()
|
||||
val decoder = GifDecoder()
|
||||
decoder.read(gifStream)
|
||||
val frames = (0 until decoder.frameCount).map { decoder.getFrame(it) }.reversed()
|
||||
val byteArrayOutputStream = ByteArrayOutputStream()
|
||||
val encoder = AnimatedGifEncoder()
|
||||
encoder.start(byteArrayOutputStream)
|
||||
encoder.setRepeat(0)
|
||||
for (i in frames.indices) {
|
||||
encoder.setDelay(decoder.getDelay(decoder.frameCount - i - 1))
|
||||
encoder.addFrame(frames[i])
|
||||
}
|
||||
encoder.finish()
|
||||
val gifBytes = byteArrayOutputStream.toByteArray()
|
||||
return gifBytes.encodeToBase64()
|
||||
}
|
||||
|
||||
suspend fun callback(listener: OBMessage, message: GetMessage) {
|
||||
val gifUrl = if (message.data.message.find { it.type == ArrayMessageType.mface } == null) {
|
||||
message.data.message.find { it.type == ArrayMessageType.image }!!.data.file!!
|
||||
} else {
|
||||
message.data.message.find { it.type == ArrayMessageType.mface }!!.data.url!!
|
||||
}
|
||||
val base64String = this.reverseGif(gifUrl)
|
||||
val msg = MessageChain.Builder()
|
||||
.addReply(message.data.messageId)
|
||||
.addImage(base64String, true)
|
||||
.build()
|
||||
listener.sendGroupMessage(message.data.groupId!!, msg)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user