Merge pull request #4 from gedoor/master

sys code
pull/933/head
ag2s20150909 4 years ago committed by GitHub
commit 776f8a5183
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      app/src/main/assets/updateLog.md
  2. 2
      app/src/main/java/io/legado/app/constant/PreferKey.kt
  3. 2
      app/src/main/java/io/legado/app/data/dao/SearchBookDao.kt
  4. 14
      app/src/main/java/io/legado/app/help/AppConfig.kt
  5. 10
      app/src/main/java/io/legado/app/model/localBook/LocalBook.kt
  6. 2
      app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt
  7. 1
      app/src/main/java/io/legado/app/model/webBook/BookContent.kt
  8. 1
      app/src/main/java/io/legado/app/model/webBook/BookInfo.kt
  9. 1
      app/src/main/java/io/legado/app/model/webBook/BookList.kt
  10. 17
      app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt
  11. 10
      app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt
  12. 7
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceAdapter.kt
  13. 11
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceDialog.kt
  14. 31
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt
  15. 14
      app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugActivity.kt
  16. 15
      app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugModel.kt
  17. 22
      app/src/main/res/layout/item_change_source.xml
  18. 5
      app/src/main/res/menu/book_cache.xml
  19. 38
      app/src/main/res/menu/book_source_debug.xml
  20. 6
      app/src/main/res/menu/change_source.xml
  21. 19
      app/src/main/res/menu/source_debug.xml
  22. 2
      app/src/main/res/values-zh-rHK/strings.xml
  23. 2
      app/src/main/res/values-zh-rTW/strings.xml
  24. 2
      app/src/main/res/values-zh/strings.xml
  25. 2
      app/src/main/res/values/strings.xml

@ -3,6 +3,12 @@
* 关注合作公众号 **[小说拾遗]** 获取好看的小说。
* 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。
**2021/04/02**
* 修复bug
* 书源调试添加源码查看
* 添加导出epub by ag2s20150909
* 换源添加是否校验作者选项
**2021/03/31**
* 优化epubLib by ag2s20150909
* 升级库,修改弃用方法

