cgit

commit a5e15537268410e268c7b26aa69d03b347c326c8

Author: Jason A. Donenfeld <Jason@zx2c4.com>

filter: add support for email filter

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>

 cgit.c | 6 ++++++
 cgit.h | 4 +++-
 cgitrc.5.txt | 18 ++++++++++++++++++
 filter.c | 3 +++
 shared.c | 1 +
 ui-commit.c | 4 ++++
 ui-log.c | 2 ++
 ui-refs.c | 9 ++++++++-
 ui-tag.c | 2 ++


diff --git a/cgit.c b/cgit.c
index 725fd65e37ee3ad6e43b58d4066b44f3e599ef5d..f3fe56bb2748bb976061c819f24f4f7ddcd2caf8 100644
--- a/cgit.c
+++ b/cgit.c
@@ -89,6 +89,8 @@ 		else if (!strcmp(name, "commit-filter"))
 			repo->commit_filter = cgit_new_filter(value, COMMIT);
 		else if (!strcmp(name, "source-filter"))
 			repo->source_filter = cgit_new_filter(value, SOURCE);
+		else if (!strcmp(name, "email-filter"))
+			repo->email_filter = cgit_new_filter(value, EMAIL);
 	}
 }
 
@@ -188,6 +190,8 @@ 	else if (!strcmp(name, "about-filter"))
 		ctx.cfg.about_filter = cgit_new_filter(value, ABOUT);
 	else if (!strcmp(name, "commit-filter"))
 		ctx.cfg.commit_filter = cgit_new_filter(value, COMMIT);
+	else if (!strcmp(name, "email-filter"))
+		ctx.cfg.email_filter = cgit_new_filter(value, EMAIL);
 	else if (!strcmp(name, "embedded"))
 		ctx.cfg.embedded = atoi(value);
 	else if (!strcmp(name, "max-atom-items"))
@@ -711,6 +715,8 @@ 	if (repo->commit_filter && repo->commit_filter != ctx.cfg.commit_filter)
 		cgit_fprintf_filter(repo->commit_filter, f, "repo.commit-filter=");
 	if (repo->source_filter && repo->source_filter != ctx.cfg.source_filter)
 		cgit_fprintf_filter(repo->source_filter, f, "repo.source-filter=");
