"search json" action: Move the JSON callback method into an own action.
[collection4.git] / src / action_search_json.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <errno.h>
5
6 #include "action_search_json.h"
7 #include "common.h"
8 #include "graph.h"
9 #include "graph_ident.h"
10 #include "graph_list.h"
11 #include "utils_cgi.h"
12
13 #include <fcgiapp.h>
14 #include <fcgi_stdio.h>
15
16 #define RESULT_LIMIT 10
17
18 struct callback_data_s
19 {
20   graph_config_t *cfg;
21   int limit;
22   _Bool first;
23 };
24 typedef struct callback_data_s callback_data_t;
25
26 static int json_begin_graph (graph_config_t *cfg) /* {{{ */
27 {
28   char desc[1024];
29
30   if (cfg == NULL)
31     return (EINVAL);
32
33   graph_get_title (cfg, desc, sizeof (desc));
34
35   printf ("{\"title\":\"%s\",\"instances\":[", desc);
36
37   return (0);
38 } /* }}} int json_begin_graph */
39
40 static int json_end_graph (void) /* {{{ */
41 {
42   printf ("]}");
43
44   return (0);
45 } /* }}} int json_end_graph */
46
47 static int json_print_instance (graph_config_t *cfg, /* {{{ */
48     graph_instance_t *inst)
49 {
50   char params[1024];
51   char desc[1024];
52
53   if ((cfg == NULL) || (inst == NULL))
54     return (EINVAL);
55
56   memset (desc, 0, sizeof (desc));
57   inst_describe (cfg, inst, desc, sizeof (desc));
58
59   memset (params, 0, sizeof (params));
60   inst_get_params (cfg, inst, params, sizeof (params));
61
62   printf ("{\"description\":\"%s\",\"params\":\"%s\"}",
63       desc, params);
64
65   return (0);
66 } /* }}} int json_print_instance */
67
68 static int json_print_graph_instance (graph_config_t *cfg, /* {{{ */
69     graph_instance_t *inst,
70     void *user_data)
71 {
72   callback_data_t *data = user_data;
73
74   if (data->cfg != cfg)
75   {
76     if (!data->first)
77     {
78       json_end_graph ();
79       printf (",\n");
80     }
81     json_begin_graph (cfg);
82
83     data->cfg = cfg;
84     data->first = 0;
85   }
86   else /* if (not first instance) */
87   {
88     printf (",\n");
89   }
90
91   json_print_instance (cfg, inst);
92
93   if (data->limit > 0)
94     data->limit--;
95
96   if (data->limit == 0)
97     return (1);
98
99   return (0);
100 } /* }}} int json_print_graph_instance */
101
102 static int list_graphs_json (const char *term) /* {{{ */
103 {
104   callback_data_t data;
105
106   time_t now;
107   char time_buffer[128];
108   int status;
109
110   printf ("Content-Type: application/json\n");
111
112   now = time (NULL);
113   status = time_to_rfc1123 (now + 300, time_buffer, sizeof (time_buffer));
114   if (status == 0)
115     printf ("Expires: %s\n"
116         "Cache-Control: public\n",
117         time_buffer);
118   printf ("\n");
119
120   data.cfg = NULL;
121   data.limit = RESULT_LIMIT;
122   data.first = 1;
123
124   printf ("[\n");
125   if (term == NULL)
126     gl_instance_get_all (json_print_graph_instance, /* user_data = */ &data);
127   else
128     gl_search (term, json_print_graph_instance, /* user_data = */ &data);
129
130   if (!data.first)
131     json_end_graph ();
132
133   printf ("\n]");
134
135   return (0);
136 } /* }}} int list_graphs_json */
137
138 int action_search_json (void) /* {{{ */
139 {
140   char *search;
141   int status;
142
143   gl_update ();
144
145   search = strtolower_copy (param ("q"));
146
147   status = list_graphs_json (search);
148
149   free (search);
150
151   return (status);
152 } /* }}} int action_search_json */
153
154 /* vim: set sw=2 sts=2 et fdm=marker : */