fix: 小修改
This commit is contained in:
parent
f95c6701e5
commit
a0f5504404
12
.idea/inspectionProfiles/Project_Default.xml
Normal file
12
.idea/inspectionProfiles/Project_Default.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="IncorrectHttpHeaderInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="customHeaders">
|
||||||
|
<set>
|
||||||
|
<option value="X-API-Key" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,107 @@
|
||||||
|
package top.r3944realms.ltdmanager.chevereto
|
||||||
|
|
||||||
|
import io.ktor.client.*
|
||||||
|
import io.ktor.client.call.*
|
||||||
|
import io.ktor.client.engine.cio.*
|
||||||
|
import io.ktor.client.plugins.contentnegotiation.*
|
||||||
|
import io.ktor.client.request.*
|
||||||
|
import io.ktor.client.request.forms.*
|
||||||
|
import io.ktor.http.*
|
||||||
|
import io.ktor.serialization.kotlinx.json.*
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import kotlinx.coroutines.sync.Mutex
|
||||||
|
import kotlinx.coroutines.sync.Semaphore
|
||||||
|
import kotlinx.coroutines.sync.withLock
|
||||||
|
import kotlinx.coroutines.sync.withPermit
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import java.io.ByteArrayInputStream
|
||||||
|
import java.io.Closeable
|
||||||
|
import java.io.File
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
|
object CheveretoUploader {
|
||||||
|
|
||||||
|
private val client = HttpClient(CIO) {
|
||||||
|
install(ContentNegotiation) {
|
||||||
|
json(Json {
|
||||||
|
ignoreUnknownKeys = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传本地文件
|
||||||
|
*/
|
||||||
|
suspend fun uploadFile(
|
||||||
|
apiUrl: String,
|
||||||
|
apiKey: String,
|
||||||
|
file: File,
|
||||||
|
title: String? = null,
|
||||||
|
description: String? = null
|
||||||
|
): CheveretoResponse {
|
||||||
|
return client.submitFormWithBinaryData(
|
||||||
|
url = apiUrl,
|
||||||
|
formData = formData {
|
||||||
|
append("source", file.readBytes(), Headers.build {
|
||||||
|
append(HttpHeaders.ContentDisposition, "form-data; name=\"source\"; filename=\"${file.name}\"")
|
||||||
|
})
|
||||||
|
append("format", "json")
|
||||||
|
title?.let { append("title", it) }
|
||||||
|
description?.let { append("description", it) }
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
headers {
|
||||||
|
append("X-API-Key", apiKey)
|
||||||
|
}
|
||||||
|
}.body()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传网络图片 URL
|
||||||
|
*/
|
||||||
|
suspend fun uploadFromUrl(
|
||||||
|
apiUrl: String,
|
||||||
|
apiKey: String,
|
||||||
|
imageUrl: String
|
||||||
|
): CheveretoResponse {
|
||||||
|
return client.submitForm(
|
||||||
|
url = apiUrl,
|
||||||
|
formParameters = Parameters.build {
|
||||||
|
append("source", imageUrl)
|
||||||
|
append("format", "json")
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
headers {
|
||||||
|
append("X-API-Key", apiKey)
|
||||||
|
}
|
||||||
|
}.body()
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 上传 ByteArrayInputStream
|
||||||
|
*/
|
||||||
|
suspend fun uploadFromStream(
|
||||||
|
apiUrl: String,
|
||||||
|
apiKey: String,
|
||||||
|
inputStream: ByteArrayInputStream,
|
||||||
|
fileName: String,
|
||||||
|
title: String? = null,
|
||||||
|
description: String? = null
|
||||||
|
): CheveretoResponse {
|
||||||
|
val bytes = inputStream.readBytes()
|
||||||
|
return client.submitFormWithBinaryData(
|
||||||
|
url = apiUrl,
|
||||||
|
formData = formData {
|
||||||
|
append("source", bytes, Headers.build {
|
||||||
|
append(HttpHeaders.ContentDisposition, "form-data; name=\"source\"; filename=\"$fileName\"")
|
||||||
|
})
|
||||||
|
append("format", "json")
|
||||||
|
title?.let { append("title", it) }
|
||||||
|
description?.let { append("description", it) }
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
headers { append("X-API-Key", apiKey) }
|
||||||
|
}.body()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.r3944realms.ltdmanager.chevereto
|
||||||
|
|
||||||
|
class CheveretoQueueItem {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
package top.r3944realms.ltdmanager.chevereto
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class CheveretoImage(
|
||||||
|
val name: String,
|
||||||
|
val extension: String,
|
||||||
|
val size: Long,
|
||||||
|
val width: Int,
|
||||||
|
val height: Int,
|
||||||
|
val date: String,
|
||||||
|
val url: String
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package top.r3944realms.ltdmanager.chevereto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class CheveretoResponse(
|
||||||
|
@SerialName("status_code")
|
||||||
|
val statusCode: Int,
|
||||||
|
val success: Map<String, String>? = null,
|
||||||
|
val image: CheveretoImage? = null
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.r3944realms.ltdmanager.chevereto.data
|
||||||
|
|
||||||
|
class File {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.r3944realms.ltdmanager.chevereto.data
|
||||||
|
|
||||||
|
class ImageFile {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
package top.r3944realms.ltdmanager.chevereto.data
|
||||||
|
|
||||||
|
data class ImageThumb()
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.r3944realms.ltdmanager.chevereto.data
|
||||||
|
|
||||||
|
class Medium {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
package top.r3944realms.ltdmanager.chevereto.data
|
||||||
|
|
||||||
|
data class Success()
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.r3944realms.ltdmanager.core.config
|
||||||
|
|
||||||
|
class ImgTuConfig {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.r3944realms.ltdmanager.dglab.model.game
|
||||||
|
|
||||||
|
class PlayerManager {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.r3944realms.ltdmanager.module
|
||||||
|
|
||||||
|
class StateModule {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.r3944realms.ltdmanager.module.common
|
||||||
|
|
||||||
|
class AdvancedCommandParser {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.r3944realms.ltdmanager.module.common.filter.type
|
||||||
|
|
||||||
|
class AdvancedCommonFilter {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.r3944realms.ltdmanager.napcat.data
|
||||||
|
|
||||||
|
class GroupMember {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.r3944realms.ltdmanager.napcat.data.msghistory
|
||||||
|
|
||||||
|
class MsgHistoryContent {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.r3944realms.ltdmanager.napcat.data.msghistory
|
||||||
|
|
||||||
|
class MsgHistoryMessage {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package top.r3944realms.ltdmanager.napcat.data.msghistory
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import top.r3944realms.ltdmanager.napcat.data.ID
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class MsgHistoryMessageData (
|
||||||
|
val text: String? = null,
|
||||||
|
val name: String? = null,
|
||||||
|
val qq: ID? = null,
|
||||||
|
val id: ID? = null,
|
||||||
|
val file: String? = null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 外显
|
||||||
|
*/
|
||||||
|
val summary: String? = null,
|
||||||
|
|
||||||
|
val data: String? = null,
|
||||||
|
val content: MsgHistoryContent? = null
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.r3944realms.ltdmanager.napcat.data.msghistory
|
||||||
|
|
||||||
|
class MsgHistorySpecificMsg {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.r3944realms.ltdmanager.napcat.serializer
|
||||||
|
|
||||||
|
object MsgHistoryContentSerializer {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
package top.r394realms.ltdmanagertest.command
|
||||||
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.r394realms.ltdmanagertest.command
|
||||||
|
|
||||||
|
class ParameterExtractionDemo {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.r394realms.ltdmanagertest.command
|
||||||
|
|
||||||
|
class testACP {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
package top.r394realms.ltdmanagertest.command
|
||||||
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.r394realms.ltdmanagertest.msg
|
||||||
|
|
||||||
|
class sendMsgTest {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.r394realms.ltdmanagertest
|
||||||
|
|
||||||
|
class testRandom {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
package top.r394realms.ltdmanagertest.util
|
||||||
|
|
||||||
|
|
||||||
|
import okhttp3.*
|
||||||
|
import okhttp3.MediaType.Companion.toMediaType
|
||||||
|
import okhttp3.RequestBody.Companion.asRequestBody
|
||||||
|
import top.r3944realms.ltdmanager.GlobalManager
|
||||||
|
import top.r3944realms.ltdmanager.utils.LoggerUtil
|
||||||
|
import java.io.File
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
object ImageUploader {
|
||||||
|
|
||||||
|
private val client = OkHttpClient().newBuilder()
|
||||||
|
.addInterceptor(HttpLoggingInterceptor().apply {
|
||||||
|
level = HttpLoggingInterceptor.Level.BODY // 查看完整的请求和响应
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
|
||||||
|
fun uploadImage(filePath: String, apiKey: String): String {
|
||||||
|
val file = File(filePath)
|
||||||
|
|
||||||
|
// 检查文件是否存在
|
||||||
|
if (!file.exists()) {
|
||||||
|
throw IllegalArgumentException("文件不存在: $filePath")
|
||||||
|
}
|
||||||
|
|
||||||
|
LoggerUtil.logger.info("开始上传文件: ${file.name}, 大小: ${file.length()} bytes")
|
||||||
|
|
||||||
|
// 创建 multipart 请求体
|
||||||
|
val requestBody = MultipartBody.Builder()
|
||||||
|
.setType(MultipartBody.FORM)
|
||||||
|
.addFormDataPart(
|
||||||
|
"source",
|
||||||
|
file.name,
|
||||||
|
file.asRequestBody("image/png".toMediaType())
|
||||||
|
)
|
||||||
|
.addFormDataPart("format", "json")
|
||||||
|
.build()
|
||||||
|
|
||||||
|
// 创建请求
|
||||||
|
val request = Request.Builder()
|
||||||
|
.url("https://pic.xiaobuawa.top/api/1/upload")
|
||||||
|
.header("X-API-Key", apiKey.trim()) // 重要:去除空格
|
||||||
|
.post(requestBody)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
// 执行请求
|
||||||
|
val response = client.newCall(request).execute()
|
||||||
|
try {
|
||||||
|
if (!response.isSuccessful) {
|
||||||
|
throw IOException("上传失败,状态码: ${response.code}, 响应: ${response.body?.string()}")
|
||||||
|
}
|
||||||
|
|
||||||
|
val responseBody = response.body?.string()
|
||||||
|
LoggerUtil.logger.info("上传成功: $responseBody")
|
||||||
|
return responseBody ?: throw IOException("响应体为空")
|
||||||
|
} finally {
|
||||||
|
response.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 异步版本(推荐用于生产环境)
|
||||||
|
fun uploadImageAsync(filePath: String, apiKey: String, callback: (Result<String>) -> Unit) {
|
||||||
|
val file = File(filePath)
|
||||||
|
|
||||||
|
if (!file.exists()) {
|
||||||
|
callback(Result.failure(IllegalArgumentException("文件不存在: $filePath")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val requestBody = MultipartBody.Builder()
|
||||||
|
.setType(MultipartBody.FORM)
|
||||||
|
.addFormDataPart(
|
||||||
|
"source",
|
||||||
|
file.name,
|
||||||
|
file.asRequestBody("image/png".toMediaType())
|
||||||
|
)
|
||||||
|
.addFormDataPart("format", "json")
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val request = Request.Builder()
|
||||||
|
.url("https://pic.xiaobuawa.top/api/1/upload")
|
||||||
|
.header("X-API-Key", apiKey.trim())
|
||||||
|
.post(requestBody)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
client.newCall(request).enqueue(object : Callback {
|
||||||
|
override fun onFailure(call: Call, e: IOException) {
|
||||||
|
callback(Result.failure(e))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResponse(call: Call, response: Response) {
|
||||||
|
try {
|
||||||
|
if (!response.isSuccessful) {
|
||||||
|
callback(Result.failure(IOException("上传失败,状态码: ${response.code}")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val responseBody = response.body?.string()
|
||||||
|
if (responseBody != null) {
|
||||||
|
callback(Result.success(responseBody))
|
||||||
|
} else {
|
||||||
|
callback(Result.failure(IOException("响应体为空")))
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
callback(Result.failure(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.r394realms.ltdmanagertest.util
|
||||||
|
|
||||||
|
class img {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
package top.r394realms.ltdmanagertest.util
|
||||||
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
package top.r394realms.ltdmanagertest.util
|
||||||
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.r394realms.ltdmanagertest.util
|
||||||
|
|
||||||
|
class imgv4 {
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user