[prev in list] [next in list] [prev in thread] [next in thread] 

List:       cgit
Subject:    Fwd: Some commits wrt atom feed
From:       Andreas Zwinkau <qznc () web ! de>
Date:       2014-06-30 7:53:14
Message-ID: CAOqBtcfPb5HvniPqxUxe7+r-E7JQCTY110gNziK2C8gEWOj4zw () mail ! gmail ! com
[Download RAW message or body]

Ok, documentation included. Clean up patchset attached. There is no
one big commit for the atom-diff feature. Is that right?

Also, I set default to off, so it should be completely backwards
compatible. (Sometimes diffs get very big and not all feed readers can
deal with that)

The patchset is also available on Github on my patchset branch:
https://github.com/qznc/cgit/compare/omaster...patchset

On Sat, Jun 28, 2014 at 4:04 PM, Jason A. Donenfeld <Jason@zx2c4.com> wrote:
> This looks good, but the new option needs documentation in cgitrc.5.txt.
> Would you make this change, and then submit a cleaned up patchset to the
> list?

-- 
Andreas Zwinkau

work email: zwinkau@kit.edu
private email: qznc@web.de
homepage: http://beza1e1.tuxen.de

["0001-Can-add-diffs-to-Atom-feed-entries.patch" (text/x-patch)]

From a4077c26cf7974ecc9955b24120f8b240a904962 Mon Sep 17 00:00:00 2001
From: Andreas Zwinkau <zwinkau@kit.edu>
Date: Fri, 25 Feb 2011 13:20:26 +0100
Subject: [PATCH 1/8] Can add diffs to Atom feed entries

Off by default. Set enable-atom-diff flag for repos to enable.

Uses HTML5's "scoped CSS" feature to colorize diff deletes and inserts.
Mainstream pre-HTML5 engines either ignore this or apply the style
document-wide, which should not break anything.

As cgit was not prepared to produce multiple diffs per run,
so this also reset some counters during the diff. Additionally,
the cgit_self_link had to be extended, as it is called during
the diffing.
---
 cgit.c              |  7 +++++++
 cgit.h              |  2 ++
 cgitrc.5.txt        |  4 ++++
 cmd.c               |  2 +-
 shared.c            |  1 +
 tests/t0112-atom.sh | 24 ++++++++++++++++++++++++
 ui-atom.c           | 22 +++++++++++++++++++---
 ui-atom.h           |  2 +-
 ui-diff.c           |  4 ++++
 ui-shared.c         |  4 ++++
 10 files changed, 67 insertions(+), 5 deletions(-)
 create mode 100755 tests/t0112-atom.sh

