mirror of
https://github.com/rebelonion/Dantotsu.git
synced 2026-02-01 06:11:02 +00:00
* Update README.md * To install multiple mangas users can enter the value required to install as there is an EditText field instead of the Text View * Issues 1)Installation of many mangas at same time now made to one to increase the installation efficiency 2)Installation order from the latest progresses chapter to the limit index 3)Tried to resolve the app crash bug * Issues 1)Installation of many mangas at same time now made to one to increase the installation efficiency 2)Installation order from the latest progresses chapter to the limit index 3)Tried to resolve the app crash bug --------- Co-authored-by: rebel onion <87634197+rebelonion@users.noreply.github.com>
134 lines
4.0 KiB
Kotlin
134 lines
4.0 KiB
Kotlin
package ani.dantotsu.media.manga
|
|
|
|
import android.content.ContentResolver
|
|
import android.content.ContentValues
|
|
import android.graphics.Bitmap
|
|
import android.graphics.BitmapFactory
|
|
import android.net.Uri
|
|
import android.os.Build
|
|
import android.os.Environment
|
|
import android.provider.MediaStore
|
|
import android.util.LruCache
|
|
import ani.dantotsu.snackString
|
|
import ani.dantotsu.util.Logger
|
|
import eu.kanade.tachiyomi.source.model.Page
|
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.withContext
|
|
import java.io.File
|
|
import java.io.FileNotFoundException
|
|
import java.io.FileOutputStream
|
|
|
|
data class ImageData(
|
|
val page: Page,
|
|
val source: HttpSource
|
|
) {
|
|
suspend fun fetchAndProcessImage(
|
|
page: Page,
|
|
httpSource: HttpSource
|
|
): Bitmap? {
|
|
return withContext(Dispatchers.IO) {
|
|
try {
|
|
// Fetch the image
|
|
val response = httpSource.getImage(page)
|
|
Logger.log("Response: ${response.code} - ${response.message}")
|
|
|
|
// Convert the Response to an InputStream
|
|
val inputStream = response.body.byteStream()
|
|
|
|
// Convert InputStream to Bitmap
|
|
val bitmap = BitmapFactory.decodeStream(inputStream)
|
|
|
|
inputStream.close()
|
|
//saveImage(bitmap, context.contentResolver, page.imageUrl!!, Bitmap.CompressFormat.JPEG, 100)
|
|
|
|
return@withContext bitmap
|
|
} catch (e: Exception) {
|
|
// Handle any exceptions
|
|
Logger.log("An error occurred: ${e.message}")
|
|
snackString("An error occurred: ${e.message}")
|
|
return@withContext null
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fun saveImage(
|
|
bitmap: Bitmap,
|
|
contentResolver: ContentResolver,
|
|
filename: String,
|
|
format: Bitmap.CompressFormat,
|
|
quality: Int
|
|
) {
|
|
try {
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
val contentValues = ContentValues().apply {
|
|
put(MediaStore.MediaColumns.DISPLAY_NAME, filename)
|
|
put(MediaStore.MediaColumns.MIME_TYPE, "image/${format.name.lowercase()}")
|
|
put(
|
|
MediaStore.MediaColumns.RELATIVE_PATH,
|
|
"${Environment.DIRECTORY_DOWNLOADS}/Dantotsu/Manga"
|
|
)
|
|
}
|
|
|
|
val uri: Uri? =
|
|
contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues)
|
|
|
|
uri?.let {
|
|
contentResolver.openOutputStream(it)?.use { os ->
|
|
bitmap.compress(format, quality, os)
|
|
} ?: throw FileNotFoundException("Failed to open output stream for URI: $uri")
|
|
}
|
|
} else {
|
|
val directory =
|
|
File("${Environment.getExternalStorageDirectory()}${File.separator}Dantotsu${File.separator}Manga")
|
|
if (!directory.exists()) {
|
|
directory.mkdirs()
|
|
}
|
|
|
|
val file = File(directory, filename)
|
|
|
|
// Check if the file already exists
|
|
if (file.exists()) {
|
|
println("File already exists: ${file.absolutePath}")
|
|
return
|
|
}
|
|
|
|
FileOutputStream(file).use { outputStream ->
|
|
bitmap.compress(format, quality, outputStream)
|
|
}
|
|
}
|
|
} catch (e: FileNotFoundException) {
|
|
println("File not found: ${e.message}")
|
|
} catch (e: Exception) {
|
|
println("Exception while saving image: ${e.message}")
|
|
}
|
|
}
|
|
|
|
class MangaCache {
|
|
private val maxMemory = (Runtime.getRuntime().maxMemory() / 1024 / 2).toInt()
|
|
private val cache = LruCache<String, ImageData>(maxMemory)
|
|
|
|
@Synchronized
|
|
fun put(key: String, imageDate: ImageData) {
|
|
cache.put(key, imageDate)
|
|
}
|
|
|
|
@Synchronized
|
|
fun get(key: String): ImageData? = cache.get(key)
|
|
|
|
@Synchronized
|
|
fun remove(key: String) {
|
|
cache.remove(key)
|
|
}
|
|
|
|
@Synchronized
|
|
fun clear() {
|
|
cache.evictAll()
|
|
}
|
|
|
|
fun size(): Int = cache.size()
|
|
|
|
|
|
}
|