author | Lars Hjemli <hjemli@gmail.com> | 2007-05-22 21:08:46 (UTC) |
---|---|---|
committer | Lars Hjemli <hjemli@gmail.com> | 2007-05-22 21:12:41 (UTC) |
commit | 5db39170b6c979655a0238dcd627e206febed88b (patch) (unidiff) | |
tree | 2c79691bde31f9db2861dc76010691e9dbdde1cb | |
parent | 3b86b44fc761cfa8b97c44bbbdd63c9fbf1127ed (diff) | |
download | cgit-5db39170b6c979655a0238dcd627e206febed88b.zip cgit-5db39170b6c979655a0238dcd627e206febed88b.tar.gz cgit-5db39170b6c979655a0238dcd627e206febed88b.tar.bz2 |
Add cgit_print_age() function
This function can be used to print relative dates, just as in gitweb. Next
step will be to actually use the new function.
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
-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
@@ -375,16 +375,41 @@ a.button:hover { | |||
375 | 375 | ||
376 | a.primary { | 376 | a.primary { |
377 | font-size: 100%; | 377 | font-size: 100%; |
378 | } | 378 | } |
379 | 379 | ||
380 | a.secondary { | 380 | a.secondary { |
381 | font-size: 90%; | 381 | font-size: 90%; |
382 | } | 382 | } |
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 | } | ||
@@ -16,32 +16,51 @@ | |||
16 | #include <log-tree.h> | 16 | #include <log-tree.h> |
17 | #include <archive.h> | 17 | #include <archive.h> |
18 | #include <xdiff/xdiff.h> | 18 | #include <xdiff/xdiff.h> |
19 | 19 | ||
20 | 20 | ||
21 | /* | 21 | /* |
22 | * The valid cgit repo-commands | 22 | * The valid cgit repo-commands |
23 | */ | 23 | */ |
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; |
40 | int fd; | 59 | int fd; |
41 | }; | 60 | }; |
42 | 61 | ||
43 | struct repoinfo { | 62 | struct repoinfo { |
44 | char *url; | 63 | char *url; |
45 | char *name; | 64 | char *name; |
46 | char *path; | 65 | char *path; |
47 | char *desc; | 66 | char *desc; |
@@ -168,33 +187,34 @@ extern int cgit_parse_query(char *txt, configfn fn); | |||
168 | extern struct commitinfo *cgit_parse_commit(struct commit *commit); | 187 | extern struct commitinfo *cgit_parse_commit(struct commit *commit); |
169 | extern struct taginfo *cgit_parse_tag(struct tag *tag); | 188 | extern struct taginfo *cgit_parse_tag(struct tag *tag); |
170 | extern void cgit_parse_url(const char *url); | 189 | extern void cgit_parse_url(const char *url); |
171 | 190 | ||
172 | extern char *cache_safe_filename(const char *unsafe); | 191 | extern char *cache_safe_filename(const char *unsafe); |
173 | extern int cache_lock(struct cacheitem *item); | 192 | extern int cache_lock(struct cacheitem *item); |
174 | extern int cache_unlock(struct cacheitem *item); | 193 | extern int cache_unlock(struct cacheitem *item); |
175 | extern int cache_cancel_lock(struct cacheitem *item); | 194 | 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); |
193 | extern void cgit_print_summary(); | 213 | extern void cgit_print_summary(); |
194 | extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *path); | 214 | extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *path); |
195 | extern void cgit_print_view(const char *hex, char *path); | 215 | extern void cgit_print_view(const char *hex, char *path); |
196 | extern void cgit_print_blob(struct cacheitem *item, const char *hex, char *path); | 216 | extern void cgit_print_blob(struct cacheitem *item, const char *hex, char *path); |
197 | extern void cgit_print_tree(const char *rev, const char *hex, char *path); | 217 | extern void cgit_print_tree(const char *rev, const char *hex, char *path); |
198 | extern void cgit_print_commit(const char *hex); | 218 | extern void cgit_print_commit(const char *hex); |
199 | extern void cgit_print_diff(const char *head, const char *old_hex, const char *new_hex, | 219 | extern void cgit_print_diff(const char *head, const char *old_hex, const char *new_hex, |
200 | char *path); | 220 | char *path); |
diff --git a/ui-commit.c b/ui-commit.c index ff1fad3..59eeb1d 100644 --- a/ui-commit.c +++ b/ui-commit.c | |||
@@ -159,40 +159,40 @@ void cgit_print_commit(const char *hex) | |||
159 | cgit_print_error(fmt("Bad object id: %s", hex)); | 159 | cgit_print_error(fmt("Bad object id: %s", hex)); |
160 | return; | 160 | return; |
161 | } | 161 | } |
162 | commit = lookup_commit_reference(sha1); | 162 | commit = lookup_commit_reference(sha1); |
163 | if (!commit) { | 163 | if (!commit) { |
164 | cgit_print_error(fmt("Bad commit reference: %s", hex)); | 164 | cgit_print_error(fmt("Bad commit reference: %s", hex)); |
165 | return; | 165 | return; |
166 | } | 166 | } |
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); |
191 | if (!parent) { | 191 | if (!parent) { |
192 | html("<tr><td colspan='3'>"); | 192 | html("<tr><td colspan='3'>"); |
193 | cgit_print_error("Error reading parent commit"); | 193 | cgit_print_error("Error reading parent commit"); |
194 | html("</td></tr>"); | 194 | html("</td></tr>"); |
195 | continue; | 195 | continue; |
196 | } | 196 | } |
197 | html("<tr><th>parent</th>" | 197 | html("<tr><th>parent</th>" |
198 | "<td colspan='2' class='sha1'>" | 198 | "<td colspan='2' class='sha1'>" |
diff --git a/ui-shared.c b/ui-shared.c index c7fbc5e..acc771b 100644 --- a/ui-shared.c +++ b/ui-shared.c | |||
@@ -75,42 +75,83 @@ char *cgit_pageurl(const char *reponame, const char *pagename, | |||
75 | } | 75 | } |
76 | } | 76 | } |
77 | 77 | ||
78 | char *cgit_currurl() | 78 | char *cgit_currurl() |
79 | { | 79 | { |
80 | if (!cgit_virtual_root) | 80 | if (!cgit_virtual_root) |
81 | return cgit_script_name; | 81 | return cgit_script_name; |
82 | else if (cgit_query_page) | 82 | else if (cgit_query_page) |
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); |
109 | html("<html>\n"); | 150 | html("<html>\n"); |
110 | html("<head>\n"); | 151 | html("<head>\n"); |
111 | html("<title>"); | 152 | html("<title>"); |
112 | html_txt(title); | 153 | html_txt(title); |
113 | html("</title>\n"); | 154 | html("</title>\n"); |
114 | htmlf("<meta name='generator' content='cgit v%s'/>\n", cgit_version); | 155 | htmlf("<meta name='generator' content='cgit v%s'/>\n", cgit_version); |
115 | html("<link rel='stylesheet' type='text/css' href='"); | 156 | html("<link rel='stylesheet' type='text/css' href='"); |
116 | html_attr(cgit_css); | 157 | html_attr(cgit_css); |
diff --git a/ui-summary.c b/ui-summary.c index e7158cc..20394de 100644 --- a/ui-summary.c +++ b/ui-summary.c | |||
@@ -15,33 +15,33 @@ static int cgit_print_branch_cb(const char *refname, const unsigned char *sha1, | |||
15 | { | 15 | { |
16 | struct commit *commit; | 16 | struct commit *commit; |
17 | struct commitinfo *info; | 17 | struct commitinfo *info; |
18 | char buf[256], *url; | 18 | char buf[256], *url; |
19 | 19 | ||
20 | strncpy(buf, refname, sizeof(buf)); | 20 | strncpy(buf, refname, sizeof(buf)); |
21 | commit = lookup_commit(sha1); | 21 | commit = lookup_commit(sha1); |
22 | if (commit && !parse_commit(commit)){ | 22 | if (commit && !parse_commit(commit)){ |
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(); |
40 | html("</td></tr>\n"); | 40 | html("</td></tr>\n"); |
41 | cgit_free_commitinfo(info); | 41 | cgit_free_commitinfo(info); |
42 | } else { | 42 | } else { |
43 | html("<tr><td>"); | 43 | html("<tr><td>"); |
44 | html_txt(buf); | 44 | html_txt(buf); |
45 | html("</td><td colspan='3'>"); | 45 | html("</td><td colspan='3'>"); |
46 | htmlf("*** bad ref %s ***", sha1_to_hex(sha1)); | 46 | htmlf("*** bad ref %s ***", sha1_to_hex(sha1)); |
47 | html("</td></tr>\n"); | 47 | html("</td></tr>\n"); |
@@ -95,33 +95,33 @@ static int cgit_print_tag_cb(const char *refname, const unsigned char *sha1, | |||
95 | if (!obj) | 95 | if (!obj) |
96 | return 1; | 96 | return 1; |
97 | if (obj->type == OBJ_TAG) { | 97 | if (obj->type == OBJ_TAG) { |
98 | tag = lookup_tag(sha1); | 98 | tag = lookup_tag(sha1); |
99 | if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) | 99 | if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) |
100 | return 2; | 100 | return 2; |
101 | if (!header) | 101 | if (!header) |
102 | print_tag_header(); | 102 | print_tag_header(); |
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) |
120 | print_tag_header(); | 120 | print_tag_header(); |
121 | html("<tr><td>"); | 121 | html("<tr><td>"); |
122 | html_txt(buf); | 122 | html_txt(buf); |
123 | html("</td><td colspan='2'/><td>"); | 123 | html("</td><td colspan='2'/><td>"); |
124 | cgit_print_object_ref(obj); | 124 | cgit_print_object_ref(obj); |
125 | html("</td></tr>\n"); | 125 | html("</td></tr>\n"); |
126 | } | 126 | } |
127 | return 0; | 127 | return 0; |