pull/32/head
parent
235f12dd40
commit
59b68e45d4
@ -0,0 +1 @@ |
||||
# web服务 |
@ -0,0 +1,56 @@ |
||||
package io.legado.app.web.controller |
||||
|
||||
import io.legado.app.App |
||||
import io.legado.app.data.entities.Book |
||||
import io.legado.app.utils.GSON |
||||
import io.legado.app.utils.fromJsonObject |
||||
import io.legado.app.web.utils.ReturnData |
||||
|
||||
class BookshelfController { |
||||
|
||||
val bookshelf: ReturnData |
||||
get() { |
||||
val books = App.db.bookDao().allBooks |
||||
val returnData = ReturnData() |
||||
return if (books.isEmpty()) { |
||||
returnData.setErrorMsg("还没有添加小说") |
||||
} else returnData.setData(books) |
||||
} |
||||
|
||||
fun getChapterList(parameters: Map<String, List<String>>): ReturnData { |
||||
val strings = parameters["url"] |
||||
val returnData = ReturnData() |
||||
if (strings == null) { |
||||
return returnData.setErrorMsg("参数url不能为空,请指定书籍地址") |
||||
} |
||||
val chapterList = App.db.bookChapterDao().getChapterList(strings[0]) |
||||
return returnData.setData(chapterList) |
||||
} |
||||
|
||||
fun getBookContent(parameters: Map<String, List<String>>): ReturnData { |
||||
val strings = parameters["url"] |
||||
val returnData = ReturnData() |
||||
if (strings == null) { |
||||
return returnData.setErrorMsg("参数url不能为空,请指定内容地址") |
||||
} |
||||
val book = App.db.bookDao().getBook(strings[0]) |
||||
val chapter = App.db.bookChapterDao().getChapter(strings[0], strings[1].toInt()) |
||||
if (book == null || chapter == null) { |
||||
returnData.setErrorMsg("未找到") |
||||
} else { |
||||
|
||||
} |
||||
return returnData |
||||
} |
||||
|
||||
fun saveBook(postData: String): ReturnData { |
||||
val book = GSON.fromJsonObject<Book>(postData) |
||||
val returnData = ReturnData() |
||||
if (book != null) { |
||||
App.db.bookDao().insert(book) |
||||
return returnData.setData("") |
||||
} |
||||
return returnData.setErrorMsg("格式不对") |
||||
} |
||||
|
||||
} |
@ -0,0 +1,79 @@ |
||||
package io.legado.app.web.controller |
||||
|
||||
|
||||
import android.text.TextUtils |
||||
import io.legado.app.App |
||||
import io.legado.app.data.entities.BookSource |
||||
import io.legado.app.utils.GSON |
||||
import io.legado.app.utils.fromJsonArray |
||||
import io.legado.app.utils.fromJsonObject |
||||
import io.legado.app.web.utils.ReturnData |
||||
|
||||
class SourceController { |
||||
|
||||
val sources: ReturnData |
||||
get() { |
||||
val bookSources = App.db.bookSourceDao().all |
||||
val returnData = ReturnData() |
||||
return if (bookSources.isEmpty()) { |
||||
returnData.setErrorMsg("设备书源列表为空") |
||||
} else returnData.setData(bookSources) |
||||
} |
||||
|
||||
fun saveSource(postData: String): ReturnData { |
||||
val returnData = ReturnData() |
||||
try { |
||||
val bookSource = GSON.fromJsonObject<BookSource>(postData) |
||||
if (bookSource != null) { |
||||
if (TextUtils.isEmpty(bookSource.bookSourceName) || TextUtils.isEmpty(bookSource.bookSourceUrl)) { |
||||
returnData.setErrorMsg("书源名称和URL不能为空") |
||||
} else { |
||||
App.db.bookSourceDao().insert(bookSource) |
||||
returnData.setData("") |
||||
} |
||||
} else { |
||||
returnData.setErrorMsg("转换书源失败") |
||||
} |
||||
} catch (e: Exception) { |
||||
returnData.setErrorMsg(e.localizedMessage) |
||||
} |
||||
return returnData |
||||
} |
||||
|
||||
fun saveSources(postData: String): ReturnData { |
||||
val okSources = arrayListOf<BookSource>() |
||||
kotlin.runCatching { |
||||
val bookSources = GSON.fromJsonArray<BookSource>(postData) |
||||
if (bookSources != null) { |
||||
for (bookSource in bookSources) { |
||||
if (bookSource.bookSourceName.isBlank() || bookSource.bookSourceUrl.isBlank()) { |
||||
continue |
||||
} |
||||
App.db.bookSourceDao().insert(bookSource) |
||||
okSources.add(bookSource) |
||||
} |
||||
} |
||||
} |
||||
return ReturnData().setData(okSources) |
||||
} |
||||
|
||||
fun getSource(parameters: Map<String, List<String>>): ReturnData { |
||||
val strings = parameters["url"] |
||||
val returnData = ReturnData() |
||||
if (strings == null) { |
||||
return returnData.setErrorMsg("参数url不能为空,请指定书源地址") |
||||
} |
||||
val bookSource = App.db.bookSourceDao().getBookSource(strings[0]) |
||||
?: return returnData.setErrorMsg("未找到书源,请检查书源地址") |
||||
return returnData.setData(bookSource) |
||||
} |
||||
|
||||
fun deleteSources(postData: String): ReturnData { |
||||
kotlin.runCatching { |
||||
GSON.fromJsonArray<BookSource>(postData)?.let { |
||||
App.db.bookSourceDao().delete(*it.toTypedArray()) |
||||
} |
||||
} |
||||
return ReturnData().setData("已执行"/*okSources*/) |
||||
} |
||||
} |
@ -0,0 +1,82 @@ |
||||
package io.legado.app.web.controller |
||||
|
||||
|
||||
import fi.iki.elonen.NanoHTTPD |
||||
import fi.iki.elonen.NanoWSD |
||||
import io.legado.app.App |
||||
import io.legado.app.R |
||||
import io.legado.app.model.WebBook |
||||
import io.legado.app.model.webbook.SourceDebug |
||||
import io.legado.app.utils.GSON |
||||
import io.legado.app.utils.fromJsonObject |
||||
import io.legado.app.utils.isJson |
||||
import kotlinx.coroutines.* |
||||
import kotlinx.coroutines.Dispatchers.IO |
||||
import java.io.IOException |
||||
|
||||
|
||||
class SourceDebugWebSocket(handshakeRequest: NanoHTTPD.IHTTPSession) : |
||||
NanoWSD.WebSocket(handshakeRequest), |
||||
CoroutineScope by MainScope(), |
||||
SourceDebug.Callback { |
||||
|
||||
|
||||
override fun onOpen() { |
||||
launch(IO) { |
||||
do { |
||||
delay(30000) |
||||
runCatching { |
||||
ping(byteArrayOf("ping".toByte())) |
||||
} |
||||
} while (isOpen) |
||||
} |
||||
} |
||||
|
||||
override fun onClose( |
||||
code: NanoWSD.WebSocketFrame.CloseCode, |
||||
reason: String, |
||||
initiatedByRemote: Boolean |
||||
) { |
||||
cancel() |
||||
SourceDebug.cancelDebug(true) |
||||
} |
||||
|
||||
override fun onMessage(message: NanoWSD.WebSocketFrame) { |
||||
if (!message.textPayload.isJson()) return |
||||
kotlin.runCatching { |
||||
val debugBean = GSON.fromJsonObject<Map<String, String>>(message.textPayload) |
||||
if (debugBean != null) { |
||||
val tag = debugBean["tag"] |
||||
val key = debugBean["key"] |
||||
if (tag.isNullOrBlank() || key.isNullOrBlank()) { |
||||
kotlin.runCatching { |
||||
send(App.INSTANCE.getString(R.string.cannot_empty)) |
||||
close(NanoWSD.WebSocketFrame.CloseCode.NormalClosure, "调试结束", false) |
||||
} |
||||
return |
||||
} |
||||
App.db.bookSourceDao().getBookSource(tag)?.let { |
||||
SourceDebug(WebBook(it), this).startDebug(key) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
override fun onPong(pong: NanoWSD.WebSocketFrame) { |
||||
|
||||
} |
||||
|
||||
override fun onException(exception: IOException) { |
||||
SourceDebug.cancelDebug(true) |
||||
} |
||||
|
||||
override fun printLog(state: Int, msg: String) { |
||||
kotlin.runCatching { |
||||
send(msg) |
||||
if (state == -1 || state == 1000) { |
||||
SourceDebug.cancelDebug(true) |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,44 @@ |
||||
package io.legado.app.web.utils |
||||
|
||||
import android.content.res.AssetManager |
||||
import android.text.TextUtils |
||||
import fi.iki.elonen.NanoHTTPD |
||||
import io.legado.app.App |
||||
import java.io.File |
||||
import java.io.IOException |
||||
|
||||
|
||||
class AssetsWeb(rootPath: String) { |
||||
private val assetManager: AssetManager = App.INSTANCE.assets |
||||
private var rootPath = "web" |
||||
|
||||
init { |
||||
if (!TextUtils.isEmpty(rootPath)) { |
||||
this.rootPath = rootPath |
||||
} |
||||
} |
||||
|
||||
@Throws(IOException::class) |
||||
fun getResponse(path: String): NanoHTTPD.Response { |
||||
var path1 = path |
||||
path1 = (rootPath + path1).replace("/+".toRegex(), File.separator) |
||||
val inputStream = assetManager.open(path1) |
||||
return NanoHTTPD.newChunkedResponse( |
||||
NanoHTTPD.Response.Status.OK, |
||||
getMimeType(path1), |
||||
inputStream |
||||
) |
||||
} |
||||
|
||||
private fun getMimeType(path: String): String { |
||||
val suffix = path.substring(path.lastIndexOf(".")) |
||||
return when { |
||||
suffix.equals(".html", ignoreCase = true) |
||||
|| suffix.equals(".htm", ignoreCase = true) -> "text/html" |
||||
suffix.equals(".js", ignoreCase = true) -> "text/javascript" |
||||
suffix.equals(".css", ignoreCase = true) -> "text/css" |
||||
suffix.equals(".ico", ignoreCase = true) -> "image/x-icon" |
||||
else -> "text/html" |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,39 @@ |
||||
package io.legado.app.web.utils |
||||
|
||||
|
||||
class ReturnData { |
||||
|
||||
var isSuccess: Boolean = false |
||||
|
||||
var errorCode: Int = 0 |
||||
|
||||
private var errorMsg: String? = null |
||||
|
||||
private var data: Any? = null |
||||
|
||||
init { |
||||
this.isSuccess = false |
||||
this.errorMsg = "未知错误,请联系开发者!" |
||||
} |
||||
|
||||
fun getErrorMsg(): String? { |
||||
return errorMsg |
||||
} |
||||
|
||||
fun setErrorMsg(errorMsg: String): ReturnData { |
||||
this.isSuccess = false |
||||
this.errorMsg = errorMsg |
||||
return this |
||||
} |
||||
|
||||
fun getData(): Any? { |
||||
return data |
||||
} |
||||
|
||||
fun setData(data: Any): ReturnData { |
||||
this.isSuccess = true |
||||
this.errorMsg = "" |
||||
this.data = data |
||||
return this |
||||
} |
||||
} |
Loading…
Reference in new issue