all repos — cgit @ f6310fec783d2721ef61815a0eec525d6a904452

a hyperfast web frontend for git written in c

ui-summary.c (view raw)

  1/* ui-summary.c: functions for generating repo summary page
  2 *
  3 * Copyright (C) 2006 Lars Hjemli
  4 *
  5 * Licensed under GNU General Public License v2
  6 *   (see COPYING for full license text)
  7 */
  8
  9#include "cgit.h"
 10
 11static int header;
 12
 13static int cmp_age(int age1, int age2)
 14{
 15	if (age1 != 0 && age2 != 0)
 16		return age2 - age1;
 17
 18	if (age1 == 0 && age2 == 0)
 19		return 0;
 20
 21	if (age1 == 0)
 22		return +1;
 23
 24	return -1;
 25}
 26
 27static int cmp_tag_age(const void *a, const void *b)
 28{
 29	struct refinfo *r1 = *(struct refinfo **)a;
 30	struct refinfo *r2 = *(struct refinfo **)b;
 31
 32	return cmp_age(r1->tag->tagger_date, r2->tag->tagger_date);
 33}
 34
 35static void cgit_print_branch(struct refinfo *ref)
 36{
 37	struct commit *commit;
 38	struct commitinfo *info;
 39	char *name = (char *)ref->refname;
 40
 41	commit = lookup_commit(ref->object->sha1);
 42	// object is not really parsed at this point, because of some fallout
 43	// from previous calls to git functions in cgit_print_log()
 44	commit->object.parsed = 0;
 45	if (commit && !parse_commit(commit)){
 46		info = cgit_parse_commit(commit);
 47		html("<tr><td>");
 48		cgit_log_link(name, NULL, NULL, name, NULL, NULL, 0);
 49		html("</td><td>");
 50		cgit_print_age(commit->date, -1, NULL);
 51		html("</td><td>");
 52		html_txt(info->author);
 53		html("</td><td>");
 54		cgit_commit_link(info->subject, NULL, NULL, name, NULL);
 55		html("</td></tr>\n");
 56		cgit_free_commitinfo(info);
 57	} else {
 58		html("<tr><td>");
 59		html_txt(name);
 60		html("</td><td colspan='3'>");
 61		htmlf("*** bad ref %s ***", sha1_to_hex(ref->object->sha1));
 62		html("</td></tr>\n");
 63	}
 64}
 65
 66static void print_tag_header()
 67{
 68	html("<tr class='nohover'><th class='left'>Tag</th>"
 69	     "<th class='left'>Age</th>"
 70	     "<th class='left'>Author</th>"
 71	     "<th class='left'>Reference</th></tr>\n");
 72	header = 1;
 73}
 74
 75static int print_tag(struct refinfo *ref)
 76{
 77	struct tag *tag;
 78	struct taginfo *info;
 79	char *url, *name = (char *)ref->refname;
 80
 81	if (ref->object->type == OBJ_TAG) {
 82		tag = lookup_tag(ref->object->sha1);
 83		if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag)))
 84			return 2;
 85		html("<tr><td>");
 86		url = cgit_pageurl(cgit_query_repo, "tag",
 87				   fmt("id=%s", name));
 88		html_link_open(url, NULL, NULL);
 89		html_txt(name);
 90		html_link_close();
 91		html("</td><td>");
 92		if (info->tagger_date > 0)
 93			cgit_print_age(info->tagger_date, -1, NULL);
 94		html("</td><td>");
 95		if (info->tagger)
 96			html(info->tagger);
 97		html("</td><td>");
 98		cgit_object_link(tag->tagged);
 99		html("</td></tr>\n");
100	} else {
101		if (!header)
102			print_tag_header();
103		html("<tr><td>");
104		html_txt(name);
105		html("</td><td colspan='2'/><td>");
106		cgit_object_link(ref->object);
107		html("</td></tr>\n");
108	}
109	return 0;
110}
111
112static int cgit_print_archive_cb(const char *refname, const unsigned char *sha1,
113				 int flags, void *cb_data)
114{
115	struct tag *tag;
116	struct taginfo *info;
117	struct object *obj;
118	char buf[256], *url;
119	unsigned char fileid[20];
120
121	if (prefixcmp(refname, "refs/archives"))
122		return 0;
123	strncpy(buf, refname+14, sizeof(buf));
124	obj = parse_object(sha1);
125	if (!obj)
126		return 1;
127	if (obj->type == OBJ_TAG) {
128		tag = lookup_tag(sha1);
129		if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag)))
130			return 0;
131		hashcpy(fileid, tag->tagged->sha1);
132	} else if (obj->type != OBJ_BLOB) {
133		return 0;
134	} else {
135		hashcpy(fileid, sha1);
136	}
137	if (!header) {
138		html("<table id='downloads'>");
139		html("<tr><th>Downloads</th></tr>");
140		header = 1;
141	}
142	html("<tr><td>");
143	url = cgit_pageurl(cgit_query_repo, "blob",
144			   fmt("id=%s&amp;path=%s", sha1_to_hex(fileid),
145			       buf));
146	html_link_open(url, NULL, NULL);
147	html_txt(buf);
148	html_link_close();
149	html("</td></tr>");
150	return 0;
151}
152
153static void cgit_print_branches()
154{
155	struct reflist list;
156	int i;
157
158	html("<tr class='nohover'><th class='left'>Branch</th>"
159	     "<th class='left'>Idle</th>"
160	     "<th class='left'>Author</th>"
161	     "<th class='left'>Head commit</th></tr>\n");
162
163	list.refs = NULL;
164	list.alloc = list.count = 0;
165	for_each_branch_ref(cgit_refs_cb, &list);
166	for(i=0; i<list.count; i++)
167		cgit_print_branch(list.refs[i]);
168}
169
170static void cgit_print_tags(int maxcount)
171{
172	struct reflist list;
173	int i;
174
175	header = 0;
176	list.refs = NULL;
177	list.alloc = list.count = 0;
178	for_each_tag_ref(cgit_refs_cb, &list);
179	if (list.count == 0)
180		return;
181	qsort(list.refs, list.count, sizeof(*list.refs), cmp_tag_age);
182	if (!maxcount)
183		maxcount = list.count;
184	else if (maxcount > list.count)
185		maxcount = list.count;
186	print_tag_header();
187	for(i=0; i<maxcount; i++)
188		print_tag(list.refs[i]);
189}
190
191static void cgit_print_archives()
192{
193	header = 0;
194	for_each_ref(cgit_print_archive_cb, NULL);
195	if (header)
196		html("</table>");
197}
198
199void cgit_print_summary()
200{
201	html("<div id='summary'>");
202	cgit_print_archives();
203	html("<h2>");
204	html_txt(cgit_repo->name);
205	html(" - ");
206	html_txt(cgit_repo->desc);
207	html("</h2>");
208	if (cgit_repo->readme)
209		html_include(cgit_repo->readme);
210	html("</div>");
211	if (cgit_summary_log > 0)
212		cgit_print_log(cgit_query_head, 0, cgit_summary_log, NULL, NULL, 0);
213	html("<table class='list nowrap'>");
214	if (cgit_summary_log > 0)
215		html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>");
216	cgit_print_branches();
217	html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>");
218	cgit_print_tags(cgit_summary_tags);
219	html("</table>");
220}