|
|
@ -10,9 +10,10 @@ import io.ktor.http.content.* |
|
|
|
import io.ktor.request.* |
|
|
|
import io.ktor.request.* |
|
|
|
import io.ktor.response.* |
|
|
|
import io.ktor.response.* |
|
|
|
import io.ktor.routing.* |
|
|
|
import io.ktor.routing.* |
|
|
|
|
|
|
|
import io.ktor.util.* |
|
|
|
import io.ktor.websocket.* |
|
|
|
import io.ktor.websocket.* |
|
|
|
|
|
|
|
import kotlinx.coroutines.Dispatchers |
|
|
|
import kotlinx.coroutines.Job |
|
|
|
import kotlinx.coroutines.Job |
|
|
|
import kotlinx.coroutines.cancel |
|
|
|
|
|
|
|
import kotlinx.coroutines.channels.Channel |
|
|
|
import kotlinx.coroutines.channels.Channel |
|
|
|
import kotlinx.coroutines.launch |
|
|
|
import kotlinx.coroutines.launch |
|
|
|
import kotlinx.html.HTML |
|
|
|
import kotlinx.html.HTML |
|
|
@ -20,87 +21,172 @@ import kotlinx.serialization.decodeFromString |
|
|
|
import kotlinx.serialization.encodeToString |
|
|
|
import kotlinx.serialization.encodeToString |
|
|
|
import kotlinx.serialization.json.Json |
|
|
|
import kotlinx.serialization.json.Json |
|
|
|
import java.io.File |
|
|
|
import java.io.File |
|
|
|
|
|
|
|
import java.io.FileOutputStream |
|
|
|
|
|
|
|
import java.util.zip.ZipEntry |
|
|
|
|
|
|
|
import java.util.zip.ZipOutputStream |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const val website = "https://gammaplus.takeshobo.co.jp" |
|
|
|
const val website = "https://gammaplus.takeshobo.co.jp" |
|
|
|
|
|
|
|
|
|
|
|
var taskChannel = Channel<ParseTask>() |
|
|
|
//漫画url |
|
|
|
val urlResultChannel = Channel<UrlResult>() |
|
|
|
val urlChannel = Channel<String>() |
|
|
|
val htmlChannel= Channel<UrlParam>() |
|
|
|
|
|
|
|
var currentJob: Job?=null |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fun Application.parse(){ |
|
|
|
//当前漫画解析任务 |
|
|
|
log.info("初始化解析任务") |
|
|
|
var currentJob: Job? = null |
|
|
|
|
|
|
|
|
|
|
|
val uploadDir = environment.config.property("ktor.deployment.filePath").getString() |
|
|
|
//合成图片打包数据 |
|
|
|
val filePath = environment.classLoader.getResource(uploadDir)?.path.apply { log.info("图片存储目录:${this}") }?:throw IllegalArgumentException("图片存储目录初始化失败") |
|
|
|
val imageDataChannel = Channel<ImageFileData>() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val webSocketChannel = Channel<TestData>() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//图片JSON解析 |
|
|
|
|
|
|
|
fun Application.parse() { |
|
|
|
launch { |
|
|
|
launch { |
|
|
|
while (true){ |
|
|
|
log.info("初始化解析任务") |
|
|
|
val resHtml= htmlChannel.receive() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
currentJob?.let { |
|
|
|
val uploadDir = environment.config.property("ktor.deployment.filePath").getString() |
|
|
|
if(it.isActive) this.cancel() |
|
|
|
val filePath = environment.classLoader.getResource(uploadDir)?.path.apply { log.info("图片存储目录:${this}") } |
|
|
|
} |
|
|
|
?: throw IllegalArgumentException("图片存储目录初始化失败") |
|
|
|
|
|
|
|
|
|
|
|
launch { |
|
|
|
while (true) { |
|
|
|
log.info("开始解析:${resHtml.url}") |
|
|
|
val urlParam = urlChannel.receive() |
|
|
|
val client = HttpClient(CIO) |
|
|
|
|
|
|
|
|
|
|
|
// |
|
|
|
val titlePrefix="title>" |
|
|
|
// currentJob?.let { |
|
|
|
val title=Regex("$titlePrefix[\\u4e00-\\u9fa5\\u0800-\\u4e00\\s\\d\\uff00-\\uffef]+").find(resHtml.html)?.value?.replace(titlePrefix,"")?:throw IllegalArgumentException("无法解析漫画标题") |
|
|
|
// if(it.isActive) this.cancel() |
|
|
|
val romajiPrefix="/manga" |
|
|
|
// } |
|
|
|
val romajiTitle=Regex("$romajiPrefix/\\w+").find(resHtml.url)?.value?.replace(romajiPrefix,"")?:throw IllegalArgumentException("无法解析漫画罗马音标题") |
|
|
|
|
|
|
|
log.info("解析漫画标题") |
|
|
|
launch { |
|
|
|
val imageDir= File(filePath,romajiTitle).apply { if(!exists()) mkdir() } |
|
|
|
log.info("开始解析:${urlParam}") |
|
|
|
|
|
|
|
val client = HttpClient(CIO) |
|
|
|
|
|
|
|
val response: HttpResponse = client.get(urlParam) |
|
|
|
|
|
|
|
if (response.status == HttpStatusCode.OK) { |
|
|
|
|
|
|
|
val resHtml = response.readText() |
|
|
|
|
|
|
|
// log.info("resHtml:\n$resHtml") |
|
|
|
|
|
|
|
val titlePrefix = "title>" |
|
|
|
|
|
|
|
val title = |
|
|
|
|
|
|
|
Regex("$titlePrefix[\\u4e00-\\u9fa5\\u0800-\\u4e00\\s\\d\\uff00-\\uffef]+").find(resHtml)?.value?.replace( |
|
|
|
|
|
|
|
titlePrefix, |
|
|
|
|
|
|
|
"" |
|
|
|
|
|
|
|
) ?: throw IllegalArgumentException("无法解析漫画标题") |
|
|
|
|
|
|
|
val romajiPrefix = "/manga/" |
|
|
|
|
|
|
|
val romajiTitle = Regex("$romajiPrefix\\w+").find(resHtml)?.value?.replace(romajiPrefix, "") |
|
|
|
|
|
|
|
?: throw IllegalArgumentException("无法解析漫画罗马音标题") |
|
|
|
|
|
|
|
log.info("漫画标题title=$title,romajiTitle=$romajiTitle") |
|
|
|
|
|
|
|
webSocketChannel.send(MangaInfo(href = urlParam, title = title, romajiTitle = romajiTitle)) |
|
|
|
|
|
|
|
val imageDir = File(filePath, romajiTitle).apply { if (!exists()) mkdir() } |
|
|
|
log.info("漫画图片存储到:${imageDir.absolutePath}") |
|
|
|
log.info("漫画图片存储到:${imageDir.absolutePath}") |
|
|
|
|
|
|
|
|
|
|
|
Regex("data/.*.json").findAll(resHtml.html) |
|
|
|
Regex("data/.*.json").findAll(resHtml) |
|
|
|
.apply { |
|
|
|
.apply { |
|
|
|
withIndex() |
|
|
|
withIndex().forEach { |
|
|
|
//TODO .forEach { |
|
|
|
log.info("开始解析:${it.value.value}") |
|
|
|
.first().let { |
|
|
|
val urlPath = "${urlParam}/${it.value.value}" |
|
|
|
log.info("开始解析:${it.value.value}") |
|
|
|
val jsonRes: HttpResponse = client.get(urlPath) |
|
|
|
val urlPath = "${resHtml.url}/${it.value.value}" |
|
|
|
if (jsonRes.status == HttpStatusCode.OK) { |
|
|
|
val jsonRes: HttpResponse = client.get(urlPath) |
|
|
|
log.info("$urlPath 请求成功") |
|
|
|
if (jsonRes.status == HttpStatusCode.OK) { |
|
|
|
val t: t = Json.decodeFromString(jsonRes.readText()) |
|
|
|
log.info("url:${urlPath} request OK") |
|
|
|
val originImagePath = "/data/${t.resources.i.src}" |
|
|
|
val t:t=Json.decodeFromString(jsonRes.readText()) |
|
|
|
val imageUrl = "${urlParam}${originImagePath}" |
|
|
|
val originImagePath="/data/${t.resources.i.src}" |
|
|
|
val imgRes: HttpResponse = client.get(imageUrl) |
|
|
|
val imageUrl="${resHtml.url}${originImagePath}" |
|
|
|
if (imgRes.status == HttpStatusCode.OK && imgRes.contentType() == ContentType.Image.JPEG) { |
|
|
|
val imgRes:HttpResponse=client.get(imageUrl) |
|
|
|
log.info("$imageUrl 请求成功") |
|
|
|
if(imgRes.status==HttpStatusCode.OK&&imgRes.contentType()==ContentType.Image.JPEG){ |
|
|
|
val filename = "${it.index + 1}.jpg" |
|
|
|
val filename="${it.index}.jpg" |
|
|
|
val file = File(imageDir, filename).apply { |
|
|
|
val file=File(imageDir,filename).apply { |
|
|
|
writeBytes(imgRes.readBytes()) |
|
|
|
writeBytes(imgRes.readBytes()) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
log.info("存储漫画图片:${file.absolutePath}") |
|
|
|
|
|
|
|
val serverImagePath="/${uploadDir}/${romajiTitle}/${filename}" |
|
|
|
|
|
|
|
log.info("serverImagePath:${serverImagePath}") |
|
|
|
|
|
|
|
urlResultChannel.send(UrlResult(originImagePath = originImagePath, t = t, |
|
|
|
|
|
|
|
serverImagePath = serverImagePath)) |
|
|
|
|
|
|
|
}else{ |
|
|
|
|
|
|
|
log.warn("image url:${imageUrl} 响应码${jsonRes.status} 响应类型${imgRes.contentType()}") |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
log.info("存储漫画图片:${file.absolutePath}") |
|
|
|
|
|
|
|
val serverImagePath = "/${uploadDir}/${romajiTitle}/${filename}" |
|
|
|
|
|
|
|
log.info("serverImagePath:${serverImagePath}") |
|
|
|
|
|
|
|
webSocketChannel.send( |
|
|
|
|
|
|
|
UrlResult( |
|
|
|
|
|
|
|
originImagePath = originImagePath, |
|
|
|
|
|
|
|
t = t, |
|
|
|
|
|
|
|
serverImagePath = serverImagePath, |
|
|
|
|
|
|
|
romajiTitle = romajiTitle, |
|
|
|
|
|
|
|
filename = filename, |
|
|
|
|
|
|
|
isLast = count() == it.index + 1 |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
log.warn("json url:${urlPath} 响应码:${jsonRes.status}") |
|
|
|
log.warn("image url:${imageUrl} 响应码${jsonRes.status} 响应类型${imgRes.contentType()}") |
|
|
|
} |
|
|
|
} |
|
|
|
taskChannel.send(ParseTask(total = count(), finish = it.index + 1,percentage = if(count()==it.index+1) 100F else String.format("%.2f",(it.index+1)*100F/count()).toFloat())) |
|
|
|
} else { |
|
|
|
|
|
|
|
log.warn("json url:${urlPath} 响应码:${jsonRes.status}") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
webSocketChannel.send( |
|
|
|
|
|
|
|
ParseTask( |
|
|
|
|
|
|
|
total = count(), |
|
|
|
|
|
|
|
finish = it.index + 1, |
|
|
|
|
|
|
|
percentage = if (count() == it.index + 1) 100F else String.format( |
|
|
|
|
|
|
|
"%.2f", |
|
|
|
|
|
|
|
(it.index + 1) * 100F / count() |
|
|
|
|
|
|
|
).toFloat() |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
client.close() |
|
|
|
} else { |
|
|
|
}.apply { |
|
|
|
log.warn("http code:${response.status}") |
|
|
|
currentJob=this |
|
|
|
webSocketChannel.send(StringResult(message = "${urlParam}解析失败")) |
|
|
|
invokeOnCompletion { |
|
|
|
|
|
|
|
log.info("${resHtml.url}解析完成") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
client.close() |
|
|
|
|
|
|
|
}.apply { |
|
|
|
|
|
|
|
currentJob = this |
|
|
|
|
|
|
|
invokeOnCompletion { |
|
|
|
|
|
|
|
log.info("${urlParam}解析完成") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
launch { |
|
|
|
|
|
|
|
log.info("初始化合成图片任务") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val zipDir = environment.config.property("ktor.deployment.zipPath").getString() |
|
|
|
|
|
|
|
val zipPath = environment.classLoader.getResource(zipDir)?.path.apply { log.info("图片压缩目录:${this}") } |
|
|
|
|
|
|
|
?: throw IllegalArgumentException("图片压缩目录初始化失败") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (true) { |
|
|
|
|
|
|
|
val imageFileData = imageDataChannel.receive() |
|
|
|
|
|
|
|
File(zipPath, imageFileData.romajiTitle).apply { |
|
|
|
|
|
|
|
imageFileData.data.apply { |
|
|
|
|
|
|
|
launch(Dispatchers.IO) { |
|
|
|
|
|
|
|
File(zipPath, "${imageFileData.romajiTitle}.zip").apply { |
|
|
|
|
|
|
|
ZipOutputStream(FileOutputStream(this)).use { out -> |
|
|
|
|
|
|
|
forEach { file -> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
out.putNextEntry( |
|
|
|
|
|
|
|
ZipEntry( |
|
|
|
|
|
|
|
file.originalFileName ?: throw IllegalArgumentException("无法获取图片名字") |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
out.write(file.streamProvider().readBytes()) |
|
|
|
|
|
|
|
out.closeEntry() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
webSocketChannel.send( |
|
|
|
|
|
|
|
ZipResult( |
|
|
|
|
|
|
|
zipUrl = "/${zipDir}/${name}", |
|
|
|
|
|
|
|
name = name, |
|
|
|
|
|
|
|
size = String.format("%.2fMB", length() / 1024 / 1024F) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
webSocketChannel.send(StringResult(message = "打包任务完成")) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fun createFrameText(message: String): Frame.Text { |
|
|
|
|
|
|
|
return Frame.Text(Json.encodeToString(WebSocketServer(body = message, dataType = WebSocketResType.Text.name))) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fun Application.configureRouting() { |
|
|
|
fun Application.configureRouting() { |
|
|
|
|
|
|
|
|
|
|
|
routing { |
|
|
|
routing { |
|
|
@ -108,65 +194,150 @@ fun Application.configureRouting() { |
|
|
|
static(uploadDir) { |
|
|
|
static(uploadDir) { |
|
|
|
resources(uploadDir) |
|
|
|
resources(uploadDir) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
val zipDir = environment.config.property("ktor.deployment.zipPath").getString() |
|
|
|
|
|
|
|
static(zipDir) { |
|
|
|
|
|
|
|
resources(zipDir) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static("/static") { |
|
|
|
static("/static") { |
|
|
|
resources() |
|
|
|
resources() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
webSocket(websocketPath) { // websocketSession |
|
|
|
webSocket(Api.websocketPath) { // websocketSession |
|
|
|
launch { |
|
|
|
|
|
|
|
while (true) { |
|
|
|
|
|
|
|
val urlResult = urlResultChannel.receive() |
|
|
|
|
|
|
|
outgoing.send(Frame.Text(Json.encodeToString(urlResult))) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
launch { |
|
|
|
launch { |
|
|
|
while (true) { |
|
|
|
while (true) { |
|
|
|
val task = taskChannel.receive() |
|
|
|
when (val data = webSocketChannel.receive()) { |
|
|
|
outgoing.send(Frame.Text(Json.encodeToString(task))) |
|
|
|
is StringResult -> outgoing.send(createFrameText(data.message)) |
|
|
|
|
|
|
|
is UrlResult -> outgoing.send( |
|
|
|
|
|
|
|
Frame.Text( |
|
|
|
|
|
|
|
Json.encodeToString( |
|
|
|
|
|
|
|
WebSocketServer( |
|
|
|
|
|
|
|
body = data, |
|
|
|
|
|
|
|
dataType = WebSocketResType.Image.name |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
is MangaInfo -> outgoing.send( |
|
|
|
|
|
|
|
Frame.Text( |
|
|
|
|
|
|
|
Json.encodeToString( |
|
|
|
|
|
|
|
WebSocketServer( |
|
|
|
|
|
|
|
body = data, |
|
|
|
|
|
|
|
dataType = WebSocketResType.Manga.name |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
is ZipResult -> outgoing.send( |
|
|
|
|
|
|
|
Frame.Text( |
|
|
|
|
|
|
|
Json.encodeToString( |
|
|
|
|
|
|
|
WebSocketServer( |
|
|
|
|
|
|
|
body = data, |
|
|
|
|
|
|
|
dataType = WebSocketResType.Zip.name |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
is ParseTask -> outgoing.send( |
|
|
|
|
|
|
|
Frame.Text( |
|
|
|
|
|
|
|
Json.encodeToString( |
|
|
|
|
|
|
|
WebSocketServer( |
|
|
|
|
|
|
|
body = data, |
|
|
|
|
|
|
|
dataType = WebSocketResType.Task.name |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (frame in incoming) { |
|
|
|
for (frame in incoming) { |
|
|
|
when (frame) { |
|
|
|
when (frame) { |
|
|
|
is Frame.Text -> { |
|
|
|
is Frame.Text -> { |
|
|
|
val text = frame.readText() |
|
|
|
val input = frame.readText() |
|
|
|
when { |
|
|
|
try { |
|
|
|
"cancel" == text -> { |
|
|
|
val webSocketMessage: WebSocketClient = Json.decodeFromString(input) |
|
|
|
if (currentJob?.isActive == true) { |
|
|
|
when (webSocketMessage.command) { |
|
|
|
currentJob?.cancel() |
|
|
|
WebSocketClientCommand.Heart.name -> { |
|
|
|
outgoing.send(Frame.Text("当前服务器解析任务已停止")) |
|
|
|
outgoing.send( |
|
|
|
} else { |
|
|
|
Frame.Text( |
|
|
|
outgoing.send(Frame.Text("当前服务器没有正在运行的解析任务")) |
|
|
|
Json.encodeToString( |
|
|
|
|
|
|
|
WebSocketServer(dataType = WebSocketResType.Heart.name, body = "心跳返回") |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
WebSocketClientCommand.Cancel.name -> { |
|
|
|
|
|
|
|
if (currentJob?.isActive == true) { |
|
|
|
|
|
|
|
currentJob?.cancel() |
|
|
|
|
|
|
|
outgoing.send( |
|
|
|
|
|
|
|
Frame.Text( |
|
|
|
|
|
|
|
Json.encodeToString( |
|
|
|
|
|
|
|
WebSocketServer( |
|
|
|
|
|
|
|
dataType = WebSocketResType.Cancel.name, |
|
|
|
|
|
|
|
body = true |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
outgoing.send(createFrameText(message = "当前服务器没有正在运行的解析任务")) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
else -> outgoing.send(createFrameText(message = "未知命令:${webSocketMessage.command}")) |
|
|
|
} |
|
|
|
} |
|
|
|
"exit" == text -> close(CloseReason(CloseReason.Codes.NORMAL, "Client said exit")) |
|
|
|
} catch (e: Exception) { |
|
|
|
|
|
|
|
log.error(e) |
|
|
|
|
|
|
|
outgoing.send(Frame.Text("非法命令:${input}")) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
is Frame.Close -> { |
|
|
|
|
|
|
|
currentJob?.cancel() |
|
|
|
|
|
|
|
log.info("取消解析任务") |
|
|
|
|
|
|
|
} |
|
|
|
else -> log.warn("无法处理${frame.frameType}类型消息") |
|
|
|
else -> log.warn("无法处理${frame.frameType}类型消息") |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get("/") { |
|
|
|
get("/") { |
|
|
|
call.respondHtml(HttpStatusCode.OK, HTML::index) |
|
|
|
call.respondHtml(HttpStatusCode.OK, HTML::index) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
post("/api/json") { |
|
|
|
//打包漫画图片 |
|
|
|
|
|
|
|
post(Api.IMAGE_API) { |
|
|
|
|
|
|
|
val d = call.receiveMultipart() |
|
|
|
|
|
|
|
d.readAllParts().apply { |
|
|
|
|
|
|
|
var romajiTitle = "" |
|
|
|
|
|
|
|
filterIsInstance<PartData.FormItem>().forEach { |
|
|
|
|
|
|
|
if (it.name == "romajiTitle") romajiTitle = it.value |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
val fileList = filterIsInstance<PartData.FileItem>() |
|
|
|
|
|
|
|
if (romajiTitle.isNotEmpty() && fileList.isNotEmpty()) { |
|
|
|
|
|
|
|
launch { |
|
|
|
|
|
|
|
imageDataChannel.send(ImageFileData(romajiTitle = romajiTitle, data = fileList)) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
call.respond(MessageResponse(message = "初始化打包任务。。。")) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
log.warn("无法打包漫画图片,参数不合法[romajiTitle:${romajiTitle},fileList=${fileList}]") |
|
|
|
|
|
|
|
call.respond(MessageResponse(message = "无法打包漫画图片,请联系管理员")) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//解析漫画图片数据 |
|
|
|
|
|
|
|
post(Api.JSON_API) { |
|
|
|
val formParameters = call.receiveParameters() |
|
|
|
val formParameters = call.receiveParameters() |
|
|
|
val urlParam = formParameters["url"] ?: "" |
|
|
|
val urlParam = formParameters["url"] ?: "" |
|
|
|
log.info("urlParam:${urlParam}") |
|
|
|
log.info("urlParam:${urlParam}") |
|
|
|
if (urlParam.startsWith(website)) { |
|
|
|
if (urlParam.startsWith(website)) { |
|
|
|
val client = HttpClient(CIO) |
|
|
|
launch { |
|
|
|
val response: HttpResponse = client.get(urlParam) |
|
|
|
urlChannel.send(urlParam.let { if (it.endsWith("/")) it else "$it/" }) |
|
|
|
if (response.status == HttpStatusCode.OK) { |
|
|
|
|
|
|
|
val resHtml = response.readText() |
|
|
|
|
|
|
|
htmlChannel.send(UrlParam(url = urlParam, html = resHtml)) |
|
|
|
|
|
|
|
call.respond(MessageResponse(message = "开始执行解析任务")) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
log.warn("http code:${response.status}") |
|
|
|
|
|
|
|
call.respond(MessageResponse(message = "请求失败")) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
client.close() |
|
|
|
call.respond(MessageResponse(message = "初始化解析任务。。。")) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
call.respond(MessageResponse(message = "${urlParam}:非法漫画地址")) |
|
|
|
call.respond(MessageResponse(message = "${urlParam}:非法漫画地址")) |
|
|
|
} |
|
|
|
} |
|
|
|