-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | cgit.h | 1 | ||||
-rw-r--r-- | cmd.c | 7 | ||||
-rw-r--r-- | ui-atom.c | 129 | ||||
-rw-r--r-- | ui-atom.h | 6 | ||||
-rw-r--r-- | ui-shared.c | 23 | ||||
-rw-r--r-- | ui-shared.h | 1 |
7 files changed, 168 insertions, 0 deletions
@@ -52,12 +52,13 @@ OBJECTS += cache.o OBJECTS += cgit.o OBJECTS += cmd.o OBJECTS += configfile.o OBJECTS += html.o OBJECTS += parsing.o OBJECTS += shared.o +OBJECTS += ui-atom.o OBJECTS += ui-blob.o OBJECTS += ui-commit.o OBJECTS += ui-diff.o OBJECTS += ui-log.o OBJECTS += ui-patch.o OBJECTS += ui-refs.o @@ -21,12 +21,13 @@ /* * Dateformats used on misc. pages */ #define FMT_LONGDATE "%Y-%m-%d %H:%M:%S (%Z)" #define FMT_SHORTDATE "%Y-%m-%d" +#define FMT_ATOMDATE "%Y-%m-%dT%H:%M:%SZ" /* * Limits used for relative dates */ #define TM_MIN 60 @@ -7,24 +7,30 @@ */ #include "cgit.h" #include "cmd.h" #include "cache.h" #include "ui-shared.h" +#include "ui-atom.h" #include "ui-blob.h" #include "ui-commit.h" #include "ui-diff.h" #include "ui-log.h" #include "ui-patch.h" #include "ui-refs.h" #include "ui-repolist.h" #include "ui-snapshot.h" #include "ui-summary.h" #include "ui-tag.h" #include "ui-tree.h" +static void atom_fn(struct cgit_context *ctx) +{ + cgit_print_atom(ctx->qry.head, ctx->qry.path, 10); +} + static void about_fn(struct cgit_context *ctx) { if (ctx->repo) cgit_print_repo_readme(); else cgit_print_site_readme(); @@ -99,12 +105,13 @@ static void tree_fn(struct cgit_context *ctx) #define def_cmd(name, want_repo, want_layout) \ {#name, name##_fn, want_repo, want_layout} struct cgit_cmd *cgit_get_cmd(struct cgit_context *ctx) { static struct cgit_cmd cmds[] = { + def_cmd(atom, 1, 0), def_cmd(about, 0, 1), def_cmd(blob, 1, 0), def_cmd(commit, 1, 1), def_cmd(diff, 1, 1), def_cmd(log, 1, 1), def_cmd(ls_cache, 0, 0), diff --git a/ui-atom.c b/ui-atom.c new file mode 100644 index 0000000..a6ea3ee --- a/dev/null +++ b/ui-atom.c @@ -0,0 +1,129 @@ +/* ui-atom.c: functions for atom feeds + * + * Copyright (C) 2008 Lars Hjemli + * + * Licensed under GNU General Public License v2 + * (see COPYING for full license text) + */ + +#include "cgit.h" +#include "html.h" +#include "ui-shared.h" + +void add_entry(struct commit *commit, char *host) +{ + char delim = '&'; + char *hex; + char *mail, *t, *t2; + struct commitinfo *info; + + info = cgit_parse_commit(commit); + hex = sha1_to_hex(commit->object.sha1); + html("<entry>\n"); + html("<title>"); + html_txt(info->subject); + html("</title>\n"); + html("<updated>"); + cgit_print_date(info->author_date, FMT_ATOMDATE, ctx.cfg.local_time); + html("</updated>\n"); + html("<author>\n"); + if (info->author) { + html("<name>"); + html_txt(info->author); + html("</name>\n"); + } + if (info->author_email) { + mail = xstrdup(info->author_email); + t = strchr(mail, '<'); + if (t) + t++; + else + t = mail; + t2 = strchr(t, '>'); + if (t2) + *t2 = '\0'; + html("<email>"); + html_txt(t); + html("</email>\n"); + free(mail); + } + html("</author>\n"); + html("<published>"); + cgit_print_date(info->author_date, FMT_ATOMDATE, ctx.cfg.local_time); + html("</published>\n"); + if (host) { + html("<link rel='alternate' type='text/html' href='http://"); + html_attr(host); + html_attr(cgit_pageurl(ctx.repo->url, "commit", NULL)); + if (ctx.cfg.virtual_root) + delim = '?'; + htmlf("%cid=%s", delim, hex); + html("'/>\n"); + } + htmlf("<id>%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"); + html_txt(info->msg); + html("</pre>\n"); + html("</div>\n"); + html("</content>\n"); + html("</entry>\n"); + cgit_free_commitinfo(info); +} + + +void cgit_print_atom(char *tip, char *path, int max_count) +{ + char *host; + const char *argv[] = {NULL, tip, NULL, NULL, NULL}; + struct commit *commit; + struct rev_info rev; + int argc = 2; + + if (!tip) + argv[1] = ctx.qry.head; + + if (path) { + argv[argc++] = "--"; + argv[argc++] = path; + } + + init_revisions(&rev, NULL); + rev.abbrev = DEFAULT_ABBREV; + rev.commit_format = CMIT_FMT_DEFAULT; + rev.verbose_header = 1; + rev.show_root_diff = 0; + rev.max_count = max_count; + setup_revisions(argc, argv, &rev, NULL); + prepare_revision_walk(&rev); + + host = cgit_hosturl(); + ctx.page.mimetype = "text/xml"; + ctx.page.charset = "utf-8"; + cgit_print_http_headers(&ctx); + html("<feed xmlns='http://www.w3.org/2005/Atom'>\n"); + html("<title>"); + html_txt(ctx.repo->name); + html("</title>\n"); + html("<subtitle>"); + html_txt(ctx.repo->desc); + html("</subtitle>\n"); + if (host) { + html("<link rel='alternate' type='text/html' href='http://"); + html_attr(host); + html_attr(cgit_repourl(ctx.repo->url)); + html("'/>\n"); + } + while ((commit = get_revision(&rev)) != NULL) { + add_entry(commit, host); + free(commit->buffer); + commit->buffer = NULL; + free_commit_list(commit->parents); + commit->parents = NULL; + } + html("</feed>\n"); +} diff --git a/ui-atom.h b/ui-atom.h new file mode 100644 index 0000000..749ffd3 --- a/dev/null +++ b/ui-atom.h @@ -0,0 +1,6 @@ +#ifndef UI_ATOM_H +#define UI_ATOM_H + +extern void cgit_print_atom(char *tip, char *path, int max_count); + +#endif diff --git a/ui-shared.c b/ui-shared.c index 197ee37..37c60b2 100644 --- a/ui-shared.c +++ b/ui-shared.c @@ -31,12 +31,27 @@ void cgit_print_error(char *msg) { html("<div class='error'>"); html_txt(msg); html("</div>\n"); } +char *cgit_hosturl() +{ + char *host, *port; + + host = getenv("SERVER_NAME"); + if (!host) + return NULL; + port = getenv("SERVER_PORT"); + if (port && atoi(port) != 80) + host = xstrdup(fmt("%s:%d", host, atoi(port))); + else + host = xstrdup(host); + return host; +} + char *cgit_rooturl() { if (ctx.cfg.virtual_root) return fmt("%s/", ctx.cfg.virtual_root); else return ctx.cfg.script_name; @@ -425,12 +440,13 @@ void cgit_print_http_headers(struct cgit_context *ctx) htmlf("Expires: %s\n", http_date(ctx->page.expires)); html("\n"); } void cgit_print_docstart(struct cgit_context *ctx) { + char *host = cgit_hosturl(); html(cgit_doctype); html("<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>\n"); html("<head>\n"); html("<title>"); html_txt(ctx->page.title); html("</title>\n"); @@ -442,12 +458,19 @@ void cgit_print_docstart(struct cgit_context *ctx) html("'/>\n"); if (ctx->cfg.favicon) { html("<link rel='shortcut icon' href='"); html_attr(ctx->cfg.favicon); html("'/>\n"); } + if (host && ctx->repo) { + html("<link rel='alternate' title='Atom feed' href='http://"); + html_attr(cgit_hosturl()); + html_attr(cgit_fileurl(ctx->repo->url, "atom", ctx->qry.path, + fmt("h=%s", ctx->qry.head))); + html("' type='application/atom+xml'/>"); + } html("</head>\n"); html("<body>\n"); } void cgit_print_docend() { diff --git a/ui-shared.h b/ui-shared.h index 07da4b4..f4123d3 100644 --- a/ui-shared.h +++ b/ui-shared.h @@ -1,9 +1,10 @@ #ifndef UI_SHARED_H #define UI_SHARED_H +extern char *cgit_hosturl(); extern char *cgit_repourl(const char *reponame); extern char *cgit_fileurl(const char *reponame, const char *pagename, const char *filename, const char *query); extern char *cgit_pageurl(const char *reponame, const char *pagename, const char *query); |