- What user did, when, where and how.
- How and where did result appear.
+- Clarify operating system requirements.
+
+- Clarify hardware requirements.
+
** System operation
- Implement CPU nice priority for inference processes to minimize the
in-progress computation. Unix process stop and continue signals
could possibly be used.
- Add support for speculative decoding to speed up inference.
+- Implement selftest command. It shall validate that configuration is
+ correct and all is operational. If errors are found, it should tell
+ what exactly is wrong and suggest how to fix it.
** Data management
-- Develop a feature to recursively aggregate files into a single
- document using Emacs org-mode syntax, facilitating the preparation
- of comprehensive problem statements for AI processing.
- - Ensure that binary files are excluded from this aggregation
- process to maintain text readability and compatibility.
+- in maildir ignore binary files, use joinfiles command as example how
+ to ignore binary files. Perhaps extract plain text file detection
+ into some utility class.
+
+- Make text editor configurable in application properties file.
** Configuration and logging
package eu.svjatoslav.alyverkko_cli.commands;
import eu.svjatoslav.alyverkko_cli.*;
-import org.apache.commons.io.FilenameUtils;
+import eu.svjatoslav.commons.cli_helper.parameter_parser.Parser;
+import eu.svjatoslav.commons.cli_helper.parameter_parser.parameter.DirectoryOption;
+import eu.svjatoslav.commons.cli_helper.parameter_parser.parameter.NullOption;
+import eu.svjatoslav.commons.cli_helper.parameter_parser.parameter.StringOption;
+import eu.svjatoslav.commons.string.GlobMatcher;
import java.io.BufferedWriter;
import java.io.File;
public class JoinFilesCommand implements Command {
+ final Parser parser = new Parser();
+
+ public DirectoryOption sourceDirectoryOption = parser.add(new DirectoryOption("Directory to join files from"))
+ .addAliases("--src-dir", "-s").mustExist();
+
+ public StringOption patternOption = parser.add(new StringOption("Pattern to match files"))
+ .addAliases("--pattern", "-p");
+
+ public StringOption topic = parser.add(new StringOption("Topic of the joined files"))
+ .addAliases("--topic", "-t").setMandatory();
+
+ public NullOption editOption = parser.add(new NullOption("Edit the joined file using text editor"))
+ .addAliases("--edit", "-e");
+
+
@Override
public String getName() {
return "joinfiles";
public Path baseDirectory;
+ public String pattern = null;
+
+ File outputFile;
+
@Override
public void execute(String[] cliArguments) throws IOException {
configuration = loadConfiguration();
return;
}
- // Ask for file name to be created
- System.out.print("Enter the output file name (without extension): ");
- String fileName = System.console().readLine();
+ if (!parser.parse(cliArguments)) {
+ System.out.println("Failed to parse commandline arguments");
+ parser.showHelp();
+ return;
+ }
- // Create the output file with .org extension
- File outputFile = new File(FilenameUtils.normalize(fileName + ".org"));
+ // build the path to the target file that is relative to the mail directory
+ outputFile = configuration.getMailDirectory().toPath().resolve(topic.getValue() + ".org").toFile();
- // create output file within the mail directory
- outputFile = new File(configuration.getMailDirectory(), outputFile.getName());
+ if (patternOption.isPresent()) {
+ pattern = patternOption.getValue();
+ joinFiles();
+ }
+ if (editOption.isPresent()) {
+ // User requested to edit the file after joining
+ System.out.println("Editing the file: " + outputFile.getAbsolutePath());
+ String editorCommand = "emc " + outputFile.getAbsolutePath();
+ Runtime.getRuntime().exec(editorCommand);
+ }
- try (BufferedWriter writer = Files.newBufferedWriter(outputFile.toPath(), StandardCharsets.UTF_8)) {
+ }
+
+ private void joinFiles() throws IOException {
+
+ // Create or append to the target file
+ boolean appendToFile = outputFile.exists();
+
+ if (sourceDirectoryOption.isPresent()) {
+ baseDirectory = sourceDirectoryOption.getValue().toPath();
+ } else {
baseDirectory = Paths.get(".");
- joinFilesRecursively(baseDirectory, writer);
}
- System.out.println("Files have been joined into: " + outputFile.getAbsolutePath());
- System.out.println("Opening editor to edit the file...");
+ try (BufferedWriter writer = Files.newBufferedWriter(
+ outputFile.toPath(), StandardCharsets.UTF_8,
+ appendToFile ? StandardOpenOption.APPEND : StandardOpenOption.CREATE)) {
- // TODO: make editor configurable
- String command = "emc " + outputFile.getAbsolutePath();
- // opening editor
- Runtime.getRuntime().exec(command);
+ // Join files that match the pattern in the specified directory
+ joinFilesRecursively(sourceDirectoryOption.getValue().toPath(), writer);
+ }
+
+ System.out.println("Files have been joined into: " + outputFile.getAbsolutePath());
}
private void joinFilesRecursively(Path directoryToIndex, BufferedWriter writer) throws IOException {
- DirectoryStream<Path> stream = Files.newDirectoryStream(directoryToIndex);
-
- for (Path entry : stream) {
- if (Files.isDirectory(entry)) {
- joinFilesRecursively(entry, writer);
- } else if (Files.isRegularFile(entry)) {
- String contentType = Files.probeContentType(entry);
-
- if (contentType != null && contentType.startsWith("text/")) writeFile(writer, entry);
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(directoryToIndex)) {
+ for (Path entry : stream) {
+ if (Files.isDirectory(entry)) {
+ joinFilesRecursively(entry, writer);
+ } else if (Files.isRegularFile(entry)) {
+ String fileName = entry.getFileName().toString();
+
+ boolean match = GlobMatcher.match(fileName, pattern);
+ if (match) {
+ System.out.println("Joining file: " + fileName);
+ writeFile(writer, entry);
+ }
+ }
}
}
}
private void writeFileHeader(BufferedWriter writer, Path entry) throws IOException {
String relativePath = baseDirectory.relativize(entry).toString();
- writer.write( "* file: " + relativePath + "\n\n");
+ writer.write("* file: " + relativePath + "\n\n");
}
}
-