"list graph" action: Search case-independent.
[collection4.git] / src / action_list_graphs.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <errno.h>
5
6 #include "action_list_graphs.h"
7 #include "graph.h"
8 #include "graph_ident.h"
9 #include "graph_list.h"
10 #include "utils_cgi.h"
11
12 #include <fcgiapp.h>
13 #include <fcgi_stdio.h>
14
15 struct callback_data_s
16 {
17   graph_config_t *cfg;
18   int limit;
19   _Bool first;
20 };
21 typedef struct callback_data_s callback_data_t;
22
23 static int json_begin_graph (graph_config_t *cfg) /* {{{ */
24 {
25   char desc[1024];
26
27   if (cfg == NULL)
28     return (EINVAL);
29
30   graph_get_title (cfg, desc, sizeof (desc));
31
32   printf ("{\"title\":\"%s\",\"instances\":[", desc);
33
34   return (0);
35 } /* }}} int json_begin_graph */
36
37 static int json_end_graph (void) /* {{{ */
38 {
39   printf ("]}");
40
41   return (0);
42 } /* }}} int json_end_graph */
43
44 static int json_print_instance (graph_config_t *cfg, /* {{{ */
45     graph_instance_t *inst)
46 {
47   char params[1024];
48   char desc[1024];
49
50   if ((cfg == NULL) || (inst == NULL))
51     return (EINVAL);
52
53   memset (desc, 0, sizeof (desc));
54   inst_describe (cfg, inst, desc, sizeof (desc));
55
56   memset (params, 0, sizeof (params));
57   inst_get_params (cfg, inst, params, sizeof (params));
58
59   printf ("{\"description\":\"%s\",\"params\":\"%s\"}",
60       desc, params);
61
62   return (0);
63 } /* }}} int json_print_instance */
64
65 static int print_graph_inst_json (graph_config_t *cfg, /* {{{ */
66     graph_instance_t *inst,
67     void *user_data)
68 {
69   callback_data_t *data = user_data;
70
71   if (data->cfg != cfg)
72   {
73     if (!data->first)
74     {
75       json_end_graph ();
76       printf (",\n");
77     }
78     json_begin_graph (cfg);
79
80     data->cfg = cfg;
81     data->first = 0;
82   }
83   else /* if (not first instance) */
84   {
85     printf (",\n");
86   }
87
88   json_print_instance (cfg, inst);
89
90   if (data->limit > 0)
91     data->limit--;
92
93   if (data->limit == 0)
94     return (1);
95
96   return (0);
97 } /* }}} int print_graph_inst_json */
98
99 static int list_graphs_json (const char *term) /* {{{ */
100 {
101   callback_data_t data;
102
103   time_t now;
104   char time_buffer[128];
105   int status;
106
107   printf ("Content-Type: application/json\n");
108
109   now = time (NULL);
110   status = time_to_rfc1123 (now + 300, time_buffer, sizeof (time_buffer));
111   if (status == 0)
112     printf ("Expires: %s\n"
113         "Cache-Control: public\n",
114         time_buffer);
115   printf ("\n");
116
117   data.cfg = NULL;
118   data.limit = 20;
119   data.first = 1;
120
121   printf ("[\n");
122   if (term == NULL)
123     gl_instance_get_all (print_graph_inst_json, /* user_data = */ &data);
124   else
125     gl_search (term, print_graph_inst_json, /* user_data = */ &data);
126
127   if (!data.first)
128     json_end_graph ();
129
130   printf ("\n]");
131
132   return (0);
133 } /* }}} int list_graphs_json */
134
135 static int print_graph_inst_html (graph_config_t *cfg, /* {{{ */
136     graph_instance_t *inst,
137     void *user_data)
138 {
139   callback_data_t *data = user_data;
140   char params[1024];
141   char desc[1024];
142
143   if (data->cfg != cfg)
144   {
145     if (data->cfg != NULL)
146       printf ("  </ul></li>\n");
147
148     memset (desc, 0, sizeof (desc));
149     graph_get_title (cfg, desc, sizeof (desc));
150     html_escape_buffer (desc, sizeof (desc));
151
152     printf ("  <li class=\"graph\">%s\n"
153         "  <ul class=\"instance_list\">\n", desc);
154
155     data->cfg = cfg;
156   }
157
158   memset (params, 0, sizeof (params));
159   inst_get_params (cfg, inst, params, sizeof (params));
160   html_escape_buffer (params, sizeof (params));
161
162   memset (desc, 0, sizeof (desc));
163   inst_describe (cfg, inst, desc, sizeof (desc));
164   html_escape_buffer (desc, sizeof (desc));
165
166   printf ("    <li class=\"instance\"><a href=\"%s?action=graph;%s\">%s</a></li>\n",
167       script_name (), params, desc);
168
169   if (data->limit > 0)
170     data->limit--;
171
172   /* Abort scan if limit is reached. */
173   if (data->limit == 0)
174     return (1);
175
176   return (0);
177 } /* }}} int print_graph_inst_html */
178
179 static int list_graphs_html (const char *term) /* {{{ */
180 {
181   callback_data_t data = { NULL, /* limit = */ 20, /* first = */ 1 };
182   char *term_html;
183
184   term_html = NULL;
185   if (term != NULL)
186     term_html = html_escape (term);
187
188   printf ("Content-Type: text/html\n\n");
189
190   printf ("<html>\n  <head>\n");
191   if (term != NULL)
192     printf ("    <title>c4: Graphs matching &quot;%s&quot;</title>\n", term);
193   else
194     printf ("    <title>c4: List of all graphs</title>\n");
195   printf ("    <link rel=\"stylesheet\" type=\"text/css\" href=\"../share/style.css\" />\n");
196   printf ("    <script type=\"text/javascript\" src=\"../share/jquery-1.4.2.min.js\">\n"
197       "    </script>\n"
198       "    <script type=\"text/javascript\" src=\"../share/collection.js\">\n"
199       "    </script>\n");
200   printf ("  </head>\n  <body>\n");
201
202   printf ("<form action=\"%s\" method=\"get\">\n"
203       "  <input type=\"hidden\" name=\"action\" value=\"list_graphs\" />\n"
204       "  <input type=\"text\" name=\"search\" value=\"%s\" id=\"search-input\" />\n"
205       "  <input type=\"submit\" name=\"button\" value=\"Search\" />\n"
206       "</form>\n",
207       script_name (), (term_html != NULL) ? term_html : "");
208
209   free (term_html);
210
211   printf ("    <ul id=\"search-output\" class=\"graph_list\">\n");
212   if (term == NULL)
213     gl_instance_get_all (print_graph_inst_html, /* user_data = */ &data);
214   else
215     gl_search (term, print_graph_inst_html, /* user_data = */ &data);
216
217   if (data.cfg != NULL)
218     printf ("      </ul></li>\n");
219
220   printf ("    </ul>\n");
221
222   printf ("  </body>\n</html>\n");
223
224   return (0);
225 } /* }}} int list_graphs_html */
226
227 int action_list_graphs (void) /* {{{ */
228 {
229   const char *format;
230   const char *search;
231   int status;
232
233   gl_update ();
234
235   search = strtolower_copy (param ("search"));
236
237   format = param ("format");
238   if (format == NULL)
239     format = "html";
240
241   if (strcmp ("json", format) == 0)
242     status = list_graphs_json (search);
243   else
244     status = list_graphs_html (search);
245
246   free (search);
247
248   return (status);
249 } /* }}} int action_list_graphs */
250
251 /* vim: set sw=2 sts=2 et fdm=marker : */