[PATCH 1/1] enable cgit to show gravatar for author, committer and tagger
Christian Hesse
mail at eworm.de
Thu Nov 28 00:00:03 CET 2013
---
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
More information about the CGit
mailing list