feat: allow the usage of multiple vault directories

This commit is contained in:
2026-04-26 20:45:42 +02:00
parent e2343dd401
commit 107519507f
7 changed files with 131 additions and 82 deletions
+44 -42
View File
@@ -1,3 +1,4 @@
#include "cjson/cJSON.h"
#include "ui.h" #include "ui.h"
#include "utils.h" #include "utils.h"
#include "notes.h" #include "notes.h"
@@ -100,20 +101,25 @@ arg_next:
if (!json) {free(data);} if (!json) {free(data);}
error(!json, "program", "JSON parse error"); error(!json, "program", "JSON parse error");
// Parse all of the directories which will( or do) contain the vaults
cJSON *dirJson = cJSON_GetObjectItem(json, "directory"); cJSON *dirJson = cJSON_GetObjectItem(json, "directory");
char *notesDirectoryString = malloc(PATH_MAX); error(dirJson && !cJSON_IsArray(dirJson), "user", "In %s, \"directory\" is missing or isn't an array", configPath);
if (dirJson && cJSON_IsString(dirJson) && cJSON_GetStringValue(dirJson) != NULL) { // we replaced all the ->valuestr and ->valueint to cJSON_GetStringValue() and cJSON_GetNumberValue() int numDirectories = cJSON_GetArraySize(dirJson);
char *rawPath = cJSON_GetStringValue(dirJson); debug("In %s, detected %d paths in \"directory\"", configPath, numDirectories);
if (rawPath[0] == '~') { // expands ~ in the path error(numDirectories == 0, "user", "In %s, \"directory\" is an empty array.", configPath);
snprintf(notesDirectoryString, PATH_MAX, "%s/%s", homedir, rawPath+1);
char **directoriesArray = malloc(numDirectories * sizeof(char*));
debug("Directories:");
cJSON *tempEntry = NULL;
int i = 0;
cJSON_ArrayForEach(tempEntry, dirJson) { // iterate over all the elements of the array _i. e._ over all the dirs
if (tempEntry && cJSON_IsString(tempEntry)) {
directoriesArray[i] = strdup(cJSON_GetStringValue(tempEntry));
altDebug("%s\n",directoriesArray[i]);
} else { } else {
notesDirectoryString = rawPath; error(1, "user", "In %s, in \"directory\", invalid type of one of the entries.", configPath);
} }
debug("In %s, \"directory\" was set to %s.", configPath, notesDirectoryString); i++;
} else {
// default vault path if it is not set in the config
snprintf(notesDirectoryString, PATH_MAX, "%s/Documents/Notes/", homedir);
debug("In %s, \"directory\" wasn't set or we encountered a abnormal type. Defaulting to %s.", configPath, notesDirectoryString);
} }
// fetch the render and jumpToEnfOfFileOnLaunch bools // fetch the render and jumpToEnfOfFileOnLaunch bools
@@ -178,7 +184,8 @@ arg_next:
int doesBackup = 0; int doesBackup = 0;
int interval = 0; // this is an int. But some times it will be inputed a string. We must translate it. int interval = 0; // this is an int. But some times it will be inputed a string. We must translate it.
char *pathToBackup = malloc(PATH_MAX); // to handle linking each directory to its backup path. We create an array of char*. If we want to backup the ith directory, the ith pointer will point to the path. Else, we set the ith pointer to NULL.
char **backupDirectoriesArray = malloc(numDirectories*sizeof(char*));
char **rsyncArgs = NULL; char **rsyncArgs = NULL;
int rsyncArgsNumber = 0; int rsyncArgsNumber = 0;
cJSON *backupJSON = cJSON_GetObjectItem(json, "backup"); cJSON *backupJSON = cJSON_GetObjectItem(json, "backup");
@@ -187,19 +194,22 @@ arg_next:
if (doesBackupJSON && cJSON_IsBool(doesBackupJSON)) { if (doesBackupJSON && cJSON_IsBool(doesBackupJSON)) {
doesBackup = cJSON_IsTrue(doesBackupJSON) ? 1 : 0; doesBackup = cJSON_IsTrue(doesBackupJSON) ? 1 : 0;
debug("doesBackup is set to %d", doesBackup); debug("doesBackup is set to %d", doesBackup);
// handles the path to the backup if (!doesBackup) {
goto backup_config_end; // easier to just go to rather than do a big if statement
}
// handles the path to the backup for each directory
cJSON *pathToBackupJSON = cJSON_GetObjectItem(backupJSON, "directory"); cJSON *pathToBackupJSON = cJSON_GetObjectItem(backupJSON, "directory");
if (pathToBackupJSON && cJSON_IsString(pathToBackupJSON)) { error(cJSON_IsObject(pathToBackupJSON), "user", "In %s, incorrect type for \"backup\". It must be a JSON object.");
char *temp = cJSON_GetStringValue(pathToBackupJSON); // we name it temp. As we can't directly set pathToBackup because snprintf doesn't like when a pointer is both an arg and the destination // temp should be freed when free(json), because cJSON_GetStringValue returns a pointer. for (int i = 0; i < numDirectories; i++) { // we iterate over every
if (temp[0] == '~') { // expands ~ cJSON *pathToBackupForIthDirectoryJSON = cJSON_GetObjectItem(pathToBackupJSON, directoriesArray[i]);
temp++; // we shift by one to remove ~ if (pathToBackupForIthDirectoryJSON) {
snprintf(pathToBackup, PATH_MAX, "%s/%s", homedir, temp); backupDirectoriesArray[i] = strdup(cJSON_GetStringValue(pathToBackupForIthDirectoryJSON));
debug("~ was expanded to %s\nThe backup path is %s", homedir, pathToBackup); } else { // else no path is set. So we won't backup it.
} else { backupDirectoriesArray[i] = NULL;
pathToBackup = strndup(temp, PATH_MAX); // temp will be freed later so strndup
debug("Directory for backup is set to %s in %s", pathToBackup, configPath);
} }
} else {error(1, "user", "%s did not contained a directory inside the backup section or the value is from an unexpected type", configPath);} }
// handles the interval of backup // handles the interval of backup
cJSON *intervalJSON = cJSON_GetObjectItem(backupJSON, "interval"); cJSON *intervalJSON = cJSON_GetObjectItem(backupJSON, "interval");
if (intervalJSON && cJSON_IsString(intervalJSON)) { if (intervalJSON && cJSON_IsString(intervalJSON)) {
@@ -237,7 +247,7 @@ arg_next:
} else { } else {
debug("In %s, \"backup\" wasn't set or we encountered a abnormal type. Defaulting to {\"enable\": false}.", configPath); debug("In %s, \"backup\" wasn't set or we encountered a abnormal type. Defaulting to {\"enable\": false}.", configPath);
} }
backup_config_end:
//cleans up //cleans up
@@ -268,11 +278,6 @@ for (int i = 1; i < argc; i++) {
overwriteConfigPath = ++i; overwriteConfigPath = ++i;
debug("--config set to %s", argv[i]); debug("--config set to %s", argv[i]);
} else if (strcmp(arg, "--directory") == 0) {
error(i + 1 == argc, "user", "Missing argument for --directory");
notesDirectoryString = argv[++i];
debug("--directory set to %s", notesDirectoryString);
} else if (strcmp(arg, "--editor") == 0) { } else if (strcmp(arg, "--editor") == 0) {
error(i + 1 == argc, "user", "Missing argument for --editor"); error(i + 1 == argc, "user", "Missing argument for --editor");
editorToOpen = argv[++i]; editorToOpen = argv[++i];
@@ -311,7 +316,6 @@ for (int i = 1; i < argc; i++) {
printf("Usage: notewrapper [options]\n"); printf("Usage: notewrapper [options]\n");
printf("Options:\n"); printf("Options:\n");
printf(" -c, --config <path/to/config> Specify the config file.\n"); printf(" -c, --config <path/to/config> Specify the config file.\n");
printf(" -d, --directory <path/to/directory> Specify the vaults' directory.\n");
printf(" -h, --help Display this message.\n"); printf(" -h, --help Display this message.\n");
printf(" -e, --editor Specify the editor to open.\n"); printf(" -e, --editor Specify the editor to open.\n");
printf(" -j, --jump Jumps to the end of the file on opening.\n"); printf(" -j, --jump Jumps to the end of the file on opening.\n");
@@ -369,7 +373,6 @@ for (int i = 1; i < argc; i++) {
printf("Usage: notewrapper [options]\n"); printf("Usage: notewrapper [options]\n");
printf("Options:\n"); printf("Options:\n");
printf(" -c, --config <path/to/config> Specify the config file.\n"); printf(" -c, --config <path/to/config> Specify the config file.\n");
printf(" -d, --directory <path/to/directory> Specify the vaults' directory.\n");
printf(" -h, --help Display this message.\n"); printf(" -h, --help Display this message.\n");
printf(" -e, --editor Specify the editor to open.\n"); printf(" -e, --editor Specify the editor to open.\n");
printf(" -j, --jump Jumps to the end of the file on opening.\n"); printf(" -j, --jump Jumps to the end of the file on opening.\n");
@@ -383,7 +386,6 @@ for (int i = 1; i < argc; i++) {
return 0; return 0;
// -------- flags with arguments (MUST be last in group) -------- // -------- flags with arguments (MUST be last in group) --------
case 'd':
case 'e': case 'e':
case 'n': case 'n':
case 'v': case 'v':
@@ -400,11 +402,6 @@ for (int i = 1; i < argc; i++) {
char *value = argv[++i]; char *value = argv[++i];
switch (opt) { switch (opt) {
case 'd':
notesDirectoryString = value;
debug("-d set directory to %s", value);
break;
case 'e': case 'e':
editorToOpen = value; editorToOpen = value;
defaultEditor = 0; defaultEditor = 0;
@@ -451,7 +448,7 @@ next_arg:
isEditorValid(editorToOpen, defaultEditor, shouldDebug); // check if editor is supported and if it is installed. If not, it will throw an error. isEditorValid(editorToOpen, defaultEditor, shouldDebug); // check if editor is supported and if it is installed. If not, it will throw an error.
if (doesBackup) { if (doesBackup) {
handleBackups(notesDirectoryString, pathToBackup, homedir, interval, (const char**)rsyncArgs, rsyncArgsNumber, shouldDebug); handleBackups(directoriesArray, numDirectories, backupDirectoriesArray, homedir, interval, (const char**)rsyncArgs, rsyncArgsNumber, shouldDebug);
} }
initscr(); //initialize ncurses initscr(); //initialize ncurses
@@ -463,7 +460,8 @@ next_arg:
char *vaultSelected = NULL; char *vaultSelected = NULL;
int vaultsCount = 0; int vaultsCount = 0;
char **vaultsArray = getVaultsFromDirectory(notesDirectoryString, &vaultsCount, shouldDebug); int *vaultsCountForEachDirectory = malloc(numDirectories*sizeof(int));
char **vaultsArray = getVaultsFromDirectories(directoriesArray, numDirectories, vaultsCountForEachDirectory, &vaultsCount, shouldDebug); // when selecting each vault won't show the directory from which they come. We will find this later.
// bypass if -v or --vault is set // bypass if -v or --vault is set
if (bypassSelectionVault) { if (bypassSelectionVault) {
@@ -505,13 +503,14 @@ next_arg:
free(vaultsArray[i]); // we must only free the vaults options and not the extraOptions to avoid segfault free(vaultsArray[i]); // we must only free the vaults options and not the extraOptions to avoid segfault
} }
} }
free(vaultsArray);
debug("Selected vault: %s", vaultSelected); debug("Selected vault: %s", vaultSelected);
if (strcmp(vaultSelected,"Create a new vault") != 0 && strcmp(vaultSelected,"Settings") != 0 && strcmp(vaultSelected,"Quit (Ctrl+C)") != 0) { if (strcmp(vaultSelected,"Create a new vault") != 0 && strcmp(vaultSelected,"Settings") != 0 && strcmp(vaultSelected,"Quit (Ctrl+C)") != 0) {
note_selection: note_selection:
bypassSelectionVault = 0; // we must reset bypassSelectionVault to not get stuck in a infinite loop of bypassing bypassSelectionVault = 0; // we must reset bypassSelectionVault to not get stuck in a infinite loop of bypassing
int shouldChangeVault = 0; int shouldChangeVault = 0;
// we must find the directory from which the vault comes again.
char *notesDirectoryString = getDirectoryFromVault(vaultSelected, vaultsArray, vaultsCount, vaultsCountForEachDirectory, directoriesArray, numDirectories, shouldDebug);
while (!shouldExit && !shouldChangeVault) { while (!shouldExit && !shouldChangeVault) {
// this loop is the note selector // this loop is the note selector
int filesCount = 0; int filesCount = 0;
@@ -598,6 +597,8 @@ note_creation:
} else if (strcmp(noteSelected,"Back to vault selection") == 0) { } else if (strcmp(noteSelected,"Back to vault selection") == 0) {
shouldChangeVault = 1; shouldChangeVault = 1;
} else if (strcmp(noteSelected, "Delete vault") == 0) { } else if (strcmp(noteSelected, "Delete vault") == 0) {
// we must find where does the vault comes from.
char *notesDirectoryString = getDirectoryFromVault(vaultSelected, vaultsArray, vaultsCount, vaultsCountForEachDirectory, directoriesArray, numDirectories, shouldDebug);
const char *yesNo[] = {"No, go back to note selection.", "Yes."}; const char *yesNo[] = {"No, go back to note selection.", "Yes."};
char *answer = ncursesSelect((char **)yesNo, "Are you sure you want to delete the entire vault? This can not be undone (Use arrows or WASD, Enter to select):", 1, 1, " ", "", "", shouldDebug); debug("You answered: %s for deleting the vault %s", answer, vaultSelected); char *answer = ncursesSelect((char **)yesNo, "Are you sure you want to delete the entire vault? This can not be undone (Use arrows or WASD, Enter to select):", 1, 1, " ", "", "", shouldDebug); debug("You answered: %s for deleting the vault %s", answer, vaultSelected);
if (strcmp(answer, "Yes.") == 0) { if (strcmp(answer, "Yes.") == 0) {
@@ -613,10 +614,10 @@ note_creation:
shouldExit = 1; shouldExit = 1;
} }
} }
free(vaultsArray);
} else if (strcmp(vaultSelected,"Create a new vault") == 0) { } else if (strcmp(vaultSelected,"Create a new vault") == 0) {
vault_creation: vault_creation:
createNewVault(notesDirectoryString, bypassSelectionVault, bypassSelectionVaultValue, shouldDebug); createNewVault(directoriesArray, numDirectories, vaultsArray, vaultsCount, bypassSelectionVault, bypassSelectionVaultValue, shouldDebug);
bypassSelectionVault = 0; // we need to reset bypassSelectionVault to avoid getting into an infinite loop of bypassing bypassSelectionVault = 0; // we need to reset bypassSelectionVault to avoid getting into an infinite loop of bypassing
} else if (strcmp(vaultSelected,"Settings") == 0) { } else if (strcmp(vaultSelected,"Settings") == 0) {
openEditor(configPath, editorToOpen, 0, 0, shouldDebug); // as this is not a md file we set render and jumptoEnfOfFile to 0 openEditor(configPath, editorToOpen, 0, 0, shouldDebug); // as this is not a md file we set render and jumptoEnfOfFile to 0
@@ -626,5 +627,6 @@ vault_creation:
} }
} }
free(configPath); free(configPath);
free(directoriesArray);
return 0; return 0;
} }
+54 -25
View File
@@ -1,5 +1,23 @@
#include "notes.h" #include "notes.h"
#include "ui.h" #include "utils.h"
char *getDirectoryFromVault(char *targetVault, char **vaultsArray, int vaultTotalNumber, int *vaultNumberPerDirectory, char **directoryArray, int directoryNumber, int shouldDebug) {
debug("Searching the vault %s inside all the directories...", targetVault);
int index = 0;
int startIndex = 0;
for (int i = 0; i < directoryNumber; i++) {
while (index - startIndex < vaultNumberPerDirectory[i]) {
if (strcmp(vaultsArray[index], targetVault) == 0) { // we found it
debug("%s found in %s. (This was the %dth step of a maximum of %d)", targetVault, directoryArray[i], index, vaultTotalNumber);
return directoryArray[i];
}
index++;
}
startIndex += vaultNumberPerDirectory[i];
}
error(1, "program", "the vault %s was not found", targetVault);
return "this makes the compiler and clangd happy. Who doesn't want GCC and clangd to be happy? Such person would be a terrible monster... One must imagine GCC and clangd happy.";
}
char **getJournalsFromVault(char *pathToVault, char *vault, char *journalRegex, int *count, int shouldDebug) { char **getJournalsFromVault(char *pathToVault, char *vault, char *journalRegex, int *count, int shouldDebug) {
debug("Searching %s for journals", vault); debug("Searching %s for journals", vault);
@@ -90,38 +108,49 @@ char** getNotesFromVault(char *pathToVault, char *vault, char *journalRegex, int
return notesArray; return notesArray;
} }
char **getVaultsFromDirectory(char *dirString, int *count, int shouldDebug) { char **getVaultsFromDirectories(char **directoryStringArray, int directoryNumber, int *vaultsPerDirectoryNumber, int *count, int shouldDebug) {
// this function is inputed a path to a directory (which comes usually from the config file) and outpus all the suitable directories (so not the hidden ones) which will serve as separate vaults for notes // to avoid having to work with a tree-dimensional array. We will use a 2d and vaultsPerDirectoryNumber will indicate the width of the directories.
debug("Opening %s ", dirString); char **vaultsArray = NULL;
int nthVault = 0; // this is only used internally to set the string into the right place in directoryStringArray.
for (int i = 0; i < directoryNumber; i++) {
debug("Opening %s", directoryStringArray[i]);
// originally from https://www.geeksforgeeks.org/c/c-program-list-files-sub-directories-directory/ // originally from https://www.geeksforgeeks.org/c/c-program-list-files-sub-directories-directory/
struct dirent *vaultsDirectoryEntry; struct dirent *vaultsDirectoryEntry;
DIR *vaultsDirectory = opendir(dirString); DIR *vaultsDirectory = opendir(directoryStringArray[i]);
error(vaultsDirectory==NULL, "program", "Could not open directory %s", dirString); error(!vaultsDirectory, "program", "Could not open directory %s", directoryStringArray[i]);
char **dirsArray = NULL; // will contain all the dirs/vaults vaultsPerDirectoryNumber[i] = 0;
int dirsCount = 0; // we need to count how many dirs there is to always readjust how many memory we alloc debug("┌------------------------------\n Detected files and dirs %s:", directoryStringArray[i]);
// Refer https://pubs.opengroup.org/onlinepubs/7990989775/xsh/readdir.html // Refer https://pubs.opengroup.org/onlinepubs/7990989775/xsh/readdir.html
// for readdir() // for readdir()
debug("┌------------------------------\n Detected files and dirs from the directory:"); while((vaultsDirectoryEntry = readdir(vaultsDirectory)) != NULL) {
while ((vaultsDirectoryEntry = readdir(vaultsDirectory)) != NULL) { char *entryName = vaultsDirectoryEntry->d_name; // gets the entry as a string value
altDebug("%s\n", vaultsDirectoryEntry->d_name); altDebug("%s", entryName);
if (vaultsDirectoryEntry->d_name[0] != '.') { // if the entry don't start with a dot (so hidden dirs and hidden files) if (entryName[0] != '.') { // if not hidden file/dir
char fullPathEntry[PATH_MAX]; // creates a string of size of the maximum path lenght char tempFullEntryPath[PATH_MAX]; // we recreate the full path to check it's proprieties
snprintf(fullPathEntry, sizeof(fullPathEntry), "%s/%s", dirString, vaultsDirectoryEntry->d_name); // sets the full absolute path to fullPathEntry snprintf(tempFullEntryPath, PATH_MAX, "%s/%s", directoryStringArray[i], entryName);
//checking the metadata to see if it is a dir
struct stat metadataPathEntry; struct stat metadataEntry;
if (stat(fullPathEntry, &metadataPathEntry) == 0 && S_ISDIR(metadataPathEntry.st_mode)) { // if this entry is a directory if (stat(tempFullEntryPath, &metadataEntry) == 0 && S_ISDIR(metadataEntry.st_mode)) { // get's the metadata (stat should return 0 if fails) and sees if it is a dir.
dirsArray = realloc(dirsArray, (dirsCount + 1)*sizeof(char*)); // resize dirsArray so that altDebug(" is a vault\n");
dirsArray[dirsCount] = strdup(vaultsDirectoryEntry->d_name); // copy the dir name into dirsArray vaultsArray = realloc(vaultsArray, sizeof(vaultsArray) + sizeof(char *)); // resize vaultsArray
dirsCount++; vaultsPerDirectoryNumber[i]++; // it will be used later to know which vaults goes into which directory
directoryStringArray[nthVault] = strdup(entryName); // we use strdup and not strcpy, because memory used with opendir and readdir will be closed.
nthVault++; // it is used immediatly to set the vault into directoryStringArray
} else {
altDebug(" is not a vault (not a dir.)\n");
} }
} else {
altDebug(" is not a vault (hidden file/dir)\n");
} }
} }
altDebug("└------------------------------\n");
// free's some used memory
closedir(vaultsDirectory); closedir(vaultsDirectory);
*count = dirsCount; }
return dirsArray; // we calculate once the total number of vaults to avoid recalculation every time we use it
count = 0;
for (int i = 0; i < directoryNumber; i++) {
count += vaultsPerDirectoryNumber[i];
}
return vaultsArray;
} }
char *updateJournal(char *path, char *journal, char *timeFormat, int *journalWasUpdated, int shouldDebug) { char *updateJournal(char *path, char *journal, char *timeFormat, int *journalWasUpdated, int shouldDebug) {
+9 -2
View File
@@ -2,6 +2,8 @@
#define NOTES_H #define NOTES_H
#include "utils.h" #include "utils.h"
#include "ui.h" #include "ui.h"
// find which directory contains targetVault
char *getDirectoryFromVault(char *targetVault, char **vaultsArray, int vaultTotalNumber, int *vaultNumberPerDirectory, char **directoryArray, int directoryNumber, int shouldDebug);
// gets the journals from the vault. // gets the journals from the vault.
//to distinguish journals from note we use regex. //to distinguish journals from note we use regex.
//Note: we must handle them separatly as journals can either be a single file (which will treat specially) or a directory. //Note: we must handle them separatly as journals can either be a single file (which will treat specially) or a directory.
@@ -9,8 +11,13 @@ char **getJournalsFromVault(char *pathToVault, char *vault, char *journalRegex,
// this function is inputed a path to a vault (which was selected before) and outpus all the suitable notes (so not the hidden ones). // this function is inputed a path to a vault (which was selected before) and outpus all the suitable notes (so not the hidden ones).
// journalRegex is the regex code for the journals. If a note matches this code, it is treated as a journal and it is not outputed from this function. // journalRegex is the regex code for the journals. If a note matches this code, it is treated as a journal and it is not outputed from this function.
char **getNotesFromVault(char *pathToVault, char *vault, char *journalRegex, int *count, int shouldDebug); char **getNotesFromVault(char *pathToVault, char *vault, char *journalRegex, int *count, int shouldDebug);
// this function is inputed a path to a directory (which comes usually from the config file) and outpus all the suitable directories (so not the hidden ones) which will serve as separate vaults for notes. // function gets as input an array of directoryNumber strings. Which are the directories the function will search for vaults.
char **getVaultsFromDirectory(char *dirString, int *count, int shouldDebug); // it returns an array of vaults.
// the vaults are organized in order per directory.
// vaultsPerDirectoryNumber and count should be initiallized before calling the function and the address be inputed.
// count is the total number of vaults.
// vaultsPerDirectoryNumber gives how many vaults each directory has.
char **getVaultsFromDirectories(char **directoryStringArray, int directoryNumber, int *vaultsPerDirectoryNumber, int *count, int shouldDebug);
// path is the path to the file. // path is the path to the file.
// journal is the name of the file. // journal is the name of the file.
// journalWasUpdated will be set to 1 if a new entry was created // journalWasUpdated will be set to 1 if a new entry was created
+10 -7
View File
@@ -1,9 +1,12 @@
#include "ui.h" #include "ui.h"
#include "utils.h"
void createNewVault(char *dirToVault, int bypass, char *bypassvalue, int shouldDebug) { void createNewVault(char **directoriesArray, int directoryCount, char **vaultsArray, int vaultCount, int bypass, char *bypassvalue, int shouldDebug) {
int duplicateWarning = 0; // set to 1 later if the vault you tried to create already existed int duplicateWarning = 0; // set to 1 later if the vault you tried to create already existed
int emptyWarning = 0; // set to 1 later if inpted empty name int emptyWarning = 0; // set to 1 later if inpted empty name
input_screen: input_screen:
// choose in which directory the vault will be created
char *dirToVault = ncursesSelect(directoriesArray, "Select a directory, in which the vault will remain (Use arrows or WASD, Enter to select)", directoryCount, 0, "", "", " ", shouldDebug);
char *vaultName = malloc(PATH_MAX); char *vaultName = malloc(PATH_MAX);
if (!bypass) { // if won't bypass (if -v or --vault weren't set) if (!bypass) { // if won't bypass (if -v or --vault weren't set)
echo(); echo();
@@ -48,13 +51,13 @@ input_screen:
sanitize(vaultName); sanitize(vaultName);
debug("Sanitized vaultName=%s", vaultName); debug("Sanitized vaultName=%s", vaultName);
struct stat st = {0}; // https://stackoverflow.com/a/7430262
char vaultFullPath[PATH_MAX]; if (!isStringInArray(vaultName, (const char**)vaultsArray, vaultCount)) { // if vault doesnt already exists. We avoid vaults with the same name even if they are from different directories.
sprintf(vaultFullPath, "%s/%s/", dirToVault, vaultName); char vaultFullPath[PATH_MAX]; // recreating the full path
if (stat(vaultFullPath, &st) == -1) { sprintf(vaultFullPath, "%s/%s/", dirToVault, vaultName);
mkdir(vaultFullPath, 0744); mkdir(vaultFullPath, 0744);
} else { } else {
// if stat(...) != -1 it means the vault already exist. We will go back to the input screen with a new message.
duplicateWarning = 1; duplicateWarning = 1;
goto input_screen; goto input_screen;
} }
@@ -260,7 +263,7 @@ char* fzfSelect(char *pathToFiles, char *selectText, int shouldDebug) {
return result; return result;
} }
char* ncursesSelect(char **options, char *optionsText, int optionsNumber, int extraOptionsNumber, char *bottomText, char *middleText, char *topText, int shouldDebug) { char* ncursesSelect(char **options, char *optionsText, int optionsNumber, int extraOptionsNumber, char *bottomText, char *middleText, char *topText, int shouldDebug) { // TODO we should see how it handles larges strings (like large directories)
int highlight = 0; //curently highlighted option int highlight = 0; //curently highlighted option
int key; int key;
+4 -2
View File
@@ -22,11 +22,13 @@ returns the path to the note.
If you want to bypass the input TUI set bypass to 1 and bypassvalue to the note name If you want to bypass the input TUI set bypass to 1 and bypassvalue to the note name
*/ */
char *createNewNote(char dirToVault[PATH_MAX], char *vaultFromDir, int bypass, char *bypassvalue, char *journalRegex, int debug); char *createNewNote(char dirToVault[PATH_MAX], char *vaultFromDir, int bypass, char *bypassvalue, char *journalRegex, int debug);
/*Uses ncurses to get an input from the user. /*
Chooses in which directory it want to create the vault.
Uses ncurses to get an input from the user.
Creates a new vault with this input. Creates a new vault with this input.
If vault already exists, prints a warning. If vault already exists, prints a warning.
returns nothing. */ returns nothing. */
void createNewVault(char *dirToVault, int bypass, char *bypassvalue, int debug); void createNewVault(char **directoriesArray, int directoryCount, char **vaultsArray, int vaultCount, int bypass, char *bypassvalue, int debug);
// uses fzf and ripgrep to search inside the files to choose between all the options. // uses fzf and ripgrep to search inside the files to choose between all the options.
char* fzfSelect(char *pathToFiles, char *selectText, int shouldDebug); char* fzfSelect(char *pathToFiles, char *selectText, int shouldDebug);
/*this function is used multiple times let the user select one options from many with ncurses in a TUI. /*this function is used multiple times let the user select one options from many with ncurses in a TUI.
+7 -3
View File
@@ -136,7 +136,7 @@ void initAppFilesAndDirs(const char *home, const int shouldDebug) {
debug("Creating default config file."); debug("Creating default config file.");
FILE *w = fopen(config_file, "w"); FILE *w = fopen(config_file, "w");
error(!w, "program", "fopen failed opening %s"); error(!w, "program", "fopen failed opening %s");
fprintf(w, fprintf(w, //TODO CHANGE default json
"{\n" "{\n"
" \"directory\": \"~/Documents/Notes/\",\n" " \"directory\": \"~/Documents/Notes/\",\n"
" \"render\": true,\n" " \"render\": true,\n"
@@ -156,7 +156,7 @@ void initAppFilesAndDirs(const char *home, const int shouldDebug) {
fclose(w); fclose(w);
} }
void handleBackups(const char *pathOfVaults, const char *pathOfBackup, const char *homeDir, const int interval, const char **rsyncArguments, const int rsyncArgumentsNumber, const int shouldDebug) { void handleBackups(char **sourceDirectoryArray, const int sourceNumber, char **destinationDirectoryArray, const char *homeDir, const int interval, const char **rsyncArguments, const int rsyncArgumentsNumber, const int shouldDebug) {
int shouldBackup = 0; int shouldBackup = 0;
time_t now = time(NULL); time_t now = time(NULL);
debug("Time since epoch is %ld", (long)now); debug("Time since epoch is %ld", (long)now);
@@ -202,7 +202,11 @@ void handleBackups(const char *pathOfVaults, const char *pathOfBackup, const cha
} }
if (shouldBackup) { if (shouldBackup) {
copyDir(pathOfVaults, pathOfBackup, rsyncArguments, rsyncArgumentsNumber, shouldDebug); for (int i = 0; i < sourceNumber; i++) {
if (destinationDirectoryArray[i]) { // if we don't want to backup it, it was set to NULL
copyDir(sourceDirectoryArray[i], destinationDirectoryArray[i], rsyncArguments, rsyncArgumentsNumber, shouldDebug);
}
}
} }
} }
+3 -1
View File
@@ -82,6 +82,8 @@ int openEditor(char *path, char *editor, int render, int shouldJumpToEndOfFile,
char *getFormatedTime(char *format, int shouldDebug); char *getFormatedTime(char *format, int shouldDebug);
/* Caclulates if we need to do another backup (by reading ~/.cache/NoteWrapper/backupTime.txt. /* Caclulates if we need to do another backup (by reading ~/.cache/NoteWrapper/backupTime.txt.
If need launches in the background rsync to do the backuping. If need launches in the background rsync to do the backuping.
Each pair of source/destination will launch one rsync process.
If a pair don't need to be backed up, the destination should be set to NULL.
rsyncArgs is the array of arguments to be passed to rsync. Do not inclue destination or source. It will be added in the function.*/ rsyncArgs is the array of arguments to be passed to rsync. Do not inclue destination or source. It will be added in the function.*/
void handleBackups(const char *pathOfVaults, const char *pathOfBackup, const char *homeDir, const int interval, const char **rsyncArgs, const int rsyncArgsNumber, const int shouldDebug); void handleBackups(char **sourceDirectoryArray, const int sourceDirectoryNumber, char **destinationDirectoryArray, const char *homeDir, const int interval, const char **rsyncArgs, const int rsyncArgsNumber, const int shouldDebug);
#endif #endif