Diffstat (limited to 'ui-summary.c')
| -rw-r--r-- | ui-summary.c | 287 |
1 files changed, 177 insertions, 110 deletions
diff --git a/ui-summary.c b/ui-summary.c index 947812a..3d5eda8 100644 --- a/ui-summary.c +++ b/ui-summary.c @@ -1,148 +1,215 @@ /* ui-summary.c: functions for generating repo summary page * - * Copyright (C) 2006-2014 cgit Development Team <cgit@lists.zx2c4.com> + * Copyright (C) 2006 Lars Hjemli * * Licensed under GNU General Public License v2 * (see COPYING for full license text) */ #include "cgit.h" -#include "ui-summary.h" -#include "html.h" -#include "ui-blob.h" -#include "ui-log.h" -#include "ui-plain.h" -#include "ui-refs.h" -#include "ui-shared.h" -static int urls; +static int header; -static void print_url(const char *url) +static int cmp_tag_age(void *a, void *b) { - int columns = 3; + struct refinfo *r1 = *(struct refinfo **)a; + struct refinfo *r2 = *(struct refinfo **)b; - if (ctx.repo->enable_log_filecount) - columns++; - if (ctx.repo->enable_log_linecount) - columns++; + if (r1->tag->tagger_date != 0 && r2->tag->tagger_date != 0) + return r2->tag->tagger_date - r1->tag->tagger_date; - if (urls++ == 0) { - htmlf("<tr class='nohover'><td colspan='%d'> </td></tr>", columns); - htmlf("<tr class='nohover'><th class='left' colspan='%d'>Clone</th></tr>\n", columns); - } + if (r1->tag->tagger_date == 0 && r2->tag->tagger_date == 0) + return 0; + + if (r1 == 0) + return +1; - htmlf("<tr><td colspan='%d'><a rel='vcs-git' href='", columns); - html_url_path(url); - html("' title='"); - html_attr(ctx.repo->name); - html(" Git repository'>"); - html_txt(url); - html("</a></td></tr>\n"); + return -1; } -void cgit_print_summary(void) +static void cgit_print_branch(struct refinfo *ref) { - int columns = 3; - - if (ctx.repo->enable_log_filecount) - columns++; - if (ctx.repo->enable_log_linecount) - columns++; + struct commit *commit; + struct commitinfo *info; + char *name = (char *)ref->refname; - cgit_print_layout_start(); - html("<table summary='repository info' class='list nowrap'>"); - cgit_print_branches(ctx.cfg.summary_branches); - htmlf("<tr class='nohover'><td colspan='%d'> </td></tr>", columns); - cgit_print_tags(ctx.cfg.summary_tags); - if (ctx.cfg.summary_log > 0) { - htmlf("<tr class='nohover'><td colspan='%d'> </td></tr>", columns); - cgit_print_log(ctx.qry.head, 0, ctx.cfg.summary_log, NULL, - NULL, NULL, 0, 0, 0); + commit = lookup_commit(ref->object->sha1); + // object is not really parsed at this point, because of some fallout + // from previous calls to git functions in cgit_print_log() + commit->object.parsed = 0; + if (commit && !parse_commit(commit)){ + info = cgit_parse_commit(commit); + html("<tr><td>"); + cgit_log_link(name, NULL, NULL, name, NULL, NULL, 0); + html("</td><td>"); + cgit_print_age(commit->date, -1, NULL); + html("</td><td>"); + html_txt(info->author); + html("</td><td>"); + cgit_commit_link(info->subject, NULL, NULL, name, NULL); + html("</td></tr>\n"); + cgit_free_commitinfo(info); + } else { + html("<tr><td>"); + html_txt(name); + html("</td><td colspan='3'>"); + htmlf("*** bad ref %s ***", sha1_to_hex(ref->object->sha1)); + html("</td></tr>\n"); } - urls = 0; - cgit_add_clone_urls(print_url); - html("</table>"); - cgit_print_layout_end(); } -/* The caller must free the return value. */ -static char* append_readme_path(const char *filename, const char *ref, const char *path) +static void print_tag_header() { - char *file, *base_dir, *full_path, *resolved_base = NULL, *resolved_full = NULL; - /* If a subpath is specified for the about page, make it relative - * to the directory containing the configured readme. */ + html("<tr class='nohover'><th class='left'>Tag</th>" + "<th class='left'>Age</th>" + "<th class='left'>Author</th>" + "<th class='left'>Reference</th></tr>\n"); + header = 1; +} - file = xstrdup(filename); - base_dir = dirname(file); - if (!strcmp(base_dir, ".") || !strcmp(base_dir, "..")) { - if (!ref) { - free(file); - return NULL; - } - full_path = xstrdup(path); - } else - full_path = fmtalloc("%s/%s", base_dir, path); +static int print_tag(struct refinfo *ref) +{ + struct tag *tag; + struct taginfo *info; + char *url, *name = (char *)ref->refname; - if (!ref) { - resolved_base = realpath(base_dir, NULL); - resolved_full = realpath(full_path, NULL); - if (!resolved_base || !resolved_full || !starts_with(resolved_full, resolved_base)) { - free(full_path); - full_path = NULL; - } + if (ref->object->type == OBJ_TAG) { + tag = lookup_tag(ref->object->sha1); + if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) + return 2; + html("<tr><td>"); + url = cgit_pageurl(cgit_query_repo, "tag", + fmt("id=%s", name)); + html_link_open(url, NULL, NULL); + html_txt(name); + html_link_close(); + html("</td><td>"); + if (info->tagger_date > 0) + cgit_print_age(info->tagger_date, -1, NULL); + html("</td><td>"); + if (info->tagger) + html(info->tagger); + html("</td><td>"); + cgit_object_link(tag->tagged); + html("</td></tr>\n"); + } else { + if (!header) + print_tag_header(); + html("<tr><td>"); + html_txt(name); + html("</td><td colspan='2'/><td>"); + cgit_object_link(ref->object); + html("</td></tr>\n"); } + return 0; +} - free(file); - free(resolved_base); - free(resolved_full); +static int cgit_print_archive_cb(const char *refname, const unsigned char *sha1, + int flags, void *cb_data) +{ + struct tag *tag; + struct taginfo *info; + struct object *obj; + char buf[256], *url; + unsigned char fileid[20]; - return full_path; + if (prefixcmp(refname, "refs/archives")) + return 0; + strncpy(buf, refname+14, sizeof(buf)); + obj = parse_object(sha1); + if (!obj) + return 1; + if (obj->type == OBJ_TAG) { + tag = lookup_tag(sha1); + if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) + return 0; + hashcpy(fileid, tag->tagged->sha1); + } else if (obj->type != OBJ_BLOB) { + return 0; + } else { + hashcpy(fileid, sha1); + } + if (!header) { + html("<table id='downloads'>"); + html("<tr><th>Downloads</th></tr>"); + header = 1; + } + html("<tr><td>"); + url = cgit_pageurl(cgit_query_repo, "blob", + fmt("id=%s&path=%s", sha1_to_hex(fileid), + buf)); + html_link_open(url, NULL, NULL); + html_txt(buf); + html_link_close(); + html("</td></tr>"); + return 0; } -void cgit_print_repo_readme(const char *path) +static void cgit_print_branches() { - char *filename, *ref, *mimetype; - int free_filename = 0; + struct reflist list; + int i; - mimetype = get_mimetype_for_filename(path); - if (mimetype && (!strncmp(mimetype, "image/", 6) || !strncmp(mimetype, "video/", 6))) { - ctx.page.mimetype = mimetype; - ctx.page.charset = NULL; - cgit_print_plain(); - free(mimetype); - return; - } - free(mimetype); + html("<tr class='nohover'><th class='left'>Branch</th>" + "<th class='left'>Idle</th>" + "<th class='left'>Author</th>" + "<th class='left'>Head commit</th></tr>\n"); - cgit_print_layout_start(); - if (ctx.repo->readme.nr == 0) - goto done; + list.refs = NULL; + list.alloc = list.count = 0; + for_each_branch_ref(cgit_refs_cb, &list); + for(i=0; i<list.count; i++) + cgit_print_branch(list.refs[i]); +} - filename = ctx.repo->readme.items[0].string; - ref = ctx.repo->readme.items[0].util; +static void cgit_print_tags(int maxcount) +{ + struct reflist list; + int i; - if (path) { - free_filename = 1; - filename = append_readme_path(filename, ref, path); - if (!filename) - goto done; - } + header = 0; + list.refs = NULL; + list.alloc = list.count = 0; + for_each_tag_ref(cgit_refs_cb, &list); + if (list.count == 0) + return; + qsort(list.refs, list.count, sizeof(*list.refs), cmp_tag_age); + if (!maxcount) + maxcount = list.count; + else if (maxcount > list.count) + maxcount = list.count; + print_tag_header(); + for(i=0; i<maxcount; i++) + print_tag(list.refs[i]); +} - /* Print the calculated readme, either from the git repo or from the - * filesystem, while applying the about-filter. - */ - html("<div id='summary'>"); - cgit_open_filter(ctx.repo->about_filter, filename); - if (ref) - cgit_print_file(filename, ref, 1); - else - html_include(filename); - cgit_close_filter(ctx.repo->about_filter); +static void cgit_print_archives() +{ + header = 0; + for_each_ref(cgit_print_archive_cb, NULL); + if (header) + html("</table>"); +} +void cgit_print_summary() +{ + html("<div id='summary'>"); + cgit_print_archives(); + html("<h2>"); + html_txt(cgit_repo->name); + html(" - "); + html_txt(cgit_repo->desc); + html("</h2>"); + if (cgit_repo->readme) + html_include(cgit_repo->readme); html("</div>"); - if (free_filename) - free(filename); - -done: - cgit_print_layout_end(); + if (cgit_summary_log > 0) + cgit_print_log(cgit_query_head, 0, cgit_summary_log, NULL, NULL, 0); + html("<table class='list nowrap'>"); + if (cgit_summary_log > 0) + html("<tr class='nohover'><td colspan='4'> </td></tr>"); + cgit_print_branches(); + html("<tr class='nohover'><td colspan='4'> </td></tr>"); + cgit_print_tags(cgit_summary_tags); + html("</table>"); } |