2 cehtehs git web frontend
5 2007, Christian Thaeter <ct@pipapo.org>
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34 /* todo configure this */
35 #define SHA1_HEADER <openssl/sha.h>
36 #include "git/cache.h"
43 Main (repository list) page
46 webgit_main_menu_action (struct webgit_query* query)
49 return html ("TODO: main menu");
53 webgit_header_action (struct webgit_query* query)
57 "webgit header action"
62 webgit_main_content_action (struct webgit_query* query)
64 Html table = html_list ();
66 html_list_append (table, html(
68 html(html_tag ("th"),"Name"),
69 html(html_tag ("th"),"Git URL"),
70 html(html_tag ("th"),"Description"),
71 html(html_tag ("th"),"Owner"),
72 html(html_tag ("th"),"Last Change"),
73 html(html_tag ("th"),"Author"),
74 html(html_tag ("th"),"Committer"),
75 html(html_tag ("th"),"Action")
81 LLIST_FOREACH (&query->repos, node)
83 struct webgit_repo_info* n = (struct webgit_repo_info*)node;
85 webgit_repoinfo_find_last (n);
87 html_list_append (table, html (
89 It would be great to have alternate rows with class="odd" or class="even"
90 html_tag ("tr", html_attr ("class", "odd")),
94 webgit_summary_link (query, n, html (n->name))),
95 html(html_tag ("td"), n->url ?
97 html_tag ("a", html_attr ("href", n->url)),
101 html(html_tag ("td"), n->description),
102 html(html_tag ("td"), n->owner),
103 html(html_tag ("td"),
104 webgit_object_link (query,
105 n->name, strlen(n->name),
109 webgit_pretty_age (n->age))
111 html(html_tag ("td"),
113 html (n->last_author_name),
114 html (n->last_author_email)
117 html(html_tag ("td"),
119 html (n->last_committer_name),
120 html (n->last_committer_email)
123 html(html_tag ("td"),
125 webgit_log_link (query,
135 //webgit_diff_link (query, n, n->last_head, html("Diff")),
137 webgit_object_link (query,
138 n->name, strlen(n->name),
150 return html (html_tag ("table", html_attr ("id", "summary")), table);
154 webgit_main_action (struct webgit_query* query)
157 html(html_tag("div", html_attr("id", "sub-menu")), webgit_header_action (query)), html_nl (),
159 I'm not sure if we need this? Is the sub-menu sufficient?
160 html(html_tag("div"), webgit_main_menu_action (query)), html_nl (),
162 html(html_tag("div", html_attr("id", "content")), webgit_main_content_action (query)), html_nl ()
168 Summary of a single repository
171 webgit_summary_menu_action (struct webgit_repo_info* repo)
174 return html ("TODO: summary");
179 webgit_summary_content_action (struct webgit_repo_info* repo)
181 Html content = html_list ();
184 html_list_append (content, html (html_tag ("h1"), repo->description));
188 html_list_append (content, html_include (repo->readme));
191 html_list_append (content,
193 html (html_tag ("h2"), "Repository information"),
199 html_tag ("a", html_attr ("href", repo->url)),
205 "Owner: ", repo->owner
210 webgit_object_link (repo->query,
211 repo->name, strlen(repo->name),
212 repo->last_commit, 40,
215 webgit_pretty_age (repo->age)),
217 webgit_log_link (repo->query,
222 html ("'", repo->last_head, "'")
229 html_list_append (content,
231 html (html_tag ("h2"), "Log of branch '", repo->last_head, "'"),
232 webgit_log_table (repo->query, repo->last_head, 5 /*TODO: config this*/, 0))
237 html_list_append (content,
239 html (html_tag ("h2"), "Branches"),
240 webgit_branch_table (repo, NULL, 5 /*TODO: config this*/)
245 html_list_append (content,
247 html (html_tag ("h2"), "Tags"),
248 webgit_tag_table (repo, NULL, 5 /*TODO: config this*/)
258 webgit_summary_action (struct webgit_query* query)
260 struct webgit_repo_info* repo = webgit_repo_enter (query);
261 webgit_repoinfo_find_last (repo);
264 html(html_tag("div"), webgit_summary_menu_action (repo)), html_nl (),
265 html(html_tag("div"), webgit_summary_content_action (repo)), html_nl ()
274 webgit_log_action (struct webgit_query* query)
276 webgit_repo_enter (query);
279 html(html_tag("div"), webgit_log_menu_action (query)), html_nl (),
280 html(html_tag("div"), webgit_log_content_action (query)), html_nl ()
289 webgit_diff_action (struct webgit_query* query)
297 pretty printed objects
300 webgit_object_action (struct webgit_query* query)
302 struct webgit_repo_info* repo = webgit_repo_enter (query);
304 unsigned char sha1[20];
305 if (get_sha1 (query->object, sha1))
306 return html("error: unknown object");
308 switch (sha1_object_info(sha1, NULL))
311 if (!query->deref_to_tree)
312 return webgit_object_commit_action (repo, sha1);
313 /* else fallthrough */
315 return webgit_object_tree_action (repo, sha1);
317 return webgit_object_blob_action (repo, sha1);
319 return webgit_object_tag_action (repo, sha1);
323 return html ("error: unknown object type");
330 treeish dereferenced to tree
333 webgit_tree_action (struct webgit_query* query)
335 query->deref_to_tree = 1;
336 return webgit_object_action (query);
344 webgit_raw_action (struct webgit_query* query)
346 webgit_repo_enter (query);
348 unsigned char sha1[20];
349 if (get_sha1 (query->object, sha1))
350 return html("error: unknown object");
355 buf = read_object_with_reference (sha1, "blob", &size, NULL);
357 free ((char*)query->content_type);
358 query->content_type = webgit_mimetype (query->path);
360 return html_binary (buf, size);
368 webgit_branch_menu_action (struct webgit_repo_info* repo)
371 return html ("TODO: branch sidebar");
376 webgit_branch_action (struct webgit_query* query)
378 struct webgit_repo_info* repo = webgit_repo_enter (query);
379 webgit_repoinfo_find_last (repo);
382 html(html_tag("div", html_attr("id", "header")), webgit_header_action (query)), html_nl (),
383 html(html_tag("div", html_attr("id", "sub-menu")), webgit_branch_menu_action (repo)), html_nl (),
384 html(html_tag("div", html_attr("id", "content")), webgit_branch_table (repo, query->head, query->count), html_nl ())
393 webgit_tag_action (struct webgit_query* query)
404 webgit_config_menu_action (struct webgit_repo_info* repo)
407 return html ("TODO: config menu");
411 webgit_config_content_action (struct webgit_repo_info* repo)
413 int readonly = !!access (git_path("config"), W_OK);
417 html_attr ("name", "config-change"),
418 html_attr ("enctype", "multipart/form-data"),
419 html_attr ("method", "post"),
422 repo->query->request->script_name
427 html_hidden ("repo", repo->name),
428 html_hidden ("action", "config"),
430 html_tag ("textarea",
431 html_attr ("name", "blob"),
432 html_attr ("rows", "40"),
433 html_attr ("cols", "80"),
434 readonly ? "readonly" : ""
436 html_include_escaped (git_path("config"))
441 html_attr ("type", "submit"),
442 html_attr ("value", "Save")
449 webgit_config_action (struct webgit_query* query)
451 struct webgit_repo_info* repo = webgit_repo_enter (query);
452 webgit_repoinfo_find_last (repo);
456 FILE* cfg = fopen (git_path ("config"), "w");
460 webgit_warn ("could not open %s for writing", git_path("config"));
463 if (fwrite (query->blob, query->blob_size, 1, cfg) < 1)
464 webgit_warn ("could not write config");
470 html (html_tag ("div"), webgit_config_menu_action (repo)), html_nl (),
471 html (html_tag ("div"), webgit_config_content_action (repo)), html_nl ()
480 webgit_edit_action (struct webgit_query* query)
490 webgit_commit_action (struct webgit_query* query)
493 return html("commit");
498 webgit_action_dispatch (struct webgit_query* query)
500 #define WEBGIT_ACTION(name, _) \
503 webgit_##name##_action, \
507 Html (*cb)(struct webgit_query* query);
508 } cmds[] = {WEBGIT_ACTIONS {"", NULL}};
511 for (struct action_table* j = cmds; j->cb; ++j)
513 if (!strcmp (j->name, query->action))
514 return j->cb (query);
516 return html("error, no such action");
524 // c-file-style: "gnu"
525 // indent-tabs-mode: nil