完善代码
This commit is contained in:
@@ -14,6 +14,7 @@ import io.ktor.server.response.*
|
||||
import io.ktor.server.routing.*
|
||||
import io.ktor.server.websocket.*
|
||||
import io.ktor.util.pipeline.*
|
||||
import io.ktor.util.toMap
|
||||
import io.legado.app.api.ReturnData
|
||||
import io.legado.app.api.controller.BookController
|
||||
import io.legado.app.api.controller.BookSourceController
|
||||
@@ -29,7 +30,9 @@ import io.legado.app.web.socket.RssSourceDebugWebSocket
|
||||
import io.legado.app.web.utils.AssetsWeb
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import splitties.init.appCtx
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
|
||||
class KtorServer(private val port: Int) {
|
||||
private var server: ApplicationEngine? = null
|
||||
@@ -62,32 +65,46 @@ class KtorServer(private val port: Int) {
|
||||
WebService.serve()
|
||||
val multipart = call.receiveMultipart()
|
||||
var fileName: String? = null
|
||||
var fileBytes: ByteArray? = null
|
||||
multipart.forEachPart { part ->
|
||||
when (part) {
|
||||
is PartData.FormItem -> {
|
||||
if (part.name == "fileName") fileName = part.value
|
||||
val tempFile = File(appCtx.cacheDir, "upload_${System.currentTimeMillis()}")
|
||||
try {
|
||||
multipart.forEachPart { part ->
|
||||
when (part) {
|
||||
is PartData.FormItem -> {
|
||||
if (part.name == "fileName") fileName = part.value
|
||||
}
|
||||
is PartData.FileItem -> {
|
||||
part.streamProvider().use { input ->
|
||||
tempFile.outputStream().use { output ->
|
||||
input.copyTo(output)
|
||||
}
|
||||
}
|
||||
if (fileName == null) {
|
||||
fileName = part.originalFileName
|
||||
}
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
is PartData.FileItem -> {
|
||||
fileBytes = part.streamProvider().readBytes()
|
||||
}
|
||||
else -> {}
|
||||
part.dispose()
|
||||
}
|
||||
part.dispose()
|
||||
}
|
||||
if (fileName != null && fileBytes != null) {
|
||||
val returnData = withContext(Dispatchers.IO) {
|
||||
kotlin.runCatching {
|
||||
val uri = LocalBook.saveBookFile(fileBytes!!.inputStream(), fileName!!)
|
||||
LocalBook.importFile(uri)
|
||||
ReturnData().setData(true)
|
||||
}.getOrElse {
|
||||
ReturnData().setErrorMsg(it.localizedMessage ?: "Save book error")
|
||||
if (fileName != null && tempFile.exists()) {
|
||||
val returnData = withContext(Dispatchers.IO) {
|
||||
kotlin.runCatching {
|
||||
tempFile.inputStream().use {
|
||||
val uri = LocalBook.saveBookFile(it, fileName!!)
|
||||
LocalBook.importFile(uri)
|
||||
ReturnData().setData(true)
|
||||
}
|
||||
}.getOrElse {
|
||||
LogUtils.e(TAG, it.stackTraceStr)
|
||||
ReturnData().setErrorMsg(it.localizedMessage ?: "Save book error")
|
||||
}
|
||||
}
|
||||
respondReturnData(returnData)
|
||||
} else {
|
||||
call.respond(HttpStatusCode.BadRequest, "Missing fileName or fileData")
|
||||
}
|
||||
respondReturnData(returnData)
|
||||
} else {
|
||||
call.respond(HttpStatusCode.BadRequest, "Missing fileName or fileData")
|
||||
} finally {
|
||||
if (tempFile.exists()) tempFile.delete()
|
||||
}
|
||||
}
|
||||
post("/saveReadConfig") { handlePost { BookController.saveWebReadConfig(it) } }
|
||||
@@ -113,12 +130,14 @@ class KtorServer(private val port: Int) {
|
||||
|
||||
get("{...}") {
|
||||
WebService.serve()
|
||||
var uri = call.request.uri.substringBefore("?")
|
||||
var uri = call.request.path()
|
||||
if (uri.endsWith("/")) uri += "index.html"
|
||||
val inputStream = assetsWeb.getInputStream(uri)
|
||||
if (inputStream != null) {
|
||||
call.respondOutputStream(ContentType.parse(assetsWeb.getMimeType(uri))) {
|
||||
inputStream.copyTo(this)
|
||||
inputStream.use { stream ->
|
||||
call.respondOutputStream(ContentType.parse(assetsWeb.getMimeType(uri))) {
|
||||
stream.copyTo(this)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
call.respond(HttpStatusCode.NotFound)
|
||||
@@ -195,12 +214,6 @@ class KtorServer(private val port: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun Parameters.toMap(): Map<String, List<String>> {
|
||||
val map = mutableMapOf<String, List<String>>()
|
||||
this.forEach { s, list -> map[s] = list }
|
||||
return map
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "KtorServer"
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ import io.legado.app.help.config.AppConfig
|
||||
import io.legado.app.ui.config.otherConfig.OtherConfig
|
||||
import io.legado.app.utils.*
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.consumeEach
|
||||
import org.koin.core.context.GlobalContext
|
||||
import splitties.init.appCtx
|
||||
|
||||
@@ -28,13 +27,13 @@ class BookSearchWebSocket(private val session: DefaultWebSocketServerSession) :
|
||||
|
||||
suspend fun handle() {
|
||||
try {
|
||||
session.incoming.consumeEach { frame ->
|
||||
for (frame in session.incoming) {
|
||||
if (frame is Frame.Text) {
|
||||
val text = frame.readText()
|
||||
if (!text.isJson()) {
|
||||
session.send("数据必须为Json格式")
|
||||
session.close(CloseReason(CloseReason.Codes.NORMAL, SEARCH_FINISH))
|
||||
return@consumeEach
|
||||
break
|
||||
}
|
||||
val searchMap = GSON.fromJsonObject<Map<String, String>>(text).getOrNull()
|
||||
if (searchMap != null) {
|
||||
@@ -42,7 +41,7 @@ class BookSearchWebSocket(private val session: DefaultWebSocketServerSession) :
|
||||
if (key.isNullOrBlank()) {
|
||||
session.send(appCtx.getString(R.string.cannot_empty))
|
||||
session.close(CloseReason(CloseReason.Codes.NORMAL, SEARCH_FINISH))
|
||||
return@consumeEach
|
||||
break
|
||||
}
|
||||
startSearch(key)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import io.legado.app.data.appDb
|
||||
import io.legado.app.model.Debug
|
||||
import io.legado.app.utils.*
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.consumeEach
|
||||
import splitties.init.appCtx
|
||||
|
||||
/**
|
||||
@@ -21,13 +20,13 @@ class BookSourceDebugWebSocket(private val session: DefaultWebSocketServerSessio
|
||||
|
||||
suspend fun handle() {
|
||||
try {
|
||||
session.incoming.consumeEach { frame ->
|
||||
for (frame in session.incoming) {
|
||||
if (frame is Frame.Text) {
|
||||
val text = frame.readText()
|
||||
if (!text.isJson()) {
|
||||
session.send("数据必须为Json格式")
|
||||
session.close(CloseReason(CloseReason.Codes.NORMAL, "调试结束"))
|
||||
return@consumeEach
|
||||
break
|
||||
}
|
||||
val debugBean = GSON.fromJsonObject<Map<String, String>>(text).getOrNull()
|
||||
if (debugBean != null) {
|
||||
@@ -36,7 +35,7 @@ class BookSourceDebugWebSocket(private val session: DefaultWebSocketServerSessio
|
||||
if (tag.isNullOrBlank() || key.isNullOrBlank()) {
|
||||
session.send(appCtx.getString(R.string.cannot_empty))
|
||||
session.close(CloseReason(CloseReason.Codes.NORMAL, "调试结束"))
|
||||
return@consumeEach
|
||||
break
|
||||
}
|
||||
appDb.bookSourceDao.getBookSource(tag)?.let {
|
||||
Debug.callback = this@BookSourceDebugWebSocket
|
||||
@@ -45,7 +44,7 @@ class BookSourceDebugWebSocket(private val session: DefaultWebSocketServerSessio
|
||||
} else {
|
||||
session.send("数据必须为Json格式")
|
||||
session.close(CloseReason(CloseReason.Codes.NORMAL, "调试结束"))
|
||||
return@consumeEach
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import io.legado.app.data.appDb
|
||||
import io.legado.app.model.Debug
|
||||
import io.legado.app.utils.*
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.consumeEach
|
||||
import splitties.init.appCtx
|
||||
|
||||
/**
|
||||
@@ -21,13 +20,13 @@ class RssSourceDebugWebSocket(private val session: DefaultWebSocketServerSession
|
||||
|
||||
suspend fun handle() {
|
||||
try {
|
||||
session.incoming.consumeEach { frame ->
|
||||
for (frame in session.incoming) {
|
||||
if (frame is Frame.Text) {
|
||||
val text = frame.readText()
|
||||
if (!text.isJson()) {
|
||||
session.send("数据必须为Json格式")
|
||||
session.close(CloseReason(CloseReason.Codes.NORMAL, "调试结束"))
|
||||
return@consumeEach
|
||||
break
|
||||
}
|
||||
val debugBean = GSON.fromJsonObject<Map<String, String>>(text).getOrNull()
|
||||
if (debugBean != null) {
|
||||
@@ -35,7 +34,7 @@ class RssSourceDebugWebSocket(private val session: DefaultWebSocketServerSession
|
||||
if (tag.isNullOrBlank()) {
|
||||
session.send(appCtx.getString(R.string.cannot_empty))
|
||||
session.close(CloseReason(CloseReason.Codes.NORMAL, "调试结束"))
|
||||
return@consumeEach
|
||||
break
|
||||
}
|
||||
appDb.rssSourceDao.getByKey(tag)?.let {
|
||||
Debug.callback = this@RssSourceDebugWebSocket
|
||||
|
||||
Reference in New Issue
Block a user