From a711335012f6ad80525331a0864930fc408ee3a1 Mon Sep 17 00:00:00 2001 From: nyne Date: Sun, 1 Dec 2024 18:06:19 +0800 Subject: [PATCH] import pica data --- lib/pages/settings/app.dart | 13 ++- lib/utils/data.dart | 213 +++++++++++++++++++++++++++--------- lib/utils/io.dart | 4 +- 3 files changed, 173 insertions(+), 57 deletions(-) diff --git a/lib/pages/settings/app.dart b/lib/pages/settings/app.dart index 234340c..c59e19e 100644 --- a/lib/pages/settings/app.dart +++ b/lib/pages/settings/app.dart @@ -110,16 +110,23 @@ class _AppSettingsState extends State { title: "Import App Data".tl, callback: () async { var controller = showLoadingDialog(context); - var file = await selectFile(ext: ['venera']); + var file = await selectFile(ext: ['venera', 'picadata']); if (file != null) { - var cacheFile = File(FilePath.join(App.cachePath, "temp.venera")); + var cacheFile = File(FilePath.join(App.cachePath, "import_data_temp")); await file.saveTo(cacheFile.path); try { - await importAppData(cacheFile); + if(file.name.endsWith('picadata')) { + await importPicaData(cacheFile); + } else { + await importAppData(cacheFile); + } } catch (e, s) { Log.error("Import data", e.toString(), s); context.showMessage(message: "Failed to import data".tl); } + finally { + cacheFile.deleteIgnoreError(); + } } controller.close(); }, diff --git a/lib/utils/data.dart b/lib/utils/data.dart index 00f4264..788191d 100644 --- a/lib/utils/data.dart +++ b/lib/utils/data.dart @@ -1,11 +1,14 @@ import 'dart:convert'; import 'dart:isolate'; +import 'package:sqlite3/sqlite3.dart'; import 'package:venera/foundation/app.dart'; import 'package:venera/foundation/appdata.dart'; import 'package:venera/foundation/comic_source/comic_source.dart'; +import 'package:venera/foundation/comic_type.dart'; import 'package:venera/foundation/favorites.dart'; import 'package:venera/foundation/history.dart'; +import 'package:venera/foundation/log.dart'; import 'package:venera/network/cookie_jar.dart'; import 'package:zip_flutter/zip_flutter.dart'; @@ -43,61 +46,165 @@ Future exportAppData() async { Future importAppData(File file, [bool checkVersion = false]) async { var cacheDirPath = FilePath.join(App.cachePath, 'temp_data'); var cacheDir = Directory(cacheDirPath); - await Isolate.run(() { - ZipFile.openAndExtract(file.path, cacheDirPath); - }); - var historyFile = cacheDir.joinFile("history.db"); - var localFavoriteFile = cacheDir.joinFile("local_favorite.db"); - var appdataFile = cacheDir.joinFile("appdata.json"); - var cookieFile = cacheDir.joinFile("cookie.db"); - if (checkVersion && appdataFile.existsSync()) { - var data = jsonDecode(await appdataFile.readAsString()); - var version = data["settings"]["dataVersion"]; - if (version is int && version <= appdata.settings["dataVersion"]) { - return; - } + if (cacheDir.existsSync()) { + cacheDir.deleteSync(recursive: true); } - if (await historyFile.exists()) { - HistoryManager().close(); - File(FilePath.join(App.dataPath, "history.db")).deleteIfExistsSync(); - historyFile.renameSync(FilePath.join(App.dataPath, "history.db")); - HistoryManager().init(); - } - if (await localFavoriteFile.exists()) { - LocalFavoritesManager().close(); - File(FilePath.join(App.dataPath, "local_favorite.db")).deleteIfExistsSync(); - localFavoriteFile - .renameSync(FilePath.join(App.dataPath, "local_favorite.db")); - LocalFavoritesManager().init(); - } - if (await appdataFile.exists()) { - // proxy settings & authorization setting should be kept - var proxySettings = appdata.settings["proxy"]; - var authSettings = appdata.settings["authorizationRequired"]; - File(FilePath.join(App.dataPath, "appdata.json")).deleteIfExistsSync(); - appdataFile.renameSync(FilePath.join(App.dataPath, "appdata.json")); - await appdata.init(); - appdata.settings["proxy"] = proxySettings; - appdata.settings["authorizationRequired"] = authSettings; - appdata.saveData(); - } - if (await cookieFile.exists()) { - SingleInstanceCookieJar.instance?.dispose(); - File(FilePath.join(App.dataPath, "cookie.db")).deleteIfExistsSync(); - cookieFile.renameSync(FilePath.join(App.dataPath, "cookie.db")); - SingleInstanceCookieJar.instance = - SingleInstanceCookieJar(FilePath.join(App.dataPath, "cookie.db")) - ..init(); - } - var comicSourceDir = FilePath.join(cacheDirPath, "comic_source"); - if (Directory(comicSourceDir).existsSync()) { - for (var file in Directory(comicSourceDir).listSync()) { - if (file is File) { - var targetFile = FilePath.join(App.dataPath, "comic_source", file.name); - File(targetFile).deleteIfExistsSync(); - await file.copy(targetFile); + cacheDir.createSync(); + try { + await Isolate.run(() { + ZipFile.openAndExtract(file.path, cacheDirPath); + }); + var historyFile = cacheDir.joinFile("history.db"); + var localFavoriteFile = cacheDir.joinFile("local_favorite.db"); + var appdataFile = cacheDir.joinFile("appdata.json"); + var cookieFile = cacheDir.joinFile("cookie.db"); + if (checkVersion && appdataFile.existsSync()) { + var data = jsonDecode(await appdataFile.readAsString()); + var version = data["settings"]["dataVersion"]; + if (version is int && version <= appdata.settings["dataVersion"]) { + return; } } - await ComicSource.reload(); + if (await historyFile.exists()) { + HistoryManager().close(); + File(FilePath.join(App.dataPath, "history.db")).deleteIfExistsSync(); + historyFile.renameSync(FilePath.join(App.dataPath, "history.db")); + HistoryManager().init(); + } + if (await localFavoriteFile.exists()) { + LocalFavoritesManager().close(); + File(FilePath.join(App.dataPath, "local_favorite.db")) + .deleteIfExistsSync(); + localFavoriteFile + .renameSync(FilePath.join(App.dataPath, "local_favorite.db")); + LocalFavoritesManager().init(); + } + if (await appdataFile.exists()) { + // proxy settings & authorization setting should be kept + var proxySettings = appdata.settings["proxy"]; + var authSettings = appdata.settings["authorizationRequired"]; + File(FilePath.join(App.dataPath, "appdata.json")).deleteIfExistsSync(); + appdataFile.renameSync(FilePath.join(App.dataPath, "appdata.json")); + await appdata.init(); + appdata.settings["proxy"] = proxySettings; + appdata.settings["authorizationRequired"] = authSettings; + appdata.saveData(); + } + if (await cookieFile.exists()) { + SingleInstanceCookieJar.instance?.dispose(); + File(FilePath.join(App.dataPath, "cookie.db")).deleteIfExistsSync(); + cookieFile.renameSync(FilePath.join(App.dataPath, "cookie.db")); + SingleInstanceCookieJar.instance = + SingleInstanceCookieJar(FilePath.join(App.dataPath, "cookie.db")) + ..init(); + } + var comicSourceDir = FilePath.join(cacheDirPath, "comic_source"); + if (Directory(comicSourceDir).existsSync()) { + for (var file in Directory(comicSourceDir).listSync()) { + if (file is File) { + var targetFile = + FilePath.join(App.dataPath, "comic_source", file.name); + File(targetFile).deleteIfExistsSync(); + await file.copy(targetFile); + } + } + await ComicSource.reload(); + } + } finally { + cacheDir.deleteIgnoreError(recursive: true); + } +} + +Future importPicaData(File file) async { + var cacheDirPath = FilePath.join(App.cachePath, 'temp_data'); + var cacheDir = Directory(cacheDirPath); + if (cacheDir.existsSync()) { + cacheDir.deleteSync(recursive: true); + } + cacheDir.createSync(); + try { + await Isolate.run(() { + ZipFile.openAndExtract(file.path, cacheDirPath); + }); + var localFavoriteFile = cacheDir.joinFile("local_favorite.db"); + if (localFavoriteFile.existsSync()) { + var db = sqlite3.open(localFavoriteFile.path); + try { + var folderNames = db + .select("SELECT name FROM sqlite_master WHERE type='table';") + .map((e) => e["name"] as String) + .toList(); + folderNames.removeWhere((e) => e == "folder_order" || e == "folder_sync"); + for (var folderName in folderNames) { + if (!LocalFavoritesManager().existsFolder(folderName)) { + LocalFavoritesManager().createFolder(folderName); + } + for (var comic in db.select("SELECT * FROM \"$folderName\";")) { + LocalFavoritesManager().addComic( + folderName, + FavoriteItem( + id: comic['target'], + name: comic['name'], + coverPath: comic['cover_path'], + author: comic['author'], + type: ComicType(switch(comic['type']) { + 0 => 'picacg'.hashCode, + 1 => 'ehentai'.hashCode, + 2 => 'jm'.hashCode, + 3 => 'hitomi'.hashCode, + 4 => 'wnacg'.hashCode, + 6 => 'nhentai'.hashCode, + _ => comic['type'] + }), + tags: comic['tags'].split(','), + ), + ); + } + } + } + catch(e) { + Log.error("Import Data", "Failed to import local favorite: $e"); + } + finally { + db.dispose(); + } + } + var historyFile = cacheDir.joinFile("history.db"); + if (historyFile.existsSync()) { + var db = sqlite3.open(historyFile.path); + try { + for (var comic in db.select("SELECT * FROM history;")) { + HistoryManager().addHistory( + History.fromMap({ + "type": switch(comic['type']) { + 0 => 'picacg'.hashCode, + 1 => 'ehentai'.hashCode, + 2 => 'jm'.hashCode, + 3 => 'hitomi'.hashCode, + 4 => 'wnacg'.hashCode, + 6 => 'nhentai'.hashCode, + _ => comic['type'] + }, + "id": comic['target'], + "maxPage": comic["max_page"], + "ep": comic["ep"], + "page": comic["page"], + "time": comic["time"], + "title": comic["title"], + "subtitle": comic["subtitle"], + "cover": comic["cover"], + }), + ); + } + } + catch(e) { + Log.error("Import Data", "Failed to import history: $e"); + } + finally { + db.dispose(); + } + } + } finally { + cacheDir.deleteIgnoreError(recursive: true); } } diff --git a/lib/utils/io.dart b/lib/utils/io.dart index 2a959ce..cb167ae 100644 --- a/lib/utils/io.dart +++ b/lib/utils/io.dart @@ -265,7 +265,9 @@ Future selectFile({required List ext}) async { file = FileSelectResult(xFile.path); } if (!ext.contains(file.path.split(".").last)) { - App.rootContext.showMessage(message: "Invalid file type"); + App.rootContext.showMessage( + message: "Invalid file type: ${file.path.split(".").last}", + ); return null; } return file;