-rw-r--r-- | ui-shared.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/ui-shared.c b/ui-shared.c index 45105dc..1418010 100644 --- a/ui-shared.c +++ b/ui-shared.c @@ -83,362 +83,365 @@ char *cgit_pageurl(const char *reponame, const char *pagename, const char *cgit_repobasename(const char *reponame) { /* I assume we don't need to store more than one repo basename */ static char rvbuf[1024]; int p; const char *rv; strncpy(rvbuf,reponame,sizeof(rvbuf)); if(rvbuf[sizeof(rvbuf)-1]) die("cgit_repobasename: truncated repository name '%s'", reponame); p = strlen(rvbuf)-1; /* strip trailing slashes */ while(p && rvbuf[p]=='/') rvbuf[p--]=0; /* strip trailing .git */ if(p>=3 && !strncmp(&rvbuf[p-3],".git",4)) { p -= 3; rvbuf[p--] = 0; } /* strip more trailing slashes if any */ while( p && rvbuf[p]=='/') rvbuf[p--]=0; /* find last slash in the remaining string */ rv = strrchr(rvbuf,'/'); if(rv) return ++rv; return rvbuf; } char *cgit_currurl() { if (!cgit_virtual_root) return cgit_script_name; else if (cgit_query_page) return fmt("%s/%s/%s/", cgit_virtual_root, cgit_query_repo, cgit_query_page); else if (cgit_query_repo) return fmt("%s/%s/", cgit_virtual_root, cgit_query_repo); else return fmt("%s/", cgit_virtual_root); } static char *repolink(char *title, char *class, char *page, char *head, char *path) { char *delim = "?"; html("<a"); if (title) { html(" title='"); html_attr(title); html("'"); } if (class) { html(" class='"); html_attr(class); html("'"); } html(" href='"); if (cgit_virtual_root) { html_attr(cgit_virtual_root); if (cgit_virtual_root[strlen(cgit_virtual_root) - 1] != '/') html("/"); html_attr(cgit_repo->url); if (cgit_repo->url[strlen(cgit_repo->url) - 1] != '/') html("/"); if (page) { html(page); html("/"); if (path) html_attr(path); } } else { html(cgit_script_name); html("?url="); html_attr(cgit_repo->url); if (cgit_repo->url[strlen(cgit_repo->url) - 1] != '/') html("/"); if (page) { html(page); html("/"); if (path) html_attr(path); } delim = "&"; } if (head && strcmp(head, cgit_repo->defbranch)) { html(delim); html("h="); html_attr(head); delim = "&"; } return fmt("%s", delim); } static void reporevlink(char *page, char *name, char *title, char *class, char *head, char *rev, char *path) { char *delim; delim = repolink(title, class, page, head, path); if (rev && strcmp(rev, cgit_query_head)) { html(delim); html("id="); html_attr(rev); } html("'>"); html_txt(name); html("</a>"); } void cgit_tree_link(char *name, char *title, char *class, char *head, char *rev, char *path) { reporevlink("tree", name, title, class, head, rev, path); } void cgit_log_link(char *name, char *title, char *class, char *head, char *rev, char *path, int ofs) { char *delim; delim = repolink(title, class, "log", head, path); if (rev && strcmp(rev, cgit_query_head)) { html(delim); html("id="); html_attr(rev); delim = "&"; } if (ofs > 0) { html(delim); html("ofs="); htmlf("%d", ofs); } html("'>"); html_txt(name); html("</a>"); } void cgit_commit_link(char *name, char *title, char *class, char *head, char *rev) { if (strlen(name) > cgit_max_msg_len && cgit_max_msg_len >= 15) { name[cgit_max_msg_len] = '\0'; name[cgit_max_msg_len - 1] = '.'; name[cgit_max_msg_len - 2] = '.'; name[cgit_max_msg_len - 3] = '.'; } reporevlink("commit", name, title, class, head, rev, NULL); } void cgit_refs_link(char *name, char *title, char *class, char *head, char *rev, char *path) { reporevlink("refs", name, title, class, head, rev, path); } void cgit_snapshot_link(char *name, char *title, char *class, char *head, char *rev, char *archivename) { reporevlink("snapshot", name, title, class, head, rev, archivename); } void cgit_diff_link(char *name, char *title, char *class, char *head, char *new_rev, char *old_rev, char *path) { char *delim; delim = repolink(title, class, "diff", head, path); if (new_rev && strcmp(new_rev, cgit_query_head)) { html(delim); html("id="); html_attr(new_rev); delim = "&"; } if (old_rev) { html(delim); html("id2="); html_attr(old_rev); } html("'>"); html_txt(name); html("</a>"); } void cgit_object_link(struct object *obj) { char *page, *arg, *url; if (obj->type == OBJ_COMMIT) { cgit_commit_link(fmt("commit %s", sha1_to_hex(obj->sha1)), NULL, NULL, cgit_query_head, sha1_to_hex(obj->sha1)); return; } else if (obj->type == OBJ_TREE) { page = "tree"; arg = "id"; + } else if (obj->type == OBJ_TAG) { + page = "tag"; + arg = "id"; } else { page = "blob"; arg = "id"; } url = cgit_pageurl(cgit_query_repo, page, fmt("%s=%s", arg, sha1_to_hex(obj->sha1))); html_link_open(url, NULL, NULL); htmlf("%s %s", typename(obj->type), sha1_to_hex(obj->sha1)); html_link_close(); } void cgit_print_date(time_t secs, char *format) { char buf[64]; struct tm *time; time = gmtime(&secs); strftime(buf, sizeof(buf)-1, format, time); html_txt(buf); } void cgit_print_age(time_t t, time_t max_relative, char *format) { time_t now, secs; time(&now); secs = now - t; if (secs > max_relative && max_relative >= 0) { cgit_print_date(t, format); return; } if (secs < TM_HOUR * 2) { htmlf("<span class='age-mins'>%.0f min.</span>", secs * 1.0 / TM_MIN); return; } if (secs < TM_DAY * 2) { htmlf("<span class='age-hours'>%.0f hours</span>", secs * 1.0 / TM_HOUR); return; } if (secs < TM_WEEK * 2) { htmlf("<span class='age-days'>%.0f days</span>", secs * 1.0 / TM_DAY); return; } if (secs < TM_MONTH * 2) { htmlf("<span class='age-weeks'>%.0f weeks</span>", secs * 1.0 / TM_WEEK); return; } if (secs < TM_YEAR * 2) { htmlf("<span class='age-months'>%.0f months</span>", secs * 1.0 / TM_MONTH); return; } htmlf("<span class='age-years'>%.0f years</span>", secs * 1.0 / TM_YEAR); } void cgit_print_docstart(char *title, struct cacheitem *item) { html("Content-Type: text/html; charset=utf-8\n"); htmlf("Last-Modified: %s\n", http_date(item->st.st_mtime)); htmlf("Expires: %s\n", http_date(item->st.st_mtime + ttl_seconds(item->ttl))); html("\n"); html(cgit_doctype); html("<html>\n"); html("<head>\n"); html("<title>"); html_txt(title); html("</title>\n"); htmlf("<meta name='generator' content='cgit %s'/>\n", cgit_version); html("<link rel='stylesheet' type='text/css' href='"); html_attr(cgit_css); html("'/>\n"); html("</head>\n"); html("<body>\n"); } void cgit_print_docend() { html("</td></tr></table>"); html("</body>\n</html>\n"); } void cgit_print_pageheader(char *title, int show_search) { html("<table id='layout'>"); html("<tr><td id='header'><a href='"); html_attr(cgit_rooturl()); html("'>"); html_txt(cgit_root_title); html("</a></td><td id='logo'>"); html("<a href='"); html_attr(cgit_logo_link); htmlf("'><img src='%s' alt='logo'/></a>", cgit_logo); html("</td></tr>"); html("<tr><td id='crumb'>"); if (cgit_query_repo) { html_txt(cgit_repo->name); html(" ("); html_txt(cgit_query_head); html(") : "); reporevlink(NULL, "summary", NULL, NULL, cgit_query_head, NULL, NULL); html(" "); cgit_log_link("log", NULL, NULL, cgit_query_head, cgit_query_sha1, cgit_query_path, 0); html(" "); cgit_tree_link("tree", NULL, NULL, cgit_query_head, cgit_query_sha1, NULL); html(" "); cgit_commit_link("commit", NULL, NULL, cgit_query_head, cgit_query_sha1); html(" "); cgit_diff_link("diff", NULL, NULL, cgit_query_head, cgit_query_sha1, cgit_query_sha2, cgit_query_path); } else { html_txt("Index of repositories"); } html("</td>"); html("<td id='search'>"); if (show_search) { html("<form method='get' action='"); html_attr(cgit_currurl()); html("'>"); if (!cgit_virtual_root) { if (cgit_query_repo) html_hidden("r", cgit_query_repo); if (cgit_query_page) html_hidden("p", cgit_query_page); } if (cgit_query_head) html_hidden("h", cgit_query_head); if (cgit_query_sha1) html_hidden("id", cgit_query_sha1); if (cgit_query_sha2) html_hidden("id2", cgit_query_sha2); html("<select name='qt'>"); html_option("grep", "log msg", cgit_query_grep); html_option("author", "author", cgit_query_grep); html_option("committer", "committer", cgit_query_grep); html("</select>"); html("<input class='txt' type='text' name='q' value='"); html_attr(cgit_query_search); html("'/><input class='btn' type='submit' value='...'/></form>"); } html("</td></tr>"); html("<tr><td id='content' colspan='2'>"); } void cgit_print_snapshot_start(const char *mimetype, const char *filename, struct cacheitem *item) { htmlf("Content-Type: %s\n", mimetype); htmlf("Content-Disposition: inline; filename=\"%s\"\n", filename); htmlf("Last-Modified: %s\n", http_date(item->st.st_mtime)); htmlf("Expires: %s\n", http_date(item->st.st_mtime + ttl_seconds(item->ttl))); html("\n"); } /* vim:set sw=8: */ |