pull/32/head
kunfei 5 years ago
parent 3a9478db8d
commit 30d5153ffc
  1. 4
      app/src/main/java/io/legado/app/data/dao/BookDao.kt
  2. 58
      app/src/main/java/io/legado/app/data/entities/Book.kt
  3. 2
      app/src/main/java/io/legado/app/data/entities/BookChapter.kt
  4. 26
      app/src/main/java/io/legado/app/data/entities/SearchBook.kt
  5. 8
      app/src/main/java/io/legado/app/help/storage/Restore.kt
  6. 5
      app/src/main/java/io/legado/app/model/webbook/BookList.kt
  7. 8
      app/src/main/java/io/legado/app/ui/bookshelf/BookshelfAdapter.kt
  8. 4
      app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfAdapter.kt

@ -24,13 +24,13 @@ interface BookDao {
@Query("SELECT * FROM books WHERE `group` = :group") @Query("SELECT * FROM books WHERE `group` = :group")
fun observeByGroup(group: Int): DataSource.Factory<Int, Book> fun observeByGroup(group: Int): DataSource.Factory<Int, Book>
@Query("SELECT descUrl FROM books WHERE `group` = :group") @Query("SELECT bookUrl FROM books WHERE `group` = :group")
fun observeUrlsByGroup(group: Int): LiveData<List<String>> fun observeUrlsByGroup(group: Int): LiveData<List<String>>
@Query("SELECT * FROM books WHERE `name` in (:names)") @Query("SELECT * FROM books WHERE `name` in (:names)")
fun findByName(vararg names: String): List<Book> fun findByName(vararg names: String): List<Book>
@get:Query("SELECT descUrl FROM books") @get:Query("SELECT bookUrl FROM books")
val allBookUrls: List<String> val allBookUrls: List<String>
@get:Query("SELECT COUNT(*) FROM books") @get:Query("SELECT COUNT(*) FROM books")

@ -13,36 +13,36 @@ import kotlinx.android.parcel.Parcelize
import kotlin.math.max import kotlin.math.max
@Parcelize @Parcelize
@Entity(tableName = "books", indices = [(Index(value = ["descUrl"], unique = true))]) @Entity(tableName = "books", indices = [(Index(value = ["bookUrl"], unique = true))])
data class Book( data class Book(
@PrimaryKey @PrimaryKey
var descUrl: String = "", // 详情页Url(本地书源存储完整文件路径) var bookUrl: String = "", // 详情页Url(本地书源存储完整文件路径)
var tocUrl: String = "", // 目录页Url (toc=table of Contents) var tocUrl: String = "", // 目录页Url (toc=table of Contents)
var origin: String = "", // 书源URL(默认BookType.local) var origin: String = "", // 书源URL(默认BookType.local)
var name: String? = null, // 书籍名称(书源获取) var name: String? = null, // 书籍名称(书源获取)
var author: String? = null, // 作者名称(书源获取) var author: String? = null, // 作者名称(书源获取)
var tag: String? = null, // 分类信息(书源获取) var tag: String? = null, // 分类信息(书源获取)
var customTag: String? = null, // 分类信息(用户修改) var customTag: String? = null, // 分类信息(用户修改)
var coverUrl: String? = null, // 封面Url(书源获取) var coverUrl: String? = null, // 封面Url(书源获取)
var customCoverUrl: String? = null, // 封面Url(用户修改) var customCoverUrl: String? = null, // 封面Url(用户修改)
var description: String? = null, // 简介内容(书源获取) var description: String? = null, // 简介内容(书源获取)
var customDescription: String? = null, // 简介内容(用户修改) var customDescription: String? = null, // 简介内容(用户修改)
var charset: String? = null, // 自定义字符集名称(仅适用于本地书籍) var charset: String? = null, // 自定义字符集名称(仅适用于本地书籍)
var type: Int = 0, // @BookType var type: Int = 0, // @BookType
var group: Int = 0, // 自定义分组索引号 var group: Int = 0, // 自定义分组索引号
var latestChapterTitle: String? = null, // 最新章节标题 var latestChapterTitle: String? = null, // 最新章节标题
var latestChapterTime: Long = 0, // 最新章节标题更新时间 var latestChapterTime: Long = 0, // 最新章节标题更新时间
var lastCheckTime: Long = 0, // 最近一次更新书籍信息的时间 var lastCheckTime: Long = 0, // 最近一次更新书籍信息的时间
var lastCheckCount: Int = 0, // 最近一次发现新章节的数量 var lastCheckCount: Int = 0, // 最近一次发现新章节的数量
var totalChapterNum: Int = 0, // 书籍目录总数 var totalChapterNum: Int = 0, // 书籍目录总数
var durChapterTitle: String? = null, // 当前章节名称 var durChapterTitle: String? = null, // 当前章节名称
var durChapterIndex: Int = 0, // 当前章节索引 var durChapterIndex: Int = 0, // 当前章节索引
var durChapterPos: Int = 0, // 当前阅读的进度(首行字符的索引位置) var durChapterPos: Int = 0, // 当前阅读的进度(首行字符的索引位置)
var durChapterTime: Long = 0, // 最近一次阅读书籍的时间(打开正文的时间) var durChapterTime: Long = 0, // 最近一次阅读书籍的时间(打开正文的时间)
var canUpdate: Boolean = true, // 刷新书架时更新书籍信息 var canUpdate: Boolean = true, // 刷新书架时更新书籍信息
var order: Int = 0, // 手动排序 var order: Int = 0, // 手动排序
var useReplaceRule: Boolean = true, // 正文使用净化替换规则 var useReplaceRule: Boolean = true, // 正文使用净化替换规则
var variable: String? = null // 自定义书籍变量信息(用于书源规则检索书籍信息) var variable: String? = null // 自定义书籍变量信息(用于书源规则检索书籍信息)
) : Parcelable, BaseBook { ) : Parcelable, BaseBook {
@IgnoredOnParcel @IgnoredOnParcel
@Ignore @Ignore

@ -14,7 +14,7 @@ import kotlinx.android.parcel.Parcelize
indices = [(Index(value = ["bookUrl"], unique = true)), (Index(value = ["bookUrl", "index"], unique = true))], indices = [(Index(value = ["bookUrl"], unique = true)), (Index(value = ["bookUrl", "index"], unique = true))],
foreignKeys = [(ForeignKey( foreignKeys = [(ForeignKey(
entity = Book::class, entity = Book::class,
parentColumns = ["descUrl"], parentColumns = ["bookUrl"],
childColumns = ["bookUrl"], childColumns = ["bookUrl"],
onDelete = ForeignKey.CASCADE onDelete = ForeignKey.CASCADE
))] ))]

@ -12,20 +12,20 @@ import kotlinx.android.parcel.IgnoredOnParcel
import kotlinx.android.parcel.Parcelize import kotlinx.android.parcel.Parcelize
@Parcelize @Parcelize
@Entity(tableName = "searchBooks", indices = [(Index(value = ["descUrl"], unique = true))]) @Entity(tableName = "searchBooks", indices = [(Index(value = ["bookUrl"], unique = true))])
data class SearchBook( data class SearchBook(
@PrimaryKey @PrimaryKey
var descUrl: String = "", var bookUrl: String = "",
var origin: String = "", // 书源规则id(默认-1,表示本地书籍) var origin: String = "", // 书源规则id(默认-1,表示本地书籍)
var name: String? = null, var name: String? = null,
var author: String? = null, var author: String? = null,
var tag: String? = null, var tag: String? = null,
var coverUrl: String? = null, var coverUrl: String? = null,
var description: String? = null, var description: String? = null,
var latestChapterTitle: String? = null, var latestChapterTitle: String? = null,
var time: Long = 0L, var time: Long = 0L,
var variable: String? = null, var variable: String? = null,
var bookInfoHtml: String? = null var bookInfoHtml: String? = null
) : Parcelable, BaseBook { ) : Parcelable, BaseBook {
@IgnoredOnParcel @IgnoredOnParcel

@ -45,16 +45,16 @@ object Restore {
for (item in items) { for (item in items) {
val jsonItem = jsonPath.parse(item) val jsonItem = jsonPath.parse(item)
val book = Book() val book = Book()
book.descUrl = jsonItem.readString("$.noteUrl") ?: "" book.bookUrl = jsonItem.readString("$.noteUrl") ?: ""
if (book.descUrl.isBlank()) continue if (book.bookUrl.isBlank()) continue
book.name = jsonItem.readString("$.bookInfoBean.name") book.name = jsonItem.readString("$.bookInfoBean.name")
if (book.descUrl in existingBooks) { if (book.bookUrl in existingBooks) {
Log.d(AppConst.APP_TAG, "Found existing book: ${book.name}") Log.d(AppConst.APP_TAG, "Found existing book: ${book.name}")
continue continue
} }
book.author = jsonItem.readString("$.bookInfoBean.author") book.author = jsonItem.readString("$.bookInfoBean.author")
book.type = if (jsonItem.readString("$.bookInfoBean.bookSourceType") == "AUDIO") 1 else 0 book.type = if (jsonItem.readString("$.bookInfoBean.bookSourceType") == "AUDIO") 1 else 0
book.tocUrl = jsonItem.readString("$.bookInfoBean.chapterUrl") ?: book.descUrl book.tocUrl = jsonItem.readString("$.bookInfoBean.chapterUrl") ?: book.bookUrl
book.coverUrl = jsonItem.readString("$.bookInfoBean.coverUrl") book.coverUrl = jsonItem.readString("$.bookInfoBean.coverUrl")
book.customCoverUrl = jsonItem.readString("$.customCoverPath") book.customCoverUrl = jsonItem.readString("$.customCoverPath")
book.lastCheckTime = jsonItem.readLong("$.bookInfoBean.finalRefreshData") ?: 0 book.lastCheckTime = jsonItem.readLong("$.bookInfoBean.finalRefreshData") ?: 0

@ -31,7 +31,7 @@ class BookList {
analyzer.setContent(body, baseUrl) analyzer.setContent(body, baseUrl)
bookSource.bookUrlPattern?.let { bookSource.bookUrlPattern?.let {
if (baseUrl.matches(it.toRegex())) { if (baseUrl.matches(it.toRegex())) {
getItem(analyzer, bookSource)?.let { searchBook -> getItem(analyzer, bookSource, baseUrl)?.let { searchBook ->
searchBook.bookInfoHtml = body searchBook.bookInfoHtml = body
bookList.add(searchBook) bookList.add(searchBook)
} }
@ -41,7 +41,7 @@ class BookList {
return bookList return bookList
} }
private fun getItem(analyzeRule: AnalyzeRule, bookSource: BookSource): SearchBook? { private fun getItem(analyzeRule: AnalyzeRule, bookSource: BookSource, baseUrl: String): SearchBook? {
val searchBook = SearchBook() val searchBook = SearchBook()
analyzeRule.setBook(searchBook) analyzeRule.setBook(searchBook)
with(bookSource.getBookInfoRule()) { with(bookSource.getBookInfoRule()) {
@ -52,6 +52,7 @@ class BookList {
if (!searchBook.name.isNullOrEmpty()) { if (!searchBook.name.isNullOrEmpty()) {
searchBook.author = analyzeRule.getString(author ?: "") searchBook.author = analyzeRule.getString(author ?: "")
searchBook.coverUrl = analyzeRule.getString(coverUrl ?: "") searchBook.coverUrl = analyzeRule.getString(coverUrl ?: "")
searchBook.bookUrl = baseUrl
return searchBook return searchBook
} }
} }

@ -1,21 +1,17 @@
package io.legado.app.ui.bookshelf package io.legado.app.ui.bookshelf
import android.text.TextUtils.isEmpty
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.paging.PagedListAdapter import androidx.paging.PagedListAdapter
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import io.legado.app.R import io.legado.app.R
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.help.ImageLoader import io.legado.app.help.ImageLoader
import io.legado.app.lib.theme.ThemeStore import io.legado.app.lib.theme.ThemeStore
import kotlinx.android.synthetic.main.item_bookshelf_list.view.* import kotlinx.android.synthetic.main.item_bookshelf_list.view.*
import kotlinx.android.synthetic.main.item_relace_rule.view.tv_name import kotlinx.android.synthetic.main.item_relace_rule.view.tv_name
import java.io.File
class BookshelfAdapter : PagedListAdapter<Book, BookshelfAdapter.MyViewHolder>(DIFF_CALLBACK) { class BookshelfAdapter : PagedListAdapter<Book, BookshelfAdapter.MyViewHolder>(DIFF_CALLBACK) {
@ -23,10 +19,10 @@ class BookshelfAdapter : PagedListAdapter<Book, BookshelfAdapter.MyViewHolder>(D
@JvmField @JvmField
val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Book>() { val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Book>() {
override fun areItemsTheSame(oldItem: Book, newItem: Book): Boolean = override fun areItemsTheSame(oldItem: Book, newItem: Book): Boolean =
oldItem.descUrl == newItem.descUrl oldItem.bookUrl == newItem.bookUrl
override fun areContentsTheSame(oldItem: Book, newItem: Book): Boolean = override fun areContentsTheSame(oldItem: Book, newItem: Book): Boolean =
oldItem.descUrl == newItem.descUrl oldItem.bookUrl == newItem.bookUrl
&& oldItem.durChapterTitle == newItem.durChapterTitle && oldItem.durChapterTitle == newItem.durChapterTitle
&& oldItem.latestChapterTitle == newItem.latestChapterTitle && oldItem.latestChapterTitle == newItem.latestChapterTitle
} }

@ -19,10 +19,10 @@ class BookshelfAdapter : PagedListAdapter<Book, BookshelfAdapter.MyViewHolder>(D
@JvmField @JvmField
val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Book>() { val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Book>() {
override fun areItemsTheSame(oldItem: Book, newItem: Book): Boolean = override fun areItemsTheSame(oldItem: Book, newItem: Book): Boolean =
oldItem.descUrl == newItem.descUrl oldItem.bookUrl == newItem.bookUrl
override fun areContentsTheSame(oldItem: Book, newItem: Book): Boolean = override fun areContentsTheSame(oldItem: Book, newItem: Book): Boolean =
oldItem.descUrl == newItem.descUrl oldItem.bookUrl == newItem.bookUrl
&& oldItem.durChapterTitle == newItem.durChapterTitle && oldItem.durChapterTitle == newItem.durChapterTitle
&& oldItem.latestChapterTitle == newItem.latestChapterTitle && oldItem.latestChapterTitle == newItem.latestChapterTitle
} }

Loading…
Cancel
Save