-rw-r--r-- | cgit.c | 3 | ||||
-rw-r--r-- | cgit.css | 10 | ||||
-rw-r--r-- | cgit.h | 1 | ||||
-rw-r--r-- | ui-repolist.c | 19 |
4 files changed, 32 insertions, 1 deletions
@@ -36,64 +36,66 @@ void config_cb(const char *name, const char *value) else if (!strcmp(name, "module-link")) ctx.cfg.module_link = xstrdup(value); else if (!strcmp(name, "virtual-root")) { ctx.cfg.virtual_root = trim_end(value, '/'); if (!ctx.cfg.virtual_root && (!strcmp(value, "/"))) ctx.cfg.virtual_root = ""; } else if (!strcmp(name, "nocache")) ctx.cfg.nocache = atoi(value); else if (!strcmp(name, "snapshots")) ctx.cfg.snapshots = cgit_parse_snapshots_mask(value); else if (!strcmp(name, "enable-index-links")) ctx.cfg.enable_index_links = atoi(value); else if (!strcmp(name, "enable-log-filecount")) ctx.cfg.enable_log_filecount = atoi(value); else if (!strcmp(name, "enable-log-linecount")) ctx.cfg.enable_log_linecount = atoi(value); else if (!strcmp(name, "cache-size")) ctx.cfg.cache_size = atoi(value); else if (!strcmp(name, "cache-root")) ctx.cfg.cache_root = xstrdup(value); else if (!strcmp(name, "cache-root-ttl")) ctx.cfg.cache_root_ttl = atoi(value); else if (!strcmp(name, "cache-repo-ttl")) ctx.cfg.cache_repo_ttl = atoi(value); else if (!strcmp(name, "cache-static-ttl")) ctx.cfg.cache_static_ttl = atoi(value); else if (!strcmp(name, "cache-dynamic-ttl")) ctx.cfg.cache_dynamic_ttl = atoi(value); else if (!strcmp(name, "max-message-length")) ctx.cfg.max_msg_len = atoi(value); else if (!strcmp(name, "max-repodesc-length")) ctx.cfg.max_repodesc_len = atoi(value); + else if (!strcmp(name, "max-repo-count")) + ctx.cfg.max_repo_count = atoi(value); else if (!strcmp(name, "max-commit-count")) ctx.cfg.max_commit_count = atoi(value); else if (!strcmp(name, "summary-log")) ctx.cfg.summary_log = atoi(value); else if (!strcmp(name, "summary-branches")) ctx.cfg.summary_branches = atoi(value); else if (!strcmp(name, "summary-tags")) ctx.cfg.summary_tags = atoi(value); else if (!strcmp(name, "agefile")) ctx.cfg.agefile = xstrdup(value); else if (!strcmp(name, "renamelimit")) ctx.cfg.renamelimit = atoi(value); else if (!strcmp(name, "robots")) ctx.cfg.robots = xstrdup(value); else if (!strcmp(name, "clone-prefix")) ctx.cfg.clone_prefix = xstrdup(value); else if (!strcmp(name, "repo.group")) ctx.cfg.repo_group = xstrdup(value); else if (!strcmp(name, "repo.url")) ctx.repo = cgit_add_repo(value); else if (!strcmp(name, "repo.name")) ctx.repo->name = xstrdup(value); else if (ctx.repo && !strcmp(name, "repo.path")) ctx.repo->path = trim_end(value, '/'); else if (ctx.repo && !strcmp(name, "repo.clone-url")) ctx.repo->clone_url = xstrdup(value); else if (ctx.repo && !strcmp(name, "repo.desc")) ctx.repo->desc = xstrdup(value); else if (ctx.repo && !strcmp(name, "repo.owner")) ctx.repo->owner = xstrdup(value); else if (ctx.repo && !strcmp(name, "repo.defbranch")) ctx.repo->defbranch = xstrdup(value); @@ -130,64 +132,65 @@ static void querystring_cb(const char *name, const char *value) } else if (!strcmp(name, "h")) { ctx.qry.head = xstrdup(value); ctx.qry.has_symref = 1; } else if (!strcmp(name, "id")) { ctx.qry.sha1 = xstrdup(value); ctx.qry.has_sha1 = 1; } else if (!strcmp(name, "id2")) { ctx.qry.sha2 = xstrdup(value); ctx.qry.has_sha1 = 1; } else if (!strcmp(name, "ofs")) { ctx.qry.ofs = atoi(value); } else if (!strcmp(name, "path")) { ctx.qry.path = trim_end(value, '/'); } else if (!strcmp(name, "name")) { ctx.qry.name = xstrdup(value); } } static void prepare_context(struct cgit_context *ctx) { memset(ctx, 0, sizeof(ctx)); ctx->cfg.agefile = "info/web/last-modified"; ctx->cfg.nocache = 0; ctx->cfg.cache_size = 0; ctx->cfg.cache_dynamic_ttl = 5; ctx->cfg.cache_max_create_time = 5; ctx->cfg.cache_repo_ttl = 5; ctx->cfg.cache_root = CGIT_CACHE_ROOT; ctx->cfg.cache_root_ttl = 5; ctx->cfg.cache_static_ttl = -1; ctx->cfg.css = "/cgit.css"; ctx->cfg.logo = "/git-logo.png"; + ctx->cfg.max_repo_count = 50; ctx->cfg.max_commit_count = 50; ctx->cfg.max_lock_attempts = 5; ctx->cfg.max_msg_len = 60; ctx->cfg.max_repodesc_len = 60; ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s"; ctx->cfg.renamelimit = -1; ctx->cfg.robots = "index, nofollow"; ctx->cfg.root_title = "Git repository browser"; ctx->cfg.root_desc = "a fast webinterface for the git dscm"; ctx->cfg.script_name = CGIT_SCRIPT_NAME; ctx->page.mimetype = "text/html"; ctx->page.charset = PAGE_ENCODING; ctx->page.filename = NULL; ctx->page.modified = time(NULL); ctx->page.expires = ctx->page.modified; } struct refmatch { char *req_ref; char *first_ref; int match; }; int find_current_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data) { struct refmatch *info; info = (struct refmatch *)cb_data; if (!strcmp(refname, info->req_ref)) info->match = 1; if (!info->first_ref) @@ -384,56 +384,66 @@ table.diff td div.del { } .right { text-align: right; } table.list td.repogroup { font-style: italic; color: #888; } a.button { font-size: 80%; padding: 0em 0.5em; } a.primary { font-size: 100%; } a.secondary { font-size: 90%; } td.toplevel-repo { } table.list td.sublevel-repo { padding-left: 1.5em; } +div.pager { + text-align: center; + margin: 1em 0em 0em 0em; +} + +div.pager a { + color: #777; + margin: 0em 0.5em; +} + span.age-mins { font-weight: bold; color: #080; } span.age-hours { color: #080; } span.age-days { color: #040; } span.age-weeks { color: #444; } span.age-months { color: #888; } span.age-years { color: #bbb; } @@ -116,64 +116,65 @@ struct cgit_query { char *sha2; char *path; char *name; int ofs; }; struct cgit_config { char *agefile; char *cache_root; char *clone_prefix; char *css; char *index_header; char *index_info; char *logo; char *logo_link; char *module_link; char *repo_group; char *robots; char *root_title; char *root_desc; char *root_readme; char *script_name; char *virtual_root; int cache_size; int cache_dynamic_ttl; int cache_max_create_time; int cache_repo_ttl; int cache_root_ttl; int cache_static_ttl; int enable_index_links; int enable_log_filecount; int enable_log_linecount; + int max_repo_count; int max_commit_count; int max_lock_attempts; int max_msg_len; int max_repodesc_len; int nocache; int renamelimit; int snapshots; int summary_branches; int summary_log; int summary_tags; }; struct cgit_page { time_t modified; time_t expires; char *mimetype; char *charset; char *filename; char *title; }; struct cgit_context { struct cgit_query qry; struct cgit_config cfg; struct cgit_repo *repo; struct cgit_page page; }; struct cgit_snapshot_format { const char *suffix; const char *mimetype; write_archive_fn_t write_func; diff --git a/ui-repolist.c b/ui-repolist.c index 3f78e28..ee4facb 100644 --- a/ui-repolist.c +++ b/ui-repolist.c @@ -42,103 +42,120 @@ static void print_modtime(struct cgit_repo *repo) if (stat(path, &s) != 0) return; cgit_print_age(s.st_mtime, -1, NULL); } int is_match(struct cgit_repo *repo) { if (!ctx.qry.search) return 1; if (repo->url && strcasestr(repo->url, ctx.qry.search)) return 1; if (repo->name && strcasestr(repo->name, ctx.qry.search)) return 1; if (repo->desc && strcasestr(repo->desc, ctx.qry.search)) return 1; if (repo->owner && strcasestr(repo->owner, ctx.qry.search)) return 1; return 0; } void print_header(int columns) { html("<tr class='nohover'>" "<th class='left'>Name</th>" "<th class='left'>Description</th>" "<th class='left'>Owner</th>" "<th class='left'>Idle</th>"); if (ctx.cfg.enable_index_links) html("<th class='left'>Links</th>"); html("</tr>\n"); } + +void print_pager(int items, int pagelen, char *search) +{ + int i; + html("<div class='pager'>"); + for(i = 0; i * pagelen < items; i++) + cgit_index_link(fmt("[%d]", i+1), fmt("Page %d", i+1), NULL, + search, i * pagelen); + html("</div>"); +} + void cgit_print_repolist() { int i, columns = 4, hits = 0, header = 0; char *last_group = NULL; if (ctx.cfg.enable_index_links) columns++; ctx.page.title = ctx.cfg.root_title; cgit_print_http_headers(&ctx); cgit_print_docstart(&ctx); cgit_print_pageheader(&ctx); if (ctx.cfg.index_header) html_include(ctx.cfg.index_header); html("<table summary='repository list' class='list nowrap'>"); for (i=0; i<cgit_repolist.count; i++) { ctx.repo = &cgit_repolist.repos[i]; if (!is_match(ctx.repo)) continue; + hits++; + if (hits <= ctx.qry.ofs) + continue; + if (hits > ctx.qry.ofs + ctx.cfg.max_repo_count) + continue; if (!header++) print_header(columns); - hits++; if ((last_group == NULL && ctx.repo->group != NULL) || (last_group != NULL && ctx.repo->group == NULL) || (last_group != NULL && ctx.repo->group != NULL && strcmp(ctx.repo->group, last_group))) { htmlf("<tr class='nohover'><td colspan='%d' class='repogroup'>", columns); html_txt(ctx.repo->group); html("</td></tr>"); last_group = ctx.repo->group; } htmlf("<tr><td class='%s'>", ctx.repo->group ? "sublevel-repo" : "toplevel-repo"); html_link_open(cgit_repourl(ctx.repo->url), NULL, NULL); html_txt(ctx.repo->name); html_link_close(); html("</td><td>"); html_link_open(cgit_repourl(ctx.repo->url), NULL, NULL); html_ntxt(ctx.cfg.max_repodesc_len, ctx.repo->desc); html_link_close(); html("</td><td>"); html_txt(ctx.repo->owner); html("</td><td>"); print_modtime(ctx.repo); html("</td>"); if (ctx.cfg.enable_index_links) { html("<td>"); html_link_open(cgit_repourl(ctx.repo->url), NULL, "button"); html("summary</a>"); cgit_log_link("log", NULL, "button", NULL, NULL, NULL, 0, NULL, NULL); cgit_tree_link("tree", NULL, "button", NULL, NULL, NULL); html("</td>"); } html("</tr>\n"); } html("</table>"); if (!hits) cgit_print_error("No repositories found"); + else if (hits > ctx.cfg.max_repo_count) + print_pager(hits, ctx.cfg.max_repo_count, ctx.qry.search); cgit_print_docend(); } void cgit_print_site_readme() { if (ctx.cfg.root_readme) html_include(ctx.cfg.root_readme); } |