List for cgit developers and users
 help / color / mirror / Atom feed
* Welcome on board Lukas Fleischer
@ 2014-01-08 14:34 Jason
  2014-01-08 14:53 ` [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger mail
  2014-01-09 19:38 ` Welcome on board Lukas Fleischer info
  0 siblings, 2 replies; 42+ messages in thread
From: Jason @ 2014-01-08 14:34 UTC (permalink / raw)


Hey folks,

To speed things up with the merges and reviews of patches on this
list, I've given Lukas Fleischer commit access. He's going to be
helping me maintain the project. We'll each be merging and committing
patches to jd/staging and lf/staging, and from there onto master. I'll
be updating the documentation to reflect this process. Lukas is also
preparing a patch that merges copyright headers and adds an AUTHORS
file with significant contributors.

If your patch has gotten lost in the queue in the last few months, now
would be a good time to resubmit. I expect to release a new version
before the end of the month.

Jason


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-08 14:34 Welcome on board Lukas Fleischer Jason
@ 2014-01-08 14:53 ` mail
  2014-01-08 15:12   ` Jason
  2014-01-09 19:38 ` Welcome on board Lukas Fleischer info
  1 sibling, 1 reply; 42+ messages in thread
From: mail @ 2014-01-08 14:53 UTC (permalink / raw)


---
 cgit.c       |  3 +++
 cgit.h       |  8 ++++++++
 cgitrc.5.txt |  4 ++++
 parsing.c    | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 shared.c     | 23 +++++++++++++++++++++++
 ui-commit.c  | 10 ++++++++++
 ui-log.c     |  5 +++++
 ui-refs.c    | 10 ++++++++++
 ui-tag.c     |  5 +++++
 9 files changed, 119 insertions(+)

diff --git a/cgit.c b/cgit.c
index 861352a..fe82580 100644
--- a/cgit.c
+++ b/cgit.c
@@ -183,6 +183,8 @@ static void config_cb(const char *name, const char *value)
 		ctx.cfg.enable_index_owner = atoi(value);
 	else if (!strcmp(name, "enable-commit-graph"))
 		ctx.cfg.enable_commit_graph = atoi(value);
+	else if (!strcmp(name, "enable-gravatar"))
+		ctx.cfg.enable_gravatar = atoi(value);
 	else if (!strcmp(name, "enable-log-filecount"))
 		ctx.cfg.enable_log_filecount = atoi(value);
 	else if (!strcmp(name, "enable-log-linecount"))
@@ -368,6 +370,7 @@ static void prepare_context(struct cgit_context *ctx)
 	ctx->cfg.logo = "/cgit.png";
 	ctx->cfg.favicon = "/favicon.ico";
 	ctx->cfg.local_time = 0;
+	ctx->cfg.enable_gravatar = 0;
 	ctx->cfg.enable_http_clone = 1;
 	ctx->cfg.enable_index_owner = 1;
 	ctx->cfg.enable_tree_linenumbers = 1;
diff --git a/cgit.h b/cgit.h
index a474d77..c5c03fb 100644
--- a/cgit.h
+++ b/cgit.h
@@ -107,9 +107,11 @@ struct commitinfo {
 	struct commit *commit;
 	char *author;
 	char *author_email;
+	char *author_gravatar;
 	unsigned long author_date;
 	char *committer;
 	char *committer_email;
+	char *committer_gravatar;
 	unsigned long committer_date;
 	char *subject;
 	char *msg;
@@ -119,6 +121,7 @@ struct commitinfo {
 struct taginfo {
 	char *tagger;
 	char *tagger_email;
+	char *tagger_gravatar;
 	unsigned long tagger_date;
 	char *msg;
 };
@@ -208,6 +211,7 @@ struct cgit_config {
 	int enable_index_links;
 	int enable_index_owner;
 	int enable_commit_graph;
+	int enable_gravatar;
 	int enable_log_filecount;
 	int enable_log_linecount;
 	int enable_remote_branches;
@@ -337,6 +341,7 @@ extern char *fmtalloc(const char *format,...);
 
 extern struct commitinfo *cgit_parse_commit(struct commit *commit);
 extern struct taginfo *cgit_parse_tag(struct tag *tag);
+char *cgit_get_gravatar(const char *email);
 extern void cgit_parse_url(const char *url);
 
 extern const char *cgit_repobasename(const char *reponame);
@@ -352,4 +357,7 @@ extern int readfile(const char *path, char **buf, size_t *size);
 
 extern char *expand_macros(const char *txt);
 
+void str_to_hex(char *dst_str, const unsigned char *src_bytes,
+		size_t src_len);
+
 #endif /* CGIT_H */
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 633cb00..b6017c2 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -180,6 +180,10 @@ enable-git-config::
 	to the corresponding "repo." key in cgit. Default value: "0". See also:
 	scan-path, section-from-path.
 
+enable-gravatar::
+	Flag which, when set to "1", will enable cgit to show gravatar icon
+	for author, committer and tagger email address. Default value: "0".
+
 favicon::
 	Url used as link to a shortcut icon for cgit. It is suggested to use
 	the value "/favicon.ico" since certain browsers will ignore other
diff --git a/parsing.c b/parsing.c
index 658621d..35087c3 100644
--- a/parsing.c
+++ b/parsing.c
@@ -8,6 +8,17 @@
 
 #include "cgit.h"
 
+/* we need md5 hashing algorithm to calculate Gravatar URL */
+#include <openssl/md5.h>
+
+/* This is the URL for Gravatar.
+ * Starting with double slash makes it automatically use the right protocol,
+ * e.g. https for cgit on encrypted sites. The default parameters make this
+ * fetch 16x16 pixel images, with "awesome generated, 8-bit arcade-style
+ * pixelated faces".
+ * https://en.gravatar.com/site/implement/images/ */
+#define GRAVATAR_URL "//www.gravatar.com/avatar/%s?s=16&d=retro"
+
 /*
  * url syntax: [repo ['/' cmd [ '/' path]]]
  *   repo: any valid repo url, may contain '/'
@@ -133,8 +144,10 @@ struct commitinfo *cgit_parse_commit(struct commit *commit)
 	ret->commit = commit;
 	ret->author = NULL;
 	ret->author_email = NULL;
+	ret->author_gravatar = NULL;
 	ret->committer = NULL;
 	ret->committer_email = NULL;
+	ret->committer_gravatar = NULL;
 	ret->subject = NULL;
 	ret->msg = NULL;
 	ret->msg_encoding = NULL;
@@ -155,11 +168,17 @@ struct commitinfo *cgit_parse_commit(struct commit *commit)
 			&ret->author_date);
 	}
 
+	if (ctx.cfg.enable_gravatar && ret->author_email != NULL)
+		ret->author_gravatar = cgit_get_gravatar(ret->author_email);
+
 	if (p && !strncmp(p, "committer ", 9)) {
 		p = parse_user(p + 9, &ret->committer, &ret->committer_email,
 			&ret->committer_date);
 	}
 
+	if (ctx.cfg.enable_gravatar && ret->committer_email != NULL)
+		ret->committer_gravatar = cgit_get_gravatar(ret->committer_email);
+
 	if (p && !strncmp(p, "encoding ", 9)) {
 		p += 9;
 		t = strchr(p, '\n');
@@ -230,6 +249,7 @@ struct taginfo *cgit_parse_tag(struct tag *tag)
 	ret = xmalloc(sizeof(*ret));
 	ret->tagger = NULL;
 	ret->tagger_email = NULL;
+	ret->tagger_gravatar = NULL;
 	ret->tagger_date = 0;
 	ret->msg = NULL;
 
@@ -249,6 +269,9 @@ struct taginfo *cgit_parse_tag(struct tag *tag)
 		}
 	}
 
+	if (ctx.cfg.enable_gravatar && ret->tagger_email != NULL)
+		ret->tagger_gravatar = cgit_get_gravatar(ret->tagger_email);
+
 	// skip empty lines between headers and message
 	while (p && *p == '\n')
 		p++;
@@ -258,3 +281,31 @@ struct taginfo *cgit_parse_tag(struct tag *tag)
 	free(data);
 	return ret;
 }
+
+char * cgit_get_gravatar(const char *email) {
+	unsigned char digest[MD5_DIGEST_LENGTH];
+	char hex[MD5_DIGEST_LENGTH * 2 + 1], *lower, *tmp;
+	char *gravatar;
+
+	/* The URL includes %s, which is replaced later on. So we do not need
+	 * extra space for termination. */
+	gravatar = malloc(strlen(GRAVATAR_URL) + MD5_DIGEST_LENGTH * 2);
+
+	/* duplicate to lower and skip brackets! */
+	lower = strdup(email + 1);
+	lower[strlen(lower) - 1] = '\0';
+
+	/* make the chars lower case */
+	for (tmp = lower; *tmp; ++tmp)
+		*tmp = tolower(*tmp);
+
+	MD5((unsigned char *)lower, strlen(lower), digest);
+
+	str_to_hex(hex, digest, MD5_DIGEST_LENGTH);
+
+	sprintf(gravatar, GRAVATAR_URL, hex);
+
+	free(lower);
+
+	return gravatar;
+}
diff --git a/shared.c b/shared.c
index 919a99e..a383dfa 100644
--- a/shared.c
+++ b/shared.c
@@ -93,8 +93,12 @@ void *cgit_free_commitinfo(struct commitinfo *info)
 {
 	free(info->author);
 	free(info->author_email);
+	if (info->author_gravatar)
+		free(info->author_gravatar);
 	free(info->committer);
 	free(info->committer_email);
+	if (info->committer_gravatar)
+		free(info->committer_gravatar);
 	free(info->subject);
 	free(info->msg);
 	free(info->msg_encoding);
@@ -204,6 +208,8 @@ static void cgit_free_taginfo(struct taginfo *tag)
 		free(tag->tagger);
 	if (tag->tagger_email)
 		free(tag->tagger_email);
+	if (tag->tagger_gravatar)
+		free(tag->tagger_gravatar);
 	if (tag->msg)
 		free(tag->msg);
 	free(tag);
@@ -588,3 +594,20 @@ char *expand_macros(const char *txt)
 	}
 	return result;
 }
+
+/* gets a string representing the binary data. dst_str must have a
+ * size of at least src_len * 2 + 1 bytes. */
+void str_to_hex(char *dst_str, const unsigned char *src_bytes,
+		size_t src_len) {
+	const char *hex = "0123456789abcdef";
+	int n;
+
+	for (n = 0; n < src_len; ++n) {
+		unsigned char val = *src_bytes++;
+
+		*dst_str++ = hex[val >> 4];
+		*dst_str++ = hex[val & 0xf];
+	}
+
+	*dst_str = 0;
+}
diff --git a/ui-commit.c b/ui-commit.c
index ef85a49..4fa5b83 100644
--- a/ui-commit.c
+++ b/ui-commit.c
@@ -44,6 +44,11 @@ void cgit_print_commit(char *hex, const char *prefix)
 	cgit_print_diff_ctrls();
 	html("<table summary='commit info' class='commit-info'>\n");
 	html("<tr><th>author</th><td>");
+	if (ctx.cfg.enable_gravatar && info->author_gravatar) {
+		html("<img src='");
+		html_txt(info->author_gravatar);
+		html("' width=16 height=16 alt='Gravatar' /> ");
+	}
 	html_txt(info->author);
 	if (!ctx.cfg.noplainemail) {
 		html(" ");
@@ -53,6 +58,11 @@ void cgit_print_commit(char *hex, const char *prefix)
 	cgit_print_date(info->author_date, FMT_LONGDATE, ctx.cfg.local_time);
 	html("</td></tr>\n");
 	html("<tr><th>committer</th><td>");
+	if (ctx.cfg.enable_gravatar && info->committer_gravatar) {
+		html("<img src='");
+		html_txt(info->committer_gravatar);
+		html("' width=16 height=16 alt='Gravatar' /> ");
+	}
 	html_txt(info->committer);
 	if (!ctx.cfg.noplainemail) {
 		html(" ");
diff --git a/ui-log.c b/ui-log.c
index c154f69..24a5c47 100644
--- a/ui-log.c
+++ b/ui-log.c
@@ -168,6 +168,11 @@ static void print_commit(struct commit *commit, struct rev_info *revs)
 			 sha1_to_hex(commit->object.sha1), ctx.qry.vpath, 0);
 	show_commit_decorations(commit);
 	html("</td><td>");
+	if (ctx.cfg.enable_gravatar && info->author_gravatar) {
+		html("<img src='");
+		html_txt(info->author_gravatar);
+		html("' width=16 height=16 alt='Gravatar' /> ");
+	}
 	html_txt(info->author);
 
 	if (revs->graph) {
diff --git a/ui-refs.c b/ui-refs.c
index 0ae0612..5e6dda9 100644
--- a/ui-refs.c
+++ b/ui-refs.c
@@ -77,6 +77,11 @@ static int print_branch(struct refinfo *ref)
 	if (ref->object->type == OBJ_COMMIT) {
 		cgit_commit_link(info->subject, NULL, NULL, name, NULL, NULL, 0);
 		html("</td><td>");
+		if (ctx.cfg.enable_gravatar && info->author_gravatar) {
+			html("<img src='");
+			html_txt(info->author_gravatar);
+			html("' width=16 height=16 alt='Gravatar' /> ");
+		}
 		html_txt(info->author);
 		html("</td><td colspan='2'>");
 		cgit_print_age(info->commit->date, -1, NULL);
@@ -154,6 +159,11 @@ static int print_tag(struct refinfo *ref)
 		cgit_object_link(obj);
 	html("</td><td>");
 	if (info) {
+		if (ctx.cfg.enable_gravatar && info->tagger_gravatar) {
+			html("<img src='");
+			html_txt(info->tagger_gravatar);
+			html("' width=16 height=16 alt='Gravatar' /> ");
+		}
 		if (info->tagger)
 			html(info->tagger);
 	} else if (ref->object->type == OBJ_COMMIT) {
diff --git a/ui-tag.c b/ui-tag.c
index aea7958..865d6d7 100644
--- a/ui-tag.c
+++ b/ui-tag.c
@@ -77,6 +77,11 @@ void cgit_print_tag(char *revname)
 		}
 		if (info->tagger) {
 			html("<tr><td>tagged by</td><td>");
+			if (ctx.cfg.enable_gravatar && info->tagger_gravatar) {
+				html("<img src='");
+				html_txt(info->tagger_gravatar);
+				html("' width=16 height=16 alt='Gravatar' /> ");
+			}
 			html_txt(info->tagger);
 			if (info->tagger_email && !ctx.cfg.noplainemail) {
 				html(" ");
-- 
1.8.5.2



^ permalink raw reply	[flat|nested] 42+ messages in thread

* [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-08 14:53 ` [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger mail
@ 2014-01-08 15:12   ` Jason
  2014-01-08 15:23     ` [PATCH " mail
                       ` (2 more replies)
  0 siblings, 3 replies; 42+ messages in thread
From: Jason @ 2014-01-08 15:12 UTC (permalink / raw)


I like this. But I could imagine a bit of backlash against it -- it's
a particular web service owned by a private corporation (Automattic),
and some detractors might argue that an open project like this has no
interest in this kind of proprietary service integration. Are there
any such detractors on this list? If so, we can fill this thread with
some sort of discussion. Otherwise, pending the nitpicks below, I'll
merge it.

On Wed, Jan 8, 2014 at 3:53 PM, Christian Hesse <mail at eworm.de> wrote:
> +
> +char * cgit_get_gravatar(const char *email) {
> +       unsigned char digest[MD5_DIGEST_LENGTH];

char *cgit_get_gravatar(const char *email)
{


> +       /* The URL includes %s, which is replaced later on. So we do not need
> +        * extra space for termination. */
> +       gravatar = malloc(strlen(GRAVATAR_URL) + MD5_DIGEST_LENGTH * 2);

This is clever, but potentially error prone.


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-08 15:12   ` Jason
@ 2014-01-08 15:23     ` mail
  2014-01-08 15:56       ` Jason
  2014-01-08 16:00       ` Jason
  2014-01-08 15:36     ` [RESEND PATCH " mathstuf
  2014-01-08 17:15     ` normalperson
  2 siblings, 2 replies; 42+ messages in thread
From: mail @ 2014-01-08 15:23 UTC (permalink / raw)


---
 cgit.c       |  3 +++
 cgit.h       |  8 ++++++++
 cgitrc.5.txt |  4 ++++
 parsing.c    | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 shared.c     | 23 +++++++++++++++++++++++
 ui-commit.c  | 10 ++++++++++
 ui-log.c     |  5 +++++
 ui-refs.c    | 10 ++++++++++
 ui-tag.c     |  5 +++++
 9 files changed, 118 insertions(+)

diff --git a/cgit.c b/cgit.c
index 861352a..fe82580 100644
--- a/cgit.c
+++ b/cgit.c
@@ -183,6 +183,8 @@ static void config_cb(const char *name, const char *value)
 		ctx.cfg.enable_index_owner = atoi(value);
 	else if (!strcmp(name, "enable-commit-graph"))
 		ctx.cfg.enable_commit_graph = atoi(value);
+	else if (!strcmp(name, "enable-gravatar"))
+		ctx.cfg.enable_gravatar = atoi(value);
 	else if (!strcmp(name, "enable-log-filecount"))
 		ctx.cfg.enable_log_filecount = atoi(value);
 	else if (!strcmp(name, "enable-log-linecount"))
@@ -368,6 +370,7 @@ static void prepare_context(struct cgit_context *ctx)
 	ctx->cfg.logo = "/cgit.png";
 	ctx->cfg.favicon = "/favicon.ico";
 	ctx->cfg.local_time = 0;
+	ctx->cfg.enable_gravatar = 0;
 	ctx->cfg.enable_http_clone = 1;
 	ctx->cfg.enable_index_owner = 1;
 	ctx->cfg.enable_tree_linenumbers = 1;
diff --git a/cgit.h b/cgit.h
index a474d77..c5c03fb 100644
--- a/cgit.h
+++ b/cgit.h
@@ -107,9 +107,11 @@ struct commitinfo {
 	struct commit *commit;
 	char *author;
 	char *author_email;
+	char *author_gravatar;
 	unsigned long author_date;
 	char *committer;
 	char *committer_email;
+	char *committer_gravatar;
 	unsigned long committer_date;
 	char *subject;
 	char *msg;
@@ -119,6 +121,7 @@ struct commitinfo {
 struct taginfo {
 	char *tagger;
 	char *tagger_email;
+	char *tagger_gravatar;
 	unsigned long tagger_date;
 	char *msg;
 };
@@ -208,6 +211,7 @@ struct cgit_config {
 	int enable_index_links;
 	int enable_index_owner;
 	int enable_commit_graph;
+	int enable_gravatar;
 	int enable_log_filecount;
 	int enable_log_linecount;
 	int enable_remote_branches;
@@ -337,6 +341,7 @@ extern char *fmtalloc(const char *format,...);
 
 extern struct commitinfo *cgit_parse_commit(struct commit *commit);
 extern struct taginfo *cgit_parse_tag(struct tag *tag);
+char *cgit_get_gravatar(const char *email);
 extern void cgit_parse_url(const char *url);
 
 extern const char *cgit_repobasename(const char *reponame);
@@ -352,4 +357,7 @@ extern int readfile(const char *path, char **buf, size_t *size);
 
 extern char *expand_macros(const char *txt);
 
+void str_to_hex(char *dst_str, const unsigned char *src_bytes,
+		size_t src_len);
+
 #endif /* CGIT_H */
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 633cb00..b6017c2 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -180,6 +180,10 @@ enable-git-config::
 	to the corresponding "repo." key in cgit. Default value: "0". See also:
 	scan-path, section-from-path.
 
+enable-gravatar::
+	Flag which, when set to "1", will enable cgit to show gravatar icon
+	for author, committer and tagger email address. Default value: "0".
+
 favicon::
 	Url used as link to a shortcut icon for cgit. It is suggested to use
 	the value "/favicon.ico" since certain browsers will ignore other
diff --git a/parsing.c b/parsing.c
index 658621d..74becd7 100644
--- a/parsing.c
+++ b/parsing.c
@@ -8,6 +8,17 @@
 
 #include "cgit.h"
 
+/* we need md5 hashing algorithm to calculate Gravatar URL */
+#include <openssl/md5.h>
+
+/* This is the URL for Gravatar.
+ * Starting with double slash makes it automatically use the right protocol,
+ * e.g. https for cgit on encrypted sites. The default parameters make this
+ * fetch 16x16 pixel images, with "awesome generated, 8-bit arcade-style
+ * pixelated faces".
+ * https://en.gravatar.com/site/implement/images/ */
+#define GRAVATAR_URL "//www.gravatar.com/avatar/%s?s=16&d=retro"
+
 /*
  * url syntax: [repo ['/' cmd [ '/' path]]]
  *   repo: any valid repo url, may contain '/'
@@ -133,8 +144,10 @@ struct commitinfo *cgit_parse_commit(struct commit *commit)
 	ret->commit = commit;
 	ret->author = NULL;
 	ret->author_email = NULL;
+	ret->author_gravatar = NULL;
 	ret->committer = NULL;
 	ret->committer_email = NULL;
+	ret->committer_gravatar = NULL;
 	ret->subject = NULL;
 	ret->msg = NULL;
 	ret->msg_encoding = NULL;
@@ -155,11 +168,17 @@ struct commitinfo *cgit_parse_commit(struct commit *commit)
 			&ret->author_date);
 	}
 
+	if (ctx.cfg.enable_gravatar && ret->author_email != NULL)
+		ret->author_gravatar = cgit_get_gravatar(ret->author_email);
+
 	if (p && !strncmp(p, "committer ", 9)) {
 		p = parse_user(p + 9, &ret->committer, &ret->committer_email,
 			&ret->committer_date);
 	}
 
+	if (ctx.cfg.enable_gravatar && ret->committer_email != NULL)
+		ret->committer_gravatar = cgit_get_gravatar(ret->committer_email);
+
 	if (p && !strncmp(p, "encoding ", 9)) {
 		p += 9;
 		t = strchr(p, '\n');
@@ -230,6 +249,7 @@ struct taginfo *cgit_parse_tag(struct tag *tag)
 	ret = xmalloc(sizeof(*ret));
 	ret->tagger = NULL;
 	ret->tagger_email = NULL;
+	ret->tagger_gravatar = NULL;
 	ret->tagger_date = 0;
 	ret->msg = NULL;
 
@@ -249,6 +269,9 @@ struct taginfo *cgit_parse_tag(struct tag *tag)
 		}
 	}
 
+	if (ctx.cfg.enable_gravatar && ret->tagger_email != NULL)
+		ret->tagger_gravatar = cgit_get_gravatar(ret->tagger_email);
+
 	// skip empty lines between headers and message
 	while (p && *p == '\n')
 		p++;
@@ -258,3 +281,30 @@ struct taginfo *cgit_parse_tag(struct tag *tag)
 	free(data);
 	return ret;
 }
+
+char *cgit_get_gravatar(const char *email)
+{
+	unsigned char digest[MD5_DIGEST_LENGTH];
+	char hex[MD5_DIGEST_LENGTH * 2 + 1], *lower, *tmp;
+	char *gravatar;
+
+	gravatar = malloc(strlen(GRAVATAR_URL) + MD5_DIGEST_LENGTH * 2 + 1);
+
+	/* duplicate to lower and skip brackets! */
+	lower = strdup(email + 1);
+	lower[strlen(lower) - 1] = '\0';
+
+	/* make the chars lower case */
+	for (tmp = lower; *tmp; ++tmp)
+		*tmp = tolower(*tmp);
+
+	MD5((unsigned char *)lower, strlen(lower), digest);
+
+	str_to_hex(hex, digest, MD5_DIGEST_LENGTH);
+
+	sprintf(gravatar, GRAVATAR_URL, hex);
+
+	free(lower);
+
+	return gravatar;
+}
diff --git a/shared.c b/shared.c
index 919a99e..a383dfa 100644
--- a/shared.c
+++ b/shared.c
@@ -93,8 +93,12 @@ void *cgit_free_commitinfo(struct commitinfo *info)
 {
 	free(info->author);
 	free(info->author_email);
+	if (info->author_gravatar)
+		free(info->author_gravatar);
 	free(info->committer);
 	free(info->committer_email);
+	if (info->committer_gravatar)
+		free(info->committer_gravatar);
 	free(info->subject);
 	free(info->msg);
 	free(info->msg_encoding);
@@ -204,6 +208,8 @@ static void cgit_free_taginfo(struct taginfo *tag)
 		free(tag->tagger);
 	if (tag->tagger_email)
 		free(tag->tagger_email);
+	if (tag->tagger_gravatar)
+		free(tag->tagger_gravatar);
 	if (tag->msg)
 		free(tag->msg);
 	free(tag);
@@ -588,3 +594,20 @@ char *expand_macros(const char *txt)
 	}
 	return result;
 }
+
+/* gets a string representing the binary data. dst_str must have a
+ * size of at least src_len * 2 + 1 bytes. */
+void str_to_hex(char *dst_str, const unsigned char *src_bytes,
+		size_t src_len) {
+	const char *hex = "0123456789abcdef";
+	int n;
+
+	for (n = 0; n < src_len; ++n) {
+		unsigned char val = *src_bytes++;
+
+		*dst_str++ = hex[val >> 4];
+		*dst_str++ = hex[val & 0xf];
+	}
+
+	*dst_str = 0;
+}
diff --git a/ui-commit.c b/ui-commit.c
index ef85a49..4fa5b83 100644
--- a/ui-commit.c
+++ b/ui-commit.c
@@ -44,6 +44,11 @@ void cgit_print_commit(char *hex, const char *prefix)
 	cgit_print_diff_ctrls();
 	html("<table summary='commit info' class='commit-info'>\n");
 	html("<tr><th>author</th><td>");
+	if (ctx.cfg.enable_gravatar && info->author_gravatar) {
+		html("<img src='");
+		html_txt(info->author_gravatar);
+		html("' width=16 height=16 alt='Gravatar' /> ");
+	}
 	html_txt(info->author);
 	if (!ctx.cfg.noplainemail) {
 		html(" ");
@@ -53,6 +58,11 @@ void cgit_print_commit(char *hex, const char *prefix)
 	cgit_print_date(info->author_date, FMT_LONGDATE, ctx.cfg.local_time);
 	html("</td></tr>\n");
 	html("<tr><th>committer</th><td>");
+	if (ctx.cfg.enable_gravatar && info->committer_gravatar) {
+		html("<img src='");
+		html_txt(info->committer_gravatar);
+		html("' width=16 height=16 alt='Gravatar' /> ");
+	}
 	html_txt(info->committer);
 	if (!ctx.cfg.noplainemail) {
 		html(" ");
diff --git a/ui-log.c b/ui-log.c
index c154f69..24a5c47 100644
--- a/ui-log.c
+++ b/ui-log.c
@@ -168,6 +168,11 @@ static void print_commit(struct commit *commit, struct rev_info *revs)
 			 sha1_to_hex(commit->object.sha1), ctx.qry.vpath, 0);
 	show_commit_decorations(commit);
 	html("</td><td>");
+	if (ctx.cfg.enable_gravatar && info->author_gravatar) {
+		html("<img src='");
+		html_txt(info->author_gravatar);
+		html("' width=16 height=16 alt='Gravatar' /> ");
+	}
 	html_txt(info->author);
 
 	if (revs->graph) {
diff --git a/ui-refs.c b/ui-refs.c
index 0ae0612..5e6dda9 100644
--- a/ui-refs.c
+++ b/ui-refs.c
@@ -77,6 +77,11 @@ static int print_branch(struct refinfo *ref)
 	if (ref->object->type == OBJ_COMMIT) {
 		cgit_commit_link(info->subject, NULL, NULL, name, NULL, NULL, 0);
 		html("</td><td>");
+		if (ctx.cfg.enable_gravatar && info->author_gravatar) {
+			html("<img src='");
+			html_txt(info->author_gravatar);
+			html("' width=16 height=16 alt='Gravatar' /> ");
+		}
 		html_txt(info->author);
 		html("</td><td colspan='2'>");
 		cgit_print_age(info->commit->date, -1, NULL);
@@ -154,6 +159,11 @@ static int print_tag(struct refinfo *ref)
 		cgit_object_link(obj);
 	html("</td><td>");
 	if (info) {
+		if (ctx.cfg.enable_gravatar && info->tagger_gravatar) {
+			html("<img src='");
+			html_txt(info->tagger_gravatar);
+			html("' width=16 height=16 alt='Gravatar' /> ");
+		}
 		if (info->tagger)
 			html(info->tagger);
 	} else if (ref->object->type == OBJ_COMMIT) {
diff --git a/ui-tag.c b/ui-tag.c
index aea7958..865d6d7 100644
--- a/ui-tag.c
+++ b/ui-tag.c
@@ -77,6 +77,11 @@ void cgit_print_tag(char *revname)
 		}
 		if (info->tagger) {
 			html("<tr><td>tagged by</td><td>");
+			if (ctx.cfg.enable_gravatar && info->tagger_gravatar) {
+				html("<img src='");
+				html_txt(info->tagger_gravatar);
+				html("' width=16 height=16 alt='Gravatar' /> ");
+			}
 			html_txt(info->tagger);
 			if (info->tagger_email && !ctx.cfg.noplainemail) {
 				html(" ");
-- 
1.8.5.2



^ permalink raw reply	[flat|nested] 42+ messages in thread

* [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-08 15:12   ` Jason
  2014-01-08 15:23     ` [PATCH " mail
@ 2014-01-08 15:36     ` mathstuf
  2014-01-08 17:15     ` normalperson
  2 siblings, 0 replies; 42+ messages in thread
From: mathstuf @ 2014-01-08 15:36 UTC (permalink / raw)


On Wed, 08 Jan, 2014 at 15:12:38 GMT, Jason A. Donenfeld wrote:
> I like this. But I could imagine a bit of backlash against it -- it's
> a particular web service owned by a private corporation (Automattic),
> and some detractors might argue that an open project like this has no
> interest in this kind of proprietary service integration. Are there
> any such detractors on this list? If so, we can fill this thread with
> some sort of discussion. Otherwise, pending the nitpicks below, I'll
> merge it.

Folks who are so against it should probably also just run RequestPolicy
(or its equivalent in $favorite_browser) and opt-out completely. I'm not
a huge fan of gravatar, but I also block access to it, so I'm not too
concerned.

Really, if people are so against using proprietary infrastructure in
such a black-and-white fashion, I'd like to know their ISP ;) .

--Ben



^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-08 15:23     ` [PATCH " mail
@ 2014-01-08 15:56       ` Jason
  2014-01-09  8:52         ` mail
  2014-01-08 16:00       ` Jason
  1 sibling, 1 reply; 42+ messages in thread
From: Jason @ 2014-01-08 15:56 UTC (permalink / raw)


On Wed, Jan 8, 2014 at 4:23 PM, Christian Hesse <mail at eworm.de> wrote:
> +       gravatar = malloc(strlen(GRAVATAR_URL) + MD5_DIGEST_LENGTH * 2 + 1);

xmalloc

> +       lower = strdup(email + 1);

xstrdup


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-08 15:23     ` [PATCH " mail
  2014-01-08 15:56       ` Jason
@ 2014-01-08 16:00       ` Jason
  2014-01-09  9:13         ` mail
  1 sibling, 1 reply; 42+ messages in thread
From: Jason @ 2014-01-08 16:00 UTC (permalink / raw)


Sorry for the extended nitpicks....

On Wed, Jan 8, 2014 at 4:23 PM, Christian Hesse <mail at eworm.de> wrote:
> +char *cgit_get_gravatar(const char *email)
> +{
> +
> +       /* duplicate to lower and skip brackets! */
> +       lower = strdup(email + 1);
> +       lower[strlen(lower) - 1] = '\0';


Can email ever be passed in with no length at all? Or without
brackets? It's not immediately clear to me from looking briefly at
parse_user in parsing.c.


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-08 15:12   ` Jason
  2014-01-08 15:23     ` [PATCH " mail
  2014-01-08 15:36     ` [RESEND PATCH " mathstuf
@ 2014-01-08 17:15     ` normalperson
  2014-01-08 17:29       ` Jason
  2 siblings, 1 reply; 42+ messages in thread
From: normalperson @ 2014-01-08 17:15 UTC (permalink / raw)


"Jason A. Donenfeld" <Jason at zx2c4.com> wrote:
> I like this. But I could imagine a bit of backlash against it -- it's
> a particular web service owned by a private corporation (Automattic),
> and some detractors might argue that an open project like this has no
> interest in this kind of proprietary service integration. Are there
> any such detractors on this list? If so, we can fill this thread with
> some sort of discussion. Otherwise, pending the nitpicks below, I'll
> merge it.

As long as it's not enabled by default, I think it's alright.
I would never enable it myself, as I hate inline images, though :P


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-08 17:15     ` normalperson
@ 2014-01-08 17:29       ` Jason
  2014-01-08 18:35         ` stefan
                           ` (2 more replies)
  0 siblings, 3 replies; 42+ messages in thread
From: Jason @ 2014-01-08 17:29 UTC (permalink / raw)


It's being previewed on http://git.zx2c4.com/cgit/

What do you think?


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-08 17:29       ` Jason
@ 2014-01-08 18:35         ` stefan
  2014-01-09  9:18         ` list
  2014-01-09 15:21         ` RFE: author/committer/tagger links (enable cgit to show gravatar for author, committer and tagger) mricon
  2 siblings, 0 replies; 42+ messages in thread
From: stefan @ 2014-01-08 18:35 UTC (permalink / raw)


Am 08.01.2014 18:29, schrieb Jason A. Donenfeld:
> It's being previewed on http://git.zx2c4.com/cgit/
> 
> What do you think?

To be honest I like this. If it is not enabled by default I think it
should be ok in such kind of open source project.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: OpenPGP digital signature
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20140108/92b60e0a/attachment.asc>


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-08 15:56       ` Jason
@ 2014-01-09  8:52         ` mail
  2014-01-09 15:13           ` Jason
  0 siblings, 1 reply; 42+ messages in thread
From: mail @ 2014-01-09  8:52 UTC (permalink / raw)


"Jason A. Donenfeld" <Jason at zx2c4.com> on Wed, 2014/01/08 16:56:
> On Wed, Jan 8, 2014 at 4:23 PM, Christian Hesse <mail at eworm.de> wrote:
> > +       gravatar = malloc(strlen(GRAVATAR_URL) + MD5_DIGEST_LENGTH * 2 +
> > 1);
> 
> xmalloc
> 
> > +       lower = strdup(email + 1);
> 
> xstrdup

Looks like you have applied this with your changes to jd/zx2c4-deployment. I
am fine with that. Or do you want an updated patch from me?
-- 
Schoene Gruesse
Chris
                         O< ascii ribbon campaign
                   stop html mail - www.asciiribbon.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20140109/be594b1c/attachment.asc>


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-08 16:00       ` Jason
@ 2014-01-09  9:13         ` mail
  0 siblings, 0 replies; 42+ messages in thread
From: mail @ 2014-01-09  9:13 UTC (permalink / raw)


"Jason A. Donenfeld" <Jason at zx2c4.com> on Wed, 2014/01/08 17:00:
> Sorry for the extended nitpicks....
> 
> On Wed, Jan 8, 2014 at 4:23 PM, Christian Hesse <mail at eworm.de> wrote:
> > +char *cgit_get_gravatar(const char *email)
> > +{
> > +
> > +       /* duplicate to lower and skip brackets! */
> > +       lower = strdup(email + 1);
> > +       lower[strlen(lower) - 1] = '\0';
> 
> Can email ever be passed in with no length at all? Or without
> brackets? It's not immediately clear to me from looking briefly at
> parse_user in parsing.c.

A really good question. Let's think about parse_user()... If t does not
include brackets the string ends up in name. If it does include brackets the
address ends up in email, including the brackets. So does (mode == 2 && *p ==
'\n') ever get true? Probably we have a piece of dead code.

I think email always includes brackets or is NULL. In later case
cgit_get_gravatar() is not executed, so everything should be fine.
-- 
Schoene Gruesse
Chris
                         O< ascii ribbon campaign
                   stop html mail - www.asciiribbon.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20140109/8fbd411d/attachment.asc>


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-08 17:29       ` Jason
  2014-01-08 18:35         ` stefan
@ 2014-01-09  9:18         ` list
  2014-01-09 15:19           ` Jason
  2014-01-09 15:21         ` RFE: author/committer/tagger links (enable cgit to show gravatar for author, committer and tagger) mricon
  2 siblings, 1 reply; 42+ messages in thread
From: list @ 2014-01-09  9:18 UTC (permalink / raw)


"Jason A. Donenfeld" <Jason at zx2c4.com> on Wed, 2014/01/08 18:29:
> It's being previewed on http://git.zx2c4.com/cgit/
> 
> What do you think?

You modified the code to make the icon match the font size, which is 10pt by
default. This is hard coded to the css file. Please note the URL includes a
size argument. Does it make sense to just retrieve a 10x10 pixel image?
-- 
main(a){char*c=/*    Schoene Gruesse                         */"B?IJj;MEH"
"CX:;",b;for(a/*    Chris           get my mail address:    */=0;b=c[a++];)
putchar(b-1/(/*               gcc -o sig sig.c && ./sig    */b/42*2-3)*42);}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20140109/d2416109/attachment.asc>


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-09  8:52         ` mail
@ 2014-01-09 15:13           ` Jason
  0 siblings, 0 replies; 42+ messages in thread
From: Jason @ 2014-01-09 15:13 UTC (permalink / raw)


On Thu, Jan 9, 2014 at 9:52 AM, Christian Hesse <mail at eworm.de> wrote:
>
> Looks like you have applied this with your changes to jd/zx2c4-deployment. I
> am fine with that. Or do you want an updated patch from me?

It's okay; I've got it handled.


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-09  9:18         ` list
@ 2014-01-09 15:19           ` Jason
  2014-01-13 14:18             ` list
  0 siblings, 1 reply; 42+ messages in thread
From: Jason @ 2014-01-09 15:19 UTC (permalink / raw)


On Thu, Jan 9, 2014 at 10:18 AM, Christian Hesse <list at eworm.de> wrote:
> You modified the code to make the icon match the font size, which is 10pt by
> default. This is hard coded to the css file. Please note the URL includes a
> size argument. Does it make sense to just retrieve a 10x10 pixel image?

Generally, 10pt is actually 13px, not 10px. I did see the size
argument of the URL, and played with changing this. But I was thinking
that often times, I make the font size slightly bigger, and requesting
the 3px larger image (16px instead of 13px) gives a little bit of
leeway for this sort of forced scaling. For my particular avatar, the
difference winds up being 13 bytes of data.


^ permalink raw reply	[flat|nested] 42+ messages in thread

* RFE: author/committer/tagger links (enable cgit to show gravatar for author, committer and tagger)
  2014-01-08 17:29       ` Jason
  2014-01-08 18:35         ` stefan
  2014-01-09  9:18         ` list
@ 2014-01-09 15:21         ` mricon
  2014-01-09 17:50           ` Jason
  2 siblings, 1 reply; 42+ messages in thread
From: mricon @ 2014-01-09 15:21 UTC (permalink / raw)


On 08/01/14 12:29 PM, Jason A. Donenfeld wrote:
> It's being previewed on http://git.zx2c4.com/cgit/
> 
> What do you think?

Hi, all:

That's pretty nifty. That reminds me -- I'm working on a web-of-trust
site for kernel.org and something I wouldn't mind having is a way to
link from cgit to the web of trust for that person. E.g. an email
address for "torvalds at linux-foundation.org" on this page
(http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=d6e0a2dd12f4067a5bcefb8bbd8ddbeff800afbc)
would be wrapped in a link such as:

<a href="https://blah.kernel.org/?user=torvalds%40linux-foundation.org">
torvalds at linux-foundation.org</a>

which will bring up a page similar to:
https://www.kernel.org/doc/wot/torvalds.html

Not sure whether that would clash with any of your existing plans for
user links, but figured I'd bring this up for a discussion.

Best,
-- 
Konstantin Ryabitsev
Senior Systems Administrator
Linux Foundation Collab Projects
Montr?al, Qu?bec

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 713 bytes
Desc: OpenPGP digital signature
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20140109/2e5a3061/attachment.asc>


^ permalink raw reply	[flat|nested] 42+ messages in thread

* RFE: author/committer/tagger links (enable cgit to show gravatar for author, committer and tagger)
  2014-01-09 15:21         ` RFE: author/committer/tagger links (enable cgit to show gravatar for author, committer and tagger) mricon
@ 2014-01-09 17:50           ` Jason
  2014-01-09 18:07             ` john
  0 siblings, 1 reply; 42+ messages in thread
From: Jason @ 2014-01-09 17:50 UTC (permalink / raw)


On Thu, Jan 9, 2014 at 4:21 PM, Konstantin Ryabitsev <mricon at kernel.org> wrote:
> That's pretty nifty.

Cool. Would you consider enabling this on kernel.org? I'll probably
merge it in a few days (still working out some bugs). Seems like the
kind of thing that might give cgit a lot of positive attention...

> That reminds me -- I'm working on a web-of-trust
> site for kernel.org and something I wouldn't mind having is a way to
> link from cgit to the web of trust for that person. E.g. an email
> address for "torvalds at linux-foundation.org" on this page
> (http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=d6e0a2dd12f4067a5bcefb8bbd8ddbeff800afbc)
> would be wrapped in a link such as:
>
> <a href="https://blah.kernel.org/?user=torvalds%40linux-foundation.org">
> torvalds at linux-foundation.org</a>
>
> which will bring up a page similar to:
> https://www.kernel.org/doc/wot/torvalds.html
>
> Not sure whether that would clash with any of your existing plans for
> user links, but figured I'd bring this up for a discussion.

We already support module-link and repo.module-link for making
clickable submodules. I don't see why we wouldn't be able to apply the
same idiom to a email-link and repo.email-link setting. I'll look into
this. I suppose a default setting, or maybe just a suggested setting
in the documentation, would be to issue a search for that email. But
this could then be used to instead link out to your upcoming web of
trust platform. How does this sound?


^ permalink raw reply	[flat|nested] 42+ messages in thread

* RFE: author/committer/tagger links (enable cgit to show gravatar for author, committer and tagger)
  2014-01-09 17:50           ` Jason
@ 2014-01-09 18:07             ` john
  2014-01-09 18:59               ` Jason
  0 siblings, 1 reply; 42+ messages in thread
From: john @ 2014-01-09 18:07 UTC (permalink / raw)


On Thu, Jan 09, 2014 at 06:50:29PM +0100, Jason A. Donenfeld wrote:
> On Thu, Jan 9, 2014 at 4:21 PM, Konstantin Ryabitsev <mricon at kernel.org> wrote:
> > That's pretty nifty.
> 
> Cool. Would you consider enabling this on kernel.org? I'll probably
> merge it in a few days (still working out some bugs). Seems like the
> kind of thing that might give cgit a lot of positive attention...
> 
> > That reminds me -- I'm working on a web-of-trust
> > site for kernel.org and something I wouldn't mind having is a way to
> > link from cgit to the web of trust for that person. E.g. an email
> > address for "torvalds at linux-foundation.org" on this page
> > (http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=d6e0a2dd12f4067a5bcefb8bbd8ddbeff800afbc)
> > would be wrapped in a link such as:
> >
> > <a href="https://blah.kernel.org/?user=torvalds%40linux-foundation.org">
> > torvalds at linux-foundation.org</a>
> >
> > which will bring up a page similar to:
> > https://www.kernel.org/doc/wot/torvalds.html
> >
> > Not sure whether that would clash with any of your existing plans for
> > user links, but figured I'd bring this up for a discussion.
> 
> We already support module-link and repo.module-link for making
> clickable submodules. I don't see why we wouldn't be able to apply the
> same idiom to a email-link and repo.email-link setting. I'll look into
> this. I suppose a default setting, or maybe just a suggested setting
> in the documentation, would be to issue a search for that email. But
> this could then be used to instead link out to your upcoming web of
> trust platform. How does this sound?

It feels to me like it might be better to allow a filter to be applied
here.  That way we don't put the Gravatar code in CGit itself but can
distribute an example script that does apply Gravatar links to email
addresses.

I'm not sure what the cost of forking a process here will end up being
though; I guess for cases where the email is likely to be repeated we
could assume that the filter is pure and memoize the result.

But that would give the greatest flexibility for both these use cases,
with a simple link value the Gravatar case needs some other forwarding
program on the server to do the hashing of the address (unless we
provide substitution values for a range of different things, but
currently everything just uses printf formats so that would be more
work unless we can reuse Git's log formatter somehow).


^ permalink raw reply	[flat|nested] 42+ messages in thread

* RFE: author/committer/tagger links (enable cgit to show gravatar for author, committer and tagger)
  2014-01-09 18:07             ` john
@ 2014-01-09 18:59               ` Jason
  2014-01-09 19:23                 ` john
  0 siblings, 1 reply; 42+ messages in thread
From: Jason @ 2014-01-09 18:59 UTC (permalink / raw)


On Thu, Jan 9, 2014 at 7:07 PM, John Keeping <john at keeping.me.uk> wrote:
> It feels to me like it might be better to allow a filter to be applied
> here.  That way we don't put the Gravatar code in CGit itself but can
> distribute an example script that does apply Gravatar links to email
> addresses.
>
> I'm not sure what the cost of forking a process here will end up being
> though; I guess for cases where the email is likely to be repeated we
> could assume that the filter is pure and memoize the result.

Gravatar icons are placed next to author names (in the log for
example) as well as the full email address (in the commit). So we'd
have to give such a filter the email address, as well as the original
string to be printed. Such memorization would then need to apply to
that pair.

>
> But that would give the greatest flexibility for both these use cases,
> with a simple link value the Gravatar case needs some other forwarding
> program on the server to do the hashing of the address (unless we
> provide substitution values for a range of different things, but
> currently everything just uses printf formats so that would be more
> work unless we can reuse Git's log formatter somehow).

I do like this idea quite a bit. But the cost of forking indeed seems
a bit high -- some listings have many many authors all at once. I'll
investigate a little bit.



-- 
Jason A. Donenfeld
Deep Space Explorer
fr: +33 6 51 90 82 66
us: +1 513 476 1200
www.jasondonenfeld.com


^ permalink raw reply	[flat|nested] 42+ messages in thread

* RFE: author/committer/tagger links (enable cgit to show gravatar for author, committer and tagger)
  2014-01-09 18:59               ` Jason
@ 2014-01-09 19:23                 ` john
  2014-01-09 19:34                   ` cgit
  0 siblings, 1 reply; 42+ messages in thread
From: john @ 2014-01-09 19:23 UTC (permalink / raw)


On Thu, Jan 09, 2014 at 07:59:27PM +0100, Jason A. Donenfeld wrote:
> On Thu, Jan 9, 2014 at 7:07 PM, John Keeping <john at keeping.me.uk> wrote:
> > It feels to me like it might be better to allow a filter to be applied
> > here.  That way we don't put the Gravatar code in CGit itself but can
> > distribute an example script that does apply Gravatar links to email
> > addresses.
> >
> > I'm not sure what the cost of forking a process here will end up being
> > though; I guess for cases where the email is likely to be repeated we
> > could assume that the filter is pure and memoize the result.
> 
> Gravatar icons are placed next to author names (in the log for
> example) as well as the full email address (in the commit). So we'd
> have to give such a filter the email address, as well as the original
> string to be printed. Such memorization would then need to apply to
> that pair.

Presumably this would just pass the "A. U. Thor <author at example.com>"
string to the filter and we could just map that to the output.

> >
> > But that would give the greatest flexibility for both these use cases,
> > with a simple link value the Gravatar case needs some other forwarding
> > program on the server to do the hashing of the address (unless we
> > provide substitution values for a range of different things, but
> > currently everything just uses printf formats so that would be more
> > work unless we can reuse Git's log formatter somehow).
> 
> I do like this idea quite a bit. But the cost of forking indeed seems
> a bit high -- some listings have many many authors all at once. I'll
> investigate a little bit.

We could take an incremental approach like git-check-attr and friends do
when GIT_FLUSH=1, but I'm not sure how well we could delimit the output
in that case - I doubt a single line would be sufficient for all cases.
If we're not careful that approach could end up with capability flags
and other complex things like the fast-import protocol.

My gut feeling is that it /should/ be OK because CGit's caching layer
means that we don't actually regenerate pages too often and CGit tends
to be blazingly fast anyway, but it would be interesting to see some
benchmarks of how much overhead a call to "true" adds.


^ permalink raw reply	[flat|nested] 42+ messages in thread

* RFE: author/committer/tagger links (enable cgit to show gravatar for author, committer and tagger)
  2014-01-09 19:23                 ` john
@ 2014-01-09 19:34                   ` cgit
  0 siblings, 0 replies; 42+ messages in thread
From: cgit @ 2014-01-09 19:34 UTC (permalink / raw)


On Thu, 09 Jan 2014 at 20:23:04, John Keeping wrote:
> [...]
> Presumably this would just pass the "A. U. Thor <author at example.com>"
> string to the filter and we could just map that to the output.
> [...]
> We could take an incremental approach like git-check-attr and friends do
> when GIT_FLUSH=1, but I'm not sure how well we could delimit the output
> in that case - I doubt a single line would be sufficient for all cases.
> If we're not careful that approach could end up with capability flags
> and other complex things like the fast-import protocol.

These ideas sound good to me -- much better than the initial Gravatar
approach -- presumed they can be implemented efficiently. In case the
choice of a delimiter becomes a problem, we could add another option to
switch between newline ("\n") and null character ("\0"), or even allow
for specifying a custom delimiter.

> 
> My gut feeling is that it /should/ be OK because CGit's caching layer
> means that we don't actually regenerate pages too often and CGit tends
> to be blazingly fast anyway, but it would be interesting to see some
> benchmarks of how much overhead a call to "true" adds.

Agreed.


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Welcome on board Lukas Fleischer
  2014-01-08 14:34 Welcome on board Lukas Fleischer Jason
  2014-01-08 14:53 ` [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger mail
@ 2014-01-09 19:38 ` info
  1 sibling, 0 replies; 42+ messages in thread
From: info @ 2014-01-09 19:38 UTC (permalink / raw)


On Wed, 08 Jan 2014 at 15:34:10, Jason A. Donenfeld wrote:
> Hey folks,
> 
> To speed things up with the merges and reviews of patches on this
> list, I've given Lukas Fleischer commit access. He's going to be
> helping me maintain the project. We'll each be merging and committing
> patches to jd/staging and lf/staging, and from there onto master. I'll
> be updating the documentation to reflect this process. Lukas is also
> preparing a patch that merges copyright headers and adds an AUTHORS
> file with significant contributors.
> 
> If your patch has gotten lost in the queue in the last few months, now
> would be a good time to resubmit. I expect to release a new version
> before the end of the month.
> 
> Jason
> _______________________________________________
> CGit mailing list
> CGit at lists.zx2c4.com
> http://lists.zx2c4.com/mailman/listinfo/cgit


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-09 15:19           ` Jason
@ 2014-01-13 14:18             ` list
  2014-01-13 14:24               ` Jason
  0 siblings, 1 reply; 42+ messages in thread
From: list @ 2014-01-13 14:18 UTC (permalink / raw)


"Jason A. Donenfeld" <Jason at zx2c4.com> on Thu, 2014/01/09 16:19:
> On Thu, Jan 9, 2014 at 10:18 AM, Christian Hesse <list at eworm.de> wrote:
> > You modified the code to make the icon match the font size, which is 10pt
> > by default. This is hard coded to the css file. Please note the URL
> > includes a size argument. Does it make sense to just retrieve a 10x10
> > pixel image?
> 
> Generally, 10pt is actually 13px, not 10px. I did see the size
> argument of the URL, and played with changing this. But I was thinking
> that often times, I make the font size slightly bigger, and requesting
> the 3px larger image (16px instead of 13px) gives a little bit of
> leeway for this sort of forced scaling. For my particular avatar, the
> difference winds up being 13 bytes of data.

Your avatar (and mine as well) are fine when scaled down. But if there is no
avatar on gravatar you get the "arcade-style pixelated faces", which look
very fuzzy when scaled by the browser...
-- 
main(a){char*c=/*    Schoene Gruesse                         */"B?IJj;MEH"
"CX:;",b;for(a/*    Chris           get my mail address:    */=0;b=c[a++];)
putchar(b-1/(/*               gcc -o sig sig.c && ./sig    */b/42*2-3)*42);}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20140113/d5543a5d/attachment.asc>


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-13 14:18             ` list
@ 2014-01-13 14:24               ` Jason
  2014-01-14 17:22                 ` list
  0 siblings, 1 reply; 42+ messages in thread
From: Jason @ 2014-01-13 14:24 UTC (permalink / raw)


On Mon, Jan 13, 2014 at 3:18 PM, Christian Hesse <list at eworm.de> wrote:
> Your avatar (and mine as well) are fine when scaled down. But if there is no
> avatar on gravatar you get the "arcade-style pixelated faces", which look
> very fuzzy when scaled by the browser...

Good point. Excuse me while I make a trivial change in the fancy new
lua script... done! It's working! : )

You're right -- the arcade faces do look a lot better at 13px. I'll
set s=13 for v2 of the filter-infra series currently going on.


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-13 14:24               ` Jason
@ 2014-01-14 17:22                 ` list
  2014-01-14 17:23                   ` Jason
  0 siblings, 1 reply; 42+ messages in thread
From: list @ 2014-01-14 17:22 UTC (permalink / raw)


"Jason A. Donenfeld" <Jason at zx2c4.com> on Mon, 2014/01/13 15:24:
> On Mon, Jan 13, 2014 at 3:18 PM, Christian Hesse <list at eworm.de> wrote:
> > Your avatar (and mine as well) are fine when scaled down. But if there is
> > no avatar on gravatar you get the "arcade-style pixelated faces", which
> > look very fuzzy when scaled by the browser...
> 
> Good point. Excuse me while I make a trivial change in the fancy new
> lua script... done! It's working! : )
> 
> You're right -- the arcade faces do look a lot better at 13px. I'll
> set s=13 for v2 of the filter-infra series currently going on.

Looks better, though not perfect.
At least firefox still scales the image a bit.
-- 
main(a){char*c=/*    Schoene Gruesse                         */"B?IJj;MEH"
"CX:;",b;for(a/*    Chris           get my mail address:    */=0;b=c[a++];)
putchar(b-1/(/*               gcc -o sig sig.c && ./sig    */b/42*2-3)*42);}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20140114/ee126efa/attachment.asc>


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-14 17:22                 ` list
@ 2014-01-14 17:23                   ` Jason
  2014-01-14 17:35                     ` list
  0 siblings, 1 reply; 42+ messages in thread
From: Jason @ 2014-01-14 17:23 UTC (permalink / raw)


On Tue, Jan 14, 2014 at 6:22 PM, Christian Hesse <list at eworm.de> wrote:
> Looks better, though not perfect.
> At least firefox still scales the image a bit.

Can you investigate the whole "px to pt" situation, line-height, and
the best way to manage this?


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-14 17:23                   ` Jason
@ 2014-01-14 17:35                     ` list
  2014-01-14 17:45                       ` 
  2014-01-14 17:51                       ` Jason
  0 siblings, 2 replies; 42+ messages in thread
From: list @ 2014-01-14 17:35 UTC (permalink / raw)


"Jason A. Donenfeld" <Jason at zx2c4.com> on Tue, 2014/01/14 18:23:
> On Tue, Jan 14, 2014 at 6:22 PM, Christian Hesse <list at eworm.de> wrote:
> > Looks better, though not perfect.
> > At least firefox still scales the image a bit.
> 
> Can you investigate the whole "px to pt" situation, line-height, and
> the best way to manage this?

pixels = points * 96 / 72

So for 10pt:

10 * 96 / 72 = 13.333333333333334

The browser scales the image, then keeps the full pixels.

Probably the only way to not have this is to use pixel only for images.
Want a patch?
-- 
main(a){char*c=/*    Schoene Gruesse                         */"B?IJj;MEH"
"CX:;",b;for(a/*    Chris           get my mail address:    */=0;b=c[a++];)
putchar(b-1/(/*               gcc -o sig sig.c && ./sig    */b/42*2-3)*42);}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20140114/c68ec7f7/attachment.asc>


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-14 17:35                     ` list
@ 2014-01-14 17:45                       ` 
  2014-01-14 17:51                       ` Jason
  1 sibling, 0 replies; 42+ messages in thread
From:  @ 2014-01-14 17:45 UTC (permalink / raw)


Am 14.01.2014 18:35, schrieb Christian Hesse:
> "Jason A. Donenfeld" <Jason at zx2c4.com> on Tue, 2014/01/14 18:23:
>> On Tue, Jan 14, 2014 at 6:22 PM, Christian Hesse <list at eworm.de> wrote:
>>> Looks better, though not perfect.
>>> At least firefox still scales the image a bit.
>>
>> Can you investigate the whole "px to pt" situation, line-height, and
>> the best way to manage this?
> 
> pixels = points * 96 / 72

96 only iff DPI=96, isn't it?


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 555 bytes
Desc: OpenPGP digital signature
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20140114/95aec028/attachment.asc>


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-14 17:35                     ` list
  2014-01-14 17:45                       ` 
@ 2014-01-14 17:51                       ` Jason
  2014-01-14 17:58                         ` list
  1 sibling, 1 reply; 42+ messages in thread
From: Jason @ 2014-01-14 17:51 UTC (permalink / raw)


On Tue, Jan 14, 2014 at 6:35 PM, Christian Hesse <list at eworm.de> wrote:
> Probably the only way to not have this is to use pixel only for images.
> Want a patch?

I think I have it handled. Would you look at git.zx2c4.com/cgit/log/
and tell me if that looks better to you?


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-14 17:51                       ` Jason
@ 2014-01-14 17:58                         ` list
  2014-01-14 18:00                           ` Jason
  0 siblings, 1 reply; 42+ messages in thread
From: list @ 2014-01-14 17:58 UTC (permalink / raw)


"Jason A. Donenfeld" <Jason at zx2c4.com> on Tue, 2014/01/14 18:51:
> On Tue, Jan 14, 2014 at 6:35 PM, Christian Hesse <list at eworm.de> wrote:
> > Probably the only way to not have this is to use pixel only for images.
> > Want a patch?
> 
> I think I have it handled. Would you look at git.zx2c4.com/cgit/log/
> and tell me if that looks better to you?

Looks good to me.

Though this may result in images that do not fit font size if dpi is a lot
more or less than 96 as Ren? pointed.
-- 
main(a){char*c=/*    Schoene Gruesse                         */"B?IJj;MEH"
"CX:;",b;for(a/*    Chris           get my mail address:    */=0;b=c[a++];)
putchar(b-1/(/*               gcc -o sig sig.c && ./sig    */b/42*2-3)*42);}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20140114/1485da61/attachment.asc>


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2014-01-14 17:58                         ` list
@ 2014-01-14 18:00                           ` Jason
  0 siblings, 0 replies; 42+ messages in thread
From: Jason @ 2014-01-14 18:00 UTC (permalink / raw)


On Tue, Jan 14, 2014 at 6:58 PM, Christian Hesse <list at eworm.de> wrote:
> Looks good to me.
>
> Though this may result in images that do not fit font size if dpi is a lot
> more or less than 96 as Ren? pointed.

Anybody want to try with a fancy retina iPad or the like?


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2013-11-27 22:59         ` list
@ 2013-11-27 23:00           ` mail
  0 siblings, 0 replies; 42+ messages in thread
From: mail @ 2013-11-27 23:00 UTC (permalink / raw)


---
 cgit.c       |  3 +++
 cgit.h       |  8 ++++++++
 cgitrc.5.txt |  4 ++++
 parsing.c    | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 shared.c     | 23 +++++++++++++++++++++++
 ui-commit.c  | 10 ++++++++++
 ui-log.c     |  5 +++++
 ui-refs.c    | 10 ++++++++++
 ui-tag.c     |  5 +++++
 9 files changed, 119 insertions(+)

diff --git a/cgit.c b/cgit.c
index 861352a..fe82580 100644
--- a/cgit.c
+++ b/cgit.c
@@ -183,6 +183,8 @@ static void config_cb(const char *name, const char *value)
 		ctx.cfg.enable_index_owner = atoi(value);
 	else if (!strcmp(name, "enable-commit-graph"))
 		ctx.cfg.enable_commit_graph = atoi(value);
+	else if (!strcmp(name, "enable-gravatar"))
+		ctx.cfg.enable_gravatar = atoi(value);
 	else if (!strcmp(name, "enable-log-filecount"))
 		ctx.cfg.enable_log_filecount = atoi(value);
 	else if (!strcmp(name, "enable-log-linecount"))
@@ -368,6 +370,7 @@ static void prepare_context(struct cgit_context *ctx)
 	ctx->cfg.logo = "/cgit.png";
 	ctx->cfg.favicon = "/favicon.ico";
 	ctx->cfg.local_time = 0;
+	ctx->cfg.enable_gravatar = 0;
 	ctx->cfg.enable_http_clone = 1;
 	ctx->cfg.enable_index_owner = 1;
 	ctx->cfg.enable_tree_linenumbers = 1;
diff --git a/cgit.h b/cgit.h
index a474d77..c5c03fb 100644
--- a/cgit.h
+++ b/cgit.h
@@ -107,9 +107,11 @@ struct commitinfo {
 	struct commit *commit;
 	char *author;
 	char *author_email;
+	char *author_gravatar;
 	unsigned long author_date;
 	char *committer;
 	char *committer_email;
+	char *committer_gravatar;
 	unsigned long committer_date;
 	char *subject;
 	char *msg;
@@ -119,6 +121,7 @@ struct commitinfo {
 struct taginfo {
 	char *tagger;
 	char *tagger_email;
+	char *tagger_gravatar;
 	unsigned long tagger_date;
 	char *msg;
 };
@@ -208,6 +211,7 @@ struct cgit_config {
 	int enable_index_links;
 	int enable_index_owner;
 	int enable_commit_graph;
+	int enable_gravatar;
 	int enable_log_filecount;
 	int enable_log_linecount;
 	int enable_remote_branches;
@@ -337,6 +341,7 @@ extern char *fmtalloc(const char *format,...);
 
 extern struct commitinfo *cgit_parse_commit(struct commit *commit);
 extern struct taginfo *cgit_parse_tag(struct tag *tag);
+char *cgit_get_gravatar(const char *email);
 extern void cgit_parse_url(const char *url);
 
 extern const char *cgit_repobasename(const char *reponame);
@@ -352,4 +357,7 @@ extern int readfile(const char *path, char **buf, size_t *size);
 
 extern char *expand_macros(const char *txt);
 
+void str_to_hex(char *dst_str, const unsigned char *src_bytes,
+		size_t src_len);
+
 #endif /* CGIT_H */
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 633cb00..b6017c2 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -180,6 +180,10 @@ enable-git-config::
 	to the corresponding "repo." key in cgit. Default value: "0". See also:
 	scan-path, section-from-path.
 
+enable-gravatar::
+	Flag which, when set to "1", will enable cgit to show gravatar icon
+	for author, committer and tagger email address. Default value: "0".
+
 favicon::
 	Url used as link to a shortcut icon for cgit. It is suggested to use
 	the value "/favicon.ico" since certain browsers will ignore other
diff --git a/parsing.c b/parsing.c
index 658621d..35087c3 100644
--- a/parsing.c
+++ b/parsing.c
@@ -8,6 +8,17 @@
 
 #include "cgit.h"
 
+/* we need md5 hashing algorithm to calculate Gravatar URL */
+#include <openssl/md5.h>
+
+/* This is the URL for Gravatar.
+ * Starting with double slash makes it automatically use the right protocol,
+ * e.g. https for cgit on encrypted sites. The default parameters make this
+ * fetch 16x16 pixel images, with "awesome generated, 8-bit arcade-style
+ * pixelated faces".
+ * https://en.gravatar.com/site/implement/images/ */
+#define GRAVATAR_URL "//www.gravatar.com/avatar/%s?s=16&d=retro"
+
 /*
  * url syntax: [repo ['/' cmd [ '/' path]]]
  *   repo: any valid repo url, may contain '/'
@@ -133,8 +144,10 @@ struct commitinfo *cgit_parse_commit(struct commit *commit)
 	ret->commit = commit;
 	ret->author = NULL;
 	ret->author_email = NULL;
+	ret->author_gravatar = NULL;
 	ret->committer = NULL;
 	ret->committer_email = NULL;
+	ret->committer_gravatar = NULL;
 	ret->subject = NULL;
 	ret->msg = NULL;
 	ret->msg_encoding = NULL;
@@ -155,11 +168,17 @@ struct commitinfo *cgit_parse_commit(struct commit *commit)
 			&ret->author_date);
 	}
 
+	if (ctx.cfg.enable_gravatar && ret->author_email != NULL)
+		ret->author_gravatar = cgit_get_gravatar(ret->author_email);
+
 	if (p && !strncmp(p, "committer ", 9)) {
 		p = parse_user(p + 9, &ret->committer, &ret->committer_email,
 			&ret->committer_date);
 	}
 
+	if (ctx.cfg.enable_gravatar && ret->committer_email != NULL)
+		ret->committer_gravatar = cgit_get_gravatar(ret->committer_email);
+
 	if (p && !strncmp(p, "encoding ", 9)) {
 		p += 9;
 		t = strchr(p, '\n');
@@ -230,6 +249,7 @@ struct taginfo *cgit_parse_tag(struct tag *tag)
 	ret = xmalloc(sizeof(*ret));
 	ret->tagger = NULL;
 	ret->tagger_email = NULL;
+	ret->tagger_gravatar = NULL;
 	ret->tagger_date = 0;
 	ret->msg = NULL;
 
@@ -249,6 +269,9 @@ struct taginfo *cgit_parse_tag(struct tag *tag)
 		}
 	}
 
+	if (ctx.cfg.enable_gravatar && ret->tagger_email != NULL)
+		ret->tagger_gravatar = cgit_get_gravatar(ret->tagger_email);
+
 	// skip empty lines between headers and message
 	while (p && *p == '\n')
 		p++;
@@ -258,3 +281,31 @@ struct taginfo *cgit_parse_tag(struct tag *tag)
 	free(data);
 	return ret;
 }
+
+char * cgit_get_gravatar(const char *email) {
+	unsigned char digest[MD5_DIGEST_LENGTH];
+	char hex[MD5_DIGEST_LENGTH * 2 + 1], *lower, *tmp;
+	char *gravatar;
+
+	/* The URL includes %s, which is replaced later on. So we do not need
+	 * extra space for termination. */
+	gravatar = malloc(strlen(GRAVATAR_URL) + MD5_DIGEST_LENGTH * 2);
+
+	/* duplicate to lower and skip brackets! */
+	lower = strdup(email + 1);
+	lower[strlen(lower) - 1] = '\0';
+
+	/* make the chars lower case */
+	for (tmp = lower; *tmp; ++tmp)
+		*tmp = tolower(*tmp);
+
+	MD5((unsigned char *)lower, strlen(lower), digest);
+
+	str_to_hex(hex, digest, MD5_DIGEST_LENGTH);
+
+	sprintf(gravatar, GRAVATAR_URL, hex);
+
+	free(lower);
+
+	return gravatar;
+}
diff --git a/shared.c b/shared.c
index 919a99e..a383dfa 100644
--- a/shared.c
+++ b/shared.c
@@ -93,8 +93,12 @@ void *cgit_free_commitinfo(struct commitinfo *info)
 {
 	free(info->author);
 	free(info->author_email);
+	if (info->author_gravatar)
+		free(info->author_gravatar);
 	free(info->committer);
 	free(info->committer_email);
+	if (info->committer_gravatar)
+		free(info->committer_gravatar);
 	free(info->subject);
 	free(info->msg);
 	free(info->msg_encoding);
@@ -204,6 +208,8 @@ static void cgit_free_taginfo(struct taginfo *tag)
 		free(tag->tagger);
 	if (tag->tagger_email)
 		free(tag->tagger_email);
+	if (tag->tagger_gravatar)
+		free(tag->tagger_gravatar);
 	if (tag->msg)
 		free(tag->msg);
 	free(tag);
@@ -588,3 +594,20 @@ char *expand_macros(const char *txt)
 	}
 	return result;
 }
+
+/* gets a string representing the binary data. dst_str must have a
+ * size of at least src_len * 2 + 1 bytes. */
+void str_to_hex(char *dst_str, const unsigned char *src_bytes,
+		size_t src_len) {
+	const char *hex = "0123456789abcdef";
+	int n;
+
+	for (n = 0; n < src_len; ++n) {
+		unsigned char val = *src_bytes++;
+
+		*dst_str++ = hex[val >> 4];
+		*dst_str++ = hex[val & 0xf];
+	}
+
+	*dst_str = 0;
+}
diff --git a/ui-commit.c b/ui-commit.c
index ef85a49..4fa5b83 100644
--- a/ui-commit.c
+++ b/ui-commit.c
@@ -44,6 +44,11 @@ void cgit_print_commit(char *hex, const char *prefix)
 	cgit_print_diff_ctrls();
 	html("<table summary='commit info' class='commit-info'>\n");
 	html("<tr><th>author</th><td>");
+	if (ctx.cfg.enable_gravatar && info->author_gravatar) {
+		html("<img src='");
+		html_txt(info->author_gravatar);
+		html("' width=16 height=16 alt='Gravatar' /> ");
+	}
 	html_txt(info->author);
 	if (!ctx.cfg.noplainemail) {
 		html(" ");
@@ -53,6 +58,11 @@ void cgit_print_commit(char *hex, const char *prefix)
 	cgit_print_date(info->author_date, FMT_LONGDATE, ctx.cfg.local_time);
 	html("</td></tr>\n");
 	html("<tr><th>committer</th><td>");
+	if (ctx.cfg.enable_gravatar && info->committer_gravatar) {
+		html("<img src='");
+		html_txt(info->committer_gravatar);
+		html("' width=16 height=16 alt='Gravatar' /> ");
+	}
 	html_txt(info->committer);
 	if (!ctx.cfg.noplainemail) {
 		html(" ");
diff --git a/ui-log.c b/ui-log.c
index 6f1249b..c1bbc00 100644
--- a/ui-log.c
+++ b/ui-log.c
@@ -168,6 +168,11 @@ static void print_commit(struct commit *commit, struct rev_info *revs)
 			 sha1_to_hex(commit->object.sha1), ctx.qry.vpath, 0);
 	show_commit_decorations(commit);
 	html("</td><td>");
+	if (ctx.cfg.enable_gravatar && info->author_gravatar) {
+		html("<img src='");
+		html_txt(info->author_gravatar);
+		html("' width=16 height=16 alt='Gravatar' /> ");
+	}
 	html_txt(info->author);
 
 	if (revs->graph) {
diff --git a/ui-refs.c b/ui-refs.c
index 0ae0612..5e6dda9 100644
--- a/ui-refs.c
+++ b/ui-refs.c
@@ -77,6 +77,11 @@ static int print_branch(struct refinfo *ref)
 	if (ref->object->type == OBJ_COMMIT) {
 		cgit_commit_link(info->subject, NULL, NULL, name, NULL, NULL, 0);
 		html("</td><td>");
+		if (ctx.cfg.enable_gravatar && info->author_gravatar) {
+			html("<img src='");
+			html_txt(info->author_gravatar);
+			html("' width=16 height=16 alt='Gravatar' /> ");
+		}
 		html_txt(info->author);
 		html("</td><td colspan='2'>");
 		cgit_print_age(info->commit->date, -1, NULL);
@@ -154,6 +159,11 @@ static int print_tag(struct refinfo *ref)
 		cgit_object_link(obj);
 	html("</td><td>");
 	if (info) {
+		if (ctx.cfg.enable_gravatar && info->tagger_gravatar) {
+			html("<img src='");
+			html_txt(info->tagger_gravatar);
+			html("' width=16 height=16 alt='Gravatar' /> ");
+		}
 		if (info->tagger)
 			html(info->tagger);
 	} else if (ref->object->type == OBJ_COMMIT) {
diff --git a/ui-tag.c b/ui-tag.c
index aea7958..865d6d7 100644
--- a/ui-tag.c
+++ b/ui-tag.c
@@ -77,6 +77,11 @@ void cgit_print_tag(char *revname)
 		}
 		if (info->tagger) {
 			html("<tr><td>tagged by</td><td>");
+			if (ctx.cfg.enable_gravatar && info->tagger_gravatar) {
+				html("<img src='");
+				html_txt(info->tagger_gravatar);
+				html("' width=16 height=16 alt='Gravatar' /> ");
+			}
 			html_txt(info->tagger);
 			if (info->tagger_email && !ctx.cfg.noplainemail) {
 				html(" ");
-- 
1.8.4.2



^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2013-11-27 22:11       ` lekensteyn
@ 2013-11-27 22:59         ` list
  2013-11-27 23:00           ` mail
  0 siblings, 1 reply; 42+ messages in thread
From: list @ 2013-11-27 22:59 UTC (permalink / raw)


Peter Wu <lekensteyn at gmail.com> on Wed, 2013/11/27 23:11:
> On Wednesday 27 November 2013 22:14:22 Christian Hesse wrote:
> > +char * cgit_get_gravatar(const char *email) {
> > +       unsigned char digest[16];
> > +       char hex[33], *lower, *tmp;
> > +       char *gravatar;
> > +
> > +       gravatar = malloc(77);
> 
> I do not quite like this magic number, does anyone have problems with
> creating a GRAVATAR_URL macro? 77 seems also small enough to throw on the
> stack. (Btw, len("//www.gravatar.com/avatar/?s=16&amp;d=retro") + 32 + 1
> says that the length is 76 including nul byte).

Created a GRAVATAR_URL macro now. I do prefer this solution as well.

Got rid of some more magic numbers for MD5 hashing.

> > +       /* duplicate to lower and skip brackets! */
> > +       lower = strdup(email + 1);
> > +       lower[strlen(lower) - 1] = '\0';
> 
> Ahh, I though it was off by one, but apparently you remove the brackets. OK.
> 
> > +
> > +       /* make the chars lower case */
> > +       for (tmp = lower; *tmp; ++tmp)
> > +               *tmp = tolower(*tmp);
> > +
> > +       MD5((unsigned char *)lower, strlen(lower), digest);
> > +
> > +       str_to_hex(hex, digest, 16);
> > +
> > +       sprintf(gravatar,
> > "//www.gravatar.com/avatar/%s?s=16&amp;d=retro", hex);
> 
> It seems ugly to me to store the HTML-escaped URL here. What do you think of
> using just "&" here and html_txt() when outputting the URL? Processing these
> few chars and performing an extra write() should not hurt performance.

Agreed.

> Regarding the GRAVATAR_URL macro mentioned earlier, if used that could
> also be inserted here. A comment could then describe why this URL is used
> (16x16 image using "awesome generated, 8-bit arcade-style pixelated faces"
> as default, https://en.gravatar.com/site/implement/images/)

Done.

> > +       free(lower);
> > +
> > +       return gravatar;
> > +}

I will replay with my updated patch.

-- 
main(a){char*c=/*    Schoene Gruesse                         */"B?IJj;MEH"
"CX:;",b;for(a/*    Chris           get my mail address:    */=0;b=c[a++];)
putchar(b-1/(/*               gcc -o sig sig.c && ./sig    */b/42*2-3)*42);}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20131127/49b03159/attachment.asc>


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2013-11-27 21:14     ` mail
@ 2013-11-27 22:11       ` lekensteyn
  2013-11-27 22:59         ` list
  0 siblings, 1 reply; 42+ messages in thread
From: lekensteyn @ 2013-11-27 22:11 UTC (permalink / raw)


On Wednesday 27 November 2013 22:14:22 Christian Hesse wrote:
> +char * cgit_get_gravatar(const char *email) {
> +       unsigned char digest[16];
> +       char hex[33], *lower, *tmp;
> +       char *gravatar;
> +
> +       gravatar = malloc(77);

I do not quite like this magic number, does anyone have problems with
creating a GRAVATAR_URL macro? 77 seems also small enough to throw on the
stack. (Btw, len("//www.gravatar.com/avatar/?s=16&amp;d=retro") + 32 + 1
says that the length is 76 including nul byte).

> +       /* duplicate to lower and skip brackets! */
> +       lower = strdup(email + 1);
> +       lower[strlen(lower) - 1] = '\0';

Ahh, I though it was off by one, but apparently you remove the brackets. OK.

> +
> +       /* make the chars lower case */
> +       for (tmp = lower; *tmp; ++tmp)
> +               *tmp = tolower(*tmp);
> +
> +       MD5((unsigned char *)lower, strlen(lower), digest);
> +
> +       str_to_hex(hex, digest, 16);
> +
> +       sprintf(gravatar, "//www.gravatar.com/avatar/%s?s=16&amp;d=retro", hex);

It seems ugly to me to store the HTML-escaped URL here. What do you think of
using just "&" here and html_txt() when outputting the URL? Processing these
few chars and performing an extra write() should not hurt performance.

Regarding the GRAVATAR_URL macro mentioned earlier, if used that could
also be inserted here. A comment could then describe why this URL is used
(16x16 image using "awesome generated, 8-bit arcade-style pixelated faces"
as default, https://en.gravatar.com/site/implement/images/)

> +       free(lower);
> +
> +       return gravatar;
> +}

Regards,
Peter


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2013-11-27 20:59   ` list
@ 2013-11-27 21:14     ` mail
  2013-11-27 22:11       ` lekensteyn
  0 siblings, 1 reply; 42+ messages in thread
From: mail @ 2013-11-27 21:14 UTC (permalink / raw)


---
 cgit.c       |  3 +++
 cgit.h       |  8 ++++++++
 cgitrc.5.txt |  4 ++++
 parsing.c    | 41 +++++++++++++++++++++++++++++++++++++++++
 shared.c     | 23 +++++++++++++++++++++++
 ui-commit.c  | 10 ++++++++++
 ui-log.c     |  5 +++++
 ui-refs.c    | 10 ++++++++++
 ui-tag.c     |  5 +++++
 9 files changed, 109 insertions(+)

diff --git a/cgit.c b/cgit.c
index 861352a..fe82580 100644
--- a/cgit.c
+++ b/cgit.c
@@ -183,6 +183,8 @@ static void config_cb(const char *name, const char *value)
 		ctx.cfg.enable_index_owner = atoi(value);
 	else if (!strcmp(name, "enable-commit-graph"))
 		ctx.cfg.enable_commit_graph = atoi(value);
+	else if (!strcmp(name, "enable-gravatar"))
+		ctx.cfg.enable_gravatar = atoi(value);
 	else if (!strcmp(name, "enable-log-filecount"))
 		ctx.cfg.enable_log_filecount = atoi(value);
 	else if (!strcmp(name, "enable-log-linecount"))
@@ -368,6 +370,7 @@ static void prepare_context(struct cgit_context *ctx)
 	ctx->cfg.logo = "/cgit.png";
 	ctx->cfg.favicon = "/favicon.ico";
 	ctx->cfg.local_time = 0;
+	ctx->cfg.enable_gravatar = 0;
 	ctx->cfg.enable_http_clone = 1;
 	ctx->cfg.enable_index_owner = 1;
 	ctx->cfg.enable_tree_linenumbers = 1;
diff --git a/cgit.h b/cgit.h
index a474d77..c5c03fb 100644
--- a/cgit.h
+++ b/cgit.h
@@ -107,9 +107,11 @@ struct commitinfo {
 	struct commit *commit;
 	char *author;
 	char *author_email;
+	char *author_gravatar;
 	unsigned long author_date;
 	char *committer;
 	char *committer_email;
+	char *committer_gravatar;
 	unsigned long committer_date;
 	char *subject;
 	char *msg;
@@ -119,6 +121,7 @@ struct commitinfo {
 struct taginfo {
 	char *tagger;
 	char *tagger_email;
+	char *tagger_gravatar;
 	unsigned long tagger_date;
 	char *msg;
 };
@@ -208,6 +211,7 @@ struct cgit_config {
 	int enable_index_links;
 	int enable_index_owner;
 	int enable_commit_graph;
+	int enable_gravatar;
 	int enable_log_filecount;
 	int enable_log_linecount;
 	int enable_remote_branches;
@@ -337,6 +341,7 @@ extern char *fmtalloc(const char *format,...);
 
 extern struct commitinfo *cgit_parse_commit(struct commit *commit);
 extern struct taginfo *cgit_parse_tag(struct tag *tag);
+char *cgit_get_gravatar(const char *email);
 extern void cgit_parse_url(const char *url);
 
 extern const char *cgit_repobasename(const char *reponame);
@@ -352,4 +357,7 @@ extern int readfile(const char *path, char **buf, size_t *size);
 
 extern char *expand_macros(const char *txt);
 
+void str_to_hex(char *dst_str, const unsigned char *src_bytes,
+		size_t src_len);
+
 #endif /* CGIT_H */
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 633cb00..b6017c2 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -180,6 +180,10 @@ enable-git-config::
 	to the corresponding "repo." key in cgit. Default value: "0". See also:
 	scan-path, section-from-path.
 
+enable-gravatar::
+	Flag which, when set to "1", will enable cgit to show gravatar icon
+	for author, committer and tagger email address. Default value: "0".
+
 favicon::
 	Url used as link to a shortcut icon for cgit. It is suggested to use
 	the value "/favicon.ico" since certain browsers will ignore other
diff --git a/parsing.c b/parsing.c
index 658621d..bd87999 100644
--- a/parsing.c
+++ b/parsing.c
@@ -8,6 +8,9 @@
 
 #include "cgit.h"
 
+/* we need md5 hashing algorithm to calculate Gravatar URL */
+#include <openssl/md5.h>
+
 /*
  * url syntax: [repo ['/' cmd [ '/' path]]]
  *   repo: any valid repo url, may contain '/'
@@ -133,8 +136,10 @@ struct commitinfo *cgit_parse_commit(struct commit *commit)
 	ret->commit = commit;
 	ret->author = NULL;
 	ret->author_email = NULL;
+	ret->author_gravatar = NULL;
 	ret->committer = NULL;
 	ret->committer_email = NULL;
+	ret->committer_gravatar = NULL;
 	ret->subject = NULL;
 	ret->msg = NULL;
 	ret->msg_encoding = NULL;
@@ -155,11 +160,17 @@ struct commitinfo *cgit_parse_commit(struct commit *commit)
 			&ret->author_date);
 	}
 
+	if (ctx.cfg.enable_gravatar && ret->author_email != NULL)
+		ret->author_gravatar = cgit_get_gravatar(ret->author_email);
+
 	if (p && !strncmp(p, "committer ", 9)) {
 		p = parse_user(p + 9, &ret->committer, &ret->committer_email,
 			&ret->committer_date);
 	}
 
+	if (ctx.cfg.enable_gravatar && ret->committer_email != NULL)
+		ret->committer_gravatar = cgit_get_gravatar(ret->committer_email);
+
 	if (p && !strncmp(p, "encoding ", 9)) {
 		p += 9;
 		t = strchr(p, '\n');
@@ -230,6 +241,7 @@ struct taginfo *cgit_parse_tag(struct tag *tag)
 	ret = xmalloc(sizeof(*ret));
 	ret->tagger = NULL;
 	ret->tagger_email = NULL;
+	ret->tagger_gravatar = NULL;
 	ret->tagger_date = 0;
 	ret->msg = NULL;
 
@@ -249,6 +261,9 @@ struct taginfo *cgit_parse_tag(struct tag *tag)
 		}
 	}
 
+	if (ctx.cfg.enable_gravatar && ret->tagger_email != NULL)
+		ret->tagger_gravatar = cgit_get_gravatar(ret->tagger_email);
+
 	// skip empty lines between headers and message
 	while (p && *p == '\n')
 		p++;
@@ -258,3 +273,29 @@ struct taginfo *cgit_parse_tag(struct tag *tag)
 	free(data);
 	return ret;
 }
+
+char * cgit_get_gravatar(const char *email) {
+	unsigned char digest[16];
+	char hex[33], *lower, *tmp;
+	char *gravatar;
+
+	gravatar = malloc(77);
+
+	/* duplicate to lower and skip brackets! */
+	lower = strdup(email + 1);
+	lower[strlen(lower) - 1] = '\0';
+
+	/* make the chars lower case */
+	for (tmp = lower; *tmp; ++tmp)
+		*tmp = tolower(*tmp);
+
+	MD5((unsigned char *)lower, strlen(lower), digest);
+
+	str_to_hex(hex, digest, 16);
+
+	sprintf(gravatar, "//www.gravatar.com/avatar/%s?s=16&amp;d=retro", hex);
+
+	free(lower);
+
+	return gravatar;
+}
diff --git a/shared.c b/shared.c
index 919a99e..a383dfa 100644
--- a/shared.c
+++ b/shared.c
@@ -93,8 +93,12 @@ void *cgit_free_commitinfo(struct commitinfo *info)
 {
 	free(info->author);
 	free(info->author_email);
+	if (info->author_gravatar)
+		free(info->author_gravatar);
 	free(info->committer);
 	free(info->committer_email);
+	if (info->committer_gravatar)
+		free(info->committer_gravatar);
 	free(info->subject);
 	free(info->msg);
 	free(info->msg_encoding);
@@ -204,6 +208,8 @@ static void cgit_free_taginfo(struct taginfo *tag)
 		free(tag->tagger);
 	if (tag->tagger_email)
 		free(tag->tagger_email);
+	if (tag->tagger_gravatar)
+		free(tag->tagger_gravatar);
 	if (tag->msg)
 		free(tag->msg);
 	free(tag);
@@ -588,3 +594,20 @@ char *expand_macros(const char *txt)
 	}
 	return result;
 }
+
+/* gets a string representing the binary data. dst_str must have a
+ * size of at least src_len * 2 + 1 bytes. */
+void str_to_hex(char *dst_str, const unsigned char *src_bytes,
+		size_t src_len) {
+	const char *hex = "0123456789abcdef";
+	int n;
+
+	for (n = 0; n < src_len; ++n) {
+		unsigned char val = *src_bytes++;
+
+		*dst_str++ = hex[val >> 4];
+		*dst_str++ = hex[val & 0xf];
+	}
+
+	*dst_str = 0;
+}
diff --git a/ui-commit.c b/ui-commit.c
index ef85a49..6303408 100644
--- a/ui-commit.c
+++ b/ui-commit.c
@@ -44,6 +44,11 @@ void cgit_print_commit(char *hex, const char *prefix)
 	cgit_print_diff_ctrls();
 	html("<table summary='commit info' class='commit-info'>\n");
 	html("<tr><th>author</th><td>");
+	if (ctx.cfg.enable_gravatar && info->author_gravatar) {
+		html("<img src='");
+		html(info->author_gravatar);
+		html("' width=16 height=16 alt='Gravatar' /> ");
+	}
 	html_txt(info->author);
 	if (!ctx.cfg.noplainemail) {
 		html(" ");
@@ -53,6 +58,11 @@ void cgit_print_commit(char *hex, const char *prefix)
 	cgit_print_date(info->author_date, FMT_LONGDATE, ctx.cfg.local_time);
 	html("</td></tr>\n");
 	html("<tr><th>committer</th><td>");
+	if (ctx.cfg.enable_gravatar && info->committer_gravatar) {
+		html("<img src='");
+		html(info->committer_gravatar);
+		html("' width=16 height=16 alt='Gravatar' /> ");
+	}
 	html_txt(info->committer);
 	if (!ctx.cfg.noplainemail) {
 		html(" ");
diff --git a/ui-log.c b/ui-log.c
index 6f1249b..7cdcca2 100644
--- a/ui-log.c
+++ b/ui-log.c
@@ -168,6 +168,11 @@ static void print_commit(struct commit *commit, struct rev_info *revs)
 			 sha1_to_hex(commit->object.sha1), ctx.qry.vpath, 0);
 	show_commit_decorations(commit);
 	html("</td><td>");
+	if (ctx.cfg.enable_gravatar && info->author_gravatar) {
+		html("<img src='");
+		html(info->author_gravatar);
+		html("' width=16 height=16 alt='Gravatar' /> ");
+	}
 	html_txt(info->author);
 
 	if (revs->graph) {
diff --git a/ui-refs.c b/ui-refs.c
index 0ae0612..6e67799 100644
--- a/ui-refs.c
+++ b/ui-refs.c
@@ -77,6 +77,11 @@ static int print_branch(struct refinfo *ref)
 	if (ref->object->type == OBJ_COMMIT) {
 		cgit_commit_link(info->subject, NULL, NULL, name, NULL, NULL, 0);
 		html("</td><td>");
+		if (ctx.cfg.enable_gravatar && info->author_gravatar) {
+			html("<img src='");
+			html(info->author_gravatar);
+			html("' width=16 height=16 alt='Gravatar' /> ");
+		}
 		html_txt(info->author);
 		html("</td><td colspan='2'>");
 		cgit_print_age(info->commit->date, -1, NULL);
@@ -154,6 +159,11 @@ static int print_tag(struct refinfo *ref)
 		cgit_object_link(obj);
 	html("</td><td>");
 	if (info) {
+		if (ctx.cfg.enable_gravatar && info->tagger_gravatar) {
+			html("<img src='");
+			html(info->tagger_gravatar);
+			html("' width=16 height=16 alt='Gravatar' /> ");
+		}
 		if (info->tagger)
 			html(info->tagger);
 	} else if (ref->object->type == OBJ_COMMIT) {
diff --git a/ui-tag.c b/ui-tag.c
index aea7958..1e041d0 100644
--- a/ui-tag.c
+++ b/ui-tag.c
@@ -77,6 +77,11 @@ void cgit_print_tag(char *revname)
 		}
 		if (info->tagger) {
 			html("<tr><td>tagged by</td><td>");
+			if (ctx.cfg.enable_gravatar && info->tagger_gravatar) {
+				html("<img src='");
+				html(info->tagger_gravatar);
+				html("' width=16 height=16 alt='Gravatar' /> ");
+			}
 			html_txt(info->tagger);
 			if (info->tagger_email && !ctx.cfg.noplainemail) {
 				html(" ");
-- 
1.8.4.2



^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2013-11-27 20:51   ` list
@ 2013-11-27 21:00     ` john
  0 siblings, 0 replies; 42+ messages in thread
From: john @ 2013-11-27 21:00 UTC (permalink / raw)


On Wed, Nov 27, 2013 at 09:51:33PM +0100, Christian Hesse wrote:
> John Keeping <john at keeping.me.uk> on Wed, 2013/11/27 16:37:
> > On Wed, Nov 27, 2013 at 04:17:17PM +0100, Christian Hesse wrote:
> > > diff --git a/parsing.c b/parsing.c
> > > index 658621d..a8005f6 100644
> > > --- a/parsing.c
> > > +++ b/parsing.c
> > > @@ -8,6 +8,9 @@
> > >  
> > >  #include "cgit.h"
> > >  
> > > +/* we need md5 hashing algorithm to calculate Gravatar URL */
> > > +#include <openssl/md5.h>
> > 
> > We don't currently depend on OpenSSL, except via Git which can use
> > alternative SHA-1 implementations.
> > 
> > At the very least Debian will not distribute GPL'd packages
> > linked against OpenSSL [1].
> > 
> > [1]
> > http://lintian.debian.org/tags/possible-gpl-code-linked-with-openssl.html
> 
> Damn licensing stuff... Ok, but cgit is already linked against libcrypt which
> belongs to openssl.
> 
> Any ideas what to use instead? Shipping a complete MD5 implementation is a
> bad idea I think.

I think writing against OpenSSL is fine, everyone else tends to have a
compatibility layer for that API anyway.  But it would be nice to define
a MD5_HEADER variable in a similar way to git.git's SHA1_HEADER.

> > > +char * cgit_get_gravatar(const char * email) {
> > > +    	int n, length;
> > > +	MD5_CTX c;
> > > +	unsigned char digest[16];
> > > +	char hex[33];
> > > +	char * gravatar = malloc(67);
> > > +
> > > +	/* skip brackets! */
> > > +	email++;
> > > +	length = strlen(email) - 1;
> > > +
> > > +	MD5_Init(&c);
> > > +
> > > +	while (length > 0) {
> > > +		if (length > 512)
> > > +			MD5_Update(&c, email, 512);
> > > +		else
> > > +			MD5_Update(&c, email, length);
> > > +		length -= 512;
> > > +		email += 512;
> > > +	}
> > > +
> > > +	MD5_Final(digest, &c);
> > 
> > Would it be possible to extract everything from MD5_Init to MD5_Final to
> > a function that just computes the MD5 of a string?  That should make it
> > easier to add alternative implementations.
> 
> I updated the code to use MD5(...), but that is still openssl.
> 
> > > +	for (n = 0; n < 16; ++n)
> > > +		snprintf(&(hex[n*2]), 16*2, "%02x", (unsigned
> > > int)digest[n]); +
> > > +	sprintf(gravatar, "http://www.gravatar.com/avatar/%s?s=", hex);
> > > +
> > > +	return gravatar;
> > > +}


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2013-11-27 16:46 ` lekensteyn
@ 2013-11-27 20:59   ` list
  2013-11-27 21:14     ` mail
  0 siblings, 1 reply; 42+ messages in thread
From: list @ 2013-11-27 20:59 UTC (permalink / raw)


Peter Wu <lekensteyn at gmail.com> on Wed, 2013/11/27 17:46:
> Hi,
> 
> See below for review.
> 
> On Wednesday 27 November 2013 16:17:17 Christian Hesse wrote:
> > ---
> >  cgit.c       |  3 +++
> >  cgit.h       |  5 +++++
> >  cgitrc.5.txt |  4 ++++
> >  parsing.c    | 47 +++++++++++++++++++++++++++++++++++++++++++++++
> >  shared.c     |  6 ++++++
> >  ui-commit.c  | 10 ++++++++++
> >  ui-log.c     |  5 +++++
> >  ui-refs.c    | 10 ++++++++++
> >  ui-tag.c     |  5 +++++
> >  9 files changed, 95 insertions(+)
> 
> [..]
> 
> > @@ -258,3 +273,35 @@ struct taginfo *cgit_parse_tag(struct tag *tag)
> >  	free(data);
> >  	return ret;
> >  }
> > +
> > +char * cgit_get_gravatar(const char * email) {
> > +    	int n, length;
> > +	MD5_CTX c;
> > +	unsigned char digest[16];
> > +	char hex[33];
> > +	char * gravatar = malloc(67);
> > +
> > +	/* skip brackets! */
> > +	email++;
> > +	length = strlen(email) - 1;
> 
> > +
> > +	MD5_Init(&c);
> > +
> > +	while (length > 0) {
> > +		if (length > 512)
> > +			MD5_Update(&c, email, 512);
> > +		else
> > +			MD5_Update(&c, email, length);
> Seems like an error from Stackoverflow[1]? According to the manual page,
> the length is in bytes, not bits.
> 
>  [1]: http://stackoverflow.com/a/8389763/427545
> 
> > +		length -= 512;
> > +		email += 512;
> > +	}
> > +
> > +	MD5_Final(digest, &c);
> 
> Since you know the full string onbeforehand, you should also be able to use 
> MD5() directly. Something like (openssl):
> 
>     MD5(email, length, digest);

Updated it to use MD5(...).

Though the licensing issue remain...

> As you mentioned, email addresses should be converted to lower case first 
> according to http://en.gravatar.com/site/implement/hash/. The below
> str_to_hex was written before I knew that.
> 
> > +
> > +	for (n = 0; n < 16; ++n)
> > +		snprintf(&(hex[n*2]), 16*2, "%02x", (unsigned
> > int)digest[n]);
> 
> This 16*2 is bogus, if you are at the 30th position, you only have two
> bytes left. What about adding a new md5_to_hex() function, similar to
> sha1_to_hex() in git? Here is a generic approach:
> 
> /* gets a string representing the binary data. dst_str must have a
>  * size of at least src_len * 2 + 1 bytes. */
>     void str_to_hex(char *dst_str, const unsigned char *src_bytes,
>                     size_t src_len) {
>         const char *hex = "0123456789abcdef";
>         int n;
> 
>         for (n = 0; n < src_len; ++n) {
>             unsigned char val = *src_bytes++;
>             *dst_str++ = hex[val >> 4];
>             *dst_str++ = hex[val & 0xf];
>         }
> 
>         *dst_str = 0;
>     }
> 
>     str_to_hex(hex, digest, 16);
> 
> The emailaddress limitation could probably be resolved here by repeatedly 
> calling:
> 
>     MD5_Update(&c, tolower(email[n]), 1)

I updated my code. It duplicates the string now, makes it lower case and uses
your function to calculate hex.

> > +
> > +	sprintf(gravatar, "http://www.gravatar.com/avatar/%s?s=", hex);
> 
> Use "//www.gravatar.com/.." instead for HTTPS sites?

Did not know this works. Great!

> > +
> > +	return gravatar;
> > +}
> 
> [..]
>
> > @@ -53,6 +58,11 @@ void cgit_print_commit(char *hex, const char *prefix)
> >  	cgit_print_date(info->author_date, FMT_LONGDATE,
> > ctx.cfg.local_time); html("</td></tr>\n");
> >  	html("<tr><th>committer</th><td>");
> > +	if (ctx.cfg.enable_gravatar && info->committer_gravatar) {
> > +		html("<img src='");
> > +		html(info->committer_gravatar);
> > +		html("' width=16 height=16 alt='Gravatar' \\>");
> 
> SHouldn't that \\ become a / for XHTML? 

I was sitting in my car on the way home when I thought about why I had to
escape this...

Of course you are right.

[...]

Thanks for your review! I will reply with an updated patch later.
-- 
main(a){char*c=/*    Schoene Gruesse                         */"B?IJj;MEH"
"CX:;",b;for(a/*    Chris           get my mail address:    */=0;b=c[a++];)
putchar(b-1/(/*               gcc -o sig sig.c && ./sig    */b/42*2-3)*42);}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20131127/5ebac967/attachment.asc>


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2013-11-27 16:37 ` john
@ 2013-11-27 20:51   ` list
  2013-11-27 21:00     ` john
  0 siblings, 1 reply; 42+ messages in thread
From: list @ 2013-11-27 20:51 UTC (permalink / raw)


John Keeping <john at keeping.me.uk> on Wed, 2013/11/27 16:37:
> On Wed, Nov 27, 2013 at 04:17:17PM +0100, Christian Hesse wrote:
> > diff --git a/parsing.c b/parsing.c
> > index 658621d..a8005f6 100644
> > --- a/parsing.c
> > +++ b/parsing.c
> > @@ -8,6 +8,9 @@
> >  
> >  #include "cgit.h"
> >  
> > +/* we need md5 hashing algorithm to calculate Gravatar URL */
> > +#include <openssl/md5.h>
> 
> We don't currently depend on OpenSSL, except via Git which can use
> alternative SHA-1 implementations.
> 
> At the very least Debian will not distribute GPL'd packages
> linked against OpenSSL [1].
> 
> [1]
> http://lintian.debian.org/tags/possible-gpl-code-linked-with-openssl.html

Damn licensing stuff... Ok, but cgit is already linked against libcrypt which
belongs to openssl.

Any ideas what to use instead? Shipping a complete MD5 implementation is a
bad idea I think.

> > +char * cgit_get_gravatar(const char * email) {
> > +    	int n, length;
> > +	MD5_CTX c;
> > +	unsigned char digest[16];
> > +	char hex[33];
> > +	char * gravatar = malloc(67);
> > +
> > +	/* skip brackets! */
> > +	email++;
> > +	length = strlen(email) - 1;
> > +
> > +	MD5_Init(&c);
> > +
> > +	while (length > 0) {
> > +		if (length > 512)
> > +			MD5_Update(&c, email, 512);
> > +		else
> > +			MD5_Update(&c, email, length);
> > +		length -= 512;
> > +		email += 512;
> > +	}
> > +
> > +	MD5_Final(digest, &c);
> 
> Would it be possible to extract everything from MD5_Init to MD5_Final to
> a function that just computes the MD5 of a string?  That should make it
> easier to add alternative implementations.

I updated the code to use MD5(...), but that is still openssl.

> > +	for (n = 0; n < 16; ++n)
> > +		snprintf(&(hex[n*2]), 16*2, "%02x", (unsigned
> > int)digest[n]); +
> > +	sprintf(gravatar, "http://www.gravatar.com/avatar/%s?s=", hex);
> > +
> > +	return gravatar;
> > +}

-- 
main(a){char*c=/*    Schoene Gruesse                         */"B?IJj;MEH"
"CX:;",b;for(a/*    Chris           get my mail address:    */=0;b=c[a++];)
putchar(b-1/(/*               gcc -o sig sig.c && ./sig    */b/42*2-3)*42);}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20131127/d426bc4f/attachment.asc>


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2013-11-27 15:17 [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger mail
  2013-11-27 16:17 ` list
  2013-11-27 16:37 ` john
@ 2013-11-27 16:46 ` lekensteyn
  2013-11-27 20:59   ` list
  2 siblings, 1 reply; 42+ messages in thread
From: lekensteyn @ 2013-11-27 16:46 UTC (permalink / raw)


Hi,

See below for review.

On Wednesday 27 November 2013 16:17:17 Christian Hesse wrote:
> ---
>  cgit.c       |  3 +++
>  cgit.h       |  5 +++++
>  cgitrc.5.txt |  4 ++++
>  parsing.c    | 47 +++++++++++++++++++++++++++++++++++++++++++++++
>  shared.c     |  6 ++++++
>  ui-commit.c  | 10 ++++++++++
>  ui-log.c     |  5 +++++
>  ui-refs.c    | 10 ++++++++++
>  ui-tag.c     |  5 +++++
>  9 files changed, 95 insertions(+)

[..]

> @@ -258,3 +273,35 @@ struct taginfo *cgit_parse_tag(struct tag *tag)
>  	free(data);
>  	return ret;
>  }
> +
> +char * cgit_get_gravatar(const char * email) {
> +    	int n, length;
> +	MD5_CTX c;
> +	unsigned char digest[16];
> +	char hex[33];
> +	char * gravatar = malloc(67);
> +
> +	/* skip brackets! */
> +	email++;
> +	length = strlen(email) - 1;

> +
> +	MD5_Init(&c);
> +
> +	while (length > 0) {
> +		if (length > 512)
> +			MD5_Update(&c, email, 512);
> +		else
> +			MD5_Update(&c, email, length);
Seems like an error from Stackoverflow[1]? According to the manual page, the 
length is in bytes, not bits.

 [1]: http://stackoverflow.com/a/8389763/427545

> +		length -= 512;
> +		email += 512;
> +	}
> +
> +	MD5_Final(digest, &c);

Since you know the full string onbeforehand, you should also be able to use 
MD5() directly. Something like (openssl):

    MD5(email, length, digest);

As you mentioned, email addresses should be converted to lower case first 
according to http://en.gravatar.com/site/implement/hash/. The below str_to_hex 
was written before I knew that.

> +
> +	for (n = 0; n < 16; ++n)
> +		snprintf(&(hex[n*2]), 16*2, "%02x", (unsigned int)digest[n]);

This 16*2 is bogus, if you are at the 30th position, you only have two bytes 
left. What about adding a new md5_to_hex() function, similar to sha1_to_hex() 
in git? Here is a generic approach:

/* gets a string representing the binary data. dst_str must have a
 * size of at least src_len * 2 + 1 bytes. */
    void str_to_hex(char *dst_str, const unsigned char *src_bytes,
                    size_t src_len) {
        const char *hex = "0123456789abcdef";
        int n;

        for (n = 0; n < src_len; ++n) {
            unsigned char val = *src_bytes++;
            *dst_str++ = hex[val >> 4];
            *dst_str++ = hex[val & 0xf];
        }

        *dst_str = 0;
    }

    str_to_hex(hex, digest, 16);

The emailaddress limitation could probably be resolved here by repeatedly 
calling:

    MD5_Update(&c, tolower(email[n]), 1)

> +
> +	sprintf(gravatar, "http://www.gravatar.com/avatar/%s?s=", hex);

Use "//www.gravatar.com/.." instead for HTTPS sites?

> +
> +	return gravatar;
> +}

[..]

> --- a/ui-commit.c
> +++ b/ui-commit.c
> @@ -44,6 +44,11 @@ void cgit_print_commit(char *hex, const char *prefix)
>  	cgit_print_diff_ctrls();
>  	html("<table summary='commit info' class='commit-info'>\n");
>  	html("<tr><th>author</th><td>");
> +	if (ctx.cfg.enable_gravatar && info->author_gravatar) {
> +		html("<img src='");
> +		html(info->author_gravatar);
> +		html("' width=16 height=16 alt='Gravatar' \\>");
> +	}
>  	html_txt(info->author);
>  	if (!ctx.cfg.noplainemail) {
>  		html(" ");
> @@ -53,6 +58,11 @@ void cgit_print_commit(char *hex, const char *prefix)
>  	cgit_print_date(info->author_date, FMT_LONGDATE, ctx.cfg.local_time);
>  	html("</td></tr>\n");
>  	html("<tr><th>committer</th><td>");
> +	if (ctx.cfg.enable_gravatar && info->committer_gravatar) {
> +		html("<img src='");
> +		html(info->committer_gravatar);
> +		html("' width=16 height=16 alt='Gravatar' \\>");

SHouldn't that \\ become a / for XHTML? 

> +	}
>  	html_txt(info->committer);
>  	if (!ctx.cfg.noplainemail) {
>  		html(" ");
> diff --git a/ui-log.c b/ui-log.c
> index 6f1249b..9974139 100644
> --- a/ui-log.c
> +++ b/ui-log.c
> @@ -168,6 +168,11 @@ static void print_commit(struct commit *commit, struct
> rev_info *revs) sha1_to_hex(commit->object.sha1), ctx.qry.vpath, 0);
>  	show_commit_decorations(commit);
>  	html("</td><td>");
> +	if (ctx.cfg.enable_gravatar && info->author_gravatar) {
> +		html("<img src='");
> +		html(info->author_gravatar);
> +		html("' width=16 height=16 alt='Gravatar' \\>");

Same here, "/>" instead of "\>".

> +	}
>  	html_txt(info->author);
> 
>  	if (revs->graph) {
> diff --git a/ui-refs.c b/ui-refs.c
> index 0ae0612..8714b2d 100644
> --- a/ui-refs.c
> +++ b/ui-refs.c
> @@ -77,6 +77,11 @@ static int print_branch(struct refinfo *ref)
>  	if (ref->object->type == OBJ_COMMIT) {
>  		cgit_commit_link(info->subject, NULL, NULL, name, NULL, NULL, 0);
>  		html("</td><td>");
> +		if (ctx.cfg.enable_gravatar && info->author_gravatar) {
> +			html("<img src='");
> +			html(info->author_gravatar);
> +			html("' width=16 height=16 alt='Gravatar' \\>");

Same..

> +		}
>  		html_txt(info->author);
>  		html("</td><td colspan='2'>");
>  		cgit_print_age(info->commit->date, -1, NULL);
> @@ -154,6 +159,11 @@ static int print_tag(struct refinfo *ref)
>  		cgit_object_link(obj);
>  	html("</td><td>");
>  	if (info) {
> +		if (ctx.cfg.enable_gravatar && info->tagger_gravatar) {
> +			html("<img src='");
> +			html(info->tagger_gravatar);
> +			html("' width=16 height=16 alt='Gravatar' \\>");

Same..

> +		}
>  		if (info->tagger)
>  			html(info->tagger);
>  	} else if (ref->object->type == OBJ_COMMIT) {
> diff --git a/ui-tag.c b/ui-tag.c
> index aea7958..ad402da 100644
> --- a/ui-tag.c
> +++ b/ui-tag.c
> @@ -77,6 +77,11 @@ void cgit_print_tag(char *revname)
>  		}
>  		if (info->tagger) {
>  			html("<tr><td>tagged by</td><td>");
> +			if (ctx.cfg.enable_gravatar && info->tagger_gravatar) {
> +				html("<img src='");
> +				html(info->tagger_gravatar);
> +				html("' width=16 height=16 alt='Gravatar' \\>");

Yep, also wrong slashes.

> +			}
>  			html_txt(info->tagger);
>  			if (info->tagger_email && !ctx.cfg.noplainemail) {
>  				html(" ");

Regards,
Peter


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2013-11-27 15:17 [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger mail
  2013-11-27 16:17 ` list
@ 2013-11-27 16:37 ` john
  2013-11-27 20:51   ` list
  2013-11-27 16:46 ` lekensteyn
  2 siblings, 1 reply; 42+ messages in thread
From: john @ 2013-11-27 16:37 UTC (permalink / raw)


On Wed, Nov 27, 2013 at 04:17:17PM +0100, Christian Hesse wrote:
> diff --git a/parsing.c b/parsing.c
> index 658621d..a8005f6 100644
> --- a/parsing.c
> +++ b/parsing.c
> @@ -8,6 +8,9 @@
>  
>  #include "cgit.h"
>  
> +/* we need md5 hashing algorithm to calculate Gravatar URL */
> +#include <openssl/md5.h>

We don't currently depend on OpenSSL, except via Git which can use
alternative SHA-1 implementations.

At the very least Debian will not distribute GPL'd packages
linked against OpenSSL [1].

[1] http://lintian.debian.org/tags/possible-gpl-code-linked-with-openssl.html

> +char * cgit_get_gravatar(const char * email) {
> +    	int n, length;
> +	MD5_CTX c;
> +	unsigned char digest[16];
> +	char hex[33];
> +	char * gravatar = malloc(67);
> +
> +	/* skip brackets! */
> +	email++;
> +	length = strlen(email) - 1;
> +
> +	MD5_Init(&c);
> +
> +	while (length > 0) {
> +		if (length > 512)
> +			MD5_Update(&c, email, 512);
> +		else
> +			MD5_Update(&c, email, length);
> +		length -= 512;
> +		email += 512;
> +	}
> +
> +	MD5_Final(digest, &c);

Would it be possible to extract everything from MD5_Init to MD5_Final to
a function that just computes the MD5 of a string?  That should make it
easier to add alternative implementations.

> +	for (n = 0; n < 16; ++n)
> +		snprintf(&(hex[n*2]), 16*2, "%02x", (unsigned int)digest[n]);
> +
> +	sprintf(gravatar, "http://www.gravatar.com/avatar/%s?s=", hex);
> +
> +	return gravatar;
> +}


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
  2013-11-27 15:17 [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger mail
@ 2013-11-27 16:17 ` list
  2013-11-27 16:37 ` john
  2013-11-27 16:46 ` lekensteyn
  2 siblings, 0 replies; 42+ messages in thread
From: list @ 2013-11-27 16:17 UTC (permalink / raw)


Christian Hesse <mail at eworm.de> on Wed, 2013/11/27 16:17:
> ---
>  cgit.c       |  3 +++
>  cgit.h       |  5 +++++
>  cgitrc.5.txt |  4 ++++
>  parsing.c    | 47 +++++++++++++++++++++++++++++++++++++++++++++++
>  shared.c     |  6 ++++++
>  ui-commit.c  | 10 ++++++++++
>  ui-log.c     |  5 +++++
>  ui-refs.c    | 10 ++++++++++
>  ui-tag.c     |  5 +++++
>  9 files changed, 95 insertions(+)

This has some minor bugs, for example mail addresses have to be converted to
lower case before hashing. And probably it makes sense to fetch smaller
images than the default 80 pixel...

However I would like to get some comments, I will update things when this
(is going to be) merged upstream.

Thanks!
-- 
main(a){char*c=/*    Schoene Gruesse                         */"B?IJj;MEH"
"CX:;",b;for(a/*    Chris           get my mail address:    */=0;b=c[a++];)
putchar(b-1/(/*               gcc -o sig sig.c && ./sig    */b/42*2-3)*42);}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20131127/88725a6e/attachment.asc>


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
@ 2013-11-27 15:17 mail
  2013-11-27 16:17 ` list
                   ` (2 more replies)
  0 siblings, 3 replies; 42+ messages in thread
From: mail @ 2013-11-27 15:17 UTC (permalink / raw)


---
 cgit.c       |  3 +++
 cgit.h       |  5 +++++
 cgitrc.5.txt |  4 ++++
 parsing.c    | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 shared.c     |  6 ++++++
 ui-commit.c  | 10 ++++++++++
 ui-log.c     |  5 +++++
 ui-refs.c    | 10 ++++++++++
 ui-tag.c     |  5 +++++
 9 files changed, 95 insertions(+)

diff --git a/cgit.c b/cgit.c
index 861352a..fe82580 100644
--- a/cgit.c
+++ b/cgit.c
@@ -183,6 +183,8 @@ static void config_cb(const char *name, const char *value)
 		ctx.cfg.enable_index_owner = atoi(value);
 	else if (!strcmp(name, "enable-commit-graph"))
 		ctx.cfg.enable_commit_graph = atoi(value);
+	else if (!strcmp(name, "enable-gravatar"))
+		ctx.cfg.enable_gravatar = atoi(value);
 	else if (!strcmp(name, "enable-log-filecount"))
 		ctx.cfg.enable_log_filecount = atoi(value);
 	else if (!strcmp(name, "enable-log-linecount"))
@@ -368,6 +370,7 @@ static void prepare_context(struct cgit_context *ctx)
 	ctx->cfg.logo = "/cgit.png";
 	ctx->cfg.favicon = "/favicon.ico";
 	ctx->cfg.local_time = 0;
+	ctx->cfg.enable_gravatar = 0;
 	ctx->cfg.enable_http_clone = 1;
 	ctx->cfg.enable_index_owner = 1;
 	ctx->cfg.enable_tree_linenumbers = 1;
diff --git a/cgit.h b/cgit.h
index a474d77..ab22e67 100644
--- a/cgit.h
+++ b/cgit.h
@@ -107,9 +107,11 @@ struct commitinfo {
 	struct commit *commit;
 	char *author;
 	char *author_email;
+	char *author_gravatar;
 	unsigned long author_date;
 	char *committer;
 	char *committer_email;
+	char *committer_gravatar;
 	unsigned long committer_date;
 	char *subject;
 	char *msg;
@@ -119,6 +121,7 @@ struct commitinfo {
 struct taginfo {
 	char *tagger;
 	char *tagger_email;
+	char *tagger_gravatar;
 	unsigned long tagger_date;
 	char *msg;
 };
@@ -208,6 +211,7 @@ struct cgit_config {
 	int enable_index_links;
 	int enable_index_owner;
 	int enable_commit_graph;
+	int enable_gravatar;
 	int enable_log_filecount;
 	int enable_log_linecount;
 	int enable_remote_branches;
@@ -337,6 +341,7 @@ extern char *fmtalloc(const char *format,...);
 
 extern struct commitinfo *cgit_parse_commit(struct commit *commit);
 extern struct taginfo *cgit_parse_tag(struct tag *tag);
+char *cgit_get_gravatar(const char *email);
 extern void cgit_parse_url(const char *url);
 
 extern const char *cgit_repobasename(const char *reponame);
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 633cb00..b6017c2 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -180,6 +180,10 @@ enable-git-config::
 	to the corresponding "repo." key in cgit. Default value: "0". See also:
 	scan-path, section-from-path.
 
+enable-gravatar::
+	Flag which, when set to "1", will enable cgit to show gravatar icon
+	for author, committer and tagger email address. Default value: "0".
+
 favicon::
 	Url used as link to a shortcut icon for cgit. It is suggested to use
 	the value "/favicon.ico" since certain browsers will ignore other
diff --git a/parsing.c b/parsing.c
index 658621d..a8005f6 100644
--- a/parsing.c
+++ b/parsing.c
@@ -8,6 +8,9 @@
 
 #include "cgit.h"
 
+/* we need md5 hashing algorithm to calculate Gravatar URL */
+#include <openssl/md5.h>
+
 /*
  * url syntax: [repo ['/' cmd [ '/' path]]]
  *   repo: any valid repo url, may contain '/'
@@ -133,8 +136,10 @@ struct commitinfo *cgit_parse_commit(struct commit *commit)
 	ret->commit = commit;
 	ret->author = NULL;
 	ret->author_email = NULL;
+	ret->author_gravatar = NULL;
 	ret->committer = NULL;
 	ret->committer_email = NULL;
+	ret->committer_gravatar = NULL;
 	ret->subject = NULL;
 	ret->msg = NULL;
 	ret->msg_encoding = NULL;
@@ -155,11 +160,17 @@ struct commitinfo *cgit_parse_commit(struct commit *commit)
 			&ret->author_date);
 	}
 
+	if (ctx.cfg.enable_gravatar && ret->author_email != NULL) 
+		ret->author_gravatar = cgit_get_gravatar(ret->author_email);
+
 	if (p && !strncmp(p, "committer ", 9)) {
 		p = parse_user(p + 9, &ret->committer, &ret->committer_email,
 			&ret->committer_date);
 	}
 
+	if (ctx.cfg.enable_gravatar && ret->committer_email != NULL) 
+		ret->committer_gravatar = cgit_get_gravatar(ret->committer_email);
+
 	if (p && !strncmp(p, "encoding ", 9)) {
 		p += 9;
 		t = strchr(p, '\n');
@@ -230,6 +241,7 @@ struct taginfo *cgit_parse_tag(struct tag *tag)
 	ret = xmalloc(sizeof(*ret));
 	ret->tagger = NULL;
 	ret->tagger_email = NULL;
+	ret->tagger_gravatar = NULL;
 	ret->tagger_date = 0;
 	ret->msg = NULL;
 
@@ -249,6 +261,9 @@ struct taginfo *cgit_parse_tag(struct tag *tag)
 		}
 	}
 
+	if (ctx.cfg.enable_gravatar && ret->tagger_email != NULL)
+		ret->tagger_gravatar = cgit_get_gravatar(ret->tagger_email);
+
 	// skip empty lines between headers and message
 	while (p && *p == '\n')
 		p++;
@@ -258,3 +273,35 @@ struct taginfo *cgit_parse_tag(struct tag *tag)
 	free(data);
 	return ret;
 }
+
+char * cgit_get_gravatar(const char * email) {
+    	int n, length;
+	MD5_CTX c;
+	unsigned char digest[16];
+	char hex[33];
+	char * gravatar = malloc(67);
+
+	/* skip brackets! */
+	email++;
+	length = strlen(email) - 1;
+
+	MD5_Init(&c);
+
+	while (length > 0) {
+		if (length > 512)
+			MD5_Update(&c, email, 512);
+		else
+			MD5_Update(&c, email, length);
+		length -= 512;
+		email += 512;
+	}
+
+	MD5_Final(digest, &c);
+
+	for (n = 0; n < 16; ++n)
+		snprintf(&(hex[n*2]), 16*2, "%02x", (unsigned int)digest[n]);
+
+	sprintf(gravatar, "http://www.gravatar.com/avatar/%s?s=", hex);
+
+	return gravatar;
+}
diff --git a/shared.c b/shared.c
index 919a99e..8ae8c3b 100644
--- a/shared.c
+++ b/shared.c
@@ -93,8 +93,12 @@ void *cgit_free_commitinfo(struct commitinfo *info)
 {
 	free(info->author);
 	free(info->author_email);
+	if (info->author_gravatar)
+		free(info->author_gravatar);
 	free(info->committer);
 	free(info->committer_email);
+	if (info->committer_gravatar)
+		free(info->committer_gravatar);
 	free(info->subject);
 	free(info->msg);
 	free(info->msg_encoding);
@@ -204,6 +208,8 @@ static void cgit_free_taginfo(struct taginfo *tag)
 		free(tag->tagger);
 	if (tag->tagger_email)
 		free(tag->tagger_email);
+	if (tag->tagger_gravatar)
+		free(tag->tagger_gravatar);
 	if (tag->msg)
 		free(tag->msg);
 	free(tag);
diff --git a/ui-commit.c b/ui-commit.c
index ef85a49..eed3ab6 100644
--- a/ui-commit.c
+++ b/ui-commit.c
@@ -44,6 +44,11 @@ void cgit_print_commit(char *hex, const char *prefix)
 	cgit_print_diff_ctrls();
 	html("<table summary='commit info' class='commit-info'>\n");
 	html("<tr><th>author</th><td>");
+	if (ctx.cfg.enable_gravatar && info->author_gravatar) {
+		html("<img src='");
+		html(info->author_gravatar);
+		html("' width=16 height=16 alt='Gravatar' \\>");
+	}
 	html_txt(info->author);
 	if (!ctx.cfg.noplainemail) {
 		html(" ");
@@ -53,6 +58,11 @@ void cgit_print_commit(char *hex, const char *prefix)
 	cgit_print_date(info->author_date, FMT_LONGDATE, ctx.cfg.local_time);
 	html("</td></tr>\n");
 	html("<tr><th>committer</th><td>");
+	if (ctx.cfg.enable_gravatar && info->committer_gravatar) {
+		html("<img src='");
+		html(info->committer_gravatar);
+		html("' width=16 height=16 alt='Gravatar' \\>");
+	}
 	html_txt(info->committer);
 	if (!ctx.cfg.noplainemail) {
 		html(" ");
diff --git a/ui-log.c b/ui-log.c
index 6f1249b..9974139 100644
--- a/ui-log.c
+++ b/ui-log.c
@@ -168,6 +168,11 @@ static void print_commit(struct commit *commit, struct rev_info *revs)
 			 sha1_to_hex(commit->object.sha1), ctx.qry.vpath, 0);
 	show_commit_decorations(commit);
 	html("</td><td>");
+	if (ctx.cfg.enable_gravatar && info->author_gravatar) {
+		html("<img src='");
+		html(info->author_gravatar);
+		html("' width=16 height=16 alt='Gravatar' \\>");
+	}
 	html_txt(info->author);
 
 	if (revs->graph) {
diff --git a/ui-refs.c b/ui-refs.c
index 0ae0612..8714b2d 100644
--- a/ui-refs.c
+++ b/ui-refs.c
@@ -77,6 +77,11 @@ static int print_branch(struct refinfo *ref)
 	if (ref->object->type == OBJ_COMMIT) {
 		cgit_commit_link(info->subject, NULL, NULL, name, NULL, NULL, 0);
 		html("</td><td>");
+		if (ctx.cfg.enable_gravatar && info->author_gravatar) {
+			html("<img src='");
+			html(info->author_gravatar);
+			html("' width=16 height=16 alt='Gravatar' \\>");
+		}
 		html_txt(info->author);
 		html("</td><td colspan='2'>");
 		cgit_print_age(info->commit->date, -1, NULL);
@@ -154,6 +159,11 @@ static int print_tag(struct refinfo *ref)
 		cgit_object_link(obj);
 	html("</td><td>");
 	if (info) {
+		if (ctx.cfg.enable_gravatar && info->tagger_gravatar) {
+			html("<img src='");
+			html(info->tagger_gravatar);
+			html("' width=16 height=16 alt='Gravatar' \\>");
+		}
 		if (info->tagger)
 			html(info->tagger);
 	} else if (ref->object->type == OBJ_COMMIT) {
diff --git a/ui-tag.c b/ui-tag.c
index aea7958..ad402da 100644
--- a/ui-tag.c
+++ b/ui-tag.c
@@ -77,6 +77,11 @@ void cgit_print_tag(char *revname)
 		}
 		if (info->tagger) {
 			html("<tr><td>tagged by</td><td>");
+			if (ctx.cfg.enable_gravatar && info->tagger_gravatar) {
+				html("<img src='");
+				html(info->tagger_gravatar);
+				html("' width=16 height=16 alt='Gravatar' \\>");
+			}
 			html_txt(info->tagger);
 			if (info->tagger_email && !ctx.cfg.noplainemail) {
 				html(" ");
-- 
1.8.4.2



^ permalink raw reply	[flat|nested] 42+ messages in thread

end of thread, other threads:[~2014-01-14 18:00 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-08 14:34 Welcome on board Lukas Fleischer Jason
2014-01-08 14:53 ` [RESEND PATCH 1/1] enable cgit to show gravatar for author, committer and tagger mail
2014-01-08 15:12   ` Jason
2014-01-08 15:23     ` [PATCH " mail
2014-01-08 15:56       ` Jason
2014-01-09  8:52         ` mail
2014-01-09 15:13           ` Jason
2014-01-08 16:00       ` Jason
2014-01-09  9:13         ` mail
2014-01-08 15:36     ` [RESEND PATCH " mathstuf
2014-01-08 17:15     ` normalperson
2014-01-08 17:29       ` Jason
2014-01-08 18:35         ` stefan
2014-01-09  9:18         ` list
2014-01-09 15:19           ` Jason
2014-01-13 14:18             ` list
2014-01-13 14:24               ` Jason
2014-01-14 17:22                 ` list
2014-01-14 17:23                   ` Jason
2014-01-14 17:35                     ` list
2014-01-14 17:45                       ` 
2014-01-14 17:51                       ` Jason
2014-01-14 17:58                         ` list
2014-01-14 18:00                           ` Jason
2014-01-09 15:21         ` RFE: author/committer/tagger links (enable cgit to show gravatar for author, committer and tagger) mricon
2014-01-09 17:50           ` Jason
2014-01-09 18:07             ` john
2014-01-09 18:59               ` Jason
2014-01-09 19:23                 ` john
2014-01-09 19:34                   ` cgit
2014-01-09 19:38 ` Welcome on board Lukas Fleischer info
  -- strict thread matches above, loose matches on Subject: below --
2013-11-27 15:17 [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger mail
2013-11-27 16:17 ` list
2013-11-27 16:37 ` john
2013-11-27 20:51   ` list
2013-11-27 21:00     ` john
2013-11-27 16:46 ` lekensteyn
2013-11-27 20:59   ` list
2013-11-27 21:14     ` mail
2013-11-27 22:11       ` lekensteyn
2013-11-27 22:59         ` list
2013-11-27 23:00           ` mail

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).