diff options
author | Aaron Ball <nullspoon@oper.io> | 2022-07-13 10:31:43 -0600 |
---|---|---|
committer | Aaron Ball <nullspoon@oper.io> | 2022-07-13 21:53:27 -0600 |
commit | 3ae876831fed6d41463fd3a5de2ce3fab7d0ac45 (patch) | |
tree | 337b93a71e2574622f8479eaee5352275c4191c6 | |
parent | 9c8ca4daaaa6a163cbb559643254e6404be8bcd3 (diff) | |
download | dailyjournal-3ae876831fed6d41463fd3a5de2ce3fab7d0ac45.tar.gz dailyjournal-3ae876831fed6d41463fd3a5de2ce3fab7d0ac45.tar.xz |
Initial commit of refactor work and addition of todo command
This renames `dailyjournal` to just `journal`. It also breaks out common
code to a new common library, and moves runtime configuration code to a
new config library, which provides a struct in which to store the config
values.
Finally, this work supports the introduction of a new command, `todo`.
This command takes the same arguments as `journal` (day count like no
argument for today, -1 for yesterday, etc), but it parses the note for a
Todo section, printing only the contents to stdout. This is for quickly
viewing todo items and can easily be rolled into a shell rc file for
even quicker viewing.
-rw-r--r-- | Makefile | 22 | ||||
-rw-r--r-- | src/common.c (renamed from src/main.c) | 89 | ||||
-rw-r--r-- | src/common.h | 34 | ||||
-rw-r--r-- | src/config.c | 36 | ||||
-rw-r--r-- | src/config.h | 32 | ||||
-rw-r--r-- | src/journal.c | 63 | ||||
-rw-r--r-- | src/todo.c | 96 |
7 files changed, 300 insertions, 72 deletions
@@ -1,10 +1,24 @@ PREFIX := /usr CCOPTS = -Wall -Werror --std=gnu18 -O2 -.DEFAULT: build -build: - cc $(CCOPTS) src/main.c -o dailyjournal +all: build_journal build_todo + +_obj: + if [ ! -d obj ]; then mkdir obj; fi + +_common: _obj + cc $(CCOPTS) src/common.c -c -o obj/common.o + +_config: _obj + cc $(CCOPTS) src/config.c -c -o obj/config.o + +build_todo: _common _config + cc $(CCOPTS) src/todo.c obj/*.o -o todo + +build_journal: _common _config + cc $(CCOPTS) src/journal.c obj/*.o -o journal install: - install -D -m 755 dailyjournal $(DESTDIR)$(PREFIX)/bin/dailyjournal + install -D -m 755 journal $(DESTDIR)$(PREFIX)/bin/journal + install -D -m 755 todo $(DESTDIR)$(PREFIX)/bin/todo install -D -m 644 template.md $(DESTDIR)$(PREFIX)/share/dailyjournal/template.md diff --git a/src/main.c b/src/common.c index faf8a9e..062c6dd 100644 --- a/src/main.c +++ b/src/common.c @@ -15,13 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#define _XOPEN_SOURCE -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#define DEFAULT_EXTENSION ".md" +#include "common.h" void get_user_editor(char* editor) { if(getenv("EDITOR") != NULL) @@ -75,78 +69,37 @@ int safe_cp(char* src, char* dest) { return 0; } -void getpath(char* base, int days, char* out, char* extension) { +void getdate(int days, char* out, int outsize) { time_t t; struct tm* tmnow; - char filename[128]; t = time(NULL); t = t + (days * 86400); tmnow = localtime(&t); - strftime(filename, 256, "%F", tmnow); + strftime(out, outsize, "%F", tmnow); +} + +void getpath(char* base, int days, char* out, char* extension) { + char filename[128]; + // time_t t; + // struct tm* tmnow; + // t = time(NULL); + // t = t + (days * 86400); + // tmnow = localtime(&t); + + //strftime(filename, 256, "%F", tmnow); + + getdate(days, filename, 128); sprintf(out, "%s/%s%s", base, filename, extension); } -int env_or_default(char* buf, char* varname, char* defaultval) { +int env_if_set(char* buf, char* varname) { char* env = getenv(varname); - if(env == NULL) { - sprintf(buf, "%s", defaultval); - return 1; - } - sprintf(buf, "%s", env); - return 0; -} - -int main(int argc, char* argv[]) { - char notepath[256] = {'\0'}; - char journaldir[512] = {'\0'}; - char templatepath[512] = {'\0'}; - char *extension = NULL; - int i = 0; - - // Set default paths - sprintf(journaldir, "%s/%s", getenv("HOME"), "Documents/dailyjournal"); - - int days = 0; - if(argc > 1) - days = strtol(argv[1], NULL, 10); - - // Set default values - env_or_default(journaldir, "DAILYJOURNAL_DIR", journaldir); - sprintf(templatepath, "%s/.template.md", journaldir); - env_or_default(templatepath, "DAILYJOURNAL_TEMPLATE", templatepath); - - extension = strrchr(templatepath, '.'); - if(!extension) - extension = DEFAULT_EXTENSION; - - // If user requests negative days, we want to skip non-existant days. So `-2` - // is really "two entries ago" rather than two days ago, which could yield - // creating an empty historical note if one does not already exist (for - // example: on Monday, opening Friday's entry which is -3 days, but -1 - // entry). - if(days < 0) { - while(days < 0) { - i--; - getpath(journaldir, i, notepath, extension); - if(fexists(notepath)) - days++; - // Stop traversing after a year to avoid infinite loops when no notes - // exist (or exist very long ago) - if(i < -365) { - fprintf(stderr, "Refusing to search further back than one year\n"); - return 1; - } - } - } else { - getpath(journaldir, days, notepath, extension); - } - - if(safe_cp(templatepath, notepath) == -2) { - printf("No template found at %s\n", templatepath); - return 2; + if(env != NULL) { + sprintf(buf, "%s", env); + return 0; } - return fedit(notepath); + return 1; } diff --git a/src/common.h b/src/common.h new file mode 100644 index 0000000..cdba2bf --- /dev/null +++ b/src/common.h @@ -0,0 +1,34 @@ +/** + * Dailyjournal is an easy tool to log daily activities + * Copyright (C) 2022 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/>. + */ + +#define _XOPEN_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#define DEFAULT_EXTENSION ".md" + +void config_getpaths(char*, char*, char*); +void get_user_editor(char*); +int fedit(char*); +int fexists(char*); +int safe_cp(char*, char*); +void getdate(int, char*, int); +void getpath(char*, int, char*, char*); +int env_if_set(char*, char*); diff --git a/src/config.c b/src/config.c new file mode 100644 index 0000000..0acd88a --- /dev/null +++ b/src/config.c @@ -0,0 +1,36 @@ +/** + * Dailyjournal is an easy tool to log daily activities + * Copyright (C) 2022 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 "config.h" + +void config_init(struct config* c) { + char* extp = NULL; + + // Set default paths first + sprintf(c->journaldir, "%s/%s", getenv("HOME"), "Documents/Journal"); + sprintf(c->templatepath, "%s/.template.md", c->journaldir); + + // Set default values, allowing override + env_if_set(c->journaldir, "DAILYJOURNAL_DIR"); + env_if_set(c->templatepath, "DAILYJOURNAL_TEMPLATE"); + + extp = strrchr(c->templatepath, '.'); + if(!extp) + strcpy(c->extension, DEFAULT_EXTENSION); + else + strcpy(c->extension, extp); +} diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..4975ef4 --- /dev/null +++ b/src/config.h @@ -0,0 +1,32 @@ +/** + * Dailyjournal is an easy tool to log daily activities + * Copyright (C) 2022 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/>. + */ +#define _XOPEN_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#include "common.h" + +struct config { + char journaldir[512]; + char templatepath[1024]; + char extension[32]; +}; + +void config_init(struct config*); diff --git a/src/journal.c b/src/journal.c new file mode 100644 index 0000000..eb38db2 --- /dev/null +++ b/src/journal.c @@ -0,0 +1,63 @@ +/** + * Dailyjournal is an easy tool to log daily activities + * Copyright (C) 2022 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/>. + */ +#define _XOPEN_SOURCE +#include <stdio.h> + +#include "common.h" +#include "config.h" + +int main(int argc, char* argv[]) { + char notepath[256] = {'\0'}; + int i = 0; + struct config c; + + memset(&c, sizeof(struct config), 1); + config_init(&c); + + int days = 0; + if(argc > 1) + days = strtol(argv[1], NULL, 10); + + // If user requests negative days, we want to skip non-existant days. So `-2` + // is really "two entries ago" rather than two days ago, which could yield + // creating an empty historical note if one does not already exist (for + // example: on Monday, opening Friday's entry which is -3 days, but -1 + // entry). + if(days < 0) { + while(days < 0) { + i--; + getpath(c.journaldir, i, notepath, c.extension); + if(fexists(notepath)) + days++; + // Stop traversing after a year to avoid infinite loops when no notes + // exist (or exist very long ago) + if(i < -365) { + fprintf(stderr, "Refusing to search further back than one year\n"); + return 1; + } + } + } else { + getpath(c.journaldir, days, notepath, c.extension); + } + + if(safe_cp(c.templatepath, notepath) == -2) { + printf("No template found at %s\n", c.templatepath); + return 2; + } + return fedit(notepath); +} diff --git a/src/todo.c b/src/todo.c new file mode 100644 index 0000000..05347ff --- /dev/null +++ b/src/todo.c @@ -0,0 +1,96 @@ +/** + * Dailytodo is an easy tool to review daily todo items + * Copyright (C) 2022 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/>. + */ +#define _XOPEN_SOURCE +#include <stdio.h> + +#include "common.h" +#include "config.h" + +int print_section(char* path, char* prefix, char* title) { + FILE* fd = NULL; + char buf[4096] = {'\0'}; + char header[512] = {'\0'}; + char hprefix[32] = {'\0'}; + int headerlen = 0; + int hprefixlen = 0; + int output = 0; + + snprintf(header, 512, "%s %s\n", prefix, title); + snprintf(hprefix, 32, "%s \n", prefix); + headerlen = strlen(header); + hprefixlen = strlen(hprefix); + + fd = fopen(path, "r"); + while(fgets(buf, 4096, fd) != NULL) { + if(strncmp(buf, header, headerlen) == 0 ) { + output = 1; + continue; + } else if(strncmp(buf, hprefix, hprefixlen) == 0 ) { + output = 0; + } + if(output == 1) + fputs(buf, stdout); + } + + fclose(fd); + return 0; +} + +int main(int argc, char* argv[]) { + char notepath[256] = {'\0'}; + char date[128] = {'\0'}; + char* prefix = "#"; + char* title = "Todo"; + int days = 0; + int i = 0; + struct config c; + + memset(&c, sizeof(struct config), 1); + config_init(&c); + + if(argc > 1) + days = strtol(argv[1], NULL, 10); + + // If user requests negative days, we want to skip non-existant days. So `-2` + // is really "two entries ago" rather than two days ago, which could yield + // creating an empty historical note if one does not already exist (for + // example: on Monday, opening Friday's entry which is -3 days, but -1 + // entry). + if(days < 0) { + while(days < 0) { + i--; + getpath(c.journaldir, i, notepath, c.extension); + if(fexists(notepath)) + days++; + // Stop traversing after a year to avoid infinite loops when no notes + // exist (or exist very long ago) + if(i < -365) { + fprintf(stderr, "Refusing to search further back than one year\n"); + return 1; + } + } + } else { + getpath(c.journaldir, days, notepath, c.extension); + } + getdate(i, date, 128); + + printf("%s %s (%s)\n", prefix, title, date); + print_section(notepath, prefix, title); + + return 0; +} |