import static eu.svjatoslav.alyverkko_cli.Main.configuration;
import static eu.svjatoslav.commons.file.IOHelper.getFileContentsAsString;
import static eu.svjatoslav.commons.file.IOHelper.saveToFile;
-import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
-import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
+import static java.nio.file.StandardWatchEventKinds.*;
/**
directoryWatcher.close();
}
- /**
- * Performs an initial scan of existing files in the mail directory,
- * adding those that need processing to the task queue.
- *
- * @throws IOException if file scanning fails.
- */
private void initialMailScanAndReply() throws IOException {
- File[] files = mailDir.listFiles();
- if (files == null) {
- return;
- }
-
- for (File file : files) {
- considerFileForQueuing(file.toPath());
- }
+ Files.walk(mailDir.toPath())
+ .filter(path -> Files.isRegularFile(path))
+ .forEach(path -> {
+ try {
+ considerFileForQueuing(path);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ });
}
/**
}
}
- /**
- * Processes a file if it has the "TOCOMPUTE:" marker, running an AI
- * query and appending the result to the file. Otherwise logs that
- * it's being ignored.
- *
- * @param file the file to possibly process.
- * @throws IOException if reading/writing the file fails.
- * @throws InterruptedException if the AI query is interrupted.
- */
- private void processMailIfNeeded(File file) throws IOException, InterruptedException {
- if (!isMailProcessingNeeded(file)) {
- System.out.println("Ignoring file: " + file.getName() + " (does not need processing for now)");
- return;
- }
-
- System.out.println("\nReplying to mail: " + file.getName());
-
- MailQuery mailQuery = buildMailQueryFromFile(file);
-
- // Run the query using the AI model while measuring the time taken
- AiTask aiTask = new AiTask(mailQuery);
- String aiGeneratedResponse = aiTask.runAiQuery();
-
- saveAiResponseToFile(file, mailQuery, aiGeneratedResponse);
- }
-
private static void saveAiResponseToFile(File file, MailQuery mailQuery, String aiResponse) throws IOException {
- // Build new content
StringBuilder resultFileContent = new StringBuilder();
- // The First line should be "TOCOMPUTE:" with settings that were used to process this file
+ // The First line should be "DONE:" with settings used to process this file
resultFileContent.append(getDoneLine(mailQuery));
// Ensure the user prompt block is labeled if it isn't already
.append(aiResponse)
.append("\n");
- // Write the combined result back to the same file
- saveToFile(file, resultFileContent.toString());
- }
+ File newFile = new File(file.getParentFile(), "DONE: " + file.getName());
+ saveToFile(newFile, resultFileContent.toString());
+ if (!file.delete()) {
+ System.err.println("Failed to delete original file: " + file.getAbsolutePath());
+ }
+ }
/**
* Processes a task by reading the file, building the MailQuery,
* @throws IOException if file processing fails.
*/
private void processDetectedFilesystemEvents(WatchKey key) throws IOException {
+
+ Path dir = (Path) key.watchable(); // ★ new line
+
for (WatchEvent<?> event : key.pollEvents()) {
+
WatchEvent.Kind<?> kind = event.kind();
+ if (kind != ENTRY_CREATE && kind != ENTRY_MODIFY) continue;
- // Skip OVERFLOW events
- if (kind == StandardWatchEventKinds.OVERFLOW) {
- continue;
- }
+ @SuppressWarnings("unchecked")
+ WatchEvent<Path> ev = (WatchEvent<Path>) event;
+ Path filename = ev.context();
- // The filename for the event
- Path filename = ((WatchEvent<Path>) event).context();
- System.out.println("Event: " + kind + " for file: " + filename);
+ Path fullPath = dir.resolve(filename);
+ System.out.printf("Event: %s – %s%n", kind.name(), fullPath);
- // Add to task queue if needed
- if (kind == ENTRY_CREATE || kind == ENTRY_MODIFY) {
- Path filePath = mailDir.toPath().resolve(filename);
- considerFileForQueuing(filePath);
+ // If the entry is a *new directory* we need to start watching it, too:
+ if (kind == ENTRY_CREATE && Files.isDirectory(fullPath)) {
+ registerAllSubdirectories(fullPath);
+ }
+
+ // And finally queue the file if it’s a regular, non-hidden file:
+ if (Files.isRegularFile(fullPath) && !Files.isHidden(fullPath)) {
+ considerFileForQueuing(fullPath);
}
}
}
- /**
- * Registers the mail directory with a WatchService for ENTRY_CREATE
- * and ENTRY_MODIFY events.
- *
- * @throws IOException if registration fails.
- */
+
private void initializeFileWatcher() throws IOException {
this.directoryWatcher = FileSystems.getDefault().newWatchService();
- Paths.get(mailDir.getAbsolutePath()).register(directoryWatcher, ENTRY_CREATE, ENTRY_MODIFY);
+ registerAllSubdirectories(mailDir.toPath());
+ }
+
+ private void registerAllSubdirectories(Path path) {
+ try {
+ System.out.println("Registering directory for watch service: " + path);
+ path.register(directoryWatcher, ENTRY_CREATE, ENTRY_MODIFY);
+ if (Files.isDirectory(path)) {
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(path)) {
+ for (Path entry : stream) {
+ if (Files.isDirectory(entry)) {
+ registerAllSubdirectories(entry);
+ }
+ }
+ }
+ }
+ } catch (IOException e) {
+ System.err.println("Failed to register directory: " + path + " - " + e.getMessage());
+ }
}
/**