Data saver: Long click a source to exclude, also downloader can be excluded.

Small rewrite of Data saver
This commit is contained in:
Jobobby04 2021-12-04 12:37:47 -05:00
parent 54c67bf22c
commit c5b2aa180e
12 changed files with 115 additions and 38 deletions

View File

@ -28,6 +28,7 @@ import eu.kanade.tachiyomi.util.storage.saveTo
import eu.kanade.tachiyomi.util.system.ImageUtil
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.toast
import exh.util.DataSaver
import kotlinx.coroutines.async
import logcat.LogPriority
import okhttp3.Response
@ -319,6 +320,10 @@ class Downloader(
Observable.just(download.pages!!)
}
val dataSaver = if (preferences.dataSaverDownloader().get()) {
DataSaver(download.source, preferences)
} else DataSaver.NoOp
pageListObservable
.doOnNext { _ ->
// Delete all temporary (unfinished) files
@ -333,7 +338,7 @@ class Downloader(
.flatMap { download.source.fetchAllImageUrlsFromPageList(it) }
// Start downloading images, consider we can have downloaded images already
// Concurrently do 5 pages at a time
.flatMap({ page -> getOrDownloadImage(page, download, tmpDir) }, 5)
.flatMap({ page -> getOrDownloadImage(page, download, tmpDir, dataSaver) }, 5)
.onBackpressureLatest()
// Do when page is downloaded.
.doOnNext { notifier.onProgressChange(download) }
@ -357,7 +362,7 @@ class Downloader(
* @param download the download of the page.
* @param tmpDir the temporary directory of the download.
*/
private fun getOrDownloadImage(page: Page, download: Download, tmpDir: UniFile): Observable<Page> {
private fun getOrDownloadImage(page: Page, download: Download, tmpDir: UniFile, dataSaver: DataSaver): Observable<Page> {
// If the image URL is empty, do nothing
if (page.imageUrl == null) {
return Observable.just(page)
@ -376,7 +381,7 @@ class Downloader(
val pageObservable = when {
imageFile != null -> Observable.just(imageFile)
chapterCache.isImageInCache(page.imageUrl!!) -> copyImageFromCache(chapterCache.getImageFile(page.imageUrl!!), tmpDir, filename)
else -> downloadImage(page, download.source, tmpDir, filename)
else -> downloadImage(page, download.source, tmpDir, filename, dataSaver)
}
return pageObservable
@ -404,11 +409,16 @@ class Downloader(
* @param tmpDir the temporary directory of the download.
* @param filename the filename of the image.
*/
private fun downloadImage(page: Page, source: HttpSource, tmpDir: UniFile, filename: String): Observable<UniFile> {
private fun downloadImage(page: Page, source: HttpSource, tmpDir: UniFile, filename: String, dataSaver: DataSaver): Observable<UniFile> {
page.status = Page.DOWNLOAD_IMAGE
page.progress = 0
val imageUrl = page.imageUrl!!
page.imageUrl = dataSaver.compress(imageUrl)
return source.fetchImage(page)
.map { response ->
// SY -->
page.imageUrl = imageUrl
// SY <--
val file = tmpDir.createFile("$filename.tmp")
try {
response.body!!.source().saveTo(file.openOutputStream())

View File

@ -369,6 +369,10 @@ object PreferenceKeys {
const val dataSaverColorBW = "data_saver_color_bw"
const val dataSaverExcludedSources = "data_saver_excluded"
const val dataSaverDownloaer = "data_saver_downloader"
const val saveChaptersAsCBZ = "save_chapter_as_cbz"
const val saveChaptersAsCBZLevel = "save_chapter_as_cbz_level"

View File

@ -491,6 +491,10 @@ class PreferencesHelper(val context: Context) {
fun dataSaverColorBW() = flowPrefs.getBoolean(Keys.dataSaverColorBW, false)
fun dataSaverExcludedSources() = flowPrefs.getStringSet(Keys.dataSaverExcludedSources, emptySet())
fun dataSaverDownloader() = flowPrefs.getBoolean(Keys.dataSaverDownloaer, true)
fun saveChaptersAsCBZ() = flowPrefs.getBoolean(Keys.saveChaptersAsCBZ, false)
fun saveChaptersAsCBZLevel() = flowPrefs.getInt(Keys.saveChaptersAsCBZLevel, 0)

View File

@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.source.model
import android.net.Uri
import eu.kanade.tachiyomi.network.ProgressListener
import exh.util.DataSaver
import rx.subjects.Subject
import tachiyomi.source.model.PageUrl
@ -10,16 +9,10 @@ open class Page(
val index: Int,
/* SY --> */
var /* SY <-- */ url: String = "",
/* SY --> var <-- SY */
imageUrl: String? = null,
var imageUrl: String? = null,
@Transient var uri: Uri? = null // Deprecated but can't be deleted due to extensions
) : ProgressListener {
// SY -->
var imageUrl = imageUrl
get() = field?.let { DataSaver.compress(it) }
// SY <--
val number: Int
get() = index + 1

View File

@ -186,7 +186,7 @@ class SourceController(bundle: Bundle? = null) :
}
// SY -->
val isWatched = preferences.latestTabSources().get().contains(item.source.id.toString())
val isWatched = item.source.id.toString() in preferences.latestTabSources().get()
if (item.source.supportsLatest) {
items.add(
@ -203,6 +203,16 @@ class SourceController(bundle: Bundle? = null) :
{ addToCategories(item.source) }
)
)
if (preferences.dataSaver().get()) {
val isExcluded = item.source.id.toString() in preferences.dataSaverExcludedSources().get()
items.add(
Pair(
activity.getString(if (isExcluded) R.string.data_saver_stop_exclude else R.string.data_saver_exclude),
{ excludeFromDataSaver(item.source, isExcluded) }
)
)
}
// SY <--
SourceOptionsDialog(item.source.toString(), items).showDialog(router)
@ -287,6 +297,14 @@ class SourceController(bundle: Bundle? = null) :
)
presenter.updateSources()
}
private fun excludeFromDataSaver(source: Source, isExcluded: Boolean) {
if (isExcluded) {
preferences.dataSaverExcludedSources() -= source.id.toString()
} else {
preferences.dataSaverExcludedSources() += source.id.toString()
}
}
// SY <--
/**

View File

@ -9,6 +9,7 @@ import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
import eu.kanade.tachiyomi.util.lang.plusAssign
import eu.kanade.tachiyomi.util.system.logcat
import exh.source.isEhBasedSource
import exh.util.DataSaver
import logcat.LogPriority
import rx.Completable
import rx.Observable
@ -46,6 +47,10 @@ class HttpPageLoader(
private val preloadSize = /* SY --> */ preferences.preloadSize().get() /* SY <-- */
// SY -->
private val dataSaver = DataSaver(source, preferences)
// SY <--
init {
// EXH -->
repeat(preferences.readerThreads().get()) {
@ -270,8 +275,17 @@ class HttpPageLoader(
*/
private fun HttpSource.cacheImage(page: ReaderPage): Observable<ReaderPage> {
page.status = Page.DOWNLOAD_IMAGE
// SY -->
val imageUrl = page.imageUrl!!
page.imageUrl = dataSaver.compress(imageUrl)
// SY <--
return fetchImage(page)
.doOnNext { chapterCache.putImageToCache(page.imageUrl!!, it) }
.doOnNext {
// SY -->
page.imageUrl = imageUrl
// SY <--
chapterCache.putImageToCache(page.imageUrl!!, it)
}
.map { page }
}

View File

@ -307,7 +307,16 @@ class SettingsAdvancedController : SettingsController() {
}
switchPreference {
titleRes = R.string.ignore_jpeg
titleRes = R.string.data_saver_downloader
key = Keys.dataSaverDownloaer
defaultValue = true
preferences.dataSaver().asImmediateFlow { isVisible = it }
.launchIn(viewScope)
}
switchPreference {
titleRes = R.string.data_saver_ignore_jpeg
key = Keys.ignoreJpeg
defaultValue = false
@ -316,7 +325,7 @@ class SettingsAdvancedController : SettingsController() {
}
switchPreference {
titleRes = R.string.ignore_gif
titleRes = R.string.data_saver_ignore_gif
key = Keys.ignoreGif
defaultValue = true

View File

@ -2,29 +2,51 @@ package exh.util
import com.tfcporciuncula.flow.Preference
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import uy.kohesive.injekt.injectLazy
import tachiyomi.source.Source
object DataSaver {
private val preferences: PreferencesHelper by injectLazy()
interface DataSaver {
fun compress(imageUrl: String): String {
return if (preferences.dataSaver().get() && preferences.dataSaverServer().get().isNotBlank() && !imageUrl.contains(preferences.dataSaverServer().get() + "/?")) {
fun compress(imageUrl: String): String
companion object {
val NoOp = object : DataSaver {
override fun compress(imageUrl: String): String {
return imageUrl
}
}
}
}
fun DataSaver(source: Source, preferences: PreferencesHelper): DataSaver {
return if (preferences.dataSaver().get() && source.id.toString() !in preferences.dataSaverExcludedSources().get()) {
return DataSaverImpl(preferences)
} else {
DataSaver.NoOp
}
}
private class DataSaverImpl(preferences: PreferencesHelper): DataSaver {
private val dataSavedServer = preferences.dataSaverServer().get().trimEnd('/')
private val ignoreJpg = preferences.ignoreJpeg().get()
private val ignoreGif = preferences.ignoreGif().get()
private val format = preferences.dataSaverImageFormatJpeg().toIntRepresentation()
private val quality = preferences.dataSaverImageQuality().get()
private val colorBW = preferences.dataSaverColorBW().toIntRepresentation()
override fun compress(imageUrl: String): String {
return if (dataSavedServer.isNotBlank() && !imageUrl.contains(dataSavedServer)) {
when {
imageUrl.contains(".jpeg", true) || imageUrl.contains(".jpg", true) -> if (preferences.ignoreJpeg().get()) imageUrl else getUrl(imageUrl)
imageUrl.contains(".gif", true) -> if (preferences.ignoreGif().get()) imageUrl else getUrl(imageUrl)
imageUrl.contains(".jpeg", true) || imageUrl.contains(".jpg", true) -> if (ignoreJpg) imageUrl else getUrl(imageUrl)
imageUrl.contains(".gif", true) -> if (ignoreGif) imageUrl else getUrl(imageUrl)
else -> getUrl(imageUrl)
}
} else imageUrl
}
private fun getUrl(imageUrl: String): String {
val server = preferences.dataSaverServer().get() + "/?"
val format = "jpg=" + preferences.dataSaverImageFormatJpeg().toIntRepresentation()
val quality = "l=" + preferences.dataSaverImageQuality().get()
val colorBW = "bw=" + preferences.dataSaverColorBW().toIntRepresentation()
val url = "url=$imageUrl"
return "$server&$format&$quality&$colorBW&$url"
return "$dataSavedServer/?jpg=$format&l=$quality&bw=$colorBW&url=$imageUrl"
}
private fun Preference<Boolean>.toIntRepresentation() = if (get()) "1" else "0"

View File

@ -143,8 +143,8 @@
</plurals>
<string name="data_saver">Économiseur de données</string>
<string name="data_saver_summary">Compresser les images avant le téléchargement ou le chargement dans le lecteur, nécessite un serveur Proxy Bandwidth Hero</string>
<string name="ignore_jpeg">Ignorer les images Jpeg</string>
<string name="ignore_gif">Ignorer les animations Gif</string>
<string name="data_saver_ignore_jpeg">Ignorer les images Jpeg</string>
<string name="data_saver_ignore_gif">Ignorer les animations Gif</string>
<string name="data_saver_image_quality">Qualité d\'image</string>
<string name="data_saver_image_quality_summary">Des valeurs plus élevées signifient qu\'un pourcentage plus élevé de la qualité d\'image est enregistré, mais cela signifie également que la taille du fichier est plus grande, 80 \% est une bonne médiane entre la taille du fichier et la qualité de l\'image</string>
<string name="data_saver_image_format">Compresser en Jpeg</string>

View File

@ -148,8 +148,8 @@
</plurals>
<string name="data_saver">Economizar Dados</string>
<string name="data_saver_summary">Comprime imagens antes de baixar ou carregar no leitor, requer um servidor Bandwidth Hero Proxy</string>
<string name="ignore_jpeg">Ignorar Imagens Jpeg</string>
<string name="ignore_gif">Ignorar Animações Gif</string>
<string name="data_saver_ignore_jpeg">Ignorar Imagens Jpeg</string>
<string name="data_saver_ignore_gif">Ignorar Animações Gif</string>
<string name="data_saver_image_quality">Qualidade da Imagem</string>
<string name="data_saver_image_quality_summary">Valores maiores indicam que um maior percentual da qualidade de imagem é salva, mas implicam aumento no tamanho do arquivo, 80 por cento é uma boa média entre tamanho de arquivo e qualidade de imagem</string>
<string name="data_saver_image_format">Comprimir em Jpeg</string>

View File

@ -145,8 +145,8 @@
</plurals>
<string name="data_saver">Экономия данных</string>
<string name="data_saver_summary">Сжатие изображений перед скачиванием или загрузкой в Читалке требует наличия прокси-сервера Bandwidth Hero</string>
<string name="ignore_jpeg">Игнорировать изображения Jpeg</string>
<string name="ignore_gif">Игнорировать Gif-Анимацию</string>
<string name="data_saver_ignore_jpeg">Игнорировать изображения Jpeg</string>
<string name="data_saver_ignore_gif">Игнорировать Gif-Анимацию</string>
<string name="data_saver_image_quality">Качество изображения</string>
<string name="data_saver_image_quality_summary">Более высокие значения означают, что сохраняется более высокий процент качества изображения, но это также означает, что размер файла больше, 80 процентов-это хорошая промежуточная величина между размером файла и качеством изображения</string>
<string name="data_saver_image_format">Сжатие в Jpeg</string>

View File

@ -148,8 +148,9 @@
</plurals>
<string name="data_saver">Data Saver</string>
<string name="data_saver_summary">Compress images before downloading or loading in reader, requires a Bandwidth Hero Proxy server</string>
<string name="ignore_jpeg">Ignore Jpeg Images</string>
<string name="ignore_gif">Ignore Gif Animations</string>
<string name="data_saver_downloader">Use data saver in the downloader</string>
<string name="data_saver_ignore_jpeg">Ignore Jpeg Images</string>
<string name="data_saver_ignore_gif">Ignore Gif Animations</string>
<string name="data_saver_image_quality">Image Quality</string>
<string name="data_saver_image_quality_summary">Higher values mean that a higher percentage of the image quality is saved, but it also means the file size is larger, 80 percent is a good median between file size and image quality</string>
<string name="data_saver_image_format">Compress to Jpeg</string>
@ -329,6 +330,8 @@
<!-- Browse -->
<!-- Sources Tab -->
<string name="find_in_another_source">Find in another source</string>
<string name="data_saver_exclude">Exclude from data saver</string>
<string name="data_saver_stop_exclude">Stop excluding from data saver</string>
<!-- Smart Search -->
<string name="searching_source">Searching source…</string>