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