+	if (repo->email_filter && repo->email_filter != ctx.cfg.email_filter)
+		cgit_fprintf_filter(repo->email_filter, f, "repo.email-filter=");
 	if (repo->snapshots != ctx.cfg.snapshots) {
 		char *tmp = build_snapshot_setting(repo->snapshots);
 		fprintf(f, "repo.snapshots=%s\n", tmp ? tmp : "");




diff --git a/cgit.h b/cgit.h
index 519d2afb3d4d223c68639d8f12235e35f5e98cc5..e200a06994c178468f670f63dcb13cc36de19d2a 100644
--- a/cgit.h
+++ b/cgit.h
@@ -53,7 +53,7 @@ typedef void (*filepair_fn)(struct diff_filepair *pair);
 typedef void (*linediff_fn)(char *line, int len);
 
 typedef enum {
-	ABOUT, COMMIT, SOURCE
+	ABOUT, COMMIT, SOURCE, EMAIL
 } filter_type;
 
 struct cgit_filter {
@@ -99,6 +99,7 @@ 	time_t mtime;
 	struct cgit_filter *about_filter;
 	struct cgit_filter *commit_filter;
 	struct cgit_filter *source_filter;
+	struct cgit_filter *email_filter;
 	struct string_list submodules;
 };
 
@@ -250,6 +251,7 @@ 	struct string_list mimetypes;
 	struct cgit_filter *about_filter;
 	struct cgit_filter *commit_filter;
 	struct cgit_filter *source_filter;
+	struct cgit_filter *email_filter;
 };
 
 struct cgit_page {




diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 78f33c8308e6379a9e643da006c660b122f571bd..b7dc5a4ca665e092a7f5f03a9f749fccd02984b1 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -117,6 +117,14 @@ css::
 	Url which specifies the css document to include in all cgit pages.
 	Default value: "/cgit.css".
 
+email-filter::
+	Specifies a command which will be invoked to format names and email
+	address of committers, authors, and taggers, as represented in various
+	places throughout the cgit interface. This command will receive an
+	email address as its only command line argument, and the text to
+	format on STDIN. It is to write the formatted text back out onto
+	STDOUT. Default value: none. See also: "FILTER API".
+
 embedded::
 	Flag which, when set to "1", will make cgit generate a html fragment
 	suitable for embedding in other html pages. Default value: none. See
@@ -457,6 +465,10 @@
 repo.desc::
 	The value to show as repository description. Default value: none.
 
+repo.email-filter::
+	Override the default email-filter. Default value: none. See also:
+	"enable-filter-overrides". See also: "FILTER API".
+
 repo.enable-commit-graph::
 	A flag which can be used to disable the global setting
 	`enable-commit-graph'. Default value: none.
@@ -606,6 +618,12 @@ commit filter::
 	This filter is given no arguments. The commit message text that is to
 	be filtered is available on standard input and the filtered text is
 	expected on standard output.
+
+email filter::
+	This filter is given a single parameter: the email address of the
+	relevent user. The filter will then receive the text string to format
+	on standard input and is expected to write to standard output the
+	formatted text to be included in the page.
 
 source filter::
 	This filter is given a single parameter: the filename of the source




diff --git a/filter.c b/filter.c
index 7983737b6bc24ab9a7d6e6e19111755864370199..08ce7a5a021a598bc304f42d3760ac9eda0bfefa 100644
--- a/filter.c
+++ b/filter.c
@@ -37,10 +37,12 @@ 	int i;
 	reap_filter(ctx.cfg.about_filter);
 	reap_filter(ctx.cfg.commit_filter);
 	reap_filter(ctx.cfg.source_filter);
+	reap_filter(ctx.cfg.email_filter);
 	for (i = 0; i < cgit_repolist.count; ++i) {
 		reap_filter(cgit_repolist.repos[i].about_filter);
 		reap_filter(cgit_repolist.repos[i].commit_filter);
 		reap_filter(cgit_repolist.repos[i].source_filter);
+		reap_filter(cgit_repolist.repos[i].email_filter);
 	}
 }
 
@@ -403,6 +405,7 @@ 	if (len == 1)
 		colon = NULL;
 
 	switch (filtertype) {
+		case EMAIL:
 		case SOURCE:
 		case ABOUT:
 			argument_count = 1;




diff --git a/shared.c b/shared.c
index 4626148535bd77dd62aebf08f6ddf60a35fdc990..7e88bbd4fb33555066d14df98402277a97e96bee 100644
--- a/shared.c
+++ b/shared.c
@@ -71,6 +71,7 @@ 	ret->mtime = -1;
 	ret->about_filter = ctx.cfg.about_filter;
 	ret->commit_filter = ctx.cfg.commit_filter;
 	ret->source_filter = ctx.cfg.source_filter;
+	ret->email_filter = ctx.cfg.email_filter;
 	ret->clone_url = ctx.cfg.clone_url;
 	ret->submodules.strdup_strings = 1;
 	return ret;




diff --git a/ui-commit.c b/ui-commit.c
index 5ac79c0c5ec35abe805e673fd4103f5c77cc6f9a..bd14ef04c7772da30f5f67457da9f457dd3f1c83 100644
--- a/ui-commit.c
+++ b/ui-commit.c
@@ -44,20 +44,24 @@
 	cgit_print_diff_ctrls();
 	html("<table summary='commit info' class='commit-info'>\n");
 	html("<tr><th>author</th><td>");
+	cgit_open_filter(ctx.repo->email_filter, info->author_email);
 	html_txt(info->author);
 	if (!ctx.cfg.noplainemail) {
 		html(" ");
 		html_txt(info->author_email);
 	}
+	cgit_close_filter(ctx.repo->email_filter);
 	html("</td><td class='right'>");
 	cgit_print_date(info->author_date, FMT_LONGDATE, ctx.cfg.local_time);
 	html("</td></tr>\n");
 	html("<tr><th>committer</th><td>");
+	cgit_open_filter(ctx.repo->email_filter, info->committer_email);
 	html_txt(info->committer);
 	if (!ctx.cfg.noplainemail) {
 		html(" ");
 		html_txt(info->committer_email);
 	}
+	cgit_close_filter(ctx.repo->email_filter);
 	html("</td><td class='right'>");
 	cgit_print_date(info->committer_date, FMT_LONGDATE, ctx.cfg.local_time);
 	html("</td></tr>\n");




diff --git a/ui-log.c b/ui-log.c
index 584336a9766c0a6d6aa4d8bb33d5f28f185d583e..957d887f0c7b5c17fd1b67697baf29ccd6ffc7ca 100644
--- a/ui-log.c
+++ b/ui-log.c
@@ -168,7 +168,9 @@ 	cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head,
 			 sha1_to_hex(commit->object.sha1), ctx.qry.vpath, 0);
 	show_commit_decorations(commit);
 	html("</td><td>");
+	cgit_open_filter(ctx.repo->email_filter, info->author_email);
 	html_txt(info->author);
+	cgit_close_filter(ctx.repo->email_filter);
 
 	if (revs->graph) {
 		html("</td><td>");




diff --git a/ui-refs.c b/ui-refs.c
index c97b0c62924cc08c1e54bbcb4958d8c5898abb1e..d125459f81264230a6a4422a22321b3375aff518 100644
--- a/ui-refs.c
+++ b/ui-refs.c
@@ -77,7 +77,9 @@
 	if (ref->object->type == OBJ_COMMIT) {
 		cgit_commit_link(info->subject, NULL, NULL, name, NULL, NULL, 0);
 		html("</td><td>");
+		cgit_open_filter(ctx.repo->email_filter, info->author_email);
 		html_txt(info->author);
+		cgit_close_filter(ctx.repo->email_filter);
 		html("</td><td colspan='2'>");
 		cgit_print_age(info->commit->date, -1, NULL);
 	} else {
@@ -154,10 +156,15 @@ 	else
 		cgit_object_link(obj);
 	html("</td><td>");
 	if (info) {
-		if (info->tagger)
+		if (info->tagger) {
+			cgit_open_filter(ctx.repo->email_filter, info->tagger_email);
 			html_txt(info->tagger);
+			cgit_close_filter(ctx.repo->email_filter);
+		}
 	} else if (ref->object->type == OBJ_COMMIT) {
+		cgit_open_filter(ctx.repo->email_filter, ref->commit->author_email);
 		html_txt(ref->commit->author);
+		cgit_close_filter(ctx.repo->email_filter);
 	}
 	html("</td><td colspan='2'>");
 	if (info) {




diff --git a/ui-tag.c b/ui-tag.c
index ec9c757db22d8196bebefb1ae020ac33ca30b627..adbdb90e3771b566e808b56629bffb78d0334aa3 100644
--- a/ui-tag.c
+++ b/ui-tag.c
@@ -77,11 +77,13 @@ 			html("\n");
 		}
 		if (info->tagger) {
 			html("<tr><td>tagged by</td><td>");
+			cgit_open_filter(ctx.repo->email_filter, info->tagger_email);
 			html_txt(info->tagger);
 			if (info->tagger_email && !ctx.cfg.noplainemail) {
 				html(" ");
 				html_txt(info->tagger_email);
 			}
+			cgit_close_filter(ctx.repo->email_filter);
 			html("</td></tr>\n");
 		}
 		html("<tr><td>tagged object</td><td class='sha1'>");