mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 15:57:25 +00:00
Fix archive download when using custom download path on Android.
This commit is contained in:
@@ -2,6 +2,8 @@ import 'dart:async';
|
|||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
|
|
||||||
import 'package:flutter/widgets.dart' show ChangeNotifier;
|
import 'package:flutter/widgets.dart' show ChangeNotifier;
|
||||||
|
import 'package:flutter_saf/flutter_saf.dart';
|
||||||
|
import 'package:venera/foundation/app.dart';
|
||||||
import 'package:venera/foundation/appdata.dart';
|
import 'package:venera/foundation/appdata.dart';
|
||||||
import 'package:venera/foundation/comic_source/comic_source.dart';
|
import 'package:venera/foundation/comic_source/comic_source.dart';
|
||||||
import 'package:venera/foundation/comic_type.dart';
|
import 'package:venera/foundation/comic_type.dart';
|
||||||
@@ -739,11 +741,12 @@ class ArchiveDownloadTask extends DownloadTask {
|
|||||||
path = dir.path;
|
path = dir.path;
|
||||||
}
|
}
|
||||||
|
|
||||||
var resultFile = File(FilePath.join(path!, "archive.zip"));
|
var archiveFile =
|
||||||
|
File(FilePath.join(App.dataPath, "archive_downloading.zip"));
|
||||||
|
|
||||||
Log.info("Download", "Downloading $archiveUrl");
|
Log.info("Download", "Downloading $archiveUrl");
|
||||||
|
|
||||||
_downloader = FileDownloader(archiveUrl, resultFile.path);
|
_downloader = FileDownloader(archiveUrl, archiveFile.path);
|
||||||
|
|
||||||
bool isDownloaded = false;
|
bool isDownloaded = false;
|
||||||
|
|
||||||
@@ -772,22 +775,33 @@ class ArchiveDownloadTask extends DownloadTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await extractArchive(path!);
|
await _extractArchive(archiveFile.path, path!);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
_setError("Failed to extract archive: $e");
|
_setError("Failed to extract archive: $e");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await resultFile.deleteIgnoreError();
|
await archiveFile.deleteIgnoreError();
|
||||||
|
|
||||||
LocalManager().completeTask(this);
|
LocalManager().completeTask(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> extractArchive(String path) async {
|
static Future<void> _extractArchive(String archive, String outDir) async {
|
||||||
var resultFile = FilePath.join(path, "archive.zip");
|
var out = Directory(outDir);
|
||||||
|
if (out is AndroidDirectory) {
|
||||||
|
// Saf directory can't be accessed by native code.
|
||||||
|
var cacheDir = FilePath.join(App.cachePath, "archive_downloading");
|
||||||
|
Directory(cacheDir).forceCreateSync();
|
||||||
await Isolate.run(() {
|
await Isolate.run(() {
|
||||||
ZipFile.openAndExtract(resultFile, path);
|
ZipFile.openAndExtract(archive, cacheDir);
|
||||||
});
|
});
|
||||||
|
await copyDirectoryIsolate(Directory(cacheDir), Directory(outDir));
|
||||||
|
await Directory(cacheDir).deleteIgnoreError(recursive: true);
|
||||||
|
} else {
|
||||||
|
await Isolate.run(() {
|
||||||
|
ZipFile.openAndExtract(archive, outDir);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@@ -40,6 +40,7 @@ extension FileSystemEntityExt on FileSystemEntity {
|
|||||||
return p.basename(path);
|
return p.basename(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Delete the file or directory and ignore errors.
|
||||||
Future<void> deleteIgnoreError({bool recursive = false}) async {
|
Future<void> deleteIgnoreError({bool recursive = false}) async {
|
||||||
try {
|
try {
|
||||||
await delete(recursive: recursive);
|
await delete(recursive: recursive);
|
||||||
@@ -48,12 +49,14 @@ extension FileSystemEntityExt on FileSystemEntity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Delete the file or directory if it exists.
|
||||||
Future<void> deleteIfExists({bool recursive = false}) async {
|
Future<void> deleteIfExists({bool recursive = false}) async {
|
||||||
if (existsSync()) {
|
if (existsSync()) {
|
||||||
await delete(recursive: recursive);
|
await delete(recursive: recursive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Delete the file or directory if it exists.
|
||||||
void deleteIfExistsSync({bool recursive = false}) {
|
void deleteIfExistsSync({bool recursive = false}) {
|
||||||
if (existsSync()) {
|
if (existsSync()) {
|
||||||
deleteSync(recursive: recursive);
|
deleteSync(recursive: recursive);
|
||||||
@@ -74,12 +77,14 @@ extension FileExtension on File {
|
|||||||
await newFile.writeAsBytes(await readAsBytes());
|
await newFile.writeAsBytes(await readAsBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the base name of the file without the extension.
|
||||||
String get basenameWithoutExt {
|
String get basenameWithoutExt {
|
||||||
return p.basenameWithoutExtension(path);
|
return p.basenameWithoutExtension(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension DirectoryExtension on Directory {
|
extension DirectoryExtension on Directory {
|
||||||
|
/// Calculate the size of the directory.
|
||||||
Future<int> get size async {
|
Future<int> get size async {
|
||||||
if (!existsSync()) return 0;
|
if (!existsSync()) return 0;
|
||||||
int total = 0;
|
int total = 0;
|
||||||
@@ -91,6 +96,7 @@ extension DirectoryExtension on Directory {
|
|||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Change the base name of the directory.
|
||||||
Directory renameX(String newName) {
|
Directory renameX(String newName) {
|
||||||
newName = sanitizeFileName(newName);
|
newName = sanitizeFileName(newName);
|
||||||
return renameSync(path.replaceLast(name, newName));
|
return renameSync(path.replaceLast(name, newName));
|
||||||
@@ -100,6 +106,7 @@ extension DirectoryExtension on Directory {
|
|||||||
return File(FilePath.join(path, name));
|
return File(FilePath.join(path, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Delete the contents of the directory.
|
||||||
void deleteContentsSync({recursive = true}) {
|
void deleteContentsSync({recursive = true}) {
|
||||||
if (!existsSync()) return;
|
if (!existsSync()) return;
|
||||||
for (var f in listSync()) {
|
for (var f in listSync()) {
|
||||||
@@ -107,14 +114,24 @@ extension DirectoryExtension on Directory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Delete the contents of the directory.
|
||||||
Future<void> deleteContents({recursive = true}) async {
|
Future<void> deleteContents({recursive = true}) async {
|
||||||
if (!existsSync()) return;
|
if (!existsSync()) return;
|
||||||
for (var f in listSync()) {
|
for (var f in listSync()) {
|
||||||
await f.deleteIfExists(recursive: recursive);
|
await f.deleteIfExists(recursive: recursive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create the directory. If the directory already exists, delete it first.
|
||||||
|
void forceCreateSync() {
|
||||||
|
if (existsSync()) {
|
||||||
|
deleteSync(recursive: true);
|
||||||
|
}
|
||||||
|
createSync(recursive: true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sanitize the file name. Remove invalid characters and trim the file name.
|
||||||
String sanitizeFileName(String fileName) {
|
String sanitizeFileName(String fileName) {
|
||||||
if (fileName.endsWith('.')) {
|
if (fileName.endsWith('.')) {
|
||||||
fileName = fileName.substring(0, fileName.length - 1);
|
fileName = fileName.substring(0, fileName.length - 1);
|
||||||
@@ -157,6 +174,8 @@ Future<void> copyDirectory(Directory source, Directory destination) async {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Copy the **contents** of the source directory to the destination directory.
|
||||||
|
/// This function is executed in an isolate to prevent the UI from freezing.
|
||||||
Future<void> copyDirectoryIsolate(
|
Future<void> copyDirectoryIsolate(
|
||||||
Directory source, Directory destination) async {
|
Directory source, Directory destination) async {
|
||||||
await Isolate.run(() => overrideIO(() => copyDirectory(source, destination)));
|
await Isolate.run(() => overrideIO(() => copyDirectory(source, destination)));
|
||||||
|
Reference in New Issue
Block a user