adding summary container id to move the summary table to the right
[webgit] / src / actions.c
1 /*
2     cehtehs git web frontend
3
4   Copyright (C)
5     2007,               Christian Thaeter <ct@pipapo.org>
6
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.
11
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.
16
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.
20 */
21
22 #include "actions.h"
23 #include "summary.h"
24 #include "object.h"
25 #include "log.h"
26 #include "repo.h"
27 #include "age.h"
28 #include "branch.h"
29 #include "tag.h"
30
31 #include "llist.h"
32 #include <cwa.h>
33
34 /* todo configure this */
35 #define SHA1_HEADER <openssl/sha.h>
36 #include "git/cache.h"
37 #include "git/refs.h"
38
39 #include <stdio.h>
40
41
42 /*
43   Main (repository list) page
44 */
45 static Html
46 webgit_main_menu_action (struct webgit_query* query)
47 {
48   (void) query;
49   return html ("TODO: main menu");
50 }
51
52 static Html
53 webgit_header_action (struct webgit_query* query)
54 {
55   (void) query;
56   return html (
57                "webgit header action"
58                );
59 }
60
61 static Html
62 webgit_main_content_action (struct webgit_query* query)
63 {
64   Html table = html_list ();
65
66   html_list_append (table, html(
67                           html(html_tag ("tr"),
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")
76                                ),
77                           html_nl()
78                           )
79               );
80
81   LLIST_FOREACH (&query->repos, node)
82     {
83       struct webgit_repo_info* n = (struct webgit_repo_info*)node;
84
85       webgit_repoinfo_find_last (n);
86
87       html_list_append (table, html (
88                                      /*
89                                        It would be great to have alternate rows with class="odd" or class="even"
90                                        html_tag ("tr", html_attr ("class", "odd")),
91                                       */
92                                      html_tag ("tr"),
93                                      html(html_tag ("td"),
94                                           webgit_summary_link (query, n, html (n->name))),
95                                      html(html_tag ("td"), n->url ?
96                                           html (
97                                                 html_tag ("a", html_attr ("href", n->url)),
98                                                 n->url)
99                                           : html("N/A")
100                                           ),
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),
106                                                               n->last_commit, 40,
107                                                               NULL,
108                                                               NULL,
109                                                               webgit_pretty_age (n->age))
110                                           ),
111                                      html(html_tag ("td"),
112                                           webgit_email_link (
113                                                              html (n->last_author_name),
114                                                              html (n->last_author_email)
115                                                              )
116                                           ),
117                                      html(html_tag ("td"),
118                                           webgit_email_link (
119                                                              html (n->last_committer_name),
120                                                              html (n->last_committer_email)
121                                                              )
122                                           ),
123                                      html(html_tag ("td"),
124                                           html(
125                                                webgit_log_link (query,
126                                                                 n->name,
127                                                                 n->last_head,
128                                                                 NULL, 0,
129                                                                 query->count,
130                                                                 html("Log")
131                                                                 ),
132                                                " ",
133
134                                                "Diff ",
135                                                //webgit_diff_link (query, n, n->last_head, html("Diff")),
136                                                //" ",
137                                                webgit_object_link (query,
138                                                                    n->name, strlen(n->name),
139                                                                    n->last_tree, 40,
140                                                                    NULL,
141                                                                    NULL,
142                                                                    html("Tree"))
143                                                )
144                                           )
145                                      ),
146                         html_nl()
147                         );
148     }
149
150   return html (html_tag ("table", html_attr ("id", "summary")), table);
151 }
152
153 static Html
154 webgit_main_action (struct webgit_query* query)
155 {
156   return html(
157               html(html_tag("div", html_attr("class", "sub-menu")), webgit_header_action (query)), html_nl (),
158               html(html_tag("div", html_attr("id", "main-menu")), webgit_main_menu_action (query)), html_nl (),
159               html(html_tag("div", html_attr("id", "summary-container")), webgit_main_content_action (query)), html_nl ()
160               );
161 }
162
163
164 /*
165   Summary of a single repository
166 */
167 static Html
168 webgit_summary_menu_action (struct webgit_repo_info* repo)
169 {
170   (void) repo;
171   return html ("TODO: summary");
172 }
173
174
175 static Html
176 webgit_summary_content_action (struct webgit_repo_info* repo)
177 {
178   Html content = html_list ();
179
180   /* Title */
181   html_list_append (content, html (html_tag ("h1"), repo->description));
182
183   /* Readme */
184   if (repo->readme)
185     html_list_append (content, html_include (repo->readme));
186
187   /* Info */
188   html_list_append (content,
189                     html (
190                           html (html_tag ("h2"), "Repository information"),
191                           repo->url ?
192                           html (
193                                 html_tag ("div"),
194                                 "Public URL: ",
195                                 html (
196                                       html_tag ("a", html_attr ("href", repo->url)),
197                                       repo->url
198                                       )
199                                 ) : html(),
200                           html (
201                                 html_tag ("div"),
202                                 "Owner: ", repo->owner
203                                 ),
204                           html(
205                                html_tag ("div"),
206                                "Last change: ",
207                                webgit_object_link (repo->query,
208                                                    repo->name, strlen(repo->name),
209                                                    repo->last_commit, 40,
210                                                    NULL,
211                                                    NULL,
212                                                    webgit_pretty_age (repo->age)),
213                                " in branch ",
214                                 webgit_log_link (repo->query,
215                                                  repo->name,
216                                                  repo->last_head,
217                                                  NULL, 0,
218                                                  repo->query->count,
219                                                  html ("'", repo->last_head, "'")
220                                                  )
221                                )
222                           )
223                     );
224
225   /* log */
226   html_list_append (content,
227                     html (
228                           html (html_tag ("h2"), "Log of branch '", repo->last_head, "'"),
229                           webgit_log_table (repo->query, repo->last_head, 5 /*TODO: config this*/, 0))
230                     );
231
232
233   /* branches */
234   html_list_append (content,
235                     html (
236                           html (html_tag ("h2"), "Branches"),
237                           webgit_branch_table (repo, NULL, 5 /*TODO: config this*/)
238                           )
239                     );
240
241   /* tags */
242   html_list_append (content,
243                     html (
244                           html (html_tag ("h2"), "Tags"),
245                           webgit_tag_table (repo, NULL, 5 /*TODO: config this*/)
246                           )
247                     );
248
249
250   return content;
251 }
252
253
254 static Html
255 webgit_summary_action (struct webgit_query* query)
256 {
257   struct webgit_repo_info* repo = webgit_repo_enter (query);
258   webgit_repoinfo_find_last (repo);
259
260   return html(
261               html(html_tag("div"), webgit_summary_menu_action (repo)), html_nl (),
262               html(html_tag("div"), webgit_summary_content_action (repo)), html_nl ()
263               );
264 }
265
266
267 /*
268   Log page
269 */
270 static Html
271 webgit_log_action (struct webgit_query* query)
272 {
273   webgit_repo_enter (query);
274
275   return html(
276               html(html_tag("div"), webgit_log_menu_action (query)), html_nl (),
277               html(html_tag("div"), webgit_log_content_action (query)), html_nl ()
278               );
279 }
280
281
282 /*
283   Diff page
284 */
285 static Html
286 webgit_diff_action (struct webgit_query* query)
287 {
288   (void) query;
289   return html("diff");
290 }
291
292
293 /*
294   pretty printed objects
295 */
296 static Html
297 webgit_object_action (struct webgit_query* query)
298 {
299   struct webgit_repo_info* repo = webgit_repo_enter (query);
300
301   unsigned char sha1[20];
302   if (get_sha1 (query->object, sha1))
303     return html("error: unknown object");
304
305   switch (sha1_object_info(sha1, NULL))
306     {
307     case OBJ_COMMIT:
308       if (!query->deref_to_tree)
309         return webgit_object_commit_action (repo, sha1);
310       /* else fallthrough */
311     case OBJ_TREE:
312       return webgit_object_tree_action (repo, sha1);
313     case OBJ_BLOB:
314       return webgit_object_blob_action (repo, sha1);
315     case OBJ_TAG:
316       return webgit_object_tag_action (repo, sha1);
317
318       break;
319     default:
320       return html ("error: unknown object type");
321       break;
322     }
323 }
324
325
326 /*
327   treeish dereferenced to tree
328 */
329 static Html
330 webgit_tree_action (struct webgit_query* query)
331 {
332   query->deref_to_tree = 1;
333   return webgit_object_action (query);
334 }
335
336
337 /*
338   spew out raw data
339 */
340 static Html
341 webgit_raw_action (struct webgit_query* query)
342 {
343   webgit_repo_enter (query);
344
345   unsigned char sha1[20];
346   if (get_sha1 (query->object, sha1))
347     return html("error: unknown object");
348
349   void* buf;
350   unsigned long size;
351
352   buf = read_object_with_reference (sha1, "blob", &size, NULL);
353
354   free ((char*)query->content_type);
355   query->content_type = webgit_mimetype (query->path);
356
357   return html_binary (buf, size);
358 }
359
360
361 /*
362   show branch
363 */
364 static Html
365 webgit_branch_menu_action (struct webgit_repo_info* repo)
366 {
367   (void) repo;
368   return html ("TODO: branch sidebar");
369 }
370
371
372 static Html
373 webgit_branch_action (struct webgit_query* query)
374 {
375   struct webgit_repo_info* repo = webgit_repo_enter (query);
376   webgit_repoinfo_find_last (repo);
377
378   return html(
379               html(html_tag("div", html_attr("id", "header")), webgit_header_action (query)), html_nl (),
380               html(html_tag("div", html_attr("class", "sub-menu")), webgit_branch_menu_action (repo)), html_nl (),
381               html(html_tag("div"), webgit_branch_table (repo, query->head, query->count), html_nl ())
382               );
383 }
384
385
386 /*
387   show tag
388 */
389 static Html
390 webgit_tag_action (struct webgit_query* query)
391 {
392   (void) query;
393   return html("tag");
394 }
395
396
397 /*
398   show and edit config
399 */
400 static Html
401 webgit_config_menu_action (struct webgit_repo_info* repo)
402 {
403   (void) repo;
404   return html ("TODO: config menu");
405 }
406
407 static Html
408 webgit_config_content_action (struct webgit_repo_info* repo)
409 {
410   int readonly = !!access (git_path("config"), W_OK);
411
412   return html (
413                html_tag ("form",
414                          html_attr ("name", "config-change"),
415                          html_attr ("enctype", "multipart/form-data"),
416                          html_attr ("method", "post"),
417                          html_attr ("action",
418                                     html_fmt ("%s",
419                                               repo->query->request->script_name
420                                               )
421                                     )
422                          ),
423
424                html_hidden ("repo", repo->name),
425                html_hidden ("action", "config"),
426                html (
427                      html_tag ("textarea",
428                                html_attr ("name", "blob"),
429                                html_attr ("rows", "40"),
430                                html_attr ("cols", "80"),
431                                readonly ? "readonly" : ""
432                                ),
433                      html_include_escaped (git_path("config"))
434                      ),
435                readonly ? html ()
436                : html (
437                        html_tag ("input",
438                                  html_attr ("type", "submit"),
439                                  html_attr ("value", "Save")
440                                  )
441                        )
442                );
443 }
444
445 static Html
446 webgit_config_action (struct webgit_query* query)
447 {
448   struct webgit_repo_info* repo = webgit_repo_enter (query);
449   webgit_repoinfo_find_last (repo);
450
451   if (query->blob)
452     {
453       FILE* cfg = fopen (git_path ("config"), "w");
454  
455       /*TODO rxpd check */
456       if (!cfg)
457         webgit_warn ("could not open %s for writing", git_path("config"));
458       else
459         {
460           if (fwrite (query->blob, query->blob_size, 1, cfg) < 1)
461             webgit_warn ("could not write config");
462           fclose (cfg);
463         }
464     }
465
466   return html(
467               html (html_tag ("div"), webgit_config_menu_action (repo)), html_nl (),
468               html (html_tag ("div"), webgit_config_content_action (repo)), html_nl ()
469               );
470 }
471
472
473 /*
474   edit an object
475 */
476 static Html
477 webgit_edit_action (struct webgit_query* query)
478 {
479   (void) query;
480   return html("edit");
481 }
482
483 /*
484   commit changes
485 */
486 static Html
487 webgit_commit_action (struct webgit_query* query)
488 {
489   (void) query;
490   return html("commit");
491 }
492
493
494 Html
495 webgit_action_dispatch (struct webgit_query* query)
496 {
497 #define WEBGIT_ACTION(name, _)                  \
498 {                                               \
499  #name,                                         \
500  webgit_##name##_action,                        \
501 },
502   struct action_table{
503     char* name;
504     Html (*cb)(struct webgit_query* query);
505   } cmds[] = {WEBGIT_ACTIONS {"", NULL}};
506 #undef WEBGIT_ACTION
507
508   for (struct action_table* j = cmds; j->cb; ++j)
509     {
510       if (!strcmp (j->name, query->action))
511         return j->cb (query);
512     }
513   return html("error, no such action");
514 }
515
516
517
518 /*
519 //      Local Variables:
520 //      mode: C
521 //      c-file-style: "gnu"
522 //      indent-tabs-mode: nil
523 //      End:
524 */