@ -40,6 +40,8 @@ object PreferKey {
const val webDavPassword = "web_dav_password"
const val webDavCreateDir = "webDavCreateDir"
const val exportToWebDav = "webDavCacheBackup"
const val exportType = "exportType"
const val changeSourceCheckAuthor = "changeSourceCheckAuthor"
const val changeSourceLoadToc = "changeSourceLoadToc"
const val changeSourceLoadInfo = "changeSourceLoadInfo"
const val chineseConverterType = "chineseConverterType"

@ -27,7 +27,7 @@ interface SearchBookDao {
select t1.name, t1.author, t1.origin, t1.originName, t1.coverUrl, t1.bookUrl, t1.type, t1.time, t1.intro, t1.kind, t1.latestChapterTitle, t1.tocUrl, t1.variable, t1.wordCount, t2.customOrder as originOrder
from searchBooks as t1 inner join book_sources as t2
on t1.origin = t2.bookSourceUrl
where t1.name = :name and t1.author = :author and t2.enabled = 1 and t2.bookSourceGroup like '%'||:sourceGroup||'%'
where t1.name = :name and t1.author like '%'||:author||'%' and t2.enabled = 1 and t2.bookSourceGroup like '%'||:sourceGroup||'%'
order by t2.customOrder
"""
)

@ -161,6 +161,18 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
appCtx.putPrefBoolean(PreferKey.exportToWebDav, value)
}
var exportType: Int
get() = appCtx.getPrefInt(PreferKey.exportType)
set(value) {
appCtx.putPrefInt(PreferKey.exportType, value)
}
var changeSourceCheckAuthor: Boolean
get() = appCtx.getPrefBoolean(PreferKey.changeSourceCheckAuthor)
set(value) {
appCtx.putPrefBoolean(PreferKey.changeSourceCheckAuthor, value)
}
val autoChangeSource: Boolean
get() = appCtx.getPrefBoolean(PreferKey.autoChangeSource, true)
@ -176,7 +188,7 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
val mediaButtonOnExit get() = appCtx.getPrefBoolean("mediaButtonOnExit", true)
val replaceEnableDefault get() = appCtx.getPrefBoolean(PreferKey.replaceEnableDefault, true)
val replaceEnableDefault get() = appCtx.getPrefBoolean(PreferKey.replaceEnableDefault, true)
private fun getPrefUserAgent(): String {
val ua = appCtx.getPrefString(PreferKey.userAgent)

@ -72,6 +72,16 @@ object LocalBook {
if (smhStart != -1 && smhEnd != -1) {
name = (name.substring(smhStart + 1, smhEnd))
}
if (author == "" && fileName.contains(" by ")) {
val rstr = fileName.reversed()
// find last ' by ' near '.txt' or '.epub' using reversed string
val pattern = """^(txt|bupe)\.(.*) yb (.*)$""".toRegex()
val matches = pattern.findAll(input = rstr)
matches.forEach { matchResult ->
name = matchResult.groupValues[3].reversed()
author = matchResult.groupValues[2].reversed()
}
}
val book = Book(
bookUrl = path,
name = name,

@ -32,7 +32,7 @@ object BookChapterList {
appCtx.getString(R.string.error_get_web_content, baseUrl)
)
Debug.log(bookSource.bookSourceUrl, "≡获取成功:${baseUrl}")
Debug.log(bookSource.bookSourceUrl, body, state = 30)
val tocRule = bookSource.getTocRule()
val nextUrlList = arrayListOf(baseUrl)
var reverse = false

@ -33,6 +33,7 @@ object BookContent {
appCtx.getString(R.string.error_get_web_content, baseUrl)
)
Debug.log(bookSource.bookSourceUrl, "≡获取成功:${baseUrl}")
Debug.log(bookSource.bookSourceUrl, body, state = 40)
val mNextChapterUrl = if (!nextChapterUrl.isNullOrEmpty()) {
nextChapterUrl
} else {

@ -29,6 +29,7 @@ object BookInfo {
appCtx.getString(R.string.error_get_web_content, baseUrl)
)
Debug.log(bookSource.bookSourceUrl, "≡获取成功:${baseUrl}")
Debug.log(bookSource.bookSourceUrl, body, state = 20)
val analyzeRule = AnalyzeRule(book)
analyzeRule.setContent(body).setBaseUrl(baseUrl)
analyzeRule.setRedirectUrl(redirectUrl)

@ -36,6 +36,7 @@ object BookList {
)
)
Debug.log(bookSource.bookSourceUrl, "≡获取成功:${analyzeUrl.ruleUrl}")
Debug.log(bookSource.bookSourceUrl, body, state = 10)
val analyzeRule = AnalyzeRule(variableBook)
analyzeRule.setContent(body).setBaseUrl(baseUrl)
analyzeRule.setRedirectUrl(baseUrl)

@ -23,6 +23,7 @@ import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.help.AppConfig
import io.legado.app.help.BookHelp
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.dialogs.selector
import io.legado.app.service.help.CacheBook
import io.legado.app.ui.document.FilePicker
import io.legado.app.ui.document.FilePickerParam
@ -122,6 +123,7 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
R.id.menu_enable_replace -> AppConfig.exportUseReplace = !item.isChecked
R.id.menu_export_web_dav -> AppConfig.exportToWebDav = !item.isChecked
R.id.menu_export_folder -> export(-1)
R.id.menu_export_type -> showExportTypeConfig()
R.id.menu_export_charset -> showCharsetConfig()
R.id.menu_log ->
TextListDialog.show(supportFragmentManager, getString(R.string.log), CacheBook.logs)
@ -239,12 +241,23 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
adapter.getItem(exportPosition)?.let { book ->
Snackbar.make(binding.titleBar, R.string.exporting, Snackbar.LENGTH_INDEFINITE)
.show()
viewModel.exportEPUB(path, book) {
binding.titleBar.snackbar(it)
when (AppConfig.exportType) {
1 -> viewModel.exportEPUB(path, book) {
binding.titleBar.snackbar(it)
}
else -> viewModel.export(path, book) {
binding.titleBar.snackbar(it)
}
}
}
}
private fun showExportTypeConfig() {
selector(R.string.export_type, arrayListOf("txt", "epub")) { _, i ->
AppConfig.exportType = i
}
}
private fun showCharsetConfig() {
alert(R.string.set_charset) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {

@ -106,7 +106,7 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
}
}
private suspend fun getAllContents(book: Book, append: (text: String) -> Unit) {
private fun getAllContents(book: Book, append: (text: String) -> Unit) {
val useReplace = AppConfig.exportUseReplace
val contentProcessor = ContentProcessor(book.name, book.origin)
append("${book.name}\n${context.getString(R.string.author_show, book.author)}")
@ -159,13 +159,13 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
}
@Suppress("BlockingMethodInNonBlockingContext")
private suspend fun exportEpub(doc: DocumentFile, book: Book) {
private fun exportEpub(doc: DocumentFile, book: Book) {
val filename = "${book.name} by ${book.author}.epub"
DocumentUtils.delete(doc, filename)
val epubBook = EpubBook()
epubBook.version = "2.0"
//set metadata
setEpubMetadata(book,epubBook)
setEpubMetadata(book, epubBook)
//set cover
setCover(book, epubBook)
@ -187,12 +187,12 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
}
}
private suspend fun exportEpub(file: File, book: Book) {
private fun exportEpub(file: File, book: Book) {
val filename = "${book.name} by ${book.author}.epub"
val epubBook = EpubBook()
epubBook.version = "2.0"
//set metadata
setEpubMetadata(book,epubBook)
setEpubMetadata(book, epubBook)
//set cover
setCover(book, epubBook)

@ -16,7 +16,11 @@ import io.legado.app.utils.visible
import splitties.views.onLongClick
class ChangeSourceAdapter(context: Context, val callBack: CallBack) :
class ChangeSourceAdapter(
context: Context,
val viewModel: ChangeSourceViewModel,
val callBack: CallBack
) :
DiffRecyclerAdapter<SearchBook, ItemChangeSourceBinding>(context) {
override val diffItemCallback: DiffUtil.ItemCallback<SearchBook>
@ -46,6 +50,7 @@ class ChangeSourceAdapter(context: Context, val callBack: CallBack) :
binding.apply {
if (bundle == null) {
tvOrigin.text = item.originName
tvAuthor.text = item.author
tvLast.text = item.getDisplayLastChapterTitle()
if (callBack.bookUrl == item.bookUrl) {
ivChecked.visible()

@ -77,13 +77,15 @@ class ChangeSourceDialog : BaseDialogFragment(),
private fun showTitle() {
binding.toolBar.title = viewModel.name
binding.toolBar.subtitle = getString(R.string.author_show, viewModel.author)
binding.toolBar.subtitle = viewModel.author
}
private fun initMenu() {
binding.toolBar.inflateMenu(R.menu.change_source)
binding.toolBar.menu.applyTint(requireContext())
binding.toolBar.setOnMenuItemClickListener(this)
binding.toolBar.menu.findItem(R.id.menu_check_author)
?.isChecked = AppConfig.changeSourceCheckAuthor
binding.toolBar.menu.findItem(R.id.menu_load_info)
?.isChecked = AppConfig.changeSourceLoadInfo
binding.toolBar.menu.findItem(R.id.menu_load_toc)
@ -91,7 +93,7 @@ class ChangeSourceDialog : BaseDialogFragment(),
}
private fun initRecyclerView() {
adapter = ChangeSourceAdapter(requireContext(), this)
adapter = ChangeSourceAdapter(requireContext(), viewModel, this)
binding.recyclerView.layoutManager = LinearLayoutManager(context)
binding.recyclerView.addItemDecoration(VerticalDivider(requireContext()))
binding.recyclerView.adapter = adapter
@ -160,6 +162,11 @@ class ChangeSourceDialog : BaseDialogFragment(),
override fun onMenuItemClick(item: MenuItem?): Boolean {
when (item?.itemId) {
R.id.menu_check_author -> {
AppConfig.changeSourceCheckAuthor = !item.isChecked
item.isChecked = !item.isChecked
viewModel.loadDbSearchBook()
}
R.id.menu_load_toc -> {
putPrefBoolean(PreferKey.changeSourceLoadToc, !item.isChecked)
item.isChecked = !item.isChecked

@ -63,12 +63,15 @@ class ChangeSourceViewModel(application: Application) : BaseViewModel(applicatio
execute {
searchBooks.clear()
upAdapter()
appDb.searchBookDao.getChangeSourceSearch(name, author, searchGroup).let {
searchBooks.addAll(it)
searchBooksLiveData.postValue(searchBooks.toList())
if (it.size <= 1) {
startSearch()
}
val sbs = if (AppConfig.changeSourceCheckAuthor) {
appDb.searchBookDao.getChangeSourceSearch(name, author, searchGroup)
} else {
appDb.searchBookDao.getChangeSourceSearch(name, "", searchGroup)
}
searchBooks.addAll(sbs)
searchBooksLiveData.postValue(searchBooks.toList())
if (sbs.size <= 1) {
startSearch()
}
}
}
@ -130,15 +133,19 @@ class ChangeSourceViewModel(application: Application) : BaseViewModel(applicatio
.timeout(60000L)
.onSuccess(IO) {
it.forEach { searchBook ->
if (searchBook.name == name && searchBook.author == author) {
if (searchBook.latestChapterTitle.isNullOrEmpty()) {
if (AppConfig.changeSourceLoadInfo || AppConfig.changeSourceLoadToc) {
loadBookInfo(webBook, searchBook.toBook())
if (searchBook.name == name) {
if ((AppConfig.changeSourceCheckAuthor && searchBook.author.contains(author))
|| !AppConfig.changeSourceCheckAuthor
) {
if (searchBook.latestChapterTitle.isNullOrEmpty()) {
if (AppConfig.changeSourceLoadInfo || AppConfig.changeSourceLoadToc) {
loadBookInfo(webBook, searchBook.toBook())
} else {
searchFinish(searchBook)
}
} else {
searchFinish(searchBook)
}
} else {
searchFinish(searchBook)
}
}
}

@ -90,15 +90,21 @@ class BookSourceDebugActivity : VMBaseActivity<ActivitySourceDebugBinding, BookS
}
override fun onCompatCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.source_debug, menu)
menuInflater.inflate(R.menu.book_source_debug, menu)
return super.onCompatCreateOptionsMenu(menu)
}
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.menu_scan -> {
qrCodeResult.launch(null)
}
R.id.menu_scan -> qrCodeResult.launch(null)
R.id.menu_search_src ->
TextDialog.show(supportFragmentManager, viewModel.searchSrc)
R.id.menu_book_src ->
TextDialog.show(supportFragmentManager, viewModel.bookSrc)
R.id.menu_toc_src ->
TextDialog.show(supportFragmentManager, viewModel.tocSrc)
R.id.menu_content_src ->
TextDialog.show(supportFragmentManager, viewModel.contentSrc)
R.id.menu_help -> showHelp()
}
return super.onCompatOptionsItemSelected(item)

@ -10,8 +10,11 @@ class BookSourceDebugModel(application: Application) : BaseViewModel(application
Debug.Callback {
private var webBook: WebBook? = null
private var callback: ((Int, String)-> Unit)? = null
private var callback: ((Int, String) -> Unit)? = null
var searchSrc: String? = null
var bookSrc: String? = null
var tocSrc: String? = null
var contentSrc: String? = null
fun init(sourceUrl: String?) {
sourceUrl?.let {
@ -39,7 +42,13 @@ class BookSourceDebugModel(application: Application) : BaseViewModel(application
}
override fun printLog(state: Int, msg: String) {
callback?.invoke(state, msg)
when (state) {
10 -> searchSrc = msg
20 -> bookSrc = msg
30 -> tocSrc = msg
40 -> contentSrc = msg
else -> callback?.invoke(state, msg)
}
}
override fun onCleared() {

@ -1,10 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="?android:attr/selectableItemBackground"
android:padding="10dp">
android:paddingLeft="10dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
tools:ignore="RtlHardcoded,RtlSymmetry">
<TextView
android:id="@+id/tv_origin"
@ -14,6 +18,16 @@
android:textColor="@color/primaryText"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/tv_author" />
<TextView
android:id="@+id/tv_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textColor="@color/secondaryText"
android:maxWidth="160dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toLeftOf="@+id/iv_checked" />
<TextView
@ -29,9 +43,9 @@
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_checked"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_margin="8dp"
android:layout_width="40dp"
android:layout_height="40dp"
android:padding="8dp"
android:src="@drawable/ic_check"
android:visibility="invisible"
app:tint="@color/primaryText"

@ -37,6 +37,11 @@
android:title="@string/export_folder"
app:showAsAction="never" />
<item
android:id="@+id/menu_export_type"
android:title="@string/export_type"
app:showAsAction="never" />
<item
android:id="@+id/menu_export_charset"
android:title="@string/export_charset"

@ -0,0 +1,38 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="AlwaysShowAction">
<item
android:id="@+id/menu_scan"
android:icon="@drawable/ic_scan"
android:title="@string/scan_qr_code"
app:showAsAction="always" />
<item
android:id="@+id/menu_search_src"
android:title="搜索源码"
app:showAsAction="never" />
<item
android:id="@+id/menu_book_src"
android:title="书籍源码"
app:showAsAction="never" />
<item
android:id="@+id/menu_toc_src"
android:title="目录源码"
app:showAsAction="never" />
<item
android:id="@+id/menu_content_src"
android:title="正文源码"
app:showAsAction="never" />
<item
android:id="@+id/menu_help"
android:title="@string/help"
app:showAsAction="never" />
</menu>

@ -23,6 +23,12 @@
android:title="@string/book_source_manage"
app:showAsAction="never" />
<item
android:id="@+id/menu_check_author"
android:title="@string/checkAuthor"
android:checkable="true"
app:showAsAction="never" />
<item
android:id="@+id/menu_load_info"
android:title="@string/load_info"

@ -1,19 +0,0 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="AlwaysShowAction">
<item
android:id="@+id/menu_scan"
android:icon="@drawable/ic_scan"
android:title="@string/scan_qr_code"
app:showAsAction="always" />
<item
android:id="@+id/menu_help"
android:icon="@drawable/ic_help"
android:title="@string/help"
app:showAsAction="always" />
</menu>

@ -811,5 +811,7 @@
<string name="use_zh_layout">使用自定义中文分行</string>
<string name="image_style">图片样式</string>
<string name="system_tts">系统TTS</string>
<string name="export_type">导出格式</string>
<string name="checkAuthor">校验作者</string>
</resources>

@ -813,5 +813,7 @@
<string name="debug">调试</string>
<string name="image_style">图片样式</string>
<string name="system_tts">系统TTS</string>
<string name="export_type">导出格式</string>
<string name="checkAuthor">校验作者</string>
</resources>

@ -815,5 +815,7 @@
<string name="use_zh_layout">使用自定义中文分行</string>
<string name="image_style">图片样式</string>
<string name="system_tts">系统TTS</string>
<string name="export_type">导出格式</string>
<string name="checkAuthor">校验作者</string>
</resources>

@ -818,5 +818,7 @@
<string name="use_zh_layout">使用自定义中文分行</string>
<string name="image_style">Image style</string>
<string name="system_tts">System TTS</string>
<string name="export_type">导出格式</string>
<string name="checkAuthor">校验作者</string>
</resources>

Loading…
Cancel
Save