From 250be1675a92c740766901258f03b6182e3b20bb Mon Sep 17 00:00:00 2001 From: Xwite <82232510+Xwite@users.noreply.github.com> Date: Mon, 27 Mar 2023 08:43:57 +0800 Subject: [PATCH 1/4] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E5=9C=A8=E7=BA=BF=E4=B9=A6=E7=B1=8Dapi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/api.md b/api.md index a6eea3ca3..3060d9b25 100644 --- a/api.md +++ b/api.md @@ -99,9 +99,8 @@ Body = { rule: [ReplaceRule], text: [String] } #### 搜索在线书籍 ``` -URL = http://127.0.0.1:1234/searchBook -Method = POST -Body = { key: [String], page: [Number] } +URL = ws://127.0.0.1:1234/searchBook +Message = { key: [String] } ``` #### 插入书籍 From 2eaa295ad69bd7d24e0b595725f46d6a4ae7cf83 Mon Sep 17 00:00:00 2001 From: Xwite <1797350009@qq.com> Date: Mon, 27 Mar 2023 09:23:48 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E4=B9=A6=E7=B1=8D=E6=B7=BB=E5=8A=A0=E4=B9=A6=E7=B1=8Dapi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/api/controller/BookController.kt | 2 +- .../main/java/io/legado/app/web/HttpServer.kt | 9 +- .../java/io/legado/app/web/WebSocketServer.kt | 3 + .../app/web/socket/BookSearchWebSocket.kt | 92 +++++++++++++++++++ 4 files changed, 99 insertions(+), 7 deletions(-) create mode 100644 app/src/main/java/io/legado/app/web/socket/BookSearchWebSocket.kt diff --git a/app/src/main/java/io/legado/app/api/controller/BookController.kt b/app/src/main/java/io/legado/app/api/controller/BookController.kt index a1244208e..38bcd35ed 100644 --- a/app/src/main/java/io/legado/app/api/controller/BookController.kt +++ b/app/src/main/java/io/legado/app/api/controller/BookController.kt @@ -200,7 +200,7 @@ object BookController { fun saveBook(postData: String?): ReturnData { val returnData = ReturnData() GSON.fromJsonObject(postData).getOrNull()?.let { book -> - appDb.bookDao.update(book) + appDb.bookDao.insert(book) AppWebDav.uploadBookProgress(book) return returnData.setData("") } diff --git a/app/src/main/java/io/legado/app/web/HttpServer.kt b/app/src/main/java/io/legado/app/web/HttpServer.kt index 71b915410..b5f4183c4 100644 --- a/app/src/main/java/io/legado/app/web/HttpServer.kt +++ b/app/src/main/java/io/legado/app/web/HttpServer.kt @@ -1,7 +1,6 @@ package io.legado.app.web import android.graphics.Bitmap -import com.google.gson.Gson import fi.iki.elonen.NanoHTTPD import io.legado.app.api.ReturnData import io.legado.app.api.controller.BookController @@ -9,13 +8,11 @@ import io.legado.app.api.controller.BookSourceController import io.legado.app.api.controller.ReplaceRuleController import io.legado.app.api.controller.RssSourceController import io.legado.app.service.WebService -import io.legado.app.utils.FileUtils -import io.legado.app.utils.externalFiles +import io.legado.app.utils.* import io.legado.app.web.utils.AssetsWeb import splitties.init.appCtx import java.io.* - class HttpServer(port: Int) : NanoHTTPD(port) { private val assetsWeb = AssetsWeb("web") @@ -100,7 +97,7 @@ class HttpServer(port: Int) : NanoHTTPD(port) { ) } else { try { - newFixedLengthResponse(Gson().toJson(returnData)) + newFixedLengthResponse(GSON.toJson(returnData)) } catch (e: OutOfMemoryError) { val path = FileUtils.getPath( appCtx.externalFiles, @@ -109,7 +106,7 @@ class HttpServer(port: Int) : NanoHTTPD(port) { ) val file = FileUtils.createFileIfNotExist(path) BufferedWriter(FileWriter(file)).use { - Gson().toJson(returnData, it) + GSON.toJson(returnData, it) } val fis = FileInputStream(file) newFixedLengthResponse( diff --git a/app/src/main/java/io/legado/app/web/WebSocketServer.kt b/app/src/main/java/io/legado/app/web/WebSocketServer.kt index 3e95c2101..fd130ae34 100644 --- a/app/src/main/java/io/legado/app/web/WebSocketServer.kt +++ b/app/src/main/java/io/legado/app/web/WebSocketServer.kt @@ -16,6 +16,9 @@ class WebSocketServer(port: Int) : NanoWSD(port) { "/rssSourceDebug" -> { RssSourceDebugWebSocket(handshake) } + "/searchBook" -> { + BookSearchWebSocket(handshake) + } else -> null } } diff --git a/app/src/main/java/io/legado/app/web/socket/BookSearchWebSocket.kt b/app/src/main/java/io/legado/app/web/socket/BookSearchWebSocket.kt new file mode 100644 index 000000000..18e6b1e11 --- /dev/null +++ b/app/src/main/java/io/legado/app/web/socket/BookSearchWebSocket.kt @@ -0,0 +1,92 @@ +package io.legado.app.web.socket + +import fi.iki.elonen.NanoHTTPD +import fi.iki.elonen.NanoWSD +import io.legado.app.R +import io.legado.app.data.entities.SearchBook +import io.legado.app.help.config.AppConfig +import io.legado.app.model.webBook.SearchModel +import io.legado.app.ui.book.search.SearchScope +import io.legado.app.utils.* +import kotlinx.coroutines.* +import kotlinx.coroutines.Dispatchers.IO +import splitties.init.appCtx + +import java.io.IOException + +class BookSearchWebSocket(handshakeRequest: NanoHTTPD.IHTTPSession) : + NanoWSD.WebSocket(handshakeRequest), + CoroutineScope by MainScope(), + SearchModel.CallBack { + + private val normalClosure = NanoWSD.WebSocketFrame.CloseCode.NormalClosure + private val searchModel = SearchModel(this, this) + + private const val SEARCH_FINISH = "Search finish" + + override fun onOpen() { + launch(IO) { + kotlin.runCatching { + while (isOpen) { + ping("ping".toByteArray()) + delay(30000) + } + } + } + } + + override fun onClose( + code: NanoWSD.WebSocketFrame.CloseCode, + reason: String, + initiatedByRemote: Boolean + ) { + cancel() + searchModel.close() + } + + override fun onMessage(message: NanoWSD.WebSocketFrame) { + launch(IO) { + kotlin.runCatching { + if (!message.textPayload.isJson()) { + send("数据必须为Json格式") + close(normalClosure, SEARCH_FINISH, false) + return@launch + } + val searchMap = + GSON.fromJsonObject>(message.textPayload).getOrNull() + if (searchMap != null) { + val key = searchMap["key"] + if (key.isNullOrBlank()) { + send(appCtx.getString(R.string.cannot_empty)) + close(normalClosure, SEARCH_FINISH, false) + return@launch + } + viewModel.search(System.currentTimeMillis(), key) + } + } + } + } + + override fun onPong(pong: NanoWSD.WebSocketFrame) { + + } + + override fun onException(exception: IOException) { + + } + + override fun getSearchScope(): SearchScope = SearchScope(AppConfig.searchScope) + + override fun onSearchStart() { + + } + + override fun onSearchSuccess(searchBooks: ArrayList) { + send(GSON.toJson(searchBooks)) + } + + override fun onSearchFinish(isEmpty: Boolean) = close(normalClosure, SEARCH_FINISH, false) + + override fun onSearchCancel(exception: Exception? = null) = close(normalClosure, exception?.toString() ?: SEARCH_FINISH, false) + +} From b10660f5b1757a1f541200bd201b133d1dd4a7e6 Mon Sep 17 00:00:00 2001 From: Xwite <1797350009@qq.com> Date: Mon, 27 Mar 2023 09:41:47 +0800 Subject: [PATCH 3/4] [skip ci]fix typo --- app/src/main/java/io/legado/app/web/WebSocketServer.kt | 3 +-- .../java/io/legado/app/web/socket/BookSearchWebSocket.kt | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/io/legado/app/web/WebSocketServer.kt b/app/src/main/java/io/legado/app/web/WebSocketServer.kt index fd130ae34..f2c7c27a0 100644 --- a/app/src/main/java/io/legado/app/web/WebSocketServer.kt +++ b/app/src/main/java/io/legado/app/web/WebSocketServer.kt @@ -2,8 +2,7 @@ package io.legado.app.web import fi.iki.elonen.NanoWSD import io.legado.app.service.WebService -import io.legado.app.web.socket.BookSourceDebugWebSocket -import io.legado.app.web.socket.RssSourceDebugWebSocket +import io.legado.app.web.socket.* class WebSocketServer(port: Int) : NanoWSD(port) { diff --git a/app/src/main/java/io/legado/app/web/socket/BookSearchWebSocket.kt b/app/src/main/java/io/legado/app/web/socket/BookSearchWebSocket.kt index 18e6b1e11..abb83af7f 100644 --- a/app/src/main/java/io/legado/app/web/socket/BookSearchWebSocket.kt +++ b/app/src/main/java/io/legado/app/web/socket/BookSearchWebSocket.kt @@ -22,7 +22,7 @@ class BookSearchWebSocket(handshakeRequest: NanoHTTPD.IHTTPSession) : private val normalClosure = NanoWSD.WebSocketFrame.CloseCode.NormalClosure private val searchModel = SearchModel(this, this) - private const val SEARCH_FINISH = "Search finish" + private val SEARCH_FINISH = "Search finish" override fun onOpen() { launch(IO) { @@ -61,7 +61,7 @@ class BookSearchWebSocket(handshakeRequest: NanoHTTPD.IHTTPSession) : close(normalClosure, SEARCH_FINISH, false) return@launch } - viewModel.search(System.currentTimeMillis(), key) + searchModel.search(System.currentTimeMillis(), key) } } } @@ -87,6 +87,6 @@ class BookSearchWebSocket(handshakeRequest: NanoHTTPD.IHTTPSession) : override fun onSearchFinish(isEmpty: Boolean) = close(normalClosure, SEARCH_FINISH, false) - override fun onSearchCancel(exception: Exception? = null) = close(normalClosure, exception?.toString() ?: SEARCH_FINISH, false) + override fun onSearchCancel(exception: Exception?) = close(normalClosure, exception?.toString() ?: SEARCH_FINISH, false) } From 316ac61e1713e5953c7430234cbb80b14a5c574c Mon Sep 17 00:00:00 2001 From: Xwite <82232510+Xwite@users.noreply.github.com> Date: Mon, 27 Mar 2023 09:47:54 +0800 Subject: [PATCH 4/4] Update api.md --- api.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/api.md b/api.md index 3060d9b25..fd92ca2fb 100644 --- a/api.md +++ b/api.md @@ -59,6 +59,16 @@ URL = http://127.0.0.1:1234/deleteRssSources Method = POST ``` +#### 调试源 + +key为书源搜索关键词,tag为源链接 + +``` +URL = ws://127.0.0.1:1235/bookSourceDebug +URL = ws://127.0.0.1:1235/rssSourceDebug +Message = { key: [String], tag: [String] } +``` + #### 获取替换规则 ``` @@ -99,7 +109,7 @@ Body = { rule: [ReplaceRule], text: [String] } #### 搜索在线书籍 ``` -URL = ws://127.0.0.1:1234/searchBook +URL = ws://127.0.0.1:1235/searchBook Message = { key: [String] } ```