diff --git a/cgit.c b/cgit.c
index f488ebf..0b5d9e1 100644
--- a/cgit.c
+++ b/cgit.c
@@ -45,6 +45,8 @@ static void repo_config(struct cgit_repo *repo, const char *name, const char *va
 		repo->defbranch = xstrdup(value);
 	else if (!strcmp(name, "snapshots"))
 		repo->snapshots = ctx.cfg.snapshots & cgit_parse_snapshots_mask(value);
+	else if (!strcmp(name, "enable-atom-diff"))
+		repo->enable_atom_diff = atoi(value);
 	else if (!strcmp(name, "enable-commit-graph"))
 		repo->enable_commit_graph = atoi(value);
 	else if (!strcmp(name, "enable-log-filecount"))
@@ -144,6 +146,8 @@ static void config_cb(const char *name, const char *value)
 		ctx.cfg.noheader = atoi(value);
 	else if (!strcmp(name, "snapshots"))
 		ctx.cfg.snapshots = cgit_parse_snapshots_mask(value);
+	else if (!strcmp(name, "enable-atom-diff"))
+		ctx.cfg.enable_atom_diff = atoi(value);
 	else if (!strcmp(name, "enable-filter-overrides"))
 		ctx.cfg.enable_filter_overrides = atoi(value);
 	else if (!strcmp(name, "enable-http-clone"))
@@ -346,6 +350,7 @@ static void prepare_context(void)
 	ctx.cfg.logo = "/cgit.png";
 	ctx.cfg.favicon = "/favicon.ico";
 	ctx.cfg.local_time = 0;
+	ctx.cfg.enable_atom_diff = 0;
 	ctx.cfg.enable_http_clone = 1;
 	ctx.cfg.enable_index_owner = 1;
 	ctx.cfg.enable_tree_linenumbers = 1;
@@ -788,6 +793,8 @@ static void print_repo(FILE *f, struct cgit_repo *repo)
 		fprintf(f, "repo.section=%s\n", repo->section);
 	if (repo->clone_url)
 		fprintf(f, "repo.clone-url=%s\n", repo->clone_url);
+	fprintf(f, "repo.enable-atom-diff=%d\n",
+		repo->enable_atom_diff);
 	fprintf(f, "repo.enable-commit-graph=%d\n",
 	        repo->enable_commit_graph);
 	fprintf(f, "repo.enable-log-filecount=%d\n",
diff --git a/cgit.h b/cgit.h
index 0badc64..3db220e 100644
--- a/cgit.h
+++ b/cgit.h
@@ -87,6 +87,7 @@ struct cgit_repo {
 	char *logo;
 	char *logo_link;
 	int snapshots;
+	int enable_atom_diff;
 	int enable_commit_graph;
 	int enable_log_filecount;
 	int enable_log_linecount;
@@ -213,6 +214,7 @@ struct cgit_config {
 	int cache_snapshot_ttl;
 	int case_sensitive_sort;
 	int embedded;
+	int enable_atom_diff;
 	int enable_filter_overrides;
 	int enable_http_clone;
 	int enable_index_links;
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index b7570db..b729294 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -141,6 +141,10 @@ embedded::
 	suitable for embedding in other html pages. Default value: none. See
 	also: "noheader".
 
+enable-atom-diff::
+	Flag which, when set to "1", will make cgit include a html-escaped diff
+	within the atom feed commit entries. Default value: "0".
+
 enable-commit-graph::
 	Flag which, when set to "1", will make cgit print an ASCII-art commit
 	history graph to the left of the commit messages in the repository
diff --git a/cmd.c b/cmd.c
index 188cd56..3d9f245 100644
--- a/cmd.c
+++ b/cmd.c
@@ -33,7 +33,7 @@ static void HEAD_fn(void)
 
 static void atom_fn(void)
 {
-	cgit_print_atom(ctx.qry.head, ctx.qry.path, ctx.cfg.max_atom_items);
+	cgit_print_atom(ctx.qry.head, ctx.qry.path, ctx.cfg.max_atom_items, ctx.repo->enable_atom_diff);
 }
 
 static void about_fn(void)
diff --git a/shared.c b/shared.c
index 8ed14c0..6bd82f9 100644
--- a/shared.c
+++ b/shared.c
@@ -57,6 +57,7 @@ struct cgit_repo *cgit_add_repo(const char *url)
 	ret->owner = NULL;
 	ret->section = ctx.cfg.section;
 	ret->snapshots = ctx.cfg.snapshots;
+	ret->enable_atom_diff = ctx.cfg.enable_atom_diff;
 	ret->enable_commit_graph = ctx.cfg.enable_commit_graph;
 	ret->enable_log_filecount = ctx.cfg.enable_log_filecount;
 	ret->enable_log_linecount = ctx.cfg.enable_log_linecount;
diff --git a/tests/t0112-atom.sh b/tests/t0112-atom.sh
new file mode 100755
index 0000000..8b5bbce
--- /dev/null
+++ b/tests/t0112-atom.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+test_description='Check content on atom feed'
+. ./setup.sh
+
+test_expect_success 'fetch feed' 'cgit_url "foo/atom/" >tmp'
+
+test_expect_success 'find feed open tag' 'grep -e "^<feed xmlns=.http://www\.w3\.org/2005/Atom.>" tmp'
+
+test_expect_success 'find title' 'grep -e "^<title>foo" tmp'
+
+test_expect_success 'find entry title' 'grep -e "^<title>commit 5</title>" tmp'
+
+test_expect_success 'find entry diffstat' 'grep -e "^<div class=.diffstat-header.>" tmp'
+
+test_expect_success 'find entry diff' 'grep -e "<table summary=.diff. class=.diff.>" tmp'
+
+test_expect_success 'find diff content 1' 'grep -e "diff --git a/file-1 b/file-1" tmp'
+
+test_expect_success 'find diff content 2' 'grep -e "@@ -0,0 +1 @@" tmp'
+
+test_expect_success 'find diff content 3' 'grep -e "+1<" tmp'
+
+test_done
diff --git a/ui-atom.c b/ui-atom.c
index b22d745..6a6a98b 100644
--- a/ui-atom.c
+++ b/ui-atom.c
@@ -10,16 +10,23 @@
 #include "ui-atom.h"
 #include "html.h"
 #include "ui-shared.h"
+#include "ui-diff.h"
 
-static void add_entry(struct commit *commit, const char *host)
+static void add_entry(struct commit *commit, const char *host, int enable_atom_diff)
 {
 	char delim = '&';
 	char *hex;
+	char *hex_parent;
 	char *mail, *t, *t2;
 	struct commitinfo *info;
 
 	info = cgit_parse_commit(commit);
 	hex = sha1_to_hex(commit->object.sha1);
+	if (commit->parents) {
+		hex_parent = sha1_to_hex(commit->parents->item->object.sha1);
+	} else {
+		hex_parent = NULL; /* means before initial commit */
+	}
 	html("<entry>\n");
 	html("<title>");
 	html_txt(info->subject);
@@ -71,6 +78,15 @@ static void add_entry(struct commit *commit, const char *host)
 	html("<pre>\n");
 	html_txt(info->msg);
 	html("</pre>\n");
+	if (enable_atom_diff) {
+		html("<pre class='diff'>\n");
+		html("<style scoped=\"scoped\">\n"); /* HTML5 with graceful degradation */
+		html("table.diff .add, span.add { background-color: #afa; }");
+		html("table.diff .del, span.remove { background-color: #faa; }");
+		html("</style>\n");
+		cgit_print_diff(hex, hex_parent, NULL, 0, 0);
+		html("</pre>");
+	}
 	html("</div>\n");
 	html("</content>\n");
 	html("</entry>\n");
@@ -78,7 +94,7 @@ static void add_entry(struct commit *commit, const char *host)
 }
 
 
-void cgit_print_atom(char *tip, char *path, int max_count)
+void cgit_print_atom(char *tip, char *path, int max_count, int enable_atom_diff)
 {
 	const char *host;
 	const char *argv[] = {NULL, tip, NULL, NULL, NULL};
@@ -132,7 +148,7 @@ void cgit_print_atom(char *tip, char *path, int max_count)
 		html("'/>\n");
 	}
 	while ((commit = get_revision(&rev)) != NULL) {
-		add_entry(commit, host);
+		add_entry(commit, host, enable_atom_diff);
 		free(commit->buffer);
 		commit->buffer = NULL;
 		free_commit_list(commit->parents);
diff --git a/ui-atom.h b/ui-atom.h
index 749ffd3..e0043f1 100644
--- a/ui-atom.h
+++ b/ui-atom.h
@@ -1,6 +1,6 @@
 #ifndef UI_ATOM_H
 #define UI_ATOM_H
 
-extern void cgit_print_atom(char *tip, char *path, int max_count);
+extern void cgit_print_atom(char *tip, char *path, int max_count, int enable_atom_diff);
 
 #endif
diff --git a/ui-diff.c b/ui-diff.c
index 71273aa..eeeeb80 100644
--- a/ui-diff.c
+++ b/ui-diff.c
@@ -363,6 +363,10 @@ void cgit_print_diff(const char *new_rev, const char *old_rev,
 	struct commit *commit, *commit2;
 	const unsigned char *old_tree_sha1, *new_tree_sha1;
 
+	/* reset global data */
+	files = 0;
+	slots = total_adds = total_rems = 0;
+
 	if (!new_rev)
 		new_rev = ctx.qry.head;
 	if (get_sha1(new_rev, new_rev_sha1)) {
diff --git a/ui-shared.c b/ui-shared.c
index 1ede2b0..6bdb52e 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -483,6 +483,10 @@ static void cgit_self_link(char *name, const char *title, const char *class)
 	else if (!strcmp(ctx.qry.page, "stats"))
 		cgit_stats_link(name, title, class, ctx.qry.head,
 				ctx.qry.path);
+	else if (!strcmp(ctx.qry.page, "atom"))
+		return cgit_diff_link(name, title, class, ctx.qry.head,
+				      ctx.qry.sha1, ctx.qry.sha2,
+				      ctx.qry.path, 0);
 	else {
 		/* Don't known how to make link for this page */
 		repolink(title, class, ctx.qry.page, ctx.qry.head, ctx.qry.path);
-- 
1.9.1


["0002-Improved-readability.patch" (text/x-patch)]

From 4e69978c28f767645784a87a1fef7ea5792ff025 Mon Sep 17 00:00:00 2001
From: Sebastian Buchwald <Sebastian.Buchwald@kit.edu>
Date: Tue, 10 Jan 2012 10:54:15 +0100
Subject: [PATCH 2/8] Improved readability.

---
 html.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/html.c b/html.c
index f0ee2d6..91047ad 100644
--- a/html.c
+++ b/html.c
@@ -193,7 +193,7 @@ void html_attr(const char *txt)
 			else if (c == '<')
 				html("&lt;");
 			else if (c == '\'')
-				html("&#x27;");
+				html("&apos;");
 			else if (c == '"')
 				html("&quot;");
 			else if (c == '&')
-- 
1.9.1


["0003-Skip-forbidden-characters.patch" (text/x-patch)]

From 3ca2c216de21b6aaf72a3e1825e58a0fb3aca879 Mon Sep 17 00:00:00 2001
From: Sebastian Buchwald <Sebastian.Buchwald@kit.edu>
Date: Wed, 11 Jan 2012 07:19:40 +0100
Subject: [PATCH 3/8] Skip forbidden characters.

---
 html.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/html.c b/html.c
index 91047ad..6037eec 100644
--- a/html.c
+++ b/html.c
@@ -129,7 +129,8 @@ void html_txt(const char *txt)
 	const char *t = txt;
 	while (t && *t) {
 		int c = *t;
-		if (c == '<' || c == '>' || c == '&') {
+		if ((c < 0x20 && c != '\t' && c != '\n' && c != '\r')
+				|| (c == '<' || c == '>' || c == '&')) {
 			html_raw(txt, t - txt);
 			if (c == '>')
 				html("&gt;");
@@ -150,7 +151,8 @@ void html_ntxt(int len, const char *txt)
 	const char *t = txt;
 	while (t && *t && len--) {
 		int c = *t;
-		if (c == '<' || c == '>' || c == '&') {
+		if ((c < 0x20 && c != '\t' && c != '\n' && c != '\r')
+				|| (c == '<' || c == '>' || c == '&')) {
 			html_raw(txt, t - txt);
 			if (c == '>')
 				html("&gt;");
@@ -186,7 +188,8 @@ void html_attr(const char *txt)
 	const char *t = txt;
 	while (t && *t) {
 		int c = *t;
-		if (c == '<' || c == '>' || c == '\'' || c == '\"' || c == '&') {
+		if (c == '<' || c == '>' || c == '\'' || c == '\"' || c == '&'
+				|| (c < 0x20 && c != '\t' && c != '\n' && c != '\r')) {
 			html_raw(txt, t - txt);
 			if (c == '>')
 				html("&gt;");
-- 
1.9.1


["0004-add-xml-header-to-atom-feed.patch" (text/x-patch)]

From 4403c125972dfd039788c4d40ad0a1a215766d56 Mon Sep 17 00:00:00 2001
From: Matthias Braun <matze@braunis.de>
Date: Mon, 18 Apr 2011 14:04:10 +0200
Subject: [PATCH 4/8] add xml-header to atom-feed

---
 ui-atom.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/ui-atom.c b/ui-atom.c
index 6a6a98b..fdc5cb3 100644
--- a/ui-atom.c
+++ b/ui-atom.c
@@ -125,6 +125,7 @@ void cgit_print_atom(char *tip, char *path, int max_count, int enable_atom_diff)
 	ctx.page.mimetype = "text/xml";
 	ctx.page.charset = "utf-8";
 	cgit_print_http_headers();
+	html("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
 	html("<feed xmlns='http://www.w3.org/2005/Atom'>\n");
 	html("<title>");
 	html_txt(ctx.repo->name);
-- 
1.9.1


["0005-display-updated-use-urn-url-for-atom-id.patch" (text/x-patch)]

From 811472df9888975b2ebe979bd45e2602814bd3b5 Mon Sep 17 00:00:00 2001
From: Matthias Braun <matze@braunis.de>
Date: Mon, 18 Apr 2011 15:31:38 +0200
Subject: [PATCH 5/8] display updated, use urn/url for atom:id

---
 ui-atom.c | 33 +++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/ui-atom.c b/ui-atom.c
index fdc5cb3..aa6a188 100644
--- a/ui-atom.c
+++ b/ui-atom.c
@@ -12,15 +12,13 @@
 #include "ui-shared.h"
 #include "ui-diff.h"
 
-static void add_entry(struct commit *commit, const char *host, int enable_atom_diff)
+static void add_entry(struct commit *commit, struct commitinfo *info, char *host, int enable_atom_diff)
 {
 	char delim = '&';
 	char *hex;
 	char *hex_parent;
 	char *mail, *t, *t2;
-	struct commitinfo *info;
 
-	info = cgit_parse_commit(commit);
 	hex = sha1_to_hex(commit->object.sha1);
 	if (commit->parents) {
 		hex_parent = sha1_to_hex(commit->parents->item->object.sha1);
@@ -68,8 +66,15 @@ static void add_entry(struct commit *commit, const char *host, int enable_atom_d
 			delim = '?';
 		htmlf("%cid=%s", delim, hex);
 		html("'/>\n");
+
+		html("<id>");
+		html(cgit_httpscheme());
+		html_attr(host);
+		html_attr(cgit_repourl(ctx.repo->url));
+		htmlf("/commit/?id=%s</id>\n", hex);
+	} else {
+		htmlf("<id>urn:tag:%s</id>\n", hex);
 	}
-	htmlf("<id>%s</id>\n", hex);
 	html("<content type='text'>\n");
 	html_txt(info->msg);
 	html("</content>\n");
@@ -90,7 +95,6 @@ static void add_entry(struct commit *commit, const char *host, int enable_atom_d
 	html("</div>\n");
 	html("</content>\n");
 	html("</entry>\n");
-	cgit_free_commitinfo(info);
 }
 
 
@@ -101,6 +105,7 @@ void cgit_print_atom(char *tip, char *path, int max_count, int enable_atom_diff)
 	struct commit *commit;
 	struct rev_info rev;
 	int argc = 2;
+	int had_global_updated = 0;
 
 	if (ctx.qry.show_all)
 		argv[1] = "--all";
@@ -147,9 +152,25 @@ void cgit_print_atom(char *tip, char *path, int max_count, int enable_atom_diff)
 		html_attr(host);
 		html_attr(cgit_repourl(ctx.repo->url));
 		html("'/>\n");
+
+		html("<id>");
+		html(cgit_httpscheme());
+		html_txt(host);
+		html_txt(cgit_repourl(ctx.repo->url));
+		html("</id>\n");
 	}
+
 	while ((commit = get_revision(&rev)) != NULL) {
-		add_entry(commit, host, enable_atom_diff);
+		struct commitinfo *info = cgit_parse_commit(commit);
+		if (!had_global_updated) {
+			html("<updated>");
+			cgit_print_date(info->committer_date, FMT_ATOMDATE, 0);
+			html("</updated>\n");
+			had_global_updated = 1;
+		}
+		add_entry(commit, info, host, enable_atom_diff);
+
+		cgit_free_commitinfo(info);
 		free(commit->buffer);
 		commit->buffer = NULL;
 		free_commit_list(commit->parents);
-- 
1.9.1


["0006-only-one-content-tag-allowed-so-remove-the-text-one.patch" (text/x-patch)]

From f02c869d1e4c9e501be76b1dcf8eb23c83e536df Mon Sep 17 00:00:00 2001
From: Matthias Braun <matze@braunis.de>
Date: Mon, 18 Apr 2011 15:32:05 +0200
Subject: [PATCH 6/8] only one content tag allowed, so remove the text one

---
 ui-atom.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/ui-atom.c b/ui-atom.c
index aa6a188..4d9ba00 100644
--- a/ui-atom.c
+++ b/ui-atom.c
@@ -75,9 +75,6 @@ static void add_entry(struct commit *commit, struct commitinfo *info, char *host
 	} else {
 		htmlf("<id>urn:tag:%s</id>\n", hex);
 	}
-	html("<content type='text'>\n");
-	html_txt(info->msg);
-	html("</content>\n");
 	html("<content type='xhtml'>\n");
 	html("<div xmlns='http://www.w3.org/1999/xhtml'>\n");
 	html("<pre>\n");
-- 
1.9.1


["0007-add-link-rel-self-to-atom-feed.patch" (text/x-patch)]

From 9219fb5089ad71f1dcf864c33678dc7163625c16 Mon Sep 17 00:00:00 2001
From: Matthias Braun <matze@braunis.de>
Date: Wed, 24 Apr 2013 13:42:06 +0200
Subject: [PATCH 7/8] add <link rel='self'> to atom feed

FEED Validator recommends it.
---
 ui-atom.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/ui-atom.c b/ui-atom.c
index 4d9ba00..6da3e36 100644
--- a/ui-atom.c
+++ b/ui-atom.c
@@ -150,6 +150,17 @@ void cgit_print_atom(char *tip, char *path, int max_count, int enable_atom_diff)
 		html_attr(cgit_repourl(ctx.repo->url));
 		html("'/>\n");
 
+		html("<link rel='self' type='application/atom+xml' href='");
+		html(cgit_httpscheme());
+		html_attr(host);
+		html_attr(cgit_repourl(ctx.repo->url));
+		html("atom");
+		if (tip) {
+			html("/?h=");
+			html_txt(tip);
+		}
+		html("'/>\n");
+
 		html("<id>");
 		html(cgit_httpscheme());
 		html_txt(host);
-- 
1.9.1


["0008-fix-html-error-in-diff-output-for-binary-files.patch" (text/x-patch)]

From ecdcde1c26d0c7e7a655d792ee610a3aca0259c6 Mon Sep 17 00:00:00 2001
From: Matthias Braun <matze@braunis.de>
Date: Wed, 24 Apr 2013 13:42:39 +0200
Subject: [PATCH 8/8] fix html error in diff output for binary files

---
 ui-diff.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/ui-diff.c b/ui-diff.c
index eeeeb80..b7bf777 100644
--- a/ui-diff.c
+++ b/ui-diff.c
@@ -108,6 +108,7 @@ static void print_fileinfo(struct fileinfo *info)
 	if (info->binary) {
 		htmlf("bin</td><td class='graph'>%ld -> %ld bytes",
 		      info->old_size, info->new_size);
+		html("</td></tr>\n");
 		return;
 	}
 	htmlf("%d", info->added + info->removed);
-- 
1.9.1



_______________________________________________
CGit mailing list
CGit@lists.zx2c4.com
http://lists.zx2c4.com/mailman/listinfo/cgit


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic