Merge remote-tracking branch 'origin/master'

# Conflicts:
#	app/src/main/java/io/legado/app/ui/sourcedebug/SourceDebugActivity.kt
pull/32/head
Administrator 5 years ago
commit c6f81ba7c4
  1. 2
      app/src/main/java/io/legado/app/help/storage/Restore.kt
  2. 2
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt
  3. 15
      app/src/main/java/io/legado/app/model/webbook/BookChapterList.kt
  4. 2
      app/src/main/java/io/legado/app/model/webbook/BookInfo.kt
  5. 41
      app/src/main/java/io/legado/app/model/webbook/SourceDebug.kt
  6. 18
      app/src/main/java/io/legado/app/ui/booksource/BookSourceActivity.kt
  7. 45
      app/src/main/java/io/legado/app/ui/sourcedebug/SourceDebugActivity.kt
  8. 11
      app/src/main/res/menu/source_debug.xml

@ -143,7 +143,7 @@ object Restore {
) )
source.ruleBookInfo = GSON.toJson(bookInfoRule) source.ruleBookInfo = GSON.toJson(bookInfoRule)
val chapterRule = TocRule( val chapterRule = TocRule(
chapterList = jsonItem.readString("ruleChapterUrlNext"), chapterList = jsonItem.readString("ruleChapterList"),
chapterName = jsonItem.readString("ruleChapterName"), chapterName = jsonItem.readString("ruleChapterName"),
chapterUrl = jsonItem.readString("ruleContentUrl"), chapterUrl = jsonItem.readString("ruleContentUrl"),
nextTocUrl = jsonItem.readString("ruleChapterUrlNext") nextTocUrl = jsonItem.readString("ruleChapterUrlNext")

@ -195,7 +195,7 @@ class AnalyzeRule(private var book: BaseBook? = null) {
Mode.Js -> result = evalJS(rule.rule, it) Mode.Js -> result = evalJS(rule.rule, it)
Mode.Json -> result = getAnalyzeByJSonPath(it).getString(rule.rule) Mode.Json -> result = getAnalyzeByJSonPath(it).getString(rule.rule)
Mode.XPath -> result = getAnalyzeByXPath(it).getString(rule.rule) Mode.XPath -> result = getAnalyzeByXPath(it).getString(rule.rule)
Mode.Default -> result = if (isUrl && !TextUtils.isEmpty(baseUrl)) { Mode.Default -> result = if (isUrl) {
getAnalyzeByJSoup(it).getString0(rule.rule) getAnalyzeByJSoup(it).getString0(rule.rule)
} else { } else {
getAnalyzeByJSoup(it).getString(rule.rule) getAnalyzeByJSoup(it).getString(rule.rule)

@ -23,7 +23,7 @@ object BookChapterList {
bookSource: BookSource, bookSource: BookSource,
analyzeUrl: AnalyzeUrl analyzeUrl: AnalyzeUrl
): List<BookChapter> { ): List<BookChapter> {
val chapterList = arrayListOf<BookChapter>() var chapterList = arrayListOf<BookChapter>()
val baseUrl: String = NetworkUtils.getUrl(response) val baseUrl: String = NetworkUtils.getUrl(response)
val body: String? = response.body() val body: String? = response.body()
body ?: throw Exception( body ?: throw Exception(
@ -58,7 +58,6 @@ object BookChapterList {
} }
} }
} }
if (reverse) chapterList.reverse()
} else if (chapterData.nextUrl.size > 1) { } else if (chapterData.nextUrl.size > 1) {
val chapterDataList = arrayListOf<ChapterData<String>>() val chapterDataList = arrayListOf<ChapterData<String>>()
for (item in chapterData.nextUrl) { for (item in chapterData.nextUrl) {
@ -85,8 +84,14 @@ object BookChapterList {
chapterList.addAll(it) chapterList.addAll(it)
} }
} }
if (reverse) chapterList.reverse()
} }
//去重
if (!reverse) {
chapterList.reverse()
}
val lh = LinkedHashSet(chapterList)
chapterList = ArrayList(lh)
chapterList.reverse()
return chapterList return chapterList
} }
@ -116,8 +121,11 @@ object BookChapterList {
} }
SourceDebug.printLog(bookSource.bookSourceUrl, 1, TextUtils.join(",", nextUrlList), printLog) SourceDebug.printLog(bookSource.bookSourceUrl, 1, TextUtils.join(",", nextUrlList), printLog)
} }
SourceDebug.printLog(bookSource.bookSourceUrl, 1, "解析目录列表", printLog)
val elements = analyzeRule.getElements(listRule) val elements = analyzeRule.getElements(listRule)
SourceDebug.printLog(bookSource.bookSourceUrl, 1, "目录数${elements.size}", printLog)
if (elements.isNotEmpty()) { if (elements.isNotEmpty()) {
SourceDebug.printLog(bookSource.bookSourceUrl, 1, "获取目录", printLog)
val nameRule = analyzeRule.splitSourceRule(tocRule.chapterName ?: "") val nameRule = analyzeRule.splitSourceRule(tocRule.chapterName ?: "")
val urlRule = analyzeRule.splitSourceRule(tocRule.chapterUrl ?: "") val urlRule = analyzeRule.splitSourceRule(tocRule.chapterUrl ?: "")
for (item in elements) { for (item in elements) {
@ -131,6 +139,7 @@ object BookChapterList {
chapterList.add(bookChapter) chapterList.add(bookChapter)
} }
} }
SourceDebug.printLog(bookSource.bookSourceUrl, 1, "${chapterList[0].title}${chapterList[0].url}", printLog)
} }
return ChapterData(chapterList, nextUrlList) return ChapterData(chapterList, nextUrlList)
} }

@ -26,7 +26,7 @@ object BookInfo {
SourceDebug.printLog(bookSource.bookSourceUrl, 1, "获取成功:$baseUrl") SourceDebug.printLog(bookSource.bookSourceUrl, 1, "获取成功:$baseUrl")
val infoRule = bookSource.getBookInfoRule() val infoRule = bookSource.getBookInfoRule()
val analyzeRule = AnalyzeRule(book) val analyzeRule = AnalyzeRule(book)
analyzeRule.setContent(body) analyzeRule.setContent(body, baseUrl)
infoRule.init?.let { infoRule.init?.let {
if (it.isNotEmpty()) { if (it.isNotEmpty()) {
SourceDebug.printLog(bookSource.bookSourceUrl, 1, "执行详情页初始化规则") SourceDebug.printLog(bookSource.bookSourceUrl, 1, "执行详情页初始化规则")

@ -20,16 +20,25 @@ class SourceDebug(private val webBook: WebBook, callback: Callback) {
@SuppressLint("ConstantLocale") @SuppressLint("ConstantLocale")
private val DEBUG_TIME_FORMAT = SimpleDateFormat("[mm:ss.SSS]", Locale.getDefault()) private val DEBUG_TIME_FORMAT = SimpleDateFormat("[mm:ss.SSS]", Locale.getDefault())
private val startTime: Long = System.currentTimeMillis() private var startTime: Long = System.currentTimeMillis()
fun printLog(sourceUrl: String?, state: Int, msg: String, print: Boolean = true, isHtml: Boolean = false) { @Synchronized
fun printLog(
sourceUrl: String?,
state: Int,
msg: String,
print: Boolean = true,
isHtml: Boolean = false,
showTime: Boolean = true
) {
if (debugSource != sourceUrl || callback == null || !print) return if (debugSource != sourceUrl || callback == null || !print) return
var printMsg = msg var printMsg = msg
if (isHtml) { if (isHtml) {
printMsg = printMsg.htmlFormat() printMsg = printMsg.htmlFormat()
} }
printMsg = if (showTime) {
String.format("%s %s", DEBUG_TIME_FORMAT.format(Date(System.currentTimeMillis() - startTime)), printMsg) printMsg = "${DEBUG_TIME_FORMAT.format(Date(System.currentTimeMillis() - startTime))} $printMsg"
}
callback?.printLog(state, printMsg) callback?.printLog(state, printMsg)
} }
@ -51,6 +60,7 @@ class SourceDebug(private val webBook: WebBook, callback: Callback) {
fun startDebug(key: String) { fun startDebug(key: String) {
cancelDebug() cancelDebug()
startTime = System.currentTimeMillis()
with(webBook) { with(webBook) {
if (key.isAbsUrl()) { if (key.isAbsUrl()) {
val book = Book() val book = Book()
@ -70,8 +80,11 @@ class SourceDebug(private val webBook: WebBook, callback: Callback) {
.onSuccess { searchBooks -> .onSuccess { searchBooks ->
searchBooks?.let { searchBooks?.let {
if (searchBooks.isNotEmpty()) { if (searchBooks.isNotEmpty()) {
callback?.printLog(1, "") printLog(debugSource, 1, "搜索完成")
printLog(debugSource, 1, "", showTime = false)
infoDebug(BookHelp.toBook(searchBooks[0])) infoDebug(BookHelp.toBook(searchBooks[0]))
} else {
printLog(debugSource, -1, "未获取到书籍")
} }
} }
} }
@ -85,7 +98,8 @@ class SourceDebug(private val webBook: WebBook, callback: Callback) {
printLog(debugSource, 1, "开始获取详情页") printLog(debugSource, 1, "开始获取详情页")
val info = webBook.getBookInfo(book) val info = webBook.getBookInfo(book)
.onSuccess { .onSuccess {
callback?.printLog(1, "") printLog(debugSource, 1, "详情页完成")
printLog(debugSource, 1, "", showTime = false)
tocDebug(book) tocDebug(book)
} }
.onError { .onError {
@ -100,8 +114,11 @@ class SourceDebug(private val webBook: WebBook, callback: Callback) {
.onSuccess { chapterList -> .onSuccess { chapterList ->
chapterList?.let { chapterList?.let {
if (it.isNotEmpty()) { if (it.isNotEmpty()) {
callback?.printLog(1, "") printLog(debugSource, 1, "目录完成")
printLog(debugSource, 1, "", showTime = false)
contentDebug(book, it[0]) contentDebug(book, it[0])
} else {
printLog(debugSource, -1, "目录列表为空")
} }
} }
} }
@ -129,14 +146,4 @@ class SourceDebug(private val webBook: WebBook, callback: Callback) {
fun printLog(state: Int, msg: String) fun printLog(state: Int, msg: String)
} }
fun printLog(
sourceUrl: String?,
state: Int,
msg: String,
print: Boolean = true,
isHtml: Boolean = false
): SourceDebug {
SourceDebug.printLog(sourceUrl, state, msg, print, isHtml)
return this
}
} }

@ -1,5 +1,6 @@
package io.legado.app.ui.booksource package io.legado.app.ui.booksource
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
@ -27,6 +28,7 @@ import kotlinx.android.synthetic.main.view_title_bar.*
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.jetbrains.anko.startActivity import org.jetbrains.anko.startActivity
import org.jetbrains.anko.startActivityForResult
class BookSourceActivity : VMBaseActivity<BookshelfViewModel>(R.layout.activity_book_source), class BookSourceActivity : VMBaseActivity<BookshelfViewModel>(R.layout.activity_book_source),
BookSourceAdapter.CallBack, BookSourceAdapter.CallBack,
@ -36,6 +38,7 @@ class BookSourceActivity : VMBaseActivity<BookshelfViewModel>(R.layout.activity_
private lateinit var adapter: BookSourceAdapter private lateinit var adapter: BookSourceAdapter
private var bookSourceLiveDate: LiveData<PagedList<BookSource>>? = null private var bookSourceLiveDate: LiveData<PagedList<BookSource>>? = null
private val qrRequestCode = 101
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
@ -55,7 +58,7 @@ class BookSourceActivity : VMBaseActivity<BookshelfViewModel>(R.layout.activity_
this.startActivity<SourceEditActivity>() this.startActivity<SourceEditActivity>()
} }
R.id.action_import_book_source_qr -> { R.id.action_import_book_source_qr -> {
this.startActivity<QrCodeActivity>() this.startActivityForResult<QrCodeActivity>(qrRequestCode)
} }
R.id.action_select_all -> { R.id.action_select_all -> {
launch(IO) { launch(IO) {
@ -135,4 +138,17 @@ class BookSourceActivity : VMBaseActivity<BookshelfViewModel>(R.layout.activity_
override fun edit(bookSource: BookSource) { override fun edit(bookSource: BookSource) {
startActivity<SourceEditActivity>(Pair("data", bookSource.bookSourceUrl)) startActivity<SourceEditActivity>(Pair("data", bookSource.bookSourceUrl))
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
qrRequestCode -> {
if (resultCode == RESULT_OK) {
data?.getStringExtra("result")?.let {
}
}
}
}
}
} }

@ -1,20 +1,22 @@
package io.legado.app.ui.sourcedebug package io.legado.app.ui.sourcedebug
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View import android.view.View
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
import io.legado.app.constant.Bus
import io.legado.app.help.EventMessage
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.ThemeStore
import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.accentColor
import io.legado.app.ui.qrcode.QrCodeActivity
import io.legado.app.utils.getViewModel import io.legado.app.utils.getViewModel
import io.legado.app.utils.observeEvent import io.legado.app.utils.hideSoftInput
import kotlinx.android.synthetic.main.activity_source_debug.* import kotlinx.android.synthetic.main.activity_source_debug.*
import kotlinx.android.synthetic.main.view_title_bar.* import kotlinx.android.synthetic.main.view_title_bar.*
import org.jetbrains.anko.startActivityForResult
import org.jetbrains.anko.toast import org.jetbrains.anko.toast
class SourceDebugActivity : VMBaseActivity<SourceDebugModel>(R.layout.activity_source_debug) { class SourceDebugActivity : VMBaseActivity<SourceDebugModel>(R.layout.activity_source_debug) {
@ -23,17 +25,12 @@ class SourceDebugActivity : VMBaseActivity<SourceDebugModel>(R.layout.activity_s
get() = getViewModel(SourceDebugModel::class.java) get() = getViewModel(SourceDebugModel::class.java)
private lateinit var adapter: SourceDebugAdapter private lateinit var adapter: SourceDebugAdapter
private val qrRequestCode = 101
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
viewModel.init(intent.getStringExtra("key")) viewModel.init(intent.getStringExtra("key"))
initRecyclerView() initRecyclerView()
initSearchView() initSearchView()
viewModel.observe{state, msg->
adapter.addItem(msg)
if (state == -1 || state == 1000) {
rotate_loading.hide()
}
}
} }
private fun initRecyclerView() { private fun initRecyclerView() {
@ -52,6 +49,7 @@ class SourceDebugActivity : VMBaseActivity<SourceDebugModel>(R.layout.activity_s
search_view.clearFocus() search_view.clearFocus()
search_view.setOnQueryTextListener(object : SearchView.OnQueryTextListener { search_view.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean { override fun onQueryTextSubmit(query: String?): Boolean {
search_view.hideSoftInput()
startSearch(query ?: "我的") startSearch(query ?: "我的")
return true return true
} }
@ -70,4 +68,31 @@ class SourceDebugActivity : VMBaseActivity<SourceDebugModel>(R.layout.activity_s
toast("未获取到书源") toast("未获取到书源")
}) })
} }
override fun onCompatCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.source_debug, menu)
return super.onCompatCreateOptionsMenu(menu)
}
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_scan -> {
startActivityForResult<QrCodeActivity>(qrRequestCode)
}
}
return super.onCompatOptionsItemSelected(item)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
qrRequestCode -> {
if (resultCode == RESULT_OK) {
data?.getStringExtra("result")?.let {
startSearch(it)
}
}
}
}
}
} }

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_scan"
android:icon="@drawable/ic_scan"
android:title="@string/scan_qr_code"
app:showAsAction="ifRoom" />
</menu>
Loading…
Cancel
Save