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