/* * Pupil, Hitomi.la viewer for Android * Copyright (C) 2019 tom5079 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package xyz.quaver.pupil.util import android.content.Context import android.net.Uri import androidx.core.content.FileProvider import androidx.documentfile.provider.DocumentFile import androidx.preference.PreferenceManager import java.io.File import java.net.URL import java.nio.charset.Charset import java.util.* fun getCachedGallery(context: Context, galleryID: Int) = getDownloadDirectory(context).findFile(galleryID.toString()) ?: DocumentFile.fromFile(File(context.cacheDir, "imageCache/$galleryID")) fun getDownloadDirectory(context: Context) : DocumentFile { val uri = PreferenceManager.getDefaultSharedPreferences(context).getString("dl_location", null).let { if (it != null) Uri.parse(it) else Uri.fromFile(context.getExternalFilesDir(null)) } return if (uri.toString().startsWith("file")) DocumentFile.fromFile(File(uri.path!!)) else DocumentFile.fromTreeUri(context, uri) ?: DocumentFile.fromFile(context.getExternalFilesDir(null)!!) } fun convertUpdateUri(context: Context, uri: Uri) : Uri = if (uri.toString().startsWith("file")) FileProvider.getUriForFile(context, context.applicationContext.packageName + ".provider", File(uri.path!!.substringAfter("file:///"))) else uri fun URL.download(context: Context, to: DocumentFile, onDownloadProgress: ((Long, Long) -> Unit)? = null) { context.contentResolver.openOutputStream(to.uri).use { out -> out!! with(openConnection()) { val fileSize = contentLength.toLong() getInputStream().use { var bytesCopied: Long = 0 val buffer = ByteArray(DEFAULT_BUFFER_SIZE) var bytes = it.read(buffer) while (bytes >= 0) { out.write(buffer, 0, bytes) bytesCopied += bytes onDownloadProgress?.invoke(bytesCopied, fileSize) bytes = it.read(buffer) } } } } } fun DocumentFile.isParentOf(file: DocumentFile?) : Boolean { var parent = file?.parentFile while (parent != null) { if (this.uri.path == parent.uri.path) return true parent = parent.parentFile } return false } fun DocumentFile.reader(context: Context, charset: Charset = Charsets.UTF_8) = context.contentResolver.openInputStream(uri)!!.reader(charset) fun DocumentFile.readBytes(context: Context) = context.contentResolver.openInputStream(uri)!!.readBytes() fun DocumentFile.readText(context: Context, charset: Charset = Charsets.UTF_8) = reader(context, charset).use { it.readText() } fun DocumentFile.writeBytes(context: Context, array: ByteArray) = context.contentResolver.openOutputStream(uri)!!.write(array) fun DocumentFile.writeText(context: Context, text: String, charset: Charset = Charsets.UTF_8) = writeBytes(context, text.toByteArray(charset)) fun DocumentFile.copyRecursively( context: Context, target: DocumentFile ) { if (!exists()) throw Exception("The source file doesn't exist.") if (this.isFile) { target.let { if (it.findFile(name!!) != null) it else createFile("null", name!!)!! }.writeBytes( context, readBytes(context) ) } else if (this.isDirectory) { target.createDirectory(name!!).also { newTarget -> listFiles().forEach { child -> child.copyRecursively(context, newTarget!!) } } } } fun DocumentFile.deleteRecursively() { if (this.isDirectory) listFiles().forEach { it.deleteRecursively() } this.delete() } fun DocumentFile.walk(state: LinkedList = LinkedList()) : Queue { if (state.isEmpty()) state.push(this) listFiles().forEach { state.push(it) if (it.isDirectory) { it.walk(state) } } return state } fun File.copyTo(context: Context, target: DocumentFile) = target.writeBytes(context, this.readBytes())