From mboxrd@z Thu Jan 1 00:00:00 1970 From: mail at eworm.de (Christian Hesse) Date: Wed, 8 Jan 2014 16:23:33 +0100 Subject: [PATCH 1/1] enable cgit to show gravatar for author, committer and tagger In-Reply-To: References: Message-ID: <1389194613-8660-1-git-send-email-mail@eworm.de> --- 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 + +/* 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("\n"); html("\n"); html("
author"); + if (ctx.cfg.enable_gravatar && info->author_gravatar) { + html("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("
committer"); + if (ctx.cfg.enable_gravatar && info->committer_gravatar) { + html("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(""); + if (ctx.cfg.enable_gravatar && info->author_gravatar) { + html("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(""); + if (ctx.cfg.enable_gravatar && info->author_gravatar) { + html("Gravatar "); + } html_txt(info->author); html(""); cgit_print_age(info->commit->date, -1, NULL); @@ -154,6 +159,11 @@ static int print_tag(struct refinfo *ref) cgit_object_link(obj); html(""); if (info) { + if (ctx.cfg.enable_gravatar && info->tagger_gravatar) { + html("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("
tagged by"); + if (ctx.cfg.enable_gravatar && info->tagger_gravatar) { + html("Gravatar "); + } html_txt(info->tagger); if (info->tagger_email && !ctx.cfg.noplainemail) { html(" "); -- 1.8.5.2