all repos — cgit @ 8efb05f98ad389d1b7f5aac17838401908622dad

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