silence a lot of compiler warnings with some stubs
[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
29 #include "llist.h"
30 #include <cwa.h>
31
32 /* todo configure this */
33 #define SHA1_HEADER <openssl/sha.h>
34 #include "git/cache.h"
35 #include "git/commit.h"
36 #include "git/diff.h"
37 #include "git/revision.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 sidebar");
50 }
51
52 static Html
53 webgit_main_content_action (struct webgit_query* query)
54 {
55   Html table = html_list ();
56
57   html_list_append (table, html(
58                           html(html_tag ("tr"),
59                                html(html_tag ("th"),"Name"),
60                                html(html_tag ("th"),"Git URL"),
61                                html(html_tag ("th"),"Description"),
62                                html(html_tag ("th"),"Owner"),
63                                html(html_tag ("th"),"Last Change"),
64                                html(html_tag ("th"),"Author"),
65                                html(html_tag ("th"),"Committer"),
66                                html(html_tag ("th"),"Action")
67                                ),
68                           html_nl()
69                           )
70               );
71
72   LLIST_FOREACH (&query->repos, node)
73     {
74       struct webgit_repo_info* n = (struct webgit_repo_info*)node;
75
76       webgit_repoinfo_find_last (n);
77
78       html_list_append (table, html (
79                                      html_tag ("tr"),
80                                      html(html_tag ("td"), webgit_summary_link (query, n, html (n->name))),
81                                      html(html_tag ("td"), n->url ?
82                                           html (
83                                                 html_tag ("a", html_attr ("href", n->url)),
84                                                 n->url)
85                                           : html("N/A")
86                                           ),
87                                      html(html_tag ("td"), n->description),
88                                      html(html_tag ("td"), n->owner),
89                                      html(html_tag ("td"),
90                                           webgit_object_link (query,
91                                                               n->name, strlen(n->name),
92                                                               n->last_commit, 40,
93                                                               NULL,
94                                                               webgit_pretty_age (n->age))
95                                           ),
96                                      html(html_tag ("td"),
97                                           webgit_email_link (
98                                                              html (n->last_author_name),
99                                                              html (n->last_author_email)
100                                                              )
101                                           ),
102                                      html(html_tag ("td"),
103                                           webgit_email_link (
104                                                              html (n->last_committer_name),
105                                                              html (n->last_committer_email)
106                                                              )
107                                           ),
108                                      html(html_tag ("td"),
109                                           html(
110                                                webgit_log_link (query,
111                                                                 n->name,
112                                                                 n->last_head,
113                                                                 NULL, 0,
114                                                                 query->count,
115                                                                 html("Log")
116                                                                 ),
117                                                " ",
118
119                                                "Diff ",
120                                                //webgit_diff_link (query, n, n->last_head, html("Diff")),
121                                                //" ",
122                                                webgit_object_link (query,
123                                                                    n->name, strlen(n->name),
124                                                                    n->last_tree, 40,
125                                                                    NULL,
126                                                                    html("Tree"))
127                                                )
128                                           )
129                                      ),
130                         html_nl()
131                         );
132     }
133
134   return html (html_tag ("table", html_attr ("border", "1")), table);
135 }
136
137 static Html
138 webgit_main_action (struct webgit_query* query)
139 {
140   return html(
141               html(html_tag("div"), webgit_main_menu_action (query)), html_nl (),
142               html(html_tag("div"), webgit_main_content_action (query)), html_nl ()
143               );
144 }
145
146
147 /*
148   Summary of a single repository
149 */
150 static Html
151 webgit_summary_action (struct webgit_query* query)
152 {
153   (void) query;
154   return html("summary");
155 }
156
157
158 /*
159   Log page
160 */
161 static Html
162 webgit_log_menu_action (struct webgit_query* query)
163 {
164   (void) query;
165   return html ("TODO: log sidebar");
166 }
167
168
169 static Html
170 webgit_log_content_action (struct webgit_query* query)
171 {
172   webgit_enter_repository (query);
173
174   struct rev_info rev;
175   const char* object;
176   if (query->object)
177     object = query->object;
178   else if (query->head)
179     object = query->head;
180   else
181     object = "HEAD";
182
183   const char* argv[] = {NULL, object, NULL};
184   int argc = 2;
185
186   init_revisions (&rev, NULL);
187   rev.verbose_header = 1;
188   rev.topo_order = 1;
189
190   setup_revisions (argc, argv, &rev, NULL);
191
192   prepare_revision_walk(&rev);
193
194   Html table = html_list ();
195   Html cont = html_list ();
196
197   fprintf (stderr, "%s\n", query->object);
198
199   unsigned char sha1[20];
200   if (query->object)
201     get_sha1 (query->object, sha1);
202
203   int cnt = query->count;
204
205   struct commit *commit;
206   while ((commit = get_revision (&rev)))
207     {
208       if (query->object)
209         {
210           if (!hashcmp (sha1, commit->object.sha1))
211             {
212               /* found first commit to display */
213               free (query->object);
214               query->object = NULL;
215             }
216           else
217             /* not yet, fall through */
218             continue;
219         }
220
221       if (!cnt--)
222         {
223           /* displayed query->count lines, finish */
224
225           html_list_append (cont,
226                             webgit_log_link (
227                                              query,
228                                              query->repo,
229                                              query->head,
230                                              sha1_to_hex(commit->object.sha1), 40,
231                                              query->count_def,
232                                              html("More..."))
233                             );
234           free(commit->buffer);
235           commit->buffer = NULL;
236           free_commit_list(commit->parents);
237           commit->parents = NULL;
238           break;
239         }
240
241       struct tm tm;
242       webgit_commit_committer_date_parse (commit, &tm);
243
244       char pretty_date[256];
245       strftime (pretty_date, 255, "%c", &tm);
246
247       html_list_append (table,
248                         html (
249                               html (
250                                     html_tag ("tr"),
251                                     html(html_tag ("td"),
252                                          html_strndup (pretty_date, 254)
253                                          ),
254                                     html(html_tag ("td"),
255                                          webgit_object_link (query,
256                                                              query->repo,
257                                                              strlen (query->repo),
258                                                              sha1_to_hex (commit->object.sha1),
259                                                              40,
260                                                              NULL,
261                                                              webgit_header_parse (commit)
262                                                              )
263                                          )
264                                     ),
265                               html (
266                                     html_tag ("tr"),
267                                     html(html_tag ("td"),
268                                          webgit_email_link (
269                                                             webgit_commit_author_name_parse (commit),
270                                                             webgit_commit_author_email_parse (commit)
271                                                             )
272                                          ),
273                                     html (html_tag ("td"),
274                                          html(
275                                               "Diff ",
276                                               " ",
277                                               webgit_object_link (query,
278                                                                   query->repo,
279                                                                   strlen (query->repo),
280                                                                   webgit_commit_tree_parse (commit),
281                                                                   40,
282                                                                   NULL,
283                                                                   html ("Tree")
284                                                                   )
285                                               )
286                                           )
287                                     ),
288                               html (
289                                     html_tag ("tr"),
290                                     html(html_tag ("td", html_attr ("colspan", "2")),
291                                          html(html_tag ("pre"),
292                                               webgit_message_parse (commit)
293                                               ),
294                                          html(html_tag ("hr"))
295                                          )
296                                     )
297                               )
298                         );
299
300
301 #if 0 /* traverse parents */
302       struct commit *parent;
303       while ((parent = pop_commit (&commit->parents)))
304         {
305         }
306 #endif
307
308       free(commit->buffer);
309       commit->buffer = NULL;
310       free_commit_list(commit->parents);
311       commit->parents = NULL;
312     }
313
314   return html (html ( html_tag ("table"), table), cont);
315 }
316
317
318 static Html
319 webgit_log_action (struct webgit_query* query)
320 {
321   return html(
322               html(html_tag("div"), webgit_log_menu_action (query)), html_nl (),
323               html(html_tag("div"), webgit_log_content_action (query)), html_nl ()
324               );
325 }
326
327
328 /*
329   Diff page
330 */
331 static Html
332 webgit_diff_action (struct webgit_query* query)
333 {
334   (void) query;
335   return html("diff");
336 }
337
338
339 /*
340   pretty printed objects
341 */
342 static Html
343 webgit_object_action (struct webgit_query* query)
344 {
345   webgit_enter_repository (query);
346
347   unsigned char sha1[20];
348   if (get_sha1 (query->object, sha1))
349     return html("error: unknown object");
350
351   switch (sha1_object_info(sha1, NULL))
352     {
353     case OBJ_COMMIT:
354       if (!query->deref_to_tree)
355         return webgit_object_commit_action (query, sha1);
356       /* else fallthrough */
357     case OBJ_TREE:
358       return webgit_object_tree_action (query, sha1);
359     case OBJ_BLOB:
360       return webgit_object_blob_action (query, sha1);
361     case OBJ_TAG:
362       return html ("its a tag");
363
364       break;
365     default:
366       return html ("error: unknown object type");
367       break;
368     }
369 }
370
371
372 /*
373   treeish dereferenced to tree
374 */
375 static Html
376 webgit_tree_action (struct webgit_query* query)
377 {
378   query->deref_to_tree = 1;
379   return webgit_object_action (query);
380 }
381
382
383 /*
384   spew out raw data
385 */
386 static Html
387 webgit_raw_action (struct webgit_query* query)
388 {
389   webgit_enter_repository (query);
390
391   unsigned char sha1[20];
392   if (get_sha1 (query->object, sha1))
393     return html("error: unknown object");
394
395   void* buf;
396   unsigned long size;
397
398   buf = read_object_with_reference (sha1, "blob", &size, NULL);
399
400   free (query->content_type);
401   query->content_type = webgit_mimetype (query->path);
402
403   return html_binary (buf, size);
404 }
405
406
407 /*
408   show tag
409 */
410 static Html
411 webgit_tag_action (struct webgit_query* query)
412 {
413   (void) query;
414   return html("tag");
415 }
416
417
418 /*
419   edit an object
420 */
421 static Html
422 webgit_edit_action (struct webgit_query* query)
423 {
424   (void) query;
425   return html("edit");
426 }
427
428 /*
429   commit changes
430 */
431 static Html
432 webgit_commit_action (struct webgit_query* query)
433 {
434   (void) query;
435   return html("commit");
436 }
437
438
439 Html
440 webgit_action_dispatch (struct webgit_query* query)
441 {
442 #define WEBGIT_ACTION(name, _)                  \
443 {                                               \
444  #name,                                         \
445  webgit_##name##_action,                        \
446 },
447   struct action_table{
448     char* name;
449     Html (*cb)(struct webgit_query* query);
450   } cmds[] = {WEBGIT_ACTIONS {"", NULL}};
451 #undef WEBGIT_ACTION
452
453   for (struct action_table* j = cmds; j->cb; ++j)
454     {
455       if (!strcmp (j->name, query->action))
456         return j->cb (query);
457     }
458   return html("error, no such action");
459 }
460
461