playing around with libcwa and webgit .. added a tiny bit of css
[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                 html_tag("h1", html_attr("id", "page-heading")),
58                 "webgit"
59               );
60 }
61
62 static Html
63 webgit_main_content_action (struct webgit_query* query)
64 {
65   Html table = html_list ();
66
67   html_list_append (table, html(
68                           html(html_tag ("tr"),
69                                html(html_tag ("th"),"Name"),
70                                html(html_tag ("th"),"Git URL"),
71                                html(html_tag ("th"),"Description"),
72                                html(html_tag ("th"),"Owner"),
73                                html(html_tag ("th"),"Last Change"),
74                                html(html_tag ("th"),"Author"),
75                                html(html_tag ("th"),"Committer"),
76                                html(html_tag ("th"),"Action")
77                                ),
78                           html_nl()
79                           )
80               );
81
82   LLIST_FOREACH (&query->repos, node)
83     {
84       struct webgit_repo_info* n = (struct webgit_repo_info*)node;
85
86       webgit_repoinfo_find_last (n);
87
88       html_list_append (table, html (
89                                      html_tag ("tr"),
90                                      html(html_tag ("td"),
91                                           webgit_summary_link (query, n, html (n->name))),
92                                      html(html_tag ("td"), n->url ?
93                                           html (
94                                                 html_tag ("a", html_attr ("href", n->url)),
95                                                 n->url)
96                                           : html("N/A")
97                                           ),
98                                      html(html_tag ("td"), n->description),
99                                      html(html_tag ("td"), n->owner),
100                                      html(html_tag ("td"),
101                                           webgit_object_link (query,
102                                                               n->name, strlen(n->name),
103                                                               n->last_commit, 40,
104                                                               NULL,
105                                                               NULL,
106                                                               webgit_pretty_age (n->age))
107                                           ),
108                                      html(html_tag ("td"),
109                                           webgit_email_link (
110                                                              html (n->last_author_name),
111                                                              html (n->last_author_email)
112                                                              )
113                                           ),
114                                      html(html_tag ("td"),
115                                           webgit_email_link (
116                                                              html (n->last_committer_name),
117                                                              html (n->last_committer_email)
118                                                              )
119                                           ),
120                                      html(html_tag ("td"),
121                                           html(
122                                                webgit_log_link (query,
123                                                                 n->name,
124                                                                 n->last_head,
125                                                                 NULL, 0,
126                                                                 query->count,
127                                                                 html("Log")
128                                                                 ),
129                                                " ",
130
131                                                "Diff ",
132                                                //webgit_diff_link (query, n, n->last_head, html("Diff")),
133                                                //" ",
134                                                webgit_object_link (query,
135                                                                    n->name, strlen(n->name),
136                                                                    n->last_tree, 40,
137                                                                    NULL,
138                                                                    NULL,
139                                                                    html("Tree"))
140                                                )
141                                           )
142                                      ),
143                         html_nl()
144                         );
145     }
146
147   return html (html_tag ("table", html_attr ("border", "1")), table);
148 }
149
150 static Html
151 webgit_main_action (struct webgit_query* query)
152 {
153   return html(
154               html(html_tag("div", html_attr("id", "header")), webgit_header_action (query)) , html_nl (),
155               html(html_tag("div", html_attr("id", "main-menu")), webgit_main_menu_action (query)), html_nl (),
156               html(html_tag("div"), webgit_main_content_action (query)), html_nl ()
157               );
158 }
159
160
161 /*
162   Summary of a single repository
163 */
164 static Html
165 webgit_summary_menu_action (struct webgit_repo_info* repo)
166 {
167   (void) repo;
168   return html ("TODO: summary");
169 }
170
171
172 static Html
173 webgit_summary_content_action (struct webgit_repo_info* repo)
174 {
175   Html content = html_list ();
176
177   /* Title */
178   html_list_append (content, html (html_tag ("h1"), repo->description));
179
180   /* Readme */
181   if (repo->readme)
182     html_list_append (content, html_include (repo->readme));
183
184   /* Info */
185   html_list_append (content,
186                     html (
187                           html (html_tag ("h2"), "Repository information"),
188                           repo->url ?
189                           html (
190                                 html_tag ("div"),
191                                 "Public URL: ",
192                                 html (
193                                       html_tag ("a", html_attr ("href", repo->url)),
194                                       repo->url
195                                       )
196                                 ) : html(),
197                           html (
198                                 html_tag ("div"),
199                                 "Owner: ", repo->owner
200                                 ),
201                           html(
202                                html_tag ("div"),
203                                "Last change: ",
204                                webgit_object_link (repo->query,
205                                                    repo->name, strlen(repo->name),
206                                                    repo->last_commit, 40,
207                                                    NULL,
208                                                    NULL,
209                                                    webgit_pretty_age (repo->age)),
210                                " in branch ",
211                                 webgit_log_link (repo->query,
212                                                  repo->name,
213                                                  repo->last_head,
214                                                  NULL, 0,
215                                                  repo->query->count,
216                                                  html ("'", repo->last_head, "'")
217                                                  )
218                                )
219                           )
220                     );
221
222   /* log */
223   html_list_append (content,
224                     html (
225                           html (html_tag ("h2"), "Log of branch '", repo->last_head, "'"),
226                           webgit_log_table (repo->query, repo->last_head, 5 /*TODO: config this*/, 0))
227                     );
228
229
230   /* branches */
231   html_list_append (content,
232                     html (
233                           html (html_tag ("h2"), "Branches"),
234                           webgit_branch_table (repo, NULL, 5 /*TODO: config this*/)
235                           )
236                     );
237
238   /* tags */
239   html_list_append (content,
240                     html (
241                           html (html_tag ("h2"), "Tags"),
242                           webgit_tag_table (repo, NULL, 5 /*TODO: config this*/)
243                           )
244                     );
245
246
247   return content;
248 }
249
250
251 static Html
252 webgit_summary_action (struct webgit_query* query)
253 {
254   struct webgit_repo_info* repo = webgit_repo_enter (query);
255   webgit_repoinfo_find_last (repo);
256
257   return html(
258               html(html_tag("div"), webgit_summary_menu_action (repo)), html_nl (),
259               html(html_tag("div"), webgit_summary_content_action (repo)), html_nl ()
260               );
261 }
262
263
264 /*
265   Log page
266 */
267 static Html
268 webgit_log_action (struct webgit_query* query)
269 {
270   webgit_repo_enter (query);
271
272   return html(
273               html(html_tag("div"), webgit_log_menu_action (query)), html_nl (),
274               html(html_tag("div"), webgit_log_content_action (query)), html_nl ()
275               );
276 }
277
278
279 /*
280   Diff page
281 */
282 static Html
283 webgit_diff_action (struct webgit_query* query)
284 {
285   (void) query;
286   return html("diff");
287 }
288
289
290 /*
291   pretty printed objects
292 */
293 static Html
294 webgit_object_action (struct webgit_query* query)
295 {
296   struct webgit_repo_info* repo = webgit_repo_enter (query);
297
298   unsigned char sha1[20];
299   if (get_sha1 (query->object, sha1))
300     return html("error: unknown object");
301
302   switch (sha1_object_info(sha1, NULL))
303     {
304     case OBJ_COMMIT:
305       if (!query->deref_to_tree)
306         return webgit_object_commit_action (repo, sha1);
307       /* else fallthrough */
308     case OBJ_TREE:
309       return webgit_object_tree_action (repo, sha1);
310     case OBJ_BLOB:
311       return webgit_object_blob_action (repo, sha1);
312     case OBJ_TAG:
313       return webgit_object_tag_action (repo, sha1);
314
315       break;
316     default:
317       return html ("error: unknown object type");
318       break;
319     }
320 }
321
322
323 /*
324   treeish dereferenced to tree
325 */
326 static Html
327 webgit_tree_action (struct webgit_query* query)
328 {
329   query->deref_to_tree = 1;
330   return webgit_object_action (query);
331 }
332
333
334 /*
335   spew out raw data
336 */
337 static Html
338 webgit_raw_action (struct webgit_query* query)
339 {
340   webgit_repo_enter (query);
341
342   unsigned char sha1[20];
343   if (get_sha1 (query->object, sha1))
344     return html("error: unknown object");
345
346   void* buf;
347   unsigned long size;
348
349   buf = read_object_with_reference (sha1, "blob", &size, NULL);
350
351   free ((char*)query->content_type);
352   query->content_type = webgit_mimetype (query->path);
353
354   return html_binary (buf, size);
355 }
356
357
358 /*
359   show branch
360 */
361 static Html
362 webgit_branch_menu_action (struct webgit_repo_info* repo)
363 {
364   (void) repo;
365   return html ("TODO: branch sidebar");
366 }
367
368
369 static Html
370 webgit_branch_action (struct webgit_query* query)
371 {
372   struct webgit_repo_info* repo = webgit_repo_enter (query);
373   webgit_repoinfo_find_last (repo);
374
375   return html(
376               html(html_tag("div"), webgit_branch_menu_action (repo)), html_nl (),
377               html(html_tag("div"), webgit_branch_table (repo, query->head, query->count), html_nl ())
378               );
379 }
380
381
382 /*
383   show tag
384 */
385 static Html
386 webgit_tag_action (struct webgit_query* query)
387 {
388   (void) query;
389   return html("tag");
390 }
391
392
393 /*
394   edit an object
395 */
396 static Html
397 webgit_edit_action (struct webgit_query* query)
398 {
399   (void) query;
400   return html("edit");
401 }
402
403 /*
404   commit changes
405 */
406 static Html
407 webgit_commit_action (struct webgit_query* query)
408 {
409   (void) query;
410   return html("commit");
411 }
412
413
414 Html
415 webgit_action_dispatch (struct webgit_query* query)
416 {
417 #define WEBGIT_ACTION(name, _)                  \
418 {                                               \
419  #name,                                         \
420  webgit_##name##_action,                        \
421 },
422   struct action_table{
423     char* name;
424     Html (*cb)(struct webgit_query* query);
425   } cmds[] = {WEBGIT_ACTIONS {"", NULL}};
426 #undef WEBGIT_ACTION
427
428   for (struct action_table* j = cmds; j->cb; ++j)
429     {
430       if (!strcmp (j->name, query->action))
431         return j->cb (query);
432     }
433   return html("error, no such action");
434 }
435
436