Refactor zip import/export using Path

This commit is contained in:
Isira Seneviratne 2025-07-07 07:52:54 +05:30 committed by Aayush Gupta
parent 668af4fc3e
commit 223b240299
6 changed files with 67 additions and 86 deletions

View file

@ -35,7 +35,6 @@ import org.schabi.newpipe.streams.io.StoredFileHelper;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.ZipHelper;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
@ -70,13 +69,12 @@ public class BackupRestoreSettingsFragment extends BasePreferenceFragment {
@Override
public void onCreatePreferences(@Nullable final Bundle savedInstanceState,
@Nullable final String rootKey) {
final File homeDir = ContextCompat.getDataDir(requireContext());
Objects.requireNonNull(homeDir);
manager = new ImportExportManager(new BackupFileLocator(homeDir));
final var dbDir = Objects.requireNonNull(ContextCompat.getDataDir(requireContext()))
.toPath();
manager = new ImportExportManager(new BackupFileLocator(dbDir));
importExportDataPathKey = getString(R.string.import_export_data_path);
addPreferencesFromResourceRegistry();
final Preference importDataPreference = requirePreference(R.string.import_data);
@ -204,9 +202,7 @@ public class BackupRestoreSettingsFragment extends BasePreferenceFragment {
}
try {
if (!manager.ensureDbDirectoryExists()) {
throw new IOException("Could not create databases dir");
}
manager.ensureDbDirectoryExists();
// replace the current database
if (!manager.extractDb(file)) {

View file

@ -1,11 +1,12 @@
package org.schabi.newpipe.settings.export
import java.io.File
import java.nio.file.Path
import kotlin.io.path.div
/**
* Locates specific files of NewPipe based on the home directory of the app.
*/
class BackupFileLocator(private val homeDir: File) {
class BackupFileLocator(homeDir: Path) {
companion object {
const val FILE_NAME_DB = "newpipe.db"
@ -17,13 +18,9 @@ class BackupFileLocator(private val homeDir: File) {
const val FILE_NAME_JSON_PREFS = "preferences.json"
}
val dbDir by lazy { File(homeDir, "/databases") }
val db by lazy { File(dbDir, FILE_NAME_DB) }
val dbJournal by lazy { File(dbDir, "$FILE_NAME_DB-journal") }
val dbShm by lazy { File(dbDir, "$FILE_NAME_DB-shm") }
val dbWal by lazy { File(dbDir, "$FILE_NAME_DB-wal") }
val dbDir = homeDir / "databases"
val db = homeDir / FILE_NAME_DB
val dbJournal = homeDir / "$FILE_NAME_DB-journal"
val dbShm = dbDir / "$FILE_NAME_DB-shm"
val dbWal = dbDir / "$FILE_NAME_DB-wal"
}

View file

@ -9,6 +9,8 @@ import java.io.FileNotFoundException
import java.io.IOException
import java.io.ObjectOutputStream
import java.util.zip.ZipOutputStream
import kotlin.io.path.createDirectories
import kotlin.io.path.deleteExisting
import org.schabi.newpipe.streams.io.SharpOutputStream
import org.schabi.newpipe.streams.io.StoredFileHelper
import org.schabi.newpipe.util.ZipHelper
@ -28,11 +30,8 @@ class ImportExportManager(private val fileLocator: BackupFileLocator) {
// previous file size, the file will retain part of the previous content and be corrupted
ZipOutputStream(SharpOutputStream(file.openAndTruncateStream()).buffered()).use { outZip ->
// add the database
ZipHelper.addFileToZip(
outZip,
BackupFileLocator.FILE_NAME_DB,
fileLocator.db.path
)
val name = BackupFileLocator.FILE_NAME_DB
ZipHelper.addFileToZip(outZip, name, fileLocator.db)
// add the legacy vulnerable serialized preferences (will be removed in the future)
ZipHelper.addFileToZip(
@ -61,11 +60,10 @@ class ImportExportManager(private val fileLocator: BackupFileLocator) {
/**
* Tries to create database directory if it does not exist.
*
* @return Whether the directory exists afterwards.
*/
fun ensureDbDirectoryExists(): Boolean {
return fileLocator.dbDir.exists() || fileLocator.dbDir.mkdir()
@Throws(IOException::class)
fun ensureDbDirectoryExists() {
fileLocator.dbDir.createDirectories()
}
/**
@ -75,16 +73,13 @@ class ImportExportManager(private val fileLocator: BackupFileLocator) {
* @return true if the database was successfully extracted, false otherwise
*/
fun extractDb(file: StoredFileHelper): Boolean {
val success = ZipHelper.extractFileFromZip(
file,
BackupFileLocator.FILE_NAME_DB,
fileLocator.db.path
)
val name = BackupFileLocator.FILE_NAME_DB
val success = ZipHelper.extractFileFromZip(file, name, fileLocator.db)
if (success) {
fileLocator.dbJournal.delete()
fileLocator.dbWal.delete()
fileLocator.dbShm.delete()
fileLocator.dbJournal.deleteExisting()
fileLocator.dbWal.deleteExisting()
fileLocator.dbShm.deleteExisting()
}
return success

View file

@ -6,12 +6,12 @@ import org.schabi.newpipe.streams.io.StoredFileHelper;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
@ -55,17 +55,17 @@ public final class ZipHelper {
/**
* This function helps to create zip files. Caution this will overwrite the original file.
* This function helps to create zip files. Caution, this will overwrite the original file.
*
* @param outZip the ZipOutputStream where the data should be stored in
* @param nameInZip the path of the file inside the zip
* @param fileOnDisk the path of the file on the disk that should be added to zip
* @param path the path of the file on the disk that should be added to zip
*/
public static void addFileToZip(final ZipOutputStream outZip,
final String nameInZip,
final String fileOnDisk) throws IOException {
try (FileInputStream fi = new FileInputStream(fileOnDisk)) {
addFileToZip(outZip, nameInZip, fi);
final Path path) throws IOException {
try (var inputStream = Files.newInputStream(path)) {
addFileToZip(outZip, nameInZip, inputStream);
}
}
@ -113,33 +113,18 @@ public final class ZipHelper {
}
/**
* This will extract data from ZipInputStream. Caution this will overwrite the original file.
* This will extract data from ZipInputStream. Caution, this will overwrite the original file.
*
* @param zipFile the zip file to extract from
* @param nameInZip the path of the file inside the zip
* @param fileOnDisk the path of the file on the disk where the data should be extracted to
* @param path the path of the file on the disk where the data should be extracted to
* @return will return true if the file was found within the zip file
*/
public static boolean extractFileFromZip(final StoredFileHelper zipFile,
final String nameInZip,
final String fileOnDisk) throws IOException {
return extractFileFromZip(zipFile, nameInZip, input -> {
// delete old file first
final File oldFile = new File(fileOnDisk);
if (oldFile.exists()) {
if (!oldFile.delete()) {
throw new IOException("Could not delete " + fileOnDisk);
}
}
final byte[] data = new byte[BUFFER_SIZE];
try (FileOutputStream outFile = new FileOutputStream(fileOnDisk)) {
int count;
while ((count = input.read(data)) != -1) {
outFile.write(data, 0, count);
}
}
});
final Path path) throws IOException {
return extractFileFromZip(zipFile, nameInZip, input ->
Files.copy(input, path, StandardCopyOption.REPLACE_EXISTING));
}
/**