-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.js
More file actions
143 lines (123 loc) Β· 4.61 KB
/
main.js
File metadata and controls
143 lines (123 loc) Β· 4.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
const { app, BrowserWindow, ipcMain } = require("electron");
const path = require("path");
const { execFile } = require("child_process");
const { dialog } = require("electron");
const fs = require("fs");
function createWindow() {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.resolve(__dirname, "preload.js"),
contextIsolation: true,
nodeIntegration: false,
},
});
win.loadFile("index.html");
}
app.whenReady().then(() => {
createWindow();
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
app.on("window-all-closed", () => {
if (process.platform !== "darwin") app.quit();
});
// π Run extractor with db + output
ipcMain.handle("run-extractor", async (event, { dbPath }) => {
return new Promise((resolve) => {
if (!dbPath) {
resolve({ success: false, error: "β Missing database file." });
return;
}
const outputDir = app.getPath("documents") + "/iExtractExports";
fs.mkdirSync(outputDir, { recursive: true });
const timestamp = Date.now();
const outFile = path.join(outputDir, `iextract_output_${timestamp}.csv`);
const isDev = !app.isPackaged;
const scriptPath = isDev
? path.join(__dirname, "extract.js")
: path.join(process.resourcesPath, "app.asar.unpacked", "extract.js");
const resolvedDbPath = path.resolve(dbPath);
const resolvedOutFile = path.resolve(outFile);
console.log("π Executing extractor with paths:", resolvedDbPath, resolvedOutFile);
execFile(process.execPath, [scriptPath, resolvedDbPath, resolvedOutFile], (err, stdout, stderr) => {
console.log("Executing:", scriptPath, resolvedDbPath, resolvedOutFile);
console.log("STDOUT:", stdout);
console.log("STDERR:", stderr);
if (err) {
console.error("β Extractor execution error:", err);
resolve({ success: false, error: stderr || err.message });
} else {
fs.access(resolvedOutFile, fs.constants.F_OK, (accessErr) => {
if (accessErr) {
console.error("β Output file was not created:", resolvedOutFile);
resolve({ success: false, error: "Output file not found after script execution." });
} else {
const { shell } = require("electron");
shell.showItemInFolder(resolvedOutFile);
console.log("β
File created successfully:", resolvedOutFile);
resolve({ success: true, filename: resolvedOutFile });
}
});
}
});
});
});
// π Merge .db + .shm + .wal
ipcMain.handle("merge-db-files", async (event, filePaths) => {
try {
const dbPath = filePaths.find(file => file.endsWith(".db"));
const shmPath = filePaths.find(file => file.endsWith(".db-shm"));
const walPath = filePaths.find(file => file.endsWith(".db-wal"));
if (!dbPath || !shmPath || !walPath) {
return { success: false, error: "All three files must be selected." };
}
const { execSync } = require("child_process");
execSync(`sqlite3 "${dbPath}" "PRAGMA wal_checkpoint(FULL);"`, { stdio: 'inherit' });
return { success: true, mergedPath: dbPath };
} catch (err) {
console.error("β Merge error:", err);
return { success: false, error: err.message };
}
});
// π Finalize (optional integrity check)
ipcMain.handle("finalizeDatabase", async (event, filePaths) => {
if (!filePaths || filePaths.length !== 3) {
return { success: false, error: "Please provide all 3 files." };
}
try {
if (!Array.isArray(filePaths) || filePaths.length !== 3 || !filePaths[0]) {
console.error("β Invalid filePaths input to finalizeDatabase:", filePaths);
return { success: false, error: "Missing or invalid input files." };
}
const sqlite3 = require("sqlite3").verbose();
const db = new sqlite3.Database(filePaths[0]);
await new Promise((resolve, reject) => {
db.get("SELECT name FROM sqlite_master WHERE type='table';", (err) => {
if (err) reject(err);
else resolve();
});
});
db.close();
return { success: true, message: "DB validated." };
} catch (err) {
console.error("β Finalize error:", err);
return { success: false, error: err.message };
}
});
// Handler for selecting a chat.db file
ipcMain.handle("choose-chat-db", async () => {
const result = await dialog.showOpenDialog({
title: "Select chat.db file",
properties: ["openFile"],
filters: [
{ name: "SQLite Database", extensions: ["db"] }
]
});
if (result.canceled || result.filePaths.length === 0) {
return null;
}
return result.filePaths[0];
});