Skip to content

Commit

Permalink
Migrated both the ZimFile and ZimFileDescriptor classes into the …
Browse files Browse the repository at this point in the history
…`ZimReaderSource`.

* Now, we have a unified class for opening the ZIM file via path/fd. The file can be opened using the `ZimReaderSource` class with different constructors for path/fd.
  • Loading branch information
MohitMaliDeveloper committed Feb 8, 2024
1 parent f982f53 commit 45c5c63
Show file tree
Hide file tree
Showing 14 changed files with 87 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class MimeTypeTest : BaseActivityTest() {
}
}
}
val zimSource = ZimReaderSource.ZimFile(zimFile)
val zimSource = ZimReaderSource(zimFile)
val zimFileReader = ZimFileReader(
zimSource,
Archive(zimFile.canonicalPath),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ import org.kiwix.kiwixmobile.core.main.MainRepositoryActions
import org.kiwix.kiwixmobile.core.navigateToAppSettings
import org.kiwix.kiwixmobile.core.navigateToSettings
import org.kiwix.kiwixmobile.core.reader.ZimFileReader
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.ZimFile
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource
import org.kiwix.kiwixmobile.core.utils.LanguageUtils
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import org.kiwix.kiwixmobile.core.utils.SimpleRecyclerViewScrollListener
Expand Down Expand Up @@ -396,7 +396,7 @@ class LocalLibraryFragment : BaseFragment() {
// local library screen. Since our application is already aware of this opened ZIM file,
// we can directly add it to the database.
// See https://github.com/kiwix/kiwix-android/issues/3650
zimReaderFactory.create(ZimFile(file))
zimReaderFactory.create(ZimReaderSource(file))
?.let { zimFileReader ->
BookOnDisk(zimFileReader).also {
mainRepositoryActions.saveBook(it)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,8 @@ import org.kiwix.kiwixmobile.core.main.CoreMainActivity
import org.kiwix.kiwixmobile.core.main.CoreReaderFragment
import org.kiwix.kiwixmobile.core.main.CoreWebViewClient
import org.kiwix.kiwixmobile.core.main.ToolbarScrollingKiwixWebView
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.Companion.fromDatabaseValue
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.ZimFile
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.ZimFileDescriptor
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import org.kiwix.kiwixmobile.core.utils.TAG_CURRENT_FILE
import org.kiwix.kiwixmobile.core.utils.TAG_KIWIX
Expand Down Expand Up @@ -119,7 +118,7 @@ class KiwixReaderFragment : CoreReaderFragment() {
activity.toast(R.string.error_file_not_found)
return
}
openZimFile(ZimFile(File(filePath)))
openZimFile(ZimReaderSource(File(filePath)))
}

override fun loadDrawerViews() {
Expand Down Expand Up @@ -296,9 +295,9 @@ class KiwixReaderFragment : CoreReaderFragment() {
super.onNewIntent(intent, activity)
intent.data?.let {
when (it.scheme) {
"file" -> openZimFile(ZimFile(it.toFile()))
"file" -> openZimFile(ZimReaderSource(it.toFile()))
"content" -> {
val zimReaderSource = ZimFileDescriptor(it)
val zimReaderSource = ZimReaderSource(it)
if (zimReaderSource.canOpenInLibkiwix()) {
zimReaderContainer?.let { zimReaderContainer ->
zimReaderContainer.setZimReaderSource(zimReaderSource)
Expand All @@ -311,7 +310,7 @@ class KiwixReaderFragment : CoreReaderFragment() {
}
}
}
openZimFile(ZimFileDescriptor(it))
openZimFile(ZimReaderSource(it))
} else {
activity.toast(R.string.cannot_open_file)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import org.kiwix.kiwixmobile.core.dao.NewBookDao
import org.kiwix.kiwixmobile.core.extensions.isFileExist
import org.kiwix.kiwixmobile.core.extensions.toast
import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource
import org.kiwix.kiwixmobile.core.utils.dialog.DialogShower
import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog.DeleteZims
import org.kiwix.kiwixmobile.core.utils.files.FileUtils
Expand Down Expand Up @@ -68,10 +67,7 @@ data class DeleteFiles(private val booksOnDiskListItems: List<BookOnDisk>) :
}

private fun deleteSpecificZimFile(book: BookOnDisk): Boolean {
val file = when (val source = book.zimReaderSource) {
is ZimReaderSource.ZimFile -> source.file
else -> null
}
val file = book.zimReaderSource.file
file?.let {
@Suppress("UnreachableCode")
FileUtils.deleteZimFile(it.path)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import io.reactivex.schedulers.Schedulers
import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao
import org.kiwix.kiwixmobile.core.downloader.model.DownloadModel
import org.kiwix.kiwixmobile.core.reader.ZimFileReader
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.ZimFile
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource
import org.kiwix.kiwixmobile.core.utils.files.FileSearch
import org.kiwix.kiwixmobile.core.utils.files.ScanningProgressListener
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk
Expand Down Expand Up @@ -55,6 +55,6 @@ class StorageObserver @Inject constructor(
downloads.firstOrNull { file.absolutePath.endsWith(it.fileNameFromUrl) } == null

private fun convertToBookOnDisk(file: File) =
zimReaderFactory.create(ZimFile(file))
zimReaderFactory.create(ZimReaderSource(file))
?.let { zimFileReader -> BookOnDisk(zimFileReader).also { zimFileReader.dispose() } }
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class NewBookDao @Inject constructor(private val box: Box<BookOnDiskEntity>) {
books.map {
BookOnDisk(
book = it,
zimReaderSource = ZimReaderSource.ZimFile(it.file!!)
zimReaderSource = ZimReaderSource(it.file!!)
)
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,5 @@ class ZimSourceConverter : PropertyConverter<ZimReaderSource, String> {
entityProperty?.toDatabase()

override fun convertToEntityProperty(databaseValue: String?): ZimReaderSource =
fromDatabaseValue(databaseValue) ?: ZimReaderSource.ZimFile(File(""))
fromDatabaseValue(databaseValue) ?: ZimReaderSource(File(""))
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ class ZimReaderContainer @Inject constructor(private val zimFileReaderFactory: F
return
}
zimFileReader =
if (zimReaderSource?.exists() == true) zimFileReaderFactory.create(zimReaderSource) else null
if (zimReaderSource?.exists() == true && zimReaderSource.canOpenInLibkiwix())
zimFileReaderFactory.create(zimReaderSource)
else null
}

fun getPageUrlFromTitle(title: String) = zimFileReader?.getPageUrlFrom(title)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,79 +31,83 @@ import org.kiwix.kiwixmobile.core.utils.files.FileUtils.isFileDescriptorCanOpenW
import org.kiwix.libzim.Archive
import java.io.File

sealed class ZimReaderSource {
abstract fun exists(): Boolean
abstract fun canOpenInLibkiwix(): Boolean
abstract fun createArchive(): Archive?
abstract fun toDatabase(): String
class ZimReaderSource(
val file: File? = null,
val uri: Uri? = null,
private val assetFileDescriptor: AssetFileDescriptor? = null
) {
constructor(uri: Uri) : this(
uri = uri,
assetFileDescriptor = getAssetFileDescriptorFromUri(CoreApp.instance, uri)
)

constructor(file: File) : this(file = file, uri = null)

companion object {
fun fromDatabaseValue(databaseValue: String?) =
databaseValue?.let {
if (it.startsWith("content://")) ZimFileDescriptor(it.toUri())
else ZimFile(File(it))
databaseValue?.run {
if (startsWith("content://")) ZimReaderSource(toUri())
else ZimReaderSource(File(this))
}
}

override fun equals(other: Any?): Boolean {
fun exists(): Boolean {
return when {
other is ZimFile && this is ZimFile -> file.canonicalPath == other.file.canonicalPath
other is ZimFileDescriptor && this is ZimFileDescriptor -> uri == other.uri
file != null -> file.isFileExist()
assetFileDescriptor != null ->
assetFileDescriptor.parcelFileDescriptor.fileDescriptor.valid()

else -> false
}
}

fun getUri(activity: AppCompatActivity): Uri? {
return when (this) {
is ZimFile -> {
FileProvider.getUriForFile(
activity,
activity.packageName + ".fileprovider",
file
)
}
fun canOpenInLibkiwix(): Boolean {
return when {
file?.canReadFile() == true -> true
assetFileDescriptor?.parcelFileDescriptor?.fd
?.let(::isFileDescriptorCanOpenWithLibkiwix) == true -> true

is ZimFileDescriptor -> uri
else -> false
}
}

override fun hashCode(): Int {
return when (this) {
is ZimFile -> file.hashCode()
is ZimFileDescriptor -> assetFileDescriptor.hashCode()
fun createArchive(): Archive? {
return file?.let {
Archive(it.canonicalPath)
} ?: assetFileDescriptor?.let {
Archive(
it.parcelFileDescriptor.dup().fileDescriptor,
it.startOffset,
it.length
)
}
}

class ZimFile(val file: File) : ZimReaderSource() {
override fun exists() = file.isFileExist()
override fun canOpenInLibkiwix(): Boolean = file.canReadFile()
fun toDatabase(): String = file?.canonicalPath ?: uri.toString()

override fun createArchive() = Archive(file.canonicalPath)
override fun toDatabase(): String = file.canonicalPath
}

class ZimFileDescriptor(val uri: Uri?, val assetFileDescriptor: AssetFileDescriptor?) :
ZimReaderSource() {

constructor(uri: Uri) : this(
uri,
getAssetFileDescriptorFromUri(CoreApp.instance, uri)
)
override fun equals(other: Any?): Boolean {
return when {
file != null && other is ZimReaderSource && other.file != null ->
file.canonicalPath == other.file.canonicalPath

override fun exists(): Boolean =
assetFileDescriptor?.parcelFileDescriptor?.fileDescriptor?.valid() == true
uri != null && other is ZimReaderSource && other.uri != null -> uri == other.uri
else -> false
}
}

override fun canOpenInLibkiwix(): Boolean =
isFileDescriptorCanOpenWithLibkiwix(assetFileDescriptor?.parcelFileDescriptor?.fd)
fun getUri(activity: AppCompatActivity): Uri? {
return when {
file != null -> {
FileProvider.getUriForFile(
activity,
"${activity.packageName}.fileprovider",
file
)
}

override fun createArchive() = assetFileDescriptor?.let {
Archive(
assetFileDescriptor.parcelFileDescriptor.dup().fileDescriptor,
assetFileDescriptor.startOffset,
assetFileDescriptor.length
)
else -> uri
}

override fun toDatabase(): String = uri.toString()
}

override fun hashCode(): Int = file?.hashCode() ?: assetFileDescriptor.hashCode()
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import org.kiwix.kiwixmobile.core.dao.entities.FetchDownloadEntity
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity.Book
import org.kiwix.kiwixmobile.core.reader.ZimFileReader
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.ZimFile
import org.kiwix.kiwixmobile.core.zim_manager.KiwixTag
import java.io.File
import java.util.Locale
Expand Down Expand Up @@ -62,7 +61,7 @@ sealed class BooksOnDiskListItem {

constructor(fetchDownloadEntity: FetchDownloadEntity) : this(
book = fetchDownloadEntity.toBook(),
zimReaderSource = ZimFile(File(fetchDownloadEntity.file))
zimReaderSource = ZimReaderSource(File(fetchDownloadEntity.file))
)

constructor(zimFileReader: ZimFileReader) : this(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import org.kiwix.kiwixmobile.core.entity.MetaLinkNetworkEntity
import org.kiwix.kiwixmobile.core.entity.MetaLinkNetworkEntity.FileElement
import org.kiwix.kiwixmobile.core.entity.MetaLinkNetworkEntity.Pieces
import org.kiwix.kiwixmobile.core.entity.MetaLinkNetworkEntity.Url
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.ZimFile
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource
import org.kiwix.kiwixmobile.core.zim_manager.Language
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk
Expand All @@ -44,7 +43,7 @@ import java.util.LinkedList
fun bookOnDisk(
databaseId: Long = 0L,
book: Book = book(),
zimReaderSource: ZimReaderSource = ZimFile(File(""))
zimReaderSource: ZimReaderSource = ZimReaderSource(File(""))
) = BookOnDisk(databaseId, book, zimReaderSource)

fun downloadModel(
Expand Down Expand Up @@ -177,7 +176,7 @@ fun recentSearchEntity(

fun bookOnDiskEntity(
id: Long = 0,
zimReaderSource: ZimReaderSource = ZimFile(File("")),
zimReaderSource: ZimReaderSource = ZimReaderSource(File("")),
bookId: String = "",
title: String = "",
description: String = "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,6 @@ class StorageObserverTest {
every { downloadModel.fileNameFromUrl } returns "test"
every { file.absolutePath } returns "This won't match"
every { file.canonicalPath } returns "This won't match"
every { (zimReaderSource as ZimReaderSource.ZimFile).file } returns file
every { zimReaderSource.file } returns file
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import org.kiwix.kiwixmobile.core.dao.entities.BookOnDiskEntity
import org.kiwix.kiwixmobile.core.dao.entities.BookOnDiskEntity_
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.ZimFile
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk
import org.kiwix.sharedFunctions.book
import org.kiwix.sharedFunctions.bookOnDisk
Expand Down Expand Up @@ -123,7 +122,7 @@ internal class NewBookDaoTest {
every {
query.find()
} returns listOf(
bookOnDiskEntity(zimReaderSource = ZimFile(File("matches_nothing")))
bookOnDiskEntity(zimReaderSource = ZimReaderSource(File("matches_nothing")))
)
slot.captured.call()
verify { box.put(listOf(BookOnDiskEntity(distinctBook))) }
Expand Down Expand Up @@ -203,7 +202,7 @@ internal class NewBookDaoTest {
BookOnDiskEntity(
BookOnDisk(
book = book,
zimReaderSource = ZimFile(book.file!!)
zimReaderSource = ZimReaderSource(book.file!!)
)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ import org.kiwix.kiwixmobile.core.base.BaseActivity
import org.kiwix.kiwixmobile.core.extensions.getResizedDrawable
import org.kiwix.kiwixmobile.core.main.CoreReaderFragment
import org.kiwix.kiwixmobile.core.main.MainMenu
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.ZimFile
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.ZimFileDescriptor
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource
import org.kiwix.kiwixmobile.core.utils.LanguageUtils
import org.kiwix.kiwixmobile.core.utils.dialog.DialogShower
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk
Expand Down Expand Up @@ -180,13 +179,14 @@ class CustomReaderFragment : CoreReaderFragment() {
onFilesFound = {
when (it) {
is ValidationState.HasFile -> {
it.assetFileDescriptor?.let { assetFileDescriptor ->
openZimFile(ZimFileDescriptor(null, assetFileDescriptor), true)
} ?: kotlin.run {
it.file?.let { file ->
openZimFile(ZimFile(file), true)
}
}
openZimFile(
ZimReaderSource(
file = it.file,
null,
it.assetFileDescriptor
),
true
)
// Save book in the database to display it in `ZimHostFragment`.
zimReaderContainer?.zimFileReader?.let { zimFileReader ->
// Check if the file is not null. If the file is null,
Expand All @@ -198,7 +198,7 @@ class CustomReaderFragment : CoreReaderFragment() {
}
is ValidationState.HasBothFiles -> {
it.zimFile.delete()
openZimFile(ZimFile(it.obbFile), true)
openZimFile(ZimReaderSource(it.obbFile), true)
}
else -> {}
}
Expand Down

0 comments on commit 45c5c63

Please sign in to comment.