summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAaron Ball <nullspoon@oper.io>2023-10-27 19:08:28 -0600
committerAaron Ball <nullspoon@oper.io>2023-10-27 19:47:35 -0600
commitcd6c0df323d0ed177397f3f6ace5dcdfcbb9796b (patch)
tree77bd8b5ab0e4e6d7737093033ae5b548d7b3fa8c /src
downloadjournal-tools-cd6c0df323d0ed177397f3f6ace5dcdfcbb9796b.tar.gz
journal-tools-cd6c0df323d0ed177397f3f6ace5dcdfcbb9796b.tar.xz
Initial commit of journal-toolsHEADmaster
This is a complete rewrite of dailyjournal to improve code quality, simplicity, maintainability, flexibility; all of the ilities. This is fully backwards compatible with dailyjournal, but it is much simpler from a code perspective, as most of the code is reusable and shared betwen tools, leaving only time window-specific code in the source for the given tool. The dailyjournal code produced one binary, `journal`, which conflicted with autocomplete with a now-ubiquitous command from everybody's favorite init system. This single command also expected entries to be made daily, not allowing for things like weekly summary reports to be easily written. This rewrite has two commmands: `dailyjournal` and `weeklyjournal`. Both behave identically in that they can be called with a +/- days/weeks argument.
Diffstat (limited to 'src')
-rw-r--r--src/daily.c61
-rw-r--r--src/edit.c68
-rw-r--r--src/edit.h22
-rw-r--r--src/path.c108
-rw-r--r--src/path.h35
-rw-r--r--src/weekly.c61
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;
+}

Generated by cgit