|  |  |  | @ -7,24 +7,30 @@ import io.legado.app.data.entities.Book | 
			
		
	
		
			
				
					|  |  |  |  | import io.legado.app.data.entities.BookChapter | 
			
		
	
		
			
				
					|  |  |  |  | import io.legado.app.data.entities.ReplaceRule | 
			
		
	
		
			
				
					|  |  |  |  | import io.legado.app.help.coroutine.Coroutine | 
			
		
	
		
			
				
					|  |  |  |  | import io.legado.app.model.analyzeRule.AnalyzeUrl | 
			
		
	
		
			
				
					|  |  |  |  | import io.legado.app.model.localBook.LocalBook | 
			
		
	
		
			
				
					|  |  |  |  | import io.legado.app.utils.FileUtils | 
			
		
	
		
			
				
					|  |  |  |  | import io.legado.app.utils.MD5Utils | 
			
		
	
		
			
				
					|  |  |  |  | import io.legado.app.utils.externalFilesDir | 
			
		
	
		
			
				
					|  |  |  |  | import io.legado.app.utils.postEvent | 
			
		
	
		
			
				
					|  |  |  |  | import io.legado.app.utils.NetworkUtils | 
			
		
	
		
			
				
					|  |  |  |  | import kotlinx.coroutines.Dispatchers.IO | 
			
		
	
		
			
				
					|  |  |  |  | import kotlinx.coroutines.Dispatchers.Main | 
			
		
	
		
			
				
					|  |  |  |  | import kotlinx.coroutines.withContext | 
			
		
	
		
			
				
					|  |  |  |  | import org.apache.commons.text.similarity.JaccardSimilarity | 
			
		
	
		
			
				
					|  |  |  |  | import org.jetbrains.anko.toast | 
			
		
	
		
			
				
					|  |  |  |  | import java.io.File | 
			
		
	
		
			
				
					|  |  |  |  | import java.util.regex.Pattern | 
			
		
	
		
			
				
					|  |  |  |  | import kotlin.math.min | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | object BookHelp { | 
			
		
	
		
			
				
					|  |  |  |  |     private const val cacheFolderName = "book_cache" | 
			
		
	
		
			
				
					|  |  |  |  |     private const val cacheImageFolderName = "images" | 
			
		
	
		
			
				
					|  |  |  |  |     private val downloadDir: File = App.INSTANCE.externalFilesDir | 
			
		
	
		
			
				
					|  |  |  |  |     private val srcPattern = | 
			
		
	
		
			
				
					|  |  |  |  |         Pattern.compile("<img .*?src.*?=.*?\"(.*?(?:,\\{.*\\})?)\".*?>", Pattern.CASE_INSENSITIVE) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     private fun bookFolderName(book: Book): String { | 
			
		
	
		
			
				
					|  |  |  |  |     fun bookFolderName(book: Book): String { | 
			
		
	
		
			
				
					|  |  |  |  |         return formatFolderName(book.name) + MD5Utils.md5Encode16(book.bookUrl) | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -63,13 +69,44 @@ object BookHelp { | 
			
		
	
		
			
				
					|  |  |  |  |     @Synchronized | 
			
		
	
		
			
				
					|  |  |  |  |     fun saveContent(book: Book, bookChapter: BookChapter, content: String) { | 
			
		
	
		
			
				
					|  |  |  |  |         if (content.isEmpty()) return | 
			
		
	
		
			
				
					|  |  |  |  |         //保存文本 | 
			
		
	
		
			
				
					|  |  |  |  |         FileUtils.createFileIfNotExist( | 
			
		
	
		
			
				
					|  |  |  |  |             downloadDir, | 
			
		
	
		
			
				
					|  |  |  |  |             formatChapterName(bookChapter), | 
			
		
	
		
			
				
					|  |  |  |  |             subDirs = *arrayOf(cacheFolderName, bookFolderName(book)) | 
			
		
	
		
			
				
					|  |  |  |  |         ).writeText(content) | 
			
		
	
		
			
				
					|  |  |  |  |         //保存图片 | 
			
		
	
		
			
				
					|  |  |  |  |         content.split("\n").forEach { | 
			
		
	
		
			
				
					|  |  |  |  |             val matcher = srcPattern.matcher(it) | 
			
		
	
		
			
				
					|  |  |  |  |             if (matcher.find()) { | 
			
		
	
		
			
				
					|  |  |  |  |                 var src = matcher.group(1) | 
			
		
	
		
			
				
					|  |  |  |  |                 src = NetworkUtils.getAbsoluteURL(bookChapter.url, src) | 
			
		
	
		
			
				
					|  |  |  |  |                 src?.let { | 
			
		
	
		
			
				
					|  |  |  |  |                     saveImage(book, src) | 
			
		
	
		
			
				
					|  |  |  |  |                  } | 
			
		
	
		
			
				
					|  |  |  |  |              } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         postEvent(EventBus.SAVE_CONTENT, bookChapter) | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun saveImage(book: Book, src:String) { | 
			
		
	
		
			
				
					|  |  |  |  |         val analyzeUrl = AnalyzeUrl(src, null, null, null, null) | 
			
		
	
		
			
				
					|  |  |  |  |         analyzeUrl.getImageBytes(book.origin)?.let { | 
			
		
	
		
			
				
					|  |  |  |  |             FileUtils.createFileIfNotExist( | 
			
		
	
		
			
				
					|  |  |  |  |                 downloadDir, | 
			
		
	
		
			
				
					|  |  |  |  |                 "${MD5Utils.md5Encode16(src)}${src.substringAfterLast(".").substringBefore(",")}", | 
			
		
	
		
			
				
					|  |  |  |  |                 subDirs = *arrayOf(cacheFolderName, bookFolderName(book), cacheImageFolderName) | 
			
		
	
		
			
				
					|  |  |  |  |             ).writeBytes(it) | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun getImage(book:Book, src:String): File { | 
			
		
	
		
			
				
					|  |  |  |  |         return FileUtils.getFile( | 
			
		
	
		
			
				
					|  |  |  |  |                     downloadDir, | 
			
		
	
		
			
				
					|  |  |  |  |                     "${MD5Utils.md5Encode16(src)}${src.substringAfterLast(".").substringBefore(",")}", | 
			
		
	
		
			
				
					|  |  |  |  |                     subDirs = *arrayOf(cacheFolderName, bookFolderName(book), cacheImageFolderName) | 
			
		
	
		
			
				
					|  |  |  |  |                 ) | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     fun getChapterFiles(book: Book): List<String> { | 
			
		
	
		
			
				
					|  |  |  |  |         val fileNameList = arrayListOf<String>() | 
			
		
	
	
		
			
				
					|  |  |  | 
 |