stagit

add atom feed support + some fixes

Hiltjo Posthuma contact@arjunchoudhary.com

commit: a09d3fd parent: 2596f93
1 files changed, 115 insertions(+), 40 deletions(-)
Murmoms.c+115-40
M · urmoms.c +115, -40
  1@@ -22,10 +22,10 @@ static int hasreadme, haslicense;
  2 int
  3 writeheader(FILE *fp)
  4 {
  5-	fprintf(fp, "<!DOCTYPE HTML>"
  6+	fputs("<!DOCTYPE HTML>"
  7 		"<html dir=\"ltr\" lang=\"en\"><head>"
  8 		"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />"
  9-		"<meta http-equiv=\"Content-Language\" content=\"en\" />");
 10+		"<meta http-equiv=\"Content-Language\" content=\"en\" />", fp);
 11 	fprintf(fp, "<title>%s%s%s</title>", name, description[0] ? " - " : "", description);
 12 	fprintf(fp, "<link rel=\"icon\" type=\"image/png\" href=\"%sfavicon.png\" />", relpath);
 13 	fprintf(fp, "<link rel=\"alternate\" type=\"application/atom+xml\" title=\"%s Atom Feed\" href=\"%satom.xml\" />",
 14@@ -35,13 +35,13 @@ writeheader(FILE *fp)
 15 	fprintf(fp, "<h1><img src=\"%slogo.png\" alt=\"\" /> %s</h1>", relpath, name);
 16 	fprintf(fp, "<span class=\"desc\">%s</span><br/>", description);
 17 	fprintf(fp, "<a href=\"%slog.html\">Log</a> |", relpath);
 18-	fprintf(fp, "<a href=\"%sfiles.html\">Files</a>| ", relpath);
 19+	fprintf(fp, "<a href=\"%sfiles.html\">Files</a> | ", relpath);
 20 	fprintf(fp, "<a href=\"%sstats.html\">Stats</a>", relpath);
 21 	if (hasreadme)
 22 		fprintf(fp, " | <a href=\"%sreadme.html\">README</a>", relpath);
 23 	if (haslicense)
 24 		fprintf(fp, " | <a href=\"%slicense.html\">LICENSE</a>", relpath);
 25-	fprintf(fp, "</center><hr/><pre>");
 26+	fputs("</center><hr/><pre>", fp);
 27 
 28 	return 0;
 29 }
 30@@ -49,9 +49,7 @@ writeheader(FILE *fp)
 31 int
 32 writefooter(FILE *fp)
 33 {
 34-	fprintf(fp, "</pre></body></html>");
 35-
 36-	return 0;
 37+	return !fputs("</pre></body></html>", fp);
 38 }
 39 
 40 FILE *
 41@@ -104,6 +102,32 @@ xbasename(const char *path)
 42 	return b;
 43 }
 44 
 45+void
 46+printtimez(FILE *fp, const git_time *intime)
 47+{
 48+	struct tm *intm;
 49+	time_t t;
 50+	int offset, hours, minutes;
 51+	char sign, out[32];
 52+
 53+	offset = intime->offset;
 54+	if (offset < 0) {
 55+		sign = '-';
 56+		offset = -offset;
 57+	} else {
 58+		sign = '+';
 59+	}
 60+
 61+	hours = offset / 60;
 62+	minutes = offset % 60;
 63+
 64+	t = (time_t) intime->time + (intime->offset * 60);
 65+
 66+	intm = gmtime(&t);
 67+	strftime(out, sizeof(out), "%Y-%m-%dT%H:%M:%SZ", intm);
 68+	fputs(out, fp);
 69+}
 70+
 71 void
 72 printtime(FILE *fp, const git_time *intime)
 73 {
 74@@ -328,6 +352,7 @@ writelog(FILE *fp)
 75 
 76 		/* TODO: show tag when commit has it */
 77 
 78+		/* TODO: collect stats per author and make stats.html page */
 79 		author = git_commit_author(commit);
 80 		summary = git_commit_summary(commit);
 81 
 82@@ -366,29 +391,107 @@ writelog(FILE *fp)
 83 	return 0;
 84 }
 85 
 86-#if 0
 87+void
 88+printcommitatom(FILE *fp, git_commit *commit)
 89+{
 90+	const git_signature *sig;
 91+	char buf[GIT_OID_HEXSZ + 1];
 92+	int i, count;
 93+	const char *scan, *eol, *summary;
 94+
 95+	fputs("<entry>", fp);
 96+
 97+	/* TODO: show tag when commit has it */
 98+	git_oid_tostr(buf, sizeof(buf), git_commit_id(commit));
 99+	fprintf(fp, "<id>%s</id>", buf);
100+
101+	sig = git_commit_author(commit);
102+
103+	if (sig) {
104+		fputs("<updated>", fp);
105+		printtimez(fp, &sig->when);
106+		fputs("</updated>", fp);
107+	}
108+
109+	if ((summary = git_commit_summary(commit))) {
110+		fputs("<title>", fp);
111+		xmlencode(fp, summary, strlen(summary));
112+		fputs("</title>", fp);
113+	}
114+
115+	fputs("<content type=\"text\">", fp);
116+	fprintf(fp, "commit %s\n", buf);
117+	if (git_oid_tostr(buf, sizeof(buf), git_commit_parent_id(commit, 0)))
118+		fprintf(fp, "parent %s\n", buf);
119+
120+	if ((count = (int)git_commit_parentcount(commit)) > 1) {
121+		fprintf(fp, "Merge:");
122+		for (i = 0; i < count; ++i) {
123+			git_oid_tostr(buf, 8, git_commit_parent_id(commit, i));
124+			fprintf(fp, " %s", buf);
125+		}
126+		fputc('\n', fp);
127+	}
128+
129+	if (sig) {
130+		fprintf(fp, "Author: ");
131+		xmlencode(fp, sig->name, strlen(sig->name));
132+		fprintf(fp, " &lt;");
133+		xmlencode(fp, sig->email, strlen(sig->email));
134+		fprintf(fp, "&gt;\nDate:   ");
135+		printtime(fp, &sig->when);
136+	}
137+	fputc('\n', fp);
138+
139+	for (scan = git_commit_message(commit); scan && *scan;) {
140+		for (eol = scan; *eol && *eol != '\n'; ++eol)	/* find eol */
141+			;
142+
143+		fprintf(fp, "    %.*s\n", (int) (eol - scan), scan);
144+		scan = *eol ? eol + 1 : NULL;
145+	}
146+	fputc('\n', fp);
147+	fputs("</content>", fp);
148+	if (sig) {
149+		fputs("<author><name>", fp);
150+		xmlencode(fp, sig->name, strlen(sig->name));
151+		fputs("</name><email>", fp);
152+		xmlencode(fp, sig->email, strlen(sig->email));
153+		fputs("</email></author>", fp);
154+	}
155+	fputs("</entry>", fp);
156+}
157+
158 int
159 writeatom(FILE *fp)
160 {
161 	git_revwalk *w = NULL;
162 	git_oid id;
163 	git_commit *c = NULL;
164+	size_t i, m = 100; /* max */
165+
166+	fputs("<feed xmlns=\"http://www.w3.org/2005/Atom\"><title>", fp);
167+	xmlencode(fp, name, strlen(name));
168+	fputs(", branch master</title><subtitle>", fp);
169+
170+	xmlencode(fp, description, strlen(description));
171+	fputs("</subtitle>", fp);
172 
173 	git_revwalk_new(&w, repo);
174 	git_revwalk_push_head(w);
175 
176-	while (!git_revwalk_next(&id, w)) {
177+	for (i = 0; i < m && !git_revwalk_next(&id, w); i++) {
178 		if (git_commit_lookup(&c, repo, &id))
179 			return 1; /* TODO: error */
180-		printcommit(fp, c);
181-		printshowfile(c);
182+		printcommitatom(fp, c);
183 		git_commit_free(c);
184 	}
185 	git_revwalk_free(w);
186 
187+	fputs("</feed>", fp);
188+
189 	return 0;
190 }
191-#endif
192 
193 int
194 writefiles(FILE *fp)
195@@ -409,32 +512,6 @@ writefiles(FILE *fp)
196 	return 0;
197 }
198 
199-#if 0
200-int
201-writebranches(FILE *fp)
202-{
203-	git_branch_iterator *branchit = NULL;
204-	git_branch_t branchtype;
205-	git_reference *branchref;
206-	char branchbuf[BUFSIZ] = "";
207-	int status;
208-
209-	git_branch_iterator_new(&branchit, repo, GIT_BRANCH_LOCAL);
210-
211-	while ((status = git_branch_next(&branchref, &branchtype, branchit)) == GIT_ITEROVER) {
212-		git_reference_normalize_name(branchbuf, sizeof(branchbuf),
213-			git_reference_name(branchref),
214-			GIT_REF_FORMAT_ALLOW_ONELEVEL | GIT_REF_FORMAT_REFSPEC_SHORTHAND);
215-
216-		/* fprintf(fp, "branch: |%s|\n", branchbuf); */
217-	}
218-
219-	git_branch_iterator_free(branchit);
220-
221-	return 0;
222-}
223-#endif
224-
225 void
226 writeblobhtml(FILE *fp, const git_blob *blob)
227 {
228@@ -516,11 +593,9 @@ main(int argc, char *argv[])
229 	writefooter(fp);
230 	fclose(fp);
231 
232-#if 0
233 	fp = efopen("atom.xml", "w+b");
234 	writeatom(fp);
235 	fclose(fp);
236-#endif
237 
238 	fp = efopen("files.html", "w+b");
239 	writeheader(fp);