mirror of
https://github.com/michaeldv/pit.git
synced 2025-12-11 08:53:01 +00:00
Parsing time args, pager refactoring
This commit is contained in:
30
src/args.c
30
src/args.c
@@ -104,27 +104,25 @@ time_t pit_arg_date(char **arg, char *required)
|
|||||||
|
|
||||||
time_t pit_arg_time(char **arg, char *required)
|
time_t pit_arg_time(char **arg, char *required)
|
||||||
{
|
{
|
||||||
time_t seconds = (time_t)-1;
|
int seconds = 0;
|
||||||
char *format;
|
|
||||||
struct tm tm;
|
|
||||||
|
|
||||||
if (required && (!*arg || pit_arg_is_option(arg))) {
|
if (required && (!*arg || pit_arg_is_option(arg))) {
|
||||||
die("missing %s", required);
|
die("missing %s", required);
|
||||||
} else {
|
} else { /* Suppored time formats are :MM, HH:MM, and HH */
|
||||||
memset(&tm, 0, sizeof(tm)); /* Suppored time formats are HH, HH:MM, and :MM */
|
char *colon = strchr(*arg, ':');
|
||||||
if (**arg == ':') {
|
if (colon == *arg) { /* :MM - minutes only */
|
||||||
format = ":%M"; /* Minutes only */
|
seconds = atoi(++colon) * 60;
|
||||||
} else if (strchr(*arg, ':')) {
|
} else if (colon) { /* HH:MM - hours and minutes */
|
||||||
format = "%H:%M"; /* Hours and minutes */
|
*colon = '\0';
|
||||||
} else {
|
seconds = atoi(*arg) * 3600 + atoi(++colon) * 60;
|
||||||
format = "%H"; /* Hours only */
|
} else { /* HH - hours only */
|
||||||
}
|
seconds = atoi(*arg) * 3600;
|
||||||
if (strptime(*arg, format, &tm)) {
|
|
||||||
seconds = mktime(&tm);
|
|
||||||
} else {
|
|
||||||
die("invalid time format: %s", *arg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!seconds) {
|
||||||
|
die("invalid time format: %s", *arg);
|
||||||
|
}
|
||||||
|
|
||||||
return seconds;
|
return seconds;
|
||||||
}
|
}
|
||||||
|
|||||||
199
src/pager.c
199
src/pager.c
@@ -4,6 +4,133 @@
|
|||||||
#include "pit.h"
|
#include "pit.h"
|
||||||
|
|
||||||
#define for_each_entry(ppager, entry) for (entry = (uchar **)ppager->entries; (uchar *)*entry; entry++)
|
#define for_each_entry(ppager, entry) for (entry = (uchar **)ppager->entries; (uchar *)*entry; entry++)
|
||||||
|
#define TASK(attr) (((PTask)*pentry)->attr)
|
||||||
|
#define PROJECT(attr) (((PProject)*pentry)->attr)
|
||||||
|
#define ACTION(attr) (((PAction)*pentry)->attr)
|
||||||
|
|
||||||
|
static void print_actions(PPager ppager)
|
||||||
|
{
|
||||||
|
uchar **pentry;
|
||||||
|
char format[64];
|
||||||
|
|
||||||
|
sprintf(format, "%%s (%%-%ds): %%s\n", ppager->max.action.username);
|
||||||
|
for_each_entry(ppager, pentry) {
|
||||||
|
printf(format, format_date(ACTION(created_at)), ACTION(username), ACTION(message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_projects(PPager ppager)
|
||||||
|
{
|
||||||
|
uchar **pentry;
|
||||||
|
char format[64];
|
||||||
|
|
||||||
|
sprintf(format, "%%c %%%dlu: (%%-%ds) [%%-%ds] %%-%ds (%%lu task%%s)\n",
|
||||||
|
ppager->max.project.id, ppager->max.project.username, ppager->max.project.status, ppager->max.project.name
|
||||||
|
);
|
||||||
|
for_each_entry(ppager, pentry) {
|
||||||
|
printf(format,
|
||||||
|
(PROJECT(id) == projects->current ? '*' : ' '),
|
||||||
|
PROJECT(id),
|
||||||
|
PROJECT(username),
|
||||||
|
PROJECT(status),
|
||||||
|
PROJECT(name),
|
||||||
|
PROJECT(number_of_tasks),
|
||||||
|
(PROJECT(number_of_tasks) != 1 ? "s" : "")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_tasks(PPager ppager)
|
||||||
|
{
|
||||||
|
uchar **pentry;
|
||||||
|
char format[64];
|
||||||
|
|
||||||
|
sprintf(format, "%%c %%%dlu: (%%-%ds) [%%-%ds] [%%-%ds] %%-%ds (%%lu note%%s)\n",
|
||||||
|
ppager->max.task.id, ppager->max.task.username, ppager->max.task.status, ppager->max.task.priority, ppager->max.task.name
|
||||||
|
);
|
||||||
|
for_each_entry(ppager, pentry) {
|
||||||
|
printf(format,
|
||||||
|
(TASK(id) == tasks->current ? '*' : ' '),
|
||||||
|
TASK(id),
|
||||||
|
TASK(username),
|
||||||
|
TASK(status),
|
||||||
|
TASK(priority),
|
||||||
|
TASK(name),
|
||||||
|
TASK(number_of_notes),
|
||||||
|
(TASK(number_of_notes) != 1 ? "s" : "")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_tasks_with_date(PPager ppager)
|
||||||
|
{
|
||||||
|
uchar **pentry;
|
||||||
|
char format[64];
|
||||||
|
|
||||||
|
sprintf(format, "%%c %%%dlu: (%%-%ds) [%%-%ds] [%%-%ds] %%-%ds %%-%ds (%%lu note%%s)\n",
|
||||||
|
ppager->max.task.id, ppager->max.task.username, ppager->max.task.status, ppager->max.task.priority, ppager->max.task.date, ppager->max.task.name
|
||||||
|
);
|
||||||
|
for_each_entry(ppager, pentry) {
|
||||||
|
printf(format,
|
||||||
|
(TASK(id) == tasks->current ? '*' : ' '),
|
||||||
|
TASK(id),
|
||||||
|
TASK(username),
|
||||||
|
TASK(status),
|
||||||
|
TASK(priority),
|
||||||
|
(TASK(date) ? format_date(TASK(date)) : ""),
|
||||||
|
TASK(name),
|
||||||
|
TASK(number_of_notes),
|
||||||
|
(TASK(number_of_notes) != 1 ? "s" : "")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_tasks_with_time(PPager ppager)
|
||||||
|
{
|
||||||
|
uchar **pentry;
|
||||||
|
char format[64];
|
||||||
|
|
||||||
|
sprintf(format, "%%c %%%dlu: (%%-%ds) %%-%ds %%-%ds %%%ds %%-%ds (%%lu note%%s)\n",
|
||||||
|
ppager->max.task.id, ppager->max.task.username, ppager->max.task.status, ppager->max.task.priority, ppager->max.task.time, ppager->max.task.name
|
||||||
|
);
|
||||||
|
for_each_entry(ppager, pentry) {
|
||||||
|
printf(format,
|
||||||
|
(TASK(id) == tasks->current ? '*' : ' '),
|
||||||
|
TASK(id),
|
||||||
|
TASK(username),
|
||||||
|
TASK(status),
|
||||||
|
TASK(priority),
|
||||||
|
(TASK(time) ? format_time(TASK(time)) : ""),
|
||||||
|
TASK(name),
|
||||||
|
TASK(number_of_notes),
|
||||||
|
(TASK(number_of_notes) != 1 ? "s" : "")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_tasks_with_date_and_time(PPager ppager)
|
||||||
|
{
|
||||||
|
uchar **pentry;
|
||||||
|
char format[64];
|
||||||
|
|
||||||
|
sprintf(format, "%%c %%%dlu: (%%-%ds) [%%-%ds] [%%-%ds] %%-%ds %%%ds %%-%ds (%%lu note%%s)\n",
|
||||||
|
ppager->max.task.id, ppager->max.task.username, ppager->max.task.status, ppager->max.task.priority, ppager->max.task.date, ppager->max.task.time, ppager->max.task.name
|
||||||
|
);
|
||||||
|
for_each_entry(ppager, pentry) {
|
||||||
|
printf(format,
|
||||||
|
(TASK(id) == tasks->current ? '*' : ' '),
|
||||||
|
TASK(id),
|
||||||
|
TASK(username),
|
||||||
|
TASK(status),
|
||||||
|
TASK(priority),
|
||||||
|
(TASK(date) ? format_date(TASK(date)) : ""),
|
||||||
|
(TASK(time) ? format_time(TASK(time)) : ""),
|
||||||
|
TASK(name),
|
||||||
|
TASK(number_of_notes),
|
||||||
|
(TASK(number_of_notes) != 1 ? "s" : "")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PPager pit_pager_initialize(ulong type, ulong number_of_entries)
|
PPager pit_pager_initialize(ulong type, ulong number_of_entries)
|
||||||
{
|
{
|
||||||
@@ -19,18 +146,25 @@ PPager pit_pager_initialize(ulong type, ulong number_of_entries)
|
|||||||
void pit_pager_print(PPager ppager, uchar *entry)
|
void pit_pager_print(PPager ppager, uchar *entry)
|
||||||
{
|
{
|
||||||
char str[32];
|
char str[32];
|
||||||
|
|
||||||
uchar **pentry = (uchar **)ppager->entries + ppager->number_of_entries++;
|
uchar **pentry = (uchar **)ppager->entries + ppager->number_of_entries++;
|
||||||
*pentry = entry;
|
*pentry = entry;
|
||||||
|
|
||||||
for_each_entry(ppager, pentry) {
|
for_each_entry(ppager, pentry) {
|
||||||
switch(ppager->type) {
|
switch(ppager->type) {
|
||||||
case PAGER_TASK:
|
case PAGER_TASK:
|
||||||
sprintf(str, "%lu", ((PTask)*pentry)->id);
|
sprintf(str, "%lu", TASK(id));
|
||||||
ppager->max.task.id = max(ppager->max.task.id, strlen(str));
|
ppager->max.task.id = max(ppager->max.task.id, strlen(str));
|
||||||
ppager->max.task.username = max(ppager->max.task.username, strlen(((PTask)*pentry)->username));
|
ppager->max.task.username = max(ppager->max.task.username, strlen(TASK(username)));
|
||||||
ppager->max.task.name = max(ppager->max.task.name, strlen(((PTask)*pentry)->name));
|
ppager->max.task.name = max(ppager->max.task.name, strlen(TASK(name)));
|
||||||
ppager->max.task.status = max(ppager->max.task.status, strlen(((PTask)*pentry)->status));
|
ppager->max.task.status = max(ppager->max.task.status, strlen(TASK(status)));
|
||||||
ppager->max.task.priority = max(ppager->max.task.priority, strlen(((PTask)*pentry)->priority));
|
ppager->max.task.priority = max(ppager->max.task.priority, strlen(TASK(priority)));
|
||||||
|
if (TASK(date)) {
|
||||||
|
ppager->max.task.date = max(ppager->max.task.date, strlen(format_date(TASK(date))));
|
||||||
|
}
|
||||||
|
if (TASK(time)) {
|
||||||
|
ppager->max.task.time = max(ppager->max.task.time, strlen(format_time(TASK(time))));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PAGER_PROJECT:
|
case PAGER_PROJECT:
|
||||||
sprintf(str, "%lu", ((PProject)*pentry)->id);
|
sprintf(str, "%lu", ((PProject)*pentry)->id);
|
||||||
@@ -51,54 +185,29 @@ void pit_pager_print(PPager ppager, uchar *entry)
|
|||||||
|
|
||||||
void pit_pager_flush(PPager ppager)
|
void pit_pager_flush(PPager ppager)
|
||||||
{
|
{
|
||||||
uchar **pentry;
|
|
||||||
char format[64], timestamp[32];
|
|
||||||
|
|
||||||
switch(ppager->type) {
|
switch(ppager->type) {
|
||||||
case PAGER_TASK:
|
case PAGER_TASK:
|
||||||
sprintf(format, "%%c %%%dlu: (%%-%ds) [%%-%ds] [%%-%ds] %%-%ds (%%lu note%%s)\n",
|
if (!ppager->max.task.date && !ppager->max.task.time) {
|
||||||
ppager->max.task.id, ppager->max.task.username, ppager->max.task.status, ppager->max.task.priority, ppager->max.task.name
|
print_tasks(ppager); /* Neither date nor time. */
|
||||||
);
|
} else if (ppager->max.task.date) {
|
||||||
for_each_entry(ppager, pentry) {
|
if (ppager->max.task.time) {
|
||||||
printf(format,
|
print_tasks_with_date_and_time(ppager); /* Both date and time. */
|
||||||
(((PTask)*pentry)->id == tasks->current ? '*' : ' '),
|
} else {
|
||||||
((PTask)*pentry)->id,
|
print_tasks_with_date(ppager); /* Date but no time. */
|
||||||
((PTask)*pentry)->username,
|
}
|
||||||
((PTask)*pentry)->status,
|
} else {
|
||||||
((PTask)*pentry)->priority,
|
print_tasks_with_time(ppager); /* Time but no date. */
|
||||||
((PTask)*pentry)->name,
|
|
||||||
((PTask)*pentry)->number_of_notes,
|
|
||||||
(((PTask)*pentry)->number_of_notes != 1 ? "s" : "")
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PAGER_PROJECT:
|
case PAGER_PROJECT:
|
||||||
sprintf(format, "%%c %%%dlu: (%%-%ds) [%%-%ds] %%-%ds (%%lu task%%s)\n",
|
print_projects(ppager);
|
||||||
ppager->max.project.id, ppager->max.project.username, ppager->max.project.status, ppager->max.project.name
|
|
||||||
);
|
|
||||||
for_each_entry(ppager, pentry) {
|
|
||||||
printf(format,
|
|
||||||
(((PProject)*pentry)->id == projects->current ? '*' : ' '),
|
|
||||||
((PProject)*pentry)->id,
|
|
||||||
((PProject)*pentry)->username,
|
|
||||||
((PProject)*pentry)->status,
|
|
||||||
((PProject)*pentry)->name,
|
|
||||||
((PProject)*pentry)->number_of_tasks,
|
|
||||||
(projects->number_of_records != 1 ? "s" : "")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PAGER_ACTION:
|
case PAGER_ACTION:
|
||||||
sprintf(format, "%%s (%%-%ds): %%s\n", ppager->max.action.username);
|
print_actions(ppager);
|
||||||
for_each_entry(ppager, pentry) {
|
|
||||||
strftime(timestamp, sizeof(timestamp), "%b %d, %Y %H:%M", localtime(&((PAction)*pentry)->created_at));
|
|
||||||
printf(format,
|
|
||||||
timestamp,
|
|
||||||
((PAction)*pentry)->username,
|
|
||||||
((PAction)*pentry)->message
|
|
||||||
);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
pit_pager_free(ppager);
|
pit_pager_free(ppager);
|
||||||
die("invalid pager type: %d\n", ppager->type);
|
die("invalid pager type: %d\n", ppager->type);
|
||||||
|
|||||||
@@ -67,5 +67,7 @@ char *mem2str(char *mem, int len);
|
|||||||
char *current_user();
|
char *current_user();
|
||||||
char *home_dir(char *username, int len);
|
char *home_dir(char *username, int len);
|
||||||
char *expand_path(char *path, char *expanded);
|
char *expand_path(char *path, char *expanded);
|
||||||
|
char *format_date(time_t date);
|
||||||
|
char *format_time(time_t time);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ static void task_create(char *name, char *status, char *priority, time_t date, t
|
|||||||
strncpy(t.username, current_user(), sizeof(t.username) - 1);
|
strncpy(t.username, current_user(), sizeof(t.username) - 1);
|
||||||
t.project_id = pp->id;
|
t.project_id = pp->id;
|
||||||
t.date = date;
|
t.date = date;
|
||||||
t.time = 0; /* TODO */
|
t.time = time;
|
||||||
|
|
||||||
pt = (PTask)pit_table_insert(tasks, (uchar *)&t);
|
pt = (PTask)pit_table_insert(tasks, (uchar *)&t);
|
||||||
pit_table_mark(tasks, pt->id);
|
pit_table_mark(tasks, pt->id);
|
||||||
|
|||||||
24
src/util.c
24
src/util.c
@@ -62,6 +62,30 @@ char *expand_path(char *path, char *expanded) {
|
|||||||
return expanded;
|
return expanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *format_date(time_t date)
|
||||||
|
{
|
||||||
|
static char str[32];
|
||||||
|
struct tm *ptm;
|
||||||
|
|
||||||
|
ptm = localtime(&date);
|
||||||
|
if (!ptm->tm_hour && !ptm->tm_min && !ptm->tm_sec) {
|
||||||
|
strftime(str, sizeof(str), "%b %d, %Y", ptm);
|
||||||
|
} else {
|
||||||
|
strftime(str, sizeof(str), "%b %d, %Y %H:%M", ptm);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *format_time(time_t time)
|
||||||
|
{
|
||||||
|
static char str[10];
|
||||||
|
int hh = time / 3600;
|
||||||
|
int mm = (time - hh * 3600) / 60;
|
||||||
|
|
||||||
|
sprintf(str, "%d:%02d", hh, mm);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
printf("your username: %s\n", current_user());
|
printf("your username: %s\n", current_user());
|
||||||
|
|||||||
Reference in New Issue
Block a user