diff --git a/app/src/main/assets/help/regexHelp.md b/app/src/main/assets/help/regexHelp.md index 8598c718a..cf0779d80 100644 --- a/app/src/main/assets/help/regexHelp.md +++ b/app/src/main/assets/help/regexHelp.md @@ -189,28 +189,6 @@ |g|全局搜索: 搜索整个输入字符串中的所有匹配。| |m|多行匹配: 会匹配输入字符串每一行。| -### 5.1 不区分大小写 - -`i` 修饰符用于执行不区分大小写匹配。例如正则表达式 `/The/gi`,表示: 大写字母 `T`,后跟小写字母 `h`,后跟字母 `e`。 -但是在正则匹配结束时 `i` 标记会告诉正则表达式引擎忽略这种情况。正如你所看到的,我们还使用了 `g` 标记,因为我们要在整个输入字符串中搜索匹配。
"The" => The fat cat sat on the mat.
"/The/gi" => The fat cat sat on the mat.
- -### 5.2 全局搜索 - -`g` 修饰符用于执行全局匹配 (会查找所有匹配,不会在查找到第一个匹配时就停止)。 -例如正则表达式 `/.(at)/g`,表示: 除换行符之外的任意字符,后跟小写字母 `a`,后跟小写字母 `t`。 -因为我们在正则表达式的末尾使用了 `g` 标记,它会从整个输入字符串中找到每个匹配项。
".(at)" => The fat cat sat on the mat.
"/.(at)/g" => The fat cat sat on the mat.
- -### 5.3 多行匹配 - -`m` 修饰符被用来执行多行的匹配。正如我们前面讨论过的 `(^, $)`,使用定位符来检查匹配字符是输入字符串开始或者结束。但是我们希望每一行都使用定位符,所以我们就使用 `m` 修饰符。 -例如正则表达式 `/at(.)?$/gm`,表示: 小写字母 `a`,后跟小写字母 `t`,匹配除了换行符以外任意字符零次或一次。而且因为 `m` 标记,现在正则表达式引擎匹配字符串中每一行的末尾。
"/.at(.)?$/" => The fat
-                cat sat
-                on the mat.
"/.at(.)?$/gm" => The fat
-                  cat sat
-                  on the mat.
- -## 常用正则表达式 - * **数字**: `\d+$` * **用户名**: `^[\w\d_.]{4,16}$` * **字母数字字符**: `^[a-zA-Z0-9]*$` diff --git a/app/src/main/java/io/legado/app/api/controller/BookController.kt b/app/src/main/java/io/legado/app/api/controller/BookController.kt index 62abec1be..7239abc47 100644 --- a/app/src/main/java/io/legado/app/api/controller/BookController.kt +++ b/app/src/main/java/io/legado/app/api/controller/BookController.kt @@ -9,7 +9,7 @@ import io.legado.app.data.appDb import io.legado.app.data.entities.Book import io.legado.app.help.BookHelp import io.legado.app.help.ContentProcessor -import io.legado.app.help.ImageLoader +import io.legado.app.help.glide.ImageLoader import io.legado.app.model.ReadBook import io.legado.app.model.localBook.EpubFile import io.legado.app.model.localBook.LocalBook diff --git a/app/src/main/java/io/legado/app/help/ImageLoader.kt b/app/src/main/java/io/legado/app/help/glide/ImageLoader.kt similarity index 95% rename from app/src/main/java/io/legado/app/help/ImageLoader.kt rename to app/src/main/java/io/legado/app/help/glide/ImageLoader.kt index 8b36f397d..62ca20f50 100644 --- a/app/src/main/java/io/legado/app/help/ImageLoader.kt +++ b/app/src/main/java/io/legado/app/help/glide/ImageLoader.kt @@ -1,4 +1,4 @@ -package io.legado.app.help +package io.legado.app.help.glide import android.content.Context import android.graphics.Bitmap @@ -21,7 +21,7 @@ object ImageLoader { fun load(context: Context, path: String?): RequestBuilder { return when { path.isNullOrEmpty() -> Glide.with(context).load(path) - path.isAbsUrl() -> Glide.with(context).load(AnalyzeUrl(path).getGlideUrl()) + path.isAbsUrl() -> GlideApp.with(context).load(AnalyzeUrl(path).getGlideUrl()) path.isContentScheme() -> Glide.with(context).load(Uri.parse(path)) else -> kotlin.runCatching { Glide.with(context).load(File(path)) diff --git a/app/src/main/java/io/legado/app/help/glide/OkHttpGlideModule.kt b/app/src/main/java/io/legado/app/help/glide/OkHttpGlideModule.kt new file mode 100644 index 000000000..f41871b07 --- /dev/null +++ b/app/src/main/java/io/legado/app/help/glide/OkHttpGlideModule.kt @@ -0,0 +1,21 @@ +package io.legado.app.help.glide + +import android.content.Context +import com.bumptech.glide.Glide +import com.bumptech.glide.Registry +import com.bumptech.glide.annotation.GlideModule +import com.bumptech.glide.load.model.GlideUrl +import com.bumptech.glide.module.AppGlideModule +import java.io.InputStream + +@Suppress("unused") +@GlideModule +class OkHttpGlideModule : AppGlideModule() { + override fun registerComponents(context: Context, glide: Glide, registry: Registry) { + registry.replace( + GlideUrl::class.java, + InputStream::class.java, + OkHttpModeLoaderFactory() + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/glide/OkHttpModeLoaderFactory.kt b/app/src/main/java/io/legado/app/help/glide/OkHttpModeLoaderFactory.kt new file mode 100644 index 000000000..ad06755ea --- /dev/null +++ b/app/src/main/java/io/legado/app/help/glide/OkHttpModeLoaderFactory.kt @@ -0,0 +1,21 @@ +package io.legado.app.help.glide + +import com.bumptech.glide.load.model.GlideUrl +import com.bumptech.glide.load.model.ModelLoader +import com.bumptech.glide.load.model.ModelLoaderFactory +import com.bumptech.glide.load.model.MultiModelLoaderFactory +import io.legado.app.help.http.okHttpClient +import java.io.InputStream + + +class OkHttpModeLoaderFactory : ModelLoaderFactory { + + override fun build(multiFactory: MultiModelLoaderFactory): ModelLoader { + return OkHttpModelLoader(okHttpClient) + } + + override fun teardown() { + // Do nothing, this instance doesn't own the client. + } + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/glide/OkHttpModelLoader.kt b/app/src/main/java/io/legado/app/help/glide/OkHttpModelLoader.kt new file mode 100644 index 000000000..3c1c693f5 --- /dev/null +++ b/app/src/main/java/io/legado/app/help/glide/OkHttpModelLoader.kt @@ -0,0 +1,24 @@ +package io.legado.app.help.glide + +import com.bumptech.glide.load.Options +import com.bumptech.glide.load.model.GlideUrl +import com.bumptech.glide.load.model.ModelLoader +import okhttp3.Call +import java.io.InputStream + +class OkHttpModelLoader(private val client: Call.Factory) : ModelLoader { + + override fun buildLoadData( + model: GlideUrl, + width: Int, + height: Int, + options: Options + ): ModelLoader.LoadData { + return ModelLoader.LoadData(model, OkHttpStreamFetcher(client, model)) + } + + override fun handles(model: GlideUrl): Boolean { + return true + } + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/glide/OkHttpStreamFetcher.kt b/app/src/main/java/io/legado/app/help/glide/OkHttpStreamFetcher.kt new file mode 100644 index 000000000..58d44c505 --- /dev/null +++ b/app/src/main/java/io/legado/app/help/glide/OkHttpStreamFetcher.kt @@ -0,0 +1,72 @@ +package io.legado.app.help.glide + +import com.bumptech.glide.Priority +import com.bumptech.glide.load.DataSource +import com.bumptech.glide.load.HttpException +import com.bumptech.glide.load.data.DataFetcher +import com.bumptech.glide.load.model.GlideUrl +import com.bumptech.glide.util.ContentLengthInputStream +import com.bumptech.glide.util.Preconditions +import okhttp3.Call +import okhttp3.Request +import okhttp3.Response +import okhttp3.ResponseBody +import java.io.IOException +import java.io.InputStream + + +class OkHttpStreamFetcher(private val client: Call.Factory, private val url: GlideUrl) : + DataFetcher, okhttp3.Callback { + private var stream: InputStream? = null + private var responseBody: ResponseBody? = null + private var callback: DataFetcher.DataCallback? = null + private var call: Call? = null + + override fun loadData(priority: Priority, callback: DataFetcher.DataCallback) { + val requestBuilder: Request.Builder = Request.Builder().url(url.toStringUrl()) + for ((key, value) in url.headers.entries) { + requestBuilder.addHeader(key, value) + } + val request: Request = requestBuilder.build() + this.callback = callback + call = client.newCall(request) + call?.enqueue(this) + } + + override fun cleanup() { + try { + stream?.close() + } catch (e: IOException) { + // Ignored + } + responseBody?.close() + callback = null + } + + override fun cancel() { + call?.cancel() + } + + override fun getDataClass(): Class { + return InputStream::class.java + } + + override fun getDataSource(): DataSource { + return DataSource.REMOTE + } + + override fun onFailure(call: Call, e: IOException) { + callback?.onLoadFailed(e) + } + + override fun onResponse(call: Call, response: Response) { + responseBody = response.body + if (response.isSuccessful) { + val contentLength: Long = Preconditions.checkNotNull(responseBody).contentLength() + stream = ContentLengthInputStream.obtain(responseBody!!.byteStream(), contentLength) + callback!!.onDataReady(stream) + } else { + callback!!.onLoadFailed(HttpException(response.message, response.code)) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt b/app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt index d13b395ca..5474bc1ed 100644 --- a/app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt @@ -20,7 +20,7 @@ import io.legado.app.constant.Theme import io.legado.app.data.entities.Book import io.legado.app.databinding.ActivityAudioPlayBinding import io.legado.app.help.BlurTransformation -import io.legado.app.help.ImageLoader +import io.legado.app.help.glide.ImageLoader import io.legado.app.lib.dialogs.alert import io.legado.app.service.help.AudioPlay import io.legado.app.ui.book.changesource.ChangeSourceDialog diff --git a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt index 17191768c..cc525b035 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt @@ -23,7 +23,7 @@ import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter import io.legado.app.databinding.ActivityBookInfoBinding import io.legado.app.help.BlurTransformation -import io.legado.app.help.ImageLoader +import io.legado.app.help.glide.ImageLoader import io.legado.app.lib.dialogs.alert import io.legado.app.lib.theme.backgroundColor import io.legado.app.lib.theme.bottomBackground diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/BgAdapter.kt b/app/src/main/java/io/legado/app/ui/book/read/config/BgAdapter.kt index f0d8ac752..439f8d554 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/BgAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/BgAdapter.kt @@ -6,10 +6,9 @@ import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.RecyclerAdapter import io.legado.app.constant.EventBus import io.legado.app.databinding.ItemBgImageBinding -import io.legado.app.help.ImageLoader import io.legado.app.help.ReadBookConfig +import io.legado.app.help.glide.ImageLoader import io.legado.app.utils.postEvent - import java.io.File class BgAdapter(context: Context, val textColor: Int) : diff --git a/app/src/main/java/io/legado/app/ui/main/rss/RssAdapter.kt b/app/src/main/java/io/legado/app/ui/main/rss/RssAdapter.kt index 1af9bdb9b..b3df28b0d 100644 --- a/app/src/main/java/io/legado/app/ui/main/rss/RssAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/main/rss/RssAdapter.kt @@ -9,7 +9,7 @@ import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.RecyclerAdapter import io.legado.app.data.entities.RssSource import io.legado.app.databinding.ItemRssBinding -import io.legado.app.help.ImageLoader +import io.legado.app.help.glide.ImageLoader import splitties.views.onLongClick class RssAdapter(context: Context, val callBack: CallBack) : diff --git a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesAdapter.kt b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesAdapter.kt index cb5605bc9..b79d8f18f 100644 --- a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesAdapter.kt @@ -11,7 +11,7 @@ import io.legado.app.R import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.data.entities.RssArticle import io.legado.app.databinding.ItemRssArticleBinding -import io.legado.app.help.ImageLoader +import io.legado.app.help.glide.ImageLoader import io.legado.app.utils.getCompatColor import io.legado.app.utils.gone import io.legado.app.utils.visible diff --git a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesAdapter1.kt b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesAdapter1.kt index 574825624..d92fb4b94 100644 --- a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesAdapter1.kt +++ b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesAdapter1.kt @@ -11,7 +11,7 @@ import io.legado.app.R import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.data.entities.RssArticle import io.legado.app.databinding.ItemRssArticle1Binding -import io.legado.app.help.ImageLoader +import io.legado.app.help.glide.ImageLoader import io.legado.app.utils.getCompatColor import io.legado.app.utils.gone import io.legado.app.utils.visible diff --git a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesAdapter2.kt b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesAdapter2.kt index c4fef291e..5a512a063 100644 --- a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesAdapter2.kt +++ b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesAdapter2.kt @@ -11,7 +11,7 @@ import io.legado.app.R import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.data.entities.RssArticle import io.legado.app.databinding.ItemRssArticle2Binding -import io.legado.app.help.ImageLoader +import io.legado.app.help.glide.ImageLoader import io.legado.app.utils.getCompatColor import io.legado.app.utils.gone import io.legado.app.utils.visible diff --git a/app/src/main/java/io/legado/app/ui/rss/favorites/RssFavoritesAdapter.kt b/app/src/main/java/io/legado/app/ui/rss/favorites/RssFavoritesAdapter.kt index 71feb0e4d..ba0a252c2 100644 --- a/app/src/main/java/io/legado/app/ui/rss/favorites/RssFavoritesAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/rss/favorites/RssFavoritesAdapter.kt @@ -11,7 +11,7 @@ import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.RecyclerAdapter import io.legado.app.data.entities.RssStar import io.legado.app.databinding.ItemRssArticleBinding -import io.legado.app.help.ImageLoader +import io.legado.app.help.glide.ImageLoader import io.legado.app.utils.gone import io.legado.app.utils.visible diff --git a/app/src/main/java/io/legado/app/ui/widget/image/CoverImageView.kt b/app/src/main/java/io/legado/app/ui/widget/image/CoverImageView.kt index 986ac63e4..0105fe933 100644 --- a/app/src/main/java/io/legado/app/ui/widget/image/CoverImageView.kt +++ b/app/src/main/java/io/legado/app/ui/widget/image/CoverImageView.kt @@ -13,7 +13,7 @@ import com.bumptech.glide.request.target.Target import io.legado.app.R import io.legado.app.constant.PreferKey import io.legado.app.help.AppConfig -import io.legado.app.help.ImageLoader +import io.legado.app.help.glide.ImageLoader import io.legado.app.utils.getPrefString import splitties.init.appCtx