-rw-r--r-- | cgit.css | 25 | ||||
-rw-r--r-- | cgit.h | 22 | ||||
-rw-r--r-- | ui-commit.c | 4 | ||||
-rw-r--r-- | ui-shared.c | 47 | ||||
-rw-r--r-- | ui-summary.c | 4 |
5 files changed, 94 insertions, 8 deletions
@@ -383,8 +383,33 @@ a.secondary { | |||
383 | 383 | ||
384 | td.toplevel-repo { | 384 | td.toplevel-repo { |
385 | 385 | ||
386 | } | 386 | } |
387 | 387 | ||
388 | table.list td.sublevel-repo { | 388 | table.list td.sublevel-repo { |
389 | padding-left: 1.5em; | 389 | padding-left: 1.5em; |
390 | } | 390 | } |
391 | |||
392 | span.age-mins { | ||
393 | font-weight: bold; | ||
394 | color: #080; | ||
395 | } | ||
396 | |||
397 | span.age-hours { | ||
398 | color: #080; | ||
399 | } | ||
400 | |||
401 | span.age-days { | ||
402 | color: #040; | ||
403 | } | ||
404 | |||
405 | span.age-weeks { | ||
406 | color: #444; | ||
407 | } | ||
408 | |||
409 | span.age-months { | ||
410 | color: #888; | ||
411 | } | ||
412 | |||
413 | span.age-years { | ||
414 | color: #bbb; | ||
415 | } | ||
@@ -24,16 +24,35 @@ | |||
24 | #define CMD_LOG 1 | 24 | #define CMD_LOG 1 |
25 | #define CMD_COMMIT 2 | 25 | #define CMD_COMMIT 2 |
26 | #define CMD_DIFF 3 | 26 | #define CMD_DIFF 3 |
27 | #define CMD_TREE 4 | 27 | #define CMD_TREE 4 |
28 | #define CMD_VIEW 5 | 28 | #define CMD_VIEW 5 |
29 | #define CMD_BLOB 6 | 29 | #define CMD_BLOB 6 |
30 | #define CMD_SNAPSHOT 7 | 30 | #define CMD_SNAPSHOT 7 |
31 | 31 | ||
32 | |||
33 | /* | ||
34 | * Dateformats used on misc. pages | ||
35 | */ | ||
36 | #define FMT_LONGDATE "%Y-%m-%d %H:%M:%S" | ||
37 | #define FMT_SHORTDATE "%Y-%m-%d" | ||
38 | |||
39 | |||
40 | /* | ||
41 | * Limits used for relative dates | ||
42 | */ | ||
43 | #define TM_MIN 60 | ||
44 | #define TM_HOUR (TM_MIN * 60) | ||
45 | #define TM_DAY (TM_HOUR * 24) | ||
46 | #define TM_WEEK (TM_DAY * 7) | ||
47 | #define TM_YEAR (TM_DAY * 365) | ||
48 | #define TM_MONTH (TM_YEAR / 12.0) | ||
49 | |||
50 | |||
32 | typedef void (*configfn)(const char *name, const char *value); | 51 | typedef void (*configfn)(const char *name, const char *value); |
33 | typedef void (*filepair_fn)(struct diff_filepair *pair); | 52 | typedef void (*filepair_fn)(struct diff_filepair *pair); |
34 | typedef void (*linediff_fn)(char *line, int len); | 53 | typedef void (*linediff_fn)(char *line, int len); |
35 | 54 | ||
36 | struct cacheitem { | 55 | struct cacheitem { |
37 | char *name; | 56 | char *name; |
38 | struct stat st; | 57 | struct stat st; |
39 | int ttl; | 58 | int ttl; |
@@ -176,17 +195,18 @@ extern int cache_cancel_lock(struct cacheitem *item); | |||
176 | extern int cache_exist(struct cacheitem *item); | 195 | extern int cache_exist(struct cacheitem *item); |
177 | extern int cache_expired(struct cacheitem *item); | 196 | extern int cache_expired(struct cacheitem *item); |
178 | 197 | ||
179 | extern char *cgit_repourl(const char *reponame); | 198 | extern char *cgit_repourl(const char *reponame); |
180 | extern char *cgit_pageurl(const char *reponame, const char *pagename, | 199 | extern char *cgit_pageurl(const char *reponame, const char *pagename, |
181 | const char *query); | 200 | const char *query); |
182 | 201 | ||
183 | extern void cgit_print_error(char *msg); | 202 | extern void cgit_print_error(char *msg); |
184 | extern void cgit_print_date(unsigned long secs); | 203 | extern void cgit_print_date(time_t secs, char *format); |
204 | extern void cgit_print_age(time_t t, time_t max_relative, char *format); | ||
185 | extern void cgit_print_docstart(char *title, struct cacheitem *item); | 205 | extern void cgit_print_docstart(char *title, struct cacheitem *item); |
186 | extern void cgit_print_docend(); | 206 | extern void cgit_print_docend(); |
187 | extern void cgit_print_pageheader(char *title, int show_search); | 207 | extern void cgit_print_pageheader(char *title, int show_search); |
188 | extern void cgit_print_snapshot_start(const char *mimetype, | 208 | extern void cgit_print_snapshot_start(const char *mimetype, |
189 | const char *filename, | 209 | const char *filename, |
190 | struct cacheitem *item); | 210 | struct cacheitem *item); |
191 | 211 | ||
192 | extern void cgit_print_repolist(struct cacheitem *item); | 212 | extern void cgit_print_repolist(struct cacheitem *item); |
diff --git a/ui-commit.c b/ui-commit.c index ff1fad3..59eeb1d 100644 --- a/ui-commit.c +++ b/ui-commit.c | |||
@@ -167,24 +167,24 @@ void cgit_print_commit(const char *hex) | |||
167 | info = cgit_parse_commit(commit); | 167 | info = cgit_parse_commit(commit); |
168 | 168 | ||
169 | html("<table class='commit-info'>\n"); | 169 | html("<table class='commit-info'>\n"); |
170 | html("<tr><th>author</th><td>"); | 170 | html("<tr><th>author</th><td>"); |
171 | html_txt(info->author); | 171 | html_txt(info->author); |
172 | html(" "); | 172 | html(" "); |
173 | html_txt(info->author_email); | 173 | html_txt(info->author_email); |
174 | html("</td><td class='right'>"); | 174 | html("</td><td class='right'>"); |
175 | cgit_print_date(info->author_date); | 175 | cgit_print_date(info->author_date, FMT_LONGDATE); |
176 | html("</td></tr>\n"); | 176 | html("</td></tr>\n"); |
177 | html("<tr><th>committer</th><td>"); | 177 | html("<tr><th>committer</th><td>"); |
178 | html_txt(info->committer); | 178 | html_txt(info->committer); |
179 | html(" "); | 179 | html(" "); |
180 | html_txt(info->committer_email); | 180 | html_txt(info->committer_email); |
181 | html("</td><td class='right'>"); | 181 | html("</td><td class='right'>"); |
182 | cgit_print_date(info->committer_date); | 182 | cgit_print_date(info->committer_date, FMT_LONGDATE); |
183 | html("</td></tr>\n"); | 183 | html("</td></tr>\n"); |
184 | html("<tr><th>tree</th><td colspan='2' class='sha1'><a href='"); | 184 | html("<tr><th>tree</th><td colspan='2' class='sha1'><a href='"); |
185 | query = fmt("h=%s&id=%s", sha1_to_hex(commit->object.sha1), | 185 | query = fmt("h=%s&id=%s", sha1_to_hex(commit->object.sha1), |
186 | sha1_to_hex(commit->tree->object.sha1)); | 186 | sha1_to_hex(commit->tree->object.sha1)); |
187 | html_attr(cgit_pageurl(cgit_query_repo, "tree", query)); | 187 | html_attr(cgit_pageurl(cgit_query_repo, "tree", query)); |
188 | htmlf("'>%s</a></td></tr>\n", sha1_to_hex(commit->tree->object.sha1)); | 188 | htmlf("'>%s</a></td></tr>\n", sha1_to_hex(commit->tree->object.sha1)); |
189 | for (p = commit->parents; p ; p = p->next) { | 189 | for (p = commit->parents; p ; p = p->next) { |
190 | parent = lookup_commit_reference(p->item->object.sha1); | 190 | parent = lookup_commit_reference(p->item->object.sha1); |
diff --git a/ui-shared.c b/ui-shared.c index c7fbc5e..acc771b 100644 --- a/ui-shared.c +++ b/ui-shared.c | |||
@@ -83,26 +83,67 @@ char *cgit_currurl() | |||
83 | return fmt("%s/%s/%s/", cgit_virtual_root, cgit_query_repo, cgit_query_page); | 83 | return fmt("%s/%s/%s/", cgit_virtual_root, cgit_query_repo, cgit_query_page); |
84 | else if (cgit_query_repo) | 84 | else if (cgit_query_repo) |
85 | return fmt("%s/%s/", cgit_virtual_root, cgit_query_repo); | 85 | return fmt("%s/%s/", cgit_virtual_root, cgit_query_repo); |
86 | else | 86 | else |
87 | return fmt("%s/", cgit_virtual_root); | 87 | return fmt("%s/", cgit_virtual_root); |
88 | } | 88 | } |
89 | 89 | ||
90 | 90 | ||
91 | void cgit_print_date(unsigned long secs) | 91 | void cgit_print_date(time_t secs, char *format) |
92 | { | 92 | { |
93 | char buf[32]; | 93 | char buf[64]; |
94 | struct tm *time; | 94 | struct tm *time; |
95 | 95 | ||
96 | time = gmtime(&secs); | 96 | time = gmtime(&secs); |
97 | strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", time); | 97 | strftime(buf, sizeof(buf)-1, format, time); |
98 | html_txt(buf); | 98 | html_txt(buf); |
99 | } | 99 | } |
100 | 100 | ||
101 | void cgit_print_age(time_t t, time_t max_relative, char *format) | ||
102 | { | ||
103 | time_t now, secs; | ||
104 | |||
105 | time(&now); | ||
106 | secs = now - t; | ||
107 | |||
108 | if (secs > max_relative && max_relative >= 0) { | ||
109 | cgit_print_date(t, format); | ||
110 | return; | ||
111 | } | ||
112 | |||
113 | if (secs < TM_HOUR * 2) { | ||
114 | htmlf("<span class='age-mins'>%.0f min.</span>", | ||
115 | secs * 1.0 / TM_MIN); | ||
116 | return; | ||
117 | } | ||
118 | if (secs < TM_DAY * 2) { | ||
119 | htmlf("<span class='age-hours'>%.0f hours</span>", | ||
120 | secs * 1.0 / TM_HOUR); | ||
121 | return; | ||
122 | } | ||
123 | if (secs < TM_WEEK * 2) { | ||
124 | htmlf("<span class='age-days'>%.0f days</span>", | ||
125 | secs * 1.0 / TM_DAY); | ||
126 | return; | ||
127 | } | ||
128 | if (secs < TM_MONTH * 2) { | ||
129 | htmlf("<span class='age-weeks'>%.0f weeks</span>", | ||
130 | secs * 1.0 / TM_WEEK); | ||
131 | return; | ||
132 | } | ||
133 | if (secs < TM_YEAR * 2) { | ||
134 | htmlf("<span class='age-months'>%.0f months</span>", | ||
135 | secs * 1.0 / TM_MONTH); | ||
136 | return; | ||
137 | } | ||
138 | htmlf("<span class='age-years'>%.0f years</span>", | ||
139 | secs * 1.0 / TM_YEAR); | ||
140 | } | ||
141 | |||
101 | void cgit_print_docstart(char *title, struct cacheitem *item) | 142 | void cgit_print_docstart(char *title, struct cacheitem *item) |
102 | { | 143 | { |
103 | html("Content-Type: text/html; charset=utf-8\n"); | 144 | html("Content-Type: text/html; charset=utf-8\n"); |
104 | htmlf("Last-Modified: %s\n", http_date(item->st.st_mtime)); | 145 | htmlf("Last-Modified: %s\n", http_date(item->st.st_mtime)); |
105 | htmlf("Expires: %s\n", http_date(item->st.st_mtime + | 146 | htmlf("Expires: %s\n", http_date(item->st.st_mtime + |
106 | ttl_seconds(item->ttl))); | 147 | ttl_seconds(item->ttl))); |
107 | html("\n"); | 148 | html("\n"); |
108 | html(cgit_doctype); | 149 | html(cgit_doctype); |
diff --git a/ui-summary.c b/ui-summary.c index e7158cc..20394de 100644 --- a/ui-summary.c +++ b/ui-summary.c | |||
@@ -23,17 +23,17 @@ static int cgit_print_branch_cb(const char *refname, const unsigned char *sha1, | |||
23 | info = cgit_parse_commit(commit); | 23 | info = cgit_parse_commit(commit); |
24 | html("<tr><td>"); | 24 | html("<tr><td>"); |
25 | url = cgit_pageurl(cgit_query_repo, "log", | 25 | url = cgit_pageurl(cgit_query_repo, "log", |
26 | fmt("h=%s", refname)); | 26 | fmt("h=%s", refname)); |
27 | html_link_open(url, NULL, NULL); | 27 | html_link_open(url, NULL, NULL); |
28 | html_txt(buf); | 28 | html_txt(buf); |
29 | html_link_close(); | 29 | html_link_close(); |
30 | html("</td><td>"); | 30 | html("</td><td>"); |
31 | cgit_print_date(commit->date); | 31 | cgit_print_date(commit->date, FMT_LONGDATE); |
32 | html("</td><td>"); | 32 | html("</td><td>"); |
33 | html_txt(info->author); | 33 | html_txt(info->author); |
34 | html("</td><td>"); | 34 | html("</td><td>"); |
35 | url = cgit_pageurl(cgit_query_repo, "commit", | 35 | url = cgit_pageurl(cgit_query_repo, "commit", |
36 | fmt("h=%s", sha1_to_hex(sha1))); | 36 | fmt("h=%s", sha1_to_hex(sha1))); |
37 | html_link_open(url, NULL, NULL); | 37 | html_link_open(url, NULL, NULL); |
38 | html_ntxt(cgit_max_msg_len, info->subject); | 38 | html_ntxt(cgit_max_msg_len, info->subject); |
39 | html_link_close(); | 39 | html_link_close(); |
@@ -103,17 +103,17 @@ static int cgit_print_tag_cb(const char *refname, const unsigned char *sha1, | |||
103 | html("<tr><td>"); | 103 | html("<tr><td>"); |
104 | url = cgit_pageurl(cgit_query_repo, "view", | 104 | url = cgit_pageurl(cgit_query_repo, "view", |
105 | fmt("id=%s", sha1_to_hex(sha1))); | 105 | fmt("id=%s", sha1_to_hex(sha1))); |
106 | html_link_open(url, NULL, NULL); | 106 | html_link_open(url, NULL, NULL); |
107 | html_txt(buf); | 107 | html_txt(buf); |
108 | html_link_close(); | 108 | html_link_close(); |
109 | html("</td><td>"); | 109 | html("</td><td>"); |
110 | if (info->tagger_date > 0) | 110 | if (info->tagger_date > 0) |
111 | cgit_print_date(info->tagger_date); | 111 | cgit_print_date(info->tagger_date, FMT_LONGDATE); |
112 | html("</td><td>"); | 112 | html("</td><td>"); |
113 | if (info->tagger) | 113 | if (info->tagger) |
114 | html(info->tagger); | 114 | html(info->tagger); |
115 | html("</td><td>"); | 115 | html("</td><td>"); |
116 | cgit_print_object_ref(tag->tagged); | 116 | cgit_print_object_ref(tag->tagged); |
117 | html("</td></tr>\n"); | 117 | html("</td></tr>\n"); |
118 | } else { | 118 | } else { |
119 | if (!header) | 119 | if (!header) |