diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/daily.c | 61 | ||||
-rw-r--r-- | src/edit.c | 68 | ||||
-rw-r--r-- | src/edit.h | 22 | ||||
-rw-r--r-- | src/path.c | 108 | ||||
-rw-r--r-- | src/path.h | 35 | ||||
-rw-r--r-- | src/weekly.c | 61 |
6 files changed, 355 insertions, 0 deletions
diff --git a/src/daily.c b/src/daily.c new file mode 100644 index 0000000..74f41c4 --- /dev/null +++ b/src/daily.c @@ -0,0 +1,61 @@ + /** + * Journal-tools daily simplifies writing daily journal entries + * Copyright (C) 2023 Aaron Ball, nullspoon@oper.io + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include <stdio.h> +#include <string.h> + +#include "path.h" +#include "edit.h" + +void path_set(struct path* path) { + // Only resolve these once + if(path->base[0] == 0) + path_get_daily_journaldir("DAILYJOURNAL_DIR", path->base, sizeof(path->base)); + if(path->ext[0] == 0) + path_get_ext("DAILYJOURNAL_EXT", path->ext, sizeof(path->ext)); + + path_date_fmt_filename("%F", path->offset, path->name, sizeof(path->name)); +} + + +int main(int argc, char* argv[]) { + int argoffset = 0; + struct path path; + + memset(&path, 0, sizeof(struct path)); // Zero mem + + // Read week offset if provided + if(argc > 1) { + argoffset = strtol(argv[1], NULL, 10); + path.offset = argoffset * 24 * 60 * 60; + } + + if(argoffset < 0) { + void (*namecb)() = &path_set; + if(path_find_timepast(argoffset, 365 * 2, namecb, &path) == -1) { + fputs("Could not find notes within past two years\n", stderr); + return 1; + } + } else { + path_set(&path); + } + + // For debugging + printf("Opening %s/%s.%s\n", path.base, path.name, path.ext); + edit_exec(path.base, path.name, path.ext); + return 0; +} diff --git a/src/edit.c b/src/edit.c new file mode 100644 index 0000000..93ad44f --- /dev/null +++ b/src/edit.c @@ -0,0 +1,68 @@ + /** + * Journal-tools provides simple tools for keeping journal entries + * Copyright (C) 2023 Aaron Ball, nullspoon@oper.io + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include "edit.h" + +// A sloppy copy function +int _cp(char* src, char* dest) { + FILE* fdsrc = NULL; + FILE* fddest = NULL; + unsigned int buf = 0; + + fdsrc = fopen(src, "r"); + if(!fdsrc) { + fprintf(stderr, "Could not open %s for reading\n", src); + return -1; + } + + fddest = fopen(dest, "w"); + if(!fddest) { + fprintf(stderr, "Could not open %s for writing\n", dest); + return -1; + } + + while((buf = fgetc(fdsrc)) != EOF) + fputc(buf, fddest); + + fclose(fdsrc); + fclose(fddest); + return 0; +} + +int edit_exec(char* dir, char* file, char* ext) { + char* editor = "vim"; + char templatebuf[512] = {0}; + char filebuf[512] = {0}; + char cmdbuf[1024] = {0}; + + if(getenv("EDITOR") != NULL) + editor = getenv("EDITOR"); + + // Populate path and template buffers + snprintf(filebuf, 512, "%s/%s.%s", dir, file, ext); + snprintf(templatebuf, 512, "%s/.template.%s", dir, ext); + + // If a template file is found, copy it to the new path before editing + // Only do this is the target file doesn't yet exist. No overwrite. + if(access(templatebuf, R_OK) == 0 && access(filebuf, R_OK) != 0) + if(_cp(templatebuf, filebuf) != 0) + exit(1); + + // Construct the command and execute + sprintf(cmdbuf, "%s %s", editor, filebuf); + return system(cmdbuf); +} diff --git a/src/edit.h b/src/edit.h new file mode 100644 index 0000000..29bbb4b --- /dev/null +++ b/src/edit.h @@ -0,0 +1,22 @@ + /** + * Journal-tools provides simple tools for keeping journal entries + * Copyright (C) 2023 Aaron Ball, nullspoon@oper.io + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +int edit_exec(char*, char*, char*); diff --git a/src/path.c b/src/path.c new file mode 100644 index 0000000..2294276 --- /dev/null +++ b/src/path.c @@ -0,0 +1,108 @@ + /** + * Journal-tools provides simple tools for keeping journal entries + * Copyright (C) 2023 Aaron Ball, nullspoon@oper.io + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include "path.h" + +void path_date_fmt_filename(char* fmt, time_t offset, char* outbuf, int size) { + time_t epoch; + struct tm* tm; + + epoch = time(NULL) + offset; + tm = localtime(&epoch); + + strftime(outbuf, size, fmt, tm); +} + +void path_get_ext(char* envvar, char* buf, int size) { + if(getenv(envvar) != NULL) + strncpy(buf, getenv(envvar), size); + else + strcpy(buf, "md"); +} + +/** + * Searches paths for existing files, stopping upon finding a certain number + * behind. This is mostly for searching predictably named files where gaps in + * the naming convention may exist but should be ignored. + * + * For example, in a directory of date stampped filenames, some days may be + * missing. Instead of "-5" being "5 days ago", this function makes it "5 files + * ago", generating filenames as provided by the callback function. + * + * @int num Number of offset + * @int max Maximum number of files to search for, existing or not + * (prevents infinite loops) + * @void (*namecb)() Callback function of call signature (struct path*) + * @void* data Path structure to pass to the callback function + */ +int path_find_timepast(int num, int max, void (*namecb)(), void* data) { + int found = 0; + int loops = 0; + struct path* pathdata = (struct path*) data; + char pathbuf[1024] = {0}; + + // Only loop up to 1 possible year + // Note this operates backwards, as offset is negative + while(found > num && loops < max) { + (*namecb)(pathdata, pathbuf, 1024); + + // Get possible note path + sprintf(pathbuf, "%s/%s.%s", pathdata->base, pathdata->name, pathdata->ext); + + // Check if it exists, and increment find counter if true + if(access(pathbuf, R_OK) == 0) + found--; + + // Decrement offset seconds by one more day + pathdata->offset -= 24 * 60 * 60; + loops++; + } + + if(loops >= max) + return -1; + return loops; +} + + +// TODO: Rewrite these. They are trash. +void path_get_daily_journaldir(char* envvar, char* buf, int size) { + if(getenv(envvar) != NULL) + strncpy(buf, getenv(envvar), size); + else + snprintf(buf, size, "%s/Documents/Journal", getenv("HOME")); + + // Abort if journaldir is not accessible + if(access(buf, W_OK) != 0) { + fprintf(stderr, "Cannot access journal dir [%s]\n", buf); + fputs("Does it exist and do you have write access?\n", stderr); + exit(1); + } +} + +void path_get_weekly_journaldir(char* envvar, char* buf, int size) { + if(getenv(envvar) != NULL) + strncpy(buf, getenv(envvar), size); + else + snprintf(buf, size, "%s/Documents/Journal/Weekly", getenv("HOME")); + + // Abort if journaldir is not accessible + if(access(buf, W_OK) != 0) { + fprintf(stderr, "Cannot access journal dir [%s]\n", buf); + fputs("Does it exist and do you have write access?\n", stderr); + exit(1); + } +} diff --git a/src/path.h b/src/path.h new file mode 100644 index 0000000..2d61a34 --- /dev/null +++ b/src/path.h @@ -0,0 +1,35 @@ + /** + * Journal-tools provides simple tools for keeping journal entries + * Copyright (C) 2023 Aaron Ball, nullspoon@oper.io + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <time.h> + +struct path { + char base[512]; + char name[64]; + char ext[16]; + time_t offset; +}; + +void path_date_fmt_filename(char*, time_t, char*, int); +void path_get_daily_journaldir(char*, char*, int); +void path_get_weekly_journaldir(char*, char*, int); +void path_get_ext(char*, char*, int); +int path_find_timepast(int, int, void (*)(), void*); diff --git a/src/weekly.c b/src/weekly.c new file mode 100644 index 0000000..8bdd4f4 --- /dev/null +++ b/src/weekly.c @@ -0,0 +1,61 @@ + /** + * Journal-tools weekly simplifies writing weekly journal entries + * Copyright (C) 2023 Aaron Ball, nullspoon@oper.io + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include <stdio.h> +#include <string.h> + +#include "path.h" +#include "edit.h" + +void path_set(struct path* path) { + // Only resolve these once + if(path->base[0] == 0) + path_get_weekly_journaldir("WEEKLYJOURNAL_DIR", path->base, sizeof(path->base)); + if(path->ext[0] == 0) + path_get_ext("WEEKLYJOURNAL_EXT", path->ext, sizeof(path->ext)); + + path_date_fmt_filename("%Gw%V", path->offset, path->name, sizeof(path->name)); +} + + +int main(int argc, char* argv[]) { + int argoffset = 0; + struct path path; + + memset(&path, 0, sizeof(struct path)); // Zero mem + + // Read week offset if provided + if(argc > 1) { + argoffset = strtol(argv[1], NULL, 10); + path.offset = argoffset * 7 * 24 * 60 * 60; + } + + if(argoffset < 0) { + void (*namecb)() = &path_set; + if(path_find_timepast(argoffset, 52 * 2, namecb, &path) == -1) { + fputs("Could not find notes within past two years\n", stderr); + return 1; + } + } else { + path_set(&path); + } + + // For debugging + //printf("Opening %s/%s.%s\n", path.base, path.name, path.ext); + edit_exec(path.base, path.name, path.ext); + return 0; +} |