From caee34449c1c8b2c8bf3049f34625db871e7d9dc Mon Sep 17 00:00:00 2001
From: Lukas Fleischer <lfleischer@calcurse.org>
Date: Fri, 15 Jan 2016 18:22:19 +0100
Subject: Export item UIDs upon request

Add a new --export-uid command line option that adds each item's hash to
the UID property when exporting.

Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
---
 src/args.c     |  9 ++++++--
 src/calcurse.c |  4 ++--
 src/calcurse.h |  4 ++--
 src/ical.c     | 67 ++++++++++++++++++++++++++++++++++++++++++++--------------
 src/io.c       |  4 ++--
 5 files changed, 64 insertions(+), 24 deletions(-)

diff --git a/src/args.c b/src/args.c
index 0e6a5a2..003760d 100644
--- a/src/args.c
+++ b/src/args.c
@@ -71,6 +71,7 @@ enum {
 	OPT_FMT_REV,
 	OPT_FMT_TODO,
 	OPT_LIST_IMPORTED,
+	OPT_EXPORT_UID,
 	OPT_READ_ONLY,
 	OPT_STATUS
 };
@@ -453,7 +454,7 @@ int parse_args(int argc, char **argv)
 	const char *fmt_todo = "%p. %m\n";
 	/* Import and export parameters */
 	int xfmt = IO_EXPORT_ICAL;
-	int list_imported = 0;
+	int list_imported = 0, export_uid = 0;
 	/* Data file locations */
 	const char *cfile = NULL, *datadir = NULL, *ifile = NULL;
 
@@ -509,6 +510,7 @@ int parse_args(int argc, char **argv)
 		{"format-event", required_argument, NULL, OPT_FMT_EV},
 		{"format-recur-event", required_argument, NULL, OPT_FMT_REV},
 		{"format-todo", required_argument, NULL, OPT_FMT_TODO},
+		{"export-uid", no_argument, NULL, OPT_EXPORT_UID},
 		{"list-imported", no_argument, NULL, OPT_LIST_IMPORTED},
 		{"read-only", no_argument, NULL, OPT_READ_ONLY},
 		{"status", no_argument, NULL, OPT_STATUS},
@@ -719,6 +721,9 @@ int parse_args(int argc, char **argv)
 		case OPT_LIST_IMPORTED:
 			list_imported = 1;
 			break;
+		case OPT_EXPORT_UID:
+			export_uid = 1;
+			break;
 		case OPT_READ_ONLY:
 			read_only = 1;
 			break;
@@ -802,7 +807,7 @@ int parse_args(int argc, char **argv)
 		io_check_file(path_apts);
 		io_check_file(path_todo);
 		io_load_data(&filter);
-		io_export_data(xfmt);
+		io_export_data(xfmt, export_uid);
 	} else {
 		/* interactive mode */
 		non_interactive = 0;
diff --git a/src/calcurse.c b/src/calcurse.c
index 9f85501..889c68c 100644
--- a/src/calcurse.c
+++ b/src/calcurse.c
@@ -293,10 +293,10 @@ static inline void key_generic_export()
 	switch (status_ask_choice
 		(export_msg, export_choices, nb_export_choices)) {
 	case 1:
-		io_export_data(IO_EXPORT_ICAL);
+		io_export_data(IO_EXPORT_ICAL, 0);
 		break;
 	case 2:
-		io_export_data(IO_EXPORT_PCAL);
+		io_export_data(IO_EXPORT_PCAL, 0);
 		break;
 	default:		/* User escaped */
 		break;
diff --git a/src/calcurse.h b/src/calcurse.h
index 380384f..2b5b055 100644
--- a/src/calcurse.h
+++ b/src/calcurse.h
@@ -799,7 +799,7 @@ int run_hook(const char *);
 /* ical.c */
 void ical_import_data(FILE *, FILE *, int, unsigned *, unsigned *, unsigned *,
 		      unsigned *, unsigned *);
-void ical_export_data(FILE *);
+void ical_export_data(FILE *, int);
 
 /* io.c */
 unsigned io_fprintln(const char *, const char *, ...);
@@ -822,7 +822,7 @@ unsigned io_file_exists(const char *);
 int io_check_file(const char *);
 int io_check_data_files(void);
 void io_startup_screen(int);
-void io_export_data(enum export_type);
+void io_export_data(enum export_type, int);
 void io_import_data(enum import_type, const char *, int);
 struct io_file *io_log_init(void);
 void io_log_print(struct io_file *, int, const char *);
diff --git a/src/ical.c b/src/ical.c
index 0c52611..93952ec 100644
--- a/src/ical.c
+++ b/src/ical.c
@@ -62,11 +62,11 @@ typedef struct {
 } ical_rpt_t;
 
 static void ical_export_header(FILE *);
-static void ical_export_recur_events(FILE *);
-static void ical_export_events(FILE *);
-static void ical_export_recur_apoints(FILE *);
-static void ical_export_apoints(FILE *);
-static void ical_export_todo(FILE *);
+static void ical_export_recur_events(FILE *, int);
+static void ical_export_events(FILE *, int);
+static void ical_export_recur_apoints(FILE *, int);
+static void ical_export_apoints(FILE *, int);
+static void ical_export_todo(FILE *, int);
 static void ical_export_footer(FILE *);
 
 static const char *ical_recur_type[RECUR_TYPES] =
@@ -98,7 +98,7 @@ static void ical_export_footer(FILE * stream)
 }
 
 /* Export recurrent events. */
-static void ical_export_recur_events(FILE * stream)
+static void ical_export_recur_events(FILE * stream, int export_uid)
 {
 	llist_item_t *i, *j;
 	char ical_date[BUFSIZ];
@@ -131,12 +131,19 @@ static void ical_export_recur_events(FILE * stream)
 		}
 
 		fprintf(stream, "SUMMARY:%s\n", rev->mesg);
+
+		if (export_uid) {
+			char *hash = recur_event_hash(rev);
+			fprintf(stream, "UID:%s\n", hash);
+			mem_free(hash);
+		}
+
 		fputs("END:VEVENT\n", stream);
 	}
 }
 
 /* Export events. */
-static void ical_export_events(FILE * stream)
+static void ical_export_events(FILE * stream, int export_uid)
 {
 	llist_item_t *i;
 	char ical_date[BUFSIZ];
@@ -147,12 +154,19 @@ static void ical_export_events(FILE * stream)
 		fputs("BEGIN:VEVENT\n", stream);
 		fprintf(stream, "DTSTART:%s\n", ical_date);
 		fprintf(stream, "SUMMARY:%s\n", ev->mesg);
+
+		if (export_uid) {
+			char *hash = event_hash(ev);
+			fprintf(stream, "UID:%s\n", hash);
+			mem_free(hash);
+		}
+
 		fputs("END:VEVENT\n", stream);
 	}
 }
 
 /* Export recurrent appointments. */
-static void ical_export_recur_apoints(FILE * stream)
+static void ical_export_recur_apoints(FILE * stream, int export_uid)
 {
 	llist_item_t *i, *j;
 	char ical_datetime[BUFSIZ];
@@ -198,13 +212,20 @@ static void ical_export_recur_apoints(FILE * stream)
 		fprintf(stream, "SUMMARY:%s\n", rapt->mesg);
 		if (rapt->state & APOINT_NOTIFY)
 			ical_export_valarm(stream);
+
+		if (export_uid) {
+			char *hash = recur_apoint_hash(rapt);
+			fprintf(stream, "UID:%s\n", hash);
+			mem_free(hash);
+		}
+
 		fputs("END:VEVENT\n", stream);
 	}
 	LLIST_TS_UNLOCK(&recur_alist_p);
 }
 
 /* Export appointments. */
-static void ical_export_apoints(FILE * stream)
+static void ical_export_apoints(FILE * stream, int export_uid)
 {
 	llist_item_t *i;
 	char ical_datetime[BUFSIZ];
@@ -226,13 +247,20 @@ static void ical_export_apoints(FILE * stream)
 		fprintf(stream, "SUMMARY:%s\n", apt->mesg);
 		if (apt->state & APOINT_NOTIFY)
 			ical_export_valarm(stream);
+
+		if (export_uid) {
+			char *hash = apoint_hash(apt);
+			fprintf(stream, "UID:%s\n", hash);
+			mem_free(hash);
+		}
+
 		fputs("END:VEVENT\n", stream);
 	}
 	LLIST_TS_UNLOCK(&alist_p);
 }
 
 /* Export todo items. */
-static void ical_export_todo(FILE * stream)
+static void ical_export_todo(FILE * stream, int export_uid)
 {
 	llist_item_t *i;
 
@@ -247,6 +275,13 @@ static void ical_export_todo(FILE * stream)
 		}
 		fprintf(stream, "PRIORITY:%d\n", priority);
 		fprintf(stream, "SUMMARY:%s\n", todo->mesg);
+
+		if (export_uid) {
+			char *hash = todo_hash(todo);
+			fprintf(stream, "UID:%s\n", hash);
+			mem_free(hash);
+		}
+
 		fputs("END:VTODO\n", stream);
 	}
 }
@@ -1123,13 +1158,13 @@ ical_import_data(FILE * stream, FILE * log, int list, unsigned *events,
 }
 
 /* Export calcurse data. */
-void ical_export_data(FILE * stream)
+void ical_export_data(FILE * stream, int export_uid)
 {
 	ical_export_header(stream);
-	ical_export_recur_events(stream);
-	ical_export_events(stream);
-	ical_export_recur_apoints(stream);
-	ical_export_apoints(stream);
-	ical_export_todo(stream);
+	ical_export_recur_events(stream, export_uid);
+	ical_export_events(stream, export_uid);
+	ical_export_recur_apoints(stream, export_uid);
+	ical_export_apoints(stream, export_uid);
+	ical_export_todo(stream, export_uid);
 	ical_export_footer(stream);
 }
diff --git a/src/io.c b/src/io.c
index 91d6ffe..374f092 100644
--- a/src/io.c
+++ b/src/io.c
@@ -1084,7 +1084,7 @@ void io_startup_screen(int no_data_file)
 }
 
 /* Export calcurse data. */
-void io_export_data(enum export_type type)
+void io_export_data(enum export_type type, int export_uid)
 {
 	FILE *stream = NULL;
 	const char *success = _("The data were successfully exported");
@@ -1109,7 +1109,7 @@ void io_export_data(enum export_type type)
 		return;
 
 	if (type == IO_EXPORT_ICAL)
-		ical_export_data(stream);
+		ical_export_data(stream, export_uid);
 	else if (type == IO_EXPORT_PCAL)
 		pcal_export_data(stream);
 
-- 
cgit v1.2.3-70-g09d2