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