author | Lars Hjemli <hjemli@gmail.com> | 2010-09-19 17:00:05 (UTC) |
---|---|---|
committer | Lars Hjemli <hjemli@gmail.com> | 2010-09-19 17:00:05 (UTC) |
commit | a9d6e6e695da6c6ed7f4bb32630ab2f3d9314806 (patch) (unidiff) | |
tree | de8271ebfabd244437cd68021c8af86391afb9bd /ui-stats.c | |
parent | 536c7a1eb201b44b9266babe087cb6f2b75e4a7f (diff) | |
parent | d187b98557d91b874836f286b955ba76ab26fb02 (diff) | |
download | cgit-a9d6e6e695da6c6ed7f4bb32630ab2f3d9314806.zip cgit-a9d6e6e695da6c6ed7f4bb32630ab2f3d9314806.tar.gz cgit-a9d6e6e695da6c6ed7f4bb32630ab2f3d9314806.tar.bz2 |
Merge branch 'ml/bugfix'
-rw-r--r-- | ui-stats.c | 18 |
1 files changed, 12 insertions, 6 deletions
@@ -1,31 +1,37 @@ | |||
1 | #include <string-list.h> | 1 | #include <string-list.h> |
2 | 2 | ||
3 | #include "cgit.h" | 3 | #include "cgit.h" |
4 | #include "html.h" | 4 | #include "html.h" |
5 | #include "ui-shared.h" | 5 | #include "ui-shared.h" |
6 | #include "ui-stats.h" | 6 | #include "ui-stats.h" |
7 | 7 | ||
8 | #ifdef NO_C99_FORMAT | ||
9 | #define SZ_FMT "%u" | ||
10 | #else | ||
11 | #define SZ_FMT "%zu" | ||
12 | #endif | ||
13 | |||
8 | #define MONTHS 6 | 14 | #define MONTHS 6 |
9 | 15 | ||
10 | struct authorstat { | 16 | struct authorstat { |
11 | long total; | 17 | long total; |
12 | struct string_list list; | 18 | struct string_list list; |
13 | }; | 19 | }; |
14 | 20 | ||
15 | #define DAY_SECS (60 * 60 * 24) | 21 | #define DAY_SECS (60 * 60 * 24) |
16 | #define WEEK_SECS (DAY_SECS * 7) | 22 | #define WEEK_SECS (DAY_SECS * 7) |
17 | 23 | ||
18 | static void trunc_week(struct tm *tm) | 24 | static void trunc_week(struct tm *tm) |
19 | { | 25 | { |
20 | time_t t = timegm(tm); | 26 | time_t t = timegm(tm); |
21 | t -= ((tm->tm_wday + 6) % 7) * DAY_SECS; | 27 | t -= ((tm->tm_wday + 6) % 7) * DAY_SECS; |
22 | gmtime_r(&t, tm); | 28 | gmtime_r(&t, tm); |
23 | } | 29 | } |
24 | 30 | ||
25 | static void dec_week(struct tm *tm) | 31 | static void dec_week(struct tm *tm) |
26 | { | 32 | { |
27 | time_t t = timegm(tm); | 33 | time_t t = timegm(tm); |
28 | t -= WEEK_SECS; | 34 | t -= WEEK_SECS; |
29 | gmtime_r(&t, tm); | 35 | gmtime_r(&t, tm); |
30 | } | 36 | } |
31 | 37 | ||
@@ -262,133 +268,133 @@ void print_combined_authorrow(struct string_list *authors, int from, int to, | |||
262 | struct tm *tm; | 268 | struct tm *tm; |
263 | char *tmp; | 269 | char *tmp; |
264 | 270 | ||
265 | time(&now); | 271 | time(&now); |
266 | tm = gmtime(&now); | 272 | tm = gmtime(&now); |
267 | period->trunc(tm); | 273 | period->trunc(tm); |
268 | for (i = 1; i < period->count; i++) | 274 | for (i = 1; i < period->count; i++) |
269 | period->dec(tm); | 275 | period->dec(tm); |
270 | 276 | ||
271 | total = 0; | 277 | total = 0; |
272 | htmlf("<tr><td class='%s'>%s</td>", leftclass, | 278 | htmlf("<tr><td class='%s'>%s</td>", leftclass, |
273 | fmt(name, to - from + 1)); | 279 | fmt(name, to - from + 1)); |
274 | for (j = 0; j < period->count; j++) { | 280 | for (j = 0; j < period->count; j++) { |
275 | tmp = period->pretty(tm); | 281 | tmp = period->pretty(tm); |
276 | period->inc(tm); | 282 | period->inc(tm); |
277 | subtotal = 0; | 283 | subtotal = 0; |
278 | for (i = from; i <= to; i++) { | 284 | for (i = from; i <= to; i++) { |
279 | author = &authors->items[i]; | 285 | author = &authors->items[i]; |
280 | authorstat = author->util; | 286 | authorstat = author->util; |
281 | items = &authorstat->list; | 287 | items = &authorstat->list; |
282 | date = string_list_lookup(items, tmp); | 288 | date = string_list_lookup(items, tmp); |
283 | if (date) | 289 | if (date) |
284 | subtotal += (size_t)date->util; | 290 | subtotal += (size_t)date->util; |
285 | } | 291 | } |
286 | htmlf("<td class='%s'>%d</td>", centerclass, subtotal); | 292 | htmlf("<td class='%s'>%ld</td>", centerclass, subtotal); |
287 | total += subtotal; | 293 | total += subtotal; |
288 | } | 294 | } |
289 | htmlf("<td class='%s'>%d</td></tr>", rightclass, total); | 295 | htmlf("<td class='%s'>%ld</td></tr>", rightclass, total); |
290 | } | 296 | } |
291 | 297 | ||
292 | void print_authors(struct string_list *authors, int top, | 298 | void print_authors(struct string_list *authors, int top, |
293 | struct cgit_period *period) | 299 | struct cgit_period *period) |
294 | { | 300 | { |
295 | struct string_list_item *author; | 301 | struct string_list_item *author; |
296 | struct authorstat *authorstat; | 302 | struct authorstat *authorstat; |
297 | struct string_list *items; | 303 | struct string_list *items; |
298 | struct string_list_item *date; | 304 | struct string_list_item *date; |
299 | time_t now; | 305 | time_t now; |
300 | long i, j, total; | 306 | long i, j, total; |
301 | struct tm *tm; | 307 | struct tm *tm; |
302 | char *tmp; | 308 | char *tmp; |
303 | 309 | ||
304 | time(&now); | 310 | time(&now); |
305 | tm = gmtime(&now); | 311 | tm = gmtime(&now); |
306 | period->trunc(tm); | 312 | period->trunc(tm); |
307 | for (i = 1; i < period->count; i++) | 313 | for (i = 1; i < period->count; i++) |
308 | period->dec(tm); | 314 | period->dec(tm); |
309 | 315 | ||
310 | html("<table class='stats'><tr><th>Author</th>"); | 316 | html("<table class='stats'><tr><th>Author</th>"); |
311 | for (j = 0; j < period->count; j++) { | 317 | for (j = 0; j < period->count; j++) { |
312 | tmp = period->pretty(tm); | 318 | tmp = period->pretty(tm); |
313 | htmlf("<th>%s</th>", tmp); | 319 | htmlf("<th>%s</th>", tmp); |
314 | period->inc(tm); | 320 | period->inc(tm); |
315 | } | 321 | } |
316 | html("<th>Total</th></tr>\n"); | 322 | html("<th>Total</th></tr>\n"); |
317 | 323 | ||
318 | if (top <= 0 || top > authors->nr) | 324 | if (top <= 0 || top > authors->nr) |
319 | top = authors->nr; | 325 | top = authors->nr; |
320 | 326 | ||
321 | for (i = 0; i < top; i++) { | 327 | for (i = 0; i < top; i++) { |
322 | author = &authors->items[i]; | 328 | author = &authors->items[i]; |
323 | html("<tr><td class='left'>"); | 329 | html("<tr><td class='left'>"); |
324 | html_txt(author->string); | 330 | html_txt(author->string); |
325 | html("</td>"); | 331 | html("</td>"); |
326 | authorstat = author->util; | 332 | authorstat = author->util; |
327 | items = &authorstat->list; | 333 | items = &authorstat->list; |
328 | total = 0; | 334 | total = 0; |
329 | for (j = 0; j < period->count; j++) | 335 | for (j = 0; j < period->count; j++) |
330 | period->dec(tm); | 336 | period->dec(tm); |
331 | for (j = 0; j < period->count; j++) { | 337 | for (j = 0; j < period->count; j++) { |
332 | tmp = period->pretty(tm); | 338 | tmp = period->pretty(tm); |
333 | period->inc(tm); | 339 | period->inc(tm); |
334 | date = string_list_lookup(items, tmp); | 340 | date = string_list_lookup(items, tmp); |
335 | if (!date) | 341 | if (!date) |
336 | html("<td>0</td>"); | 342 | html("<td>0</td>"); |
337 | else { | 343 | else { |
338 | htmlf("<td>%d</td>", date->util); | 344 | htmlf("<td>"SZ_FMT"</td>", (size_t)date->util); |
339 | total += (size_t)date->util; | 345 | total += (size_t)date->util; |
340 | } | 346 | } |
341 | } | 347 | } |
342 | htmlf("<td class='sum'>%d</td></tr>", total); | 348 | htmlf("<td class='sum'>%ld</td></tr>", total); |
343 | } | 349 | } |
344 | 350 | ||
345 | if (top < authors->nr) | 351 | if (top < authors->nr) |
346 | print_combined_authorrow(authors, top, authors->nr - 1, | 352 | print_combined_authorrow(authors, top, authors->nr - 1, |
347 | "Others (%d)", "left", "", "sum", period); | 353 | "Others (%ld)", "left", "", "sum", period); |
348 | 354 | ||
349 | print_combined_authorrow(authors, 0, authors->nr - 1, "Total", | 355 | print_combined_authorrow(authors, 0, authors->nr - 1, "Total", |
350 | "total", "sum", "sum", period); | 356 | "total", "sum", "sum", period); |
351 | html("</table>"); | 357 | html("</table>"); |
352 | } | 358 | } |
353 | 359 | ||
354 | /* Create a sorted string_list with one entry per author. The util-field | 360 | /* Create a sorted string_list with one entry per author. The util-field |
355 | * for each author is another string_list which is used to calculate the | 361 | * for each author is another string_list which is used to calculate the |
356 | * number of commits per time-interval. | 362 | * number of commits per time-interval. |
357 | */ | 363 | */ |
358 | void cgit_show_stats(struct cgit_context *ctx) | 364 | void cgit_show_stats(struct cgit_context *ctx) |
359 | { | 365 | { |
360 | struct string_list authors; | 366 | struct string_list authors; |
361 | struct cgit_period *period; | 367 | struct cgit_period *period; |
362 | int top, i; | 368 | int top, i; |
363 | const char *code = "w"; | 369 | const char *code = "w"; |
364 | 370 | ||
365 | if (ctx->qry.period) | 371 | if (ctx->qry.period) |
366 | code = ctx->qry.period; | 372 | code = ctx->qry.period; |
367 | 373 | ||
368 | i = cgit_find_stats_period(code, &period); | 374 | i = cgit_find_stats_period(code, &period); |
369 | if (!i) { | 375 | if (!i) { |
370 | cgit_print_error(fmt("Unknown statistics type: %c", code)); | 376 | cgit_print_error(fmt("Unknown statistics type: %c", code[0])); |
371 | return; | 377 | return; |
372 | } | 378 | } |
373 | if (i > ctx->repo->max_stats) { | 379 | if (i > ctx->repo->max_stats) { |
374 | cgit_print_error(fmt("Statistics type disabled: %s", | 380 | cgit_print_error(fmt("Statistics type disabled: %s", |
375 | period->name)); | 381 | period->name)); |
376 | return; | 382 | return; |
377 | } | 383 | } |
378 | authors = collect_stats(ctx, period); | 384 | authors = collect_stats(ctx, period); |
379 | qsort(authors.items, authors.nr, sizeof(struct string_list_item), | 385 | qsort(authors.items, authors.nr, sizeof(struct string_list_item), |
380 | cmp_total_commits); | 386 | cmp_total_commits); |
381 | 387 | ||
382 | top = ctx->qry.ofs; | 388 | top = ctx->qry.ofs; |
383 | if (!top) | 389 | if (!top) |
384 | top = 10; | 390 | top = 10; |
385 | htmlf("<h2>Commits per author per %s", period->name); | 391 | htmlf("<h2>Commits per author per %s", period->name); |
386 | if (ctx->qry.path) { | 392 | if (ctx->qry.path) { |
387 | html(" (path '"); | 393 | html(" (path '"); |
388 | html_txt(ctx->qry.path); | 394 | html_txt(ctx->qry.path); |
389 | html("')"); | 395 | html("')"); |
390 | } | 396 | } |
391 | html("</h2>"); | 397 | html("</h2>"); |
392 | 398 | ||
393 | html("<form method='get' action='' style='float: right; text-align: right;'>"); | 399 | html("<form method='get' action='' style='float: right; text-align: right;'>"); |
394 | cgit_add_hidden_formfields(1, 0, "stats"); | 400 | cgit_add_hidden_formfields(1, 0, "stats"); |