From 35f45513aa8777313390d03c4e76bb5d79371477 Mon Sep 17 00:00:00 2001 From: Tom Hicks Date: Tue, 22 Sep 2026 20:35:44 -0700 Subject: [PATCH] Initialize ID for PF2e imported monsters to prevent SQLite exceptions --- .../monstercards/data/ImportConfig.java | 16 +- .../importers/GitRepoImporterService.java | 29 ++- .../monstercards/importers/Pf2eImporter.java | 2 + .../monstercards/models/ImportSource.java | 4 +- .../MonsterCards.xcdatamodel/contents | 170 ++++++++++-------- .../MonsterCards_1.xcdatamodel/contents | 79 ++++++++ 6 files changed, 213 insertions(+), 87 deletions(-) create mode 100644 iOS/MonsterCards/MonsterCards.xcdatamodeld/MonsterCards_1.xcdatamodel/contents diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/data/ImportConfig.java b/Android/app/src/main/java/com/majinnaibu/monstercards/data/ImportConfig.java index 37b2c0b..36554ff 100644 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/data/ImportConfig.java +++ b/Android/app/src/main/java/com/majinnaibu/monstercards/data/ImportConfig.java @@ -17,6 +17,7 @@ public class ImportConfig { ImportSource.ImportType.OPEN5E_API, null, null, + null, null )); @@ -28,7 +29,20 @@ public class ImportConfig { ImportSource.ImportType.GIT_ARCHIVE, "https://github.com/foundryvtt/pf2e/archive/refs/heads/master.zip", "com.majinnaibu.monstercards.importers.Pf2eImporter", - ".json" + ".json", + "packs/pf2e" + )); + + SOURCES.add(new ImportSource( + "sf2e_foundry", + "Starfinder 2e Foundry VTT", + "foundryvtt", + "https://github.com/foundryvtt/pf2e", + ImportSource.ImportType.GIT_ARCHIVE, + "https://github.com/foundryvtt/pf2e/archive/refs/heads/master.zip", + "com.majinnaibu.monstercards.importers.Pf2eImporter", + ".json", + "packs/sf2e" )); } } diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/importers/GitRepoImporterService.java b/Android/app/src/main/java/com/majinnaibu/monstercards/importers/GitRepoImporterService.java index 0e04cad..55f81d9 100644 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/importers/GitRepoImporterService.java +++ b/Android/app/src/main/java/com/majinnaibu/monstercards/importers/GitRepoImporterService.java @@ -1,7 +1,7 @@ package com.majinnaibu.monstercards.importers; import android.content.Context; -import android.net.Uri; +import android.os.Environment; import androidx.annotation.NonNull; @@ -31,19 +31,30 @@ public class GitRepoImporterService { public static int importFromGitRepository(Context context, ImportSource source, BooleanSupplier isCancelled) throws Exception { int totalImported = 0; - File tempZip = File.createTempFile("repo_download", ".zip", context.getCacheDir()); + File downloadsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); + if (!downloadsDir.exists()) { + downloadsDir.mkdirs(); + } + + File tempZip = null; + File[] existingZips = downloadsDir.listFiles((dir, name) -> name.startsWith(source.id + "_download") && name.endsWith(".zip")); + if (existingZips != null && existingZips.length > 0) { + tempZip = existingZips[0]; + } else { + tempZip = new File(downloadsDir, source.id + "_download_" + System.currentTimeMillis() + ".zip"); + downloadZip(source.downloadUrl, tempZip, isCancelled); + } + File extractDir = new File(context.getCacheDir(), "repo_extracted_" + System.currentTimeMillis()); try { - downloadZip(source.downloadUrl, tempZip, isCancelled); - if (isCancelled.getAsBoolean()) return 0; if (!extractDir.exists()) { extractDir.mkdirs(); } - unzipAndFilter(tempZip, extractDir, source.fileExtension, isCancelled); + unzipAndFilter(tempZip, extractDir, source.fileExtension, source.subfolder, isCancelled); if (isCancelled.getAsBoolean()) return 0; @@ -58,7 +69,8 @@ public class GitRepoImporterService { totalImported = processDirectory(extractDir, importer, repository, isCancelled); } finally { - deleteFileOrDir(tempZip); + // We no longer delete tempZip since the user wants to keep the downloaded zip + // deleteFileOrDir(tempZip); deleteFileOrDir(extractDir); } @@ -97,14 +109,15 @@ public class GitRepoImporterService { } } - private static void unzipAndFilter(File zipFile, File extractDir, String filterExtension, BooleanSupplier isCancelled) throws IOException { + private static void unzipAndFilter(File zipFile, File extractDir, String filterExtension, String subfolder, BooleanSupplier isCancelled) throws IOException { try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile))) { ZipEntry entry; while ((entry = zis.getNextEntry()) != null) { if (isCancelled.getAsBoolean()) break; if (!entry.isDirectory()) { String name = entry.getName(); - if (filterExtension == null || name.endsWith(filterExtension)) { + boolean inSubfolder = subfolder == null || subfolder.isEmpty() || name.contains("/" + subfolder + "/") || name.startsWith(subfolder + "/"); + if (inSubfolder && (filterExtension == null || name.endsWith(filterExtension))) { File outFile = new File(extractDir, new File(name).getName()); if (outFile.exists()) { outFile = new File(extractDir, System.currentTimeMillis() + "_" + new File(name).getName()); diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/importers/Pf2eImporter.java b/Android/app/src/main/java/com/majinnaibu/monstercards/importers/Pf2eImporter.java index 02df785..8176648 100644 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/importers/Pf2eImporter.java +++ b/Android/app/src/main/java/com/majinnaibu/monstercards/importers/Pf2eImporter.java @@ -16,6 +16,7 @@ import com.majinnaibu.monstercards.models.Skill; import com.majinnaibu.monstercards.models.Trait; import java.util.Locale; +import java.util.UUID; public class Pf2eImporter implements EntityImporter { @Override @@ -43,6 +44,7 @@ public class Pf2eImporter implements EntityImporter { JsonObject system = root.has("system") ? root.getAsJsonObject("system") : new JsonObject(); Monster monster = new Monster(); + monster.id = UUID.randomUUID(); // Name if (root.has("name") && !root.get("name").isJsonNull()) { diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/models/ImportSource.java b/Android/app/src/main/java/com/majinnaibu/monstercards/models/ImportSource.java index 819d19d..617644d 100644 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/models/ImportSource.java +++ b/Android/app/src/main/java/com/majinnaibu/monstercards/models/ImportSource.java @@ -16,8 +16,9 @@ public class ImportSource { public String downloadUrl; public String importerClassName; public String fileExtension; + public String subfolder; - public ImportSource(String id, String projectName, String creatorName, String creatorPageLink, ImportType importType, String downloadUrl, String importerClassName, String fileExtension) { + public ImportSource(String id, String projectName, String creatorName, String creatorPageLink, ImportType importType, String downloadUrl, String importerClassName, String fileExtension, String subfolder) { this.id = id; this.projectName = projectName; this.creatorName = creatorName; @@ -26,5 +27,6 @@ public class ImportSource { this.downloadUrl = downloadUrl; this.importerClassName = importerClassName; this.fileExtension = fileExtension; + this.subfolder = subfolder; } } diff --git a/iOS/MonsterCards/MonsterCards.xcdatamodeld/MonsterCards.xcdatamodel/contents b/iOS/MonsterCards/MonsterCards.xcdatamodeld/MonsterCards.xcdatamodel/contents index d51cf96..5551597 100644 --- a/iOS/MonsterCards/MonsterCards.xcdatamodeld/MonsterCards.xcdatamodel/contents +++ b/iOS/MonsterCards/MonsterCards.xcdatamodeld/MonsterCards.xcdatamodel/contents @@ -1,79 +1,95 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOS/MonsterCards/MonsterCards.xcdatamodeld/MonsterCards_1.xcdatamodel/contents b/iOS/MonsterCards/MonsterCards.xcdatamodeld/MonsterCards_1.xcdatamodel/contents new file mode 100644 index 0000000..d51cf96 --- /dev/null +++ b/iOS/MonsterCards/MonsterCards.xcdatamodeld/MonsterCards_1.xcdatamodel/contents @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file