mobley

C Git HTTP server
Log | Files | Refs | Submodules | README | git clone https://git.ne02ptzero.me/git/mobley

commit d89fc1df0c7f983ba7537ae07df02250bacd87fe
parent b8bd8cf95c6848ace11a7e1adb4e03186cd964da
Author: Louis Solofrizzo <lsolofrizzo@online.net>
Date:   Fri, 21 Dec 2018 11:56:54 +0100

Add static file serving for repository, and image preview in tree

Signed-off-by: Louis Solofrizzo <lsolofrizzo@online.net>

Diffstat:
Mfile.c | 26+++++++++++++++++++++-----
Mmobley.h | 12++++++++++++
Mrepository_handler.c | 7++++++-
Mstatic.c | 93++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Mstyle/main.css | 31++++++++++++++++++++++++-------
5 files changed, 151 insertions(+), 18 deletions(-)

diff --git a/file.c b/file.c @@ -40,21 +40,35 @@ static bool file_show_raw(mobley_t *ctx, server_req_t *r, git_blob *blob) return true; } +static bool file_show_image(mobley_t *ctx, server_req_t *r, const char *path) +{ + html_open("center") { + html_nd("img", + .class = "file-img-preview", + .src = __format("/static/%s/%s", r->repo->name, path), + .closing_slash = true + ); + } html_close("center"); + return true; +} + static bool file_show_header(mobley_t *ctx, server_req_t *r, git_blob *blob, const char *path) { html_open("table", .class = "file-header") { html_open("tr") { html_open("td") { html_nd("i", .class = __format("fa fa-%s fa-fw", file_icon(path))); - } html_close("td"); - - html_open("td") { html("b", path); + html_raw("%zu Bytes", git_blob_rawsize(blob)); } html_close("td"); - html_open("td") { - html_raw("%zu Bytes", git_blob_rawsize(blob)); + html_open("td", .align = "right") { + html("button", "Blame"); + html_open("a", .href = __format("/static/%s/%s", r->repo->name, r->path)) { + html("button", "Raw"); + } html_close("a"); } html_close("td"); + } html_close("tr"); } html_close("table"); html_nd("hr"); @@ -76,6 +90,8 @@ bool file_show(mobley_t *ctx, server_req_t *r, git_tree_entry *entry, bool heade html_open("div", .class = "file-content") { if (file_is_markdown(path)) ret = file_show_markdown(ctx, r, (git_blob *)obj); + else if (file_is_image(path)) + ret = file_show_image(ctx, r, r->path); else ret = file_show_raw(ctx, r, (git_blob *)obj); } html_close("div"); diff --git a/mobley.h b/mobley.h @@ -121,4 +121,16 @@ static inline bool mobley_run(mobley_t *ctx) return true; } +static inline bool mobley_str_is_repo(const mobley_t *ctx, const char *s) +{ + repository_t *repo; + + list_for_each_entry(repo, &ctx->repos.repos, node) + { + if (strcmp(repo->name, s) == 0) + return true; + } + return false; +} + #endif /* MOBLEY_H */ diff --git a/repository_handler.c b/repository_handler.c @@ -245,10 +245,15 @@ static bool repository_route_tree_handler(mobley_t *ctx, server_req_t *r) } else { + r->path = path; ret = file_show(ctx, r, tree, true); } } + if (tree != NULL) + git_tree_entry_free(tree); + git_tree_free(root); + git_commit_free(head); return ret; } @@ -276,7 +281,7 @@ static bool repository_show_readme(mobley_t *ctx, server_req_t *r) if (tree == NULL) goto end; - ret = file_show(ctx, r, tree, true); + ret = file_show(ctx, r, tree, false); end: git_commit_free(head); git_tree_free(root); diff --git a/static.c b/static.c @@ -44,6 +44,62 @@ static bool static_send_file(server_req_t *r, const char *path) return true; } +static bool static_send_raw_repo_object(server_req_t *r, git_blob *blob) +{ + evbuffer_add(r->req->buffer_out, git_blob_rawcontent(blob), git_blob_rawsize(blob)); + return true; +} + +static bool static_send_repo_file(const mobley_t *ctx, server_req_t *r, const char *repo, const char *path) +{ + repository_t *iter = NULL; + git_object *obj; + git_commit *head; + git_tree *root; + git_tree_entry *entry; + bool ret = false; + + list_for_each_entry(iter, &ctx->repos.repos, node) + { + if (strcmp(repo, iter->name) == 0) + break ; + } + + if (iter == NULL) + return false; + + head = repository_get_last_commit(iter, "master"); + if (head == NULL) + goto end; + + git_commit_tree(&root, head); + if (root == NULL) + goto end; + + git_tree_entry_bypath(&entry, root, path); + if (entry == NULL) + goto end; + + git_tree_entry_to_object(&obj, iter->repo, entry); + if (obj == NULL) + goto end; + + if (git_tree_entry_filemode(entry) & GIT_FILEMODE_TREE) + goto end; + + ret = static_send_raw_repo_object(r, (git_blob *)obj); +end: + if (head != NULL) + git_commit_free(head); + if (root != NULL) + git_tree_free(root); + if (entry != NULL) + git_tree_entry_free(entry); + if (obj != NULL) + git_object_free(obj); + return ret; +} + bool static_route_handler(const mobley_t *ctx, server_req_t *r) { string_array_t *node; @@ -51,13 +107,40 @@ bool static_route_handler(const mobley_t *ctx, server_req_t *r) char *cur = path; char *end = path + sizeof(path); - cur += snprintf(path, end - cur, "%s", ctx->conf.static_dir); + node = list_first_entry(&r->uri, string_array_t, node); - list_for_each_entry(node, &r->uri, node) - cur += snprintf(cur, end - cur, "/%s", node->val); + if (!mobley_str_is_repo(ctx, node->val)) + { + cur += snprintf(path, end - cur, "%s", ctx->conf.static_dir); + list_for_each_entry(node, &r->uri, node) + { + cur += snprintf(cur, end - cur, "/%s", node->val); + } - if (!static_send_file(r, path)) - return false; + if (!static_send_file(r, path)) + return false; + } + else + { + char *repo = node->val; + + list_for_each_entry(node, r->uri.next, node) + { + if (node->val == NULL) + continue ; + + if (cur == path) + cur += snprintf(cur, end - cur, "%s", node->val); + else + cur += snprintf(cur, end - cur, "/%s", node->val); + } + + if (!static_send_repo_file(ctx, r, repo, path)) + { + r->res = EVHTP_RES_NOTFOUND; + return false; + } + } return true; } diff --git a/style/main.css b/style/main.css @@ -14,6 +14,21 @@ body { font-size: 15px; } +button { + border: 0; + background: 0; + font-family: 'Inconsolata', monospace; + border: 1px solid #777; + padding: 5px 15px; + color: white; + margin-right: 5px; +} + +button:hover { + background: #b5e853; + cursor: pointer; +} + .desc { color: #777; } @@ -87,7 +102,7 @@ a:hover { } #content { - padding: 5px; + /*padding: 5px;*/ } table { @@ -130,18 +145,15 @@ table tbody .commit a { background: black; } -.file-header { - width: auto; - margin-left: 10px; -} - .file-header tr td { padding: 0; margin: 0; + vertical-align: middle; } .file-header tr i { - margin-right: 0; + margin-right: 2px; + margin-left: 5px; } .file-header tr b { @@ -177,3 +189,8 @@ table tbody .commit a { border: 0 !important; font-size: .85em !important; } + +.file-img-preview { + margin-top: 10px; + background-image: url("data:image/gif;base64,R0lGODlhCgAKAIAAABoaGgAAACwAAAAACgAKAAACEYQdmYcaDNxjEspKndVZbc8UADs="); +}