Fawkes API  Fawkes Development Version
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
blackboard_processor.cpp
1 
2 /***************************************************************************
3  * blackboard_processor.cpp - Web request processor for BlackBoard info
4  *
5  * Created: Thu Oct 23 16:10:21 2008
6  * Copyright 2006-2008 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL file in the doc directory.
21  */
22 
23 #include "blackboard_processor.h"
24 #include <webview/page_reply.h>
25 
26 #include <blackboard/blackboard.h>
27 #include <interface/interface.h>
28 #include <interface/field_iterator.h>
29 #include <interface/interface_info.h>
30 #include <utils/time/time.h>
31 
32 #include <string>
33 #include <cstring>
34 #include <cstdlib>
35 
36 using namespace fawkes;
37 
38 /** @class WebviewBlackBoardRequestProcessor "blackboard_processor.h"
39  * BlackBoard web request processor.
40  * Provides access to BlackBoard introspection features.
41  * @author Tim Niemueller
42  */
43 
44 /** Constructor.
45  * @param baseurl Base URL where processor is mounted
46  * @param blackboard BlackBoard instance
47  */
49  BlackBoard *blackboard)
50 {
51  __baseurl = strdup(baseurl);
52  __baseurl_len = strlen(__baseurl);
53  __blackboard = blackboard;
54 }
55 
56 
57 /** Destructor. */
59 {
60  free(__baseurl);
61  for (__ifi = __interfaces.begin(); __ifi != __interfaces.end(); ++__ifi) {
62  __blackboard->close(__ifi->second);
63  }
64  __interfaces.clear();
65 }
66 
67 
68 WebReply *
70  const char *method,
71  const char *version,
72  const char *upload_data,
73  size_t *upload_data_size,
74  void **session_data)
75 {
76  if ( strncmp(__baseurl, url, __baseurl_len) == 0 ) {
77  // It is in our URL prefix range
78  std::string subpath = std::string(url).substr(__baseurl_len);
79 
80  WebPageReply *r = new WebPageReply("BlackBoard");
81  r->set_html_header(" <link type=\"text/css\" href=\"/static/css/jqtheme/jquery-ui.custom.css\" rel=\"stylesheet\" />\n"
82  " <script type=\"text/javascript\" src=\"/static/js/jquery.min.js\"></script>\n"
83  " <script type=\"text/javascript\" src=\"/static/js/jquery-ui.custom.min.js\"></script>\n");
84 
85  *r += "<script type=\"text/javascript\">\n"
86  " $(function(){\n"
87  " $(\"#blackboard-interfaces-title\").click(function(){\n"
88  " if ( $(\"#blackboard-interfaces\").is(\":visible\") ) {\n"
89  " $(\"#blackboard-interfaces\").hide(\"blind\");\n"
90  " $(\"#blackboard-interfaces-icon\").attr(\"src\", \"/static/images/icon-triangle-e.png\");\n"
91  " } else {\n"
92  " $(\"#blackboard-interfaces\").show(\"blind\");\n"
93  " $(\"#blackboard-interfaces-icon\").attr(\"src\", \"/static/images/icon-triangle-s.png\");\n"
94  " }\n"
95  " });\n"
96  " $(\"#blackboard-interfaces\").hide();\n"
97  " });\n"
98  "</script>\n"
99  "<div id=\"blackboard-box\">\n"
100  " <div><a id=\"blackboard-interfaces-title\" href=\"#\"><img id=\"blackboard-interfaces-icon\" "
101  "class=\"blackboard-interfaces-icon\" src=\"/static/images/icon-triangle-e.png\" />"
102  "BlackBoard Interfaces</a></div>\n"
103  " <div id=\"blackboard-interfaces\">\n";
104 
105  bool found_some = false;
106  InterfaceInfoList *iil = __blackboard->list_all();
107  iil->sort();
108  for (InterfaceInfoList::iterator i = iil->begin(); i != iil->end(); ++i) {
109  if (! found_some) {
110  *r += "<table>\n";
111  *r += "<tr><th>Interface</th><th>Reader(s)</th><th>Writer</th></tr>\n";
112  found_some = true;
113  }
114  r->append_body("<tr><td><a href=\"%s/view/%s::%s\">%s::%s</a></td><td>%u</td><td style=\"color:%s\">%s</td></tr>\n",
115  __baseurl, i->type(), i->id(), i->type(), i->id(),
116  i->num_readers(), i->has_writer() ? "green" : "red", i->has_writer() ? "yes" : "no");
117  }
118  delete iil;
119 
120  if (found_some) {
121  *r += "</table>\n";
122  } else {
123  *r += "<b>No interfaces found.</b>\n";
124  }
125 
126  *r += " </div>\n"
127  "</div>\n";
128 
129  if (subpath.find("/view/") == 0) {
130  std::string iuid = subpath.substr(subpath.find_first_not_of("/", std::string("/view/").length()));
131  std::string iftype = iuid.substr(0, iuid.find("::"));
132  std::string ifname = iuid.substr(iuid.find("::") + 2);
133 
134  r->append_body("<h2>Interface: %s</h2>\n", iuid.c_str());
135  if (__interfaces.find(iuid) == __interfaces.end()) {
136  try {
137  Interface *iface = __blackboard->open_for_reading(iftype.c_str(), ifname.c_str());
138  __interfaces[iuid] = iface;
139  } catch (Exception &e) {
140  r->append_body("Failed to open interface: %s\n", e.what());
141  }
142  }
143  if (__interfaces.find(iuid) != __interfaces.end()) {
144  Interface *iface = __interfaces[iuid];
145  iface->read();
146 
147  /*
148  *r += "<script type=\"text/javascript\">\n"
149  " $(function(){\n"
150  " $(\"#blackboard-interface-details-title\").click(function(){\n"
151  " if ( $(\"#blackboard-interface-details\").is(\":visible\") ) {\n"
152  " $(\"#blackboard-interface-details\").hide(\"blind\");\n"
153  " $(\"#blackboard-interfaces-icon\").attr(\"src\", "
154  "\"/static/images/icon-triangle-e.png\");\n"
155  " } else {\n"
156  " $(\"#blackboard-interface-details\").show(\"blind\");\n"
157  " $(\"#blackboard-interfaces-icon\").attr(\"src\", "
158  "\"/static/images/icon-triangle-s.png\");\n"
159  " }\n"
160  " });\n"
161  " $(\"#blackboard-interface-details\").hide();\n"
162  " });\n"
163  "</script>\n"
164  "<div id=\"blackboard-box\">\n"
165  " <div><a id=\"blackboard-interface-details-title\" href=\"#\">"
166  "<img id=\"blackboard-interfaces-icon\" "
167  "class=\"blackboard-interfaces-icon\" "
168  "src=\"/static/images/icon-triangle-e.png\" />"
169  "Interface details</a></div>\n"
170  " <div id=\"blackboard-interface-details\">\n";
171  */
172 
173  r->append_body("<table>\n"
174  " <tr><td><b>Type:</b></td><td>%s</td></tr>\n"
175  " <tr><td><b>ID:</b></td><td>%s</td></tr>\n"
176  " <tr><td><b>Has writer?:</b></td><td>%s</td></tr>\n"
177  " <tr><td><b>Num readers:</b></td><td>%u</td></tr>\n"
178  " <tr><td><b>Serial:</b></td><td>%u</td></tr>\n"
179  " <tr><td><b>Data size:</b></td><td>%u</td></tr>\n"
180  " <tr><td><b>Hash:</b></td><td>%s</td></tr>\n"
181  " <tr><td><b>Data changed:</b></td>"
182  "<td>%s (last at %s)</td></tr>\n"
183  "</table>\n",
184  iface->type(), iface->id(), iface->has_writer() ? "yes" : "no",
185  iface->num_readers(), iface->serial(),
186  iface->datasize(), iface->hash_printable(),
187  iface->changed() ? "yes" : "no", iface->timestamp()->str());
188 
189  /*
190  *r += " </div>\n"
191  "</div>\n";
192  */
193 
194  r->append_body("<table>\n"
195  " <tr>\n"
196  " <th>Name</th><th>Type</th><th>Value</th>\n"
197  " </tr>\n");
198  for (InterfaceFieldIterator fi = iface->fields(); fi != iface->fields_end(); ++fi) {
199  bool is_string = (fi.get_type() == IFT_STRING);
200  *r += " <tr>\n";
201  if ( fi.get_length() > 1 ) {
202  r->append_body(" <td>%s</td><td>%s [%zu]</td><td>%s%s%s</td>\n",
203  fi.get_name(), fi.get_typename(),
204  fi.get_length(), is_string ? "<pre>" : "",
205  fi.get_value_string(), is_string ? "</pre>" : "");
206  } else {
207  r->append_body(" <td>%s</td><td>%s</td><td>%s%s%s</td>\n",
208  fi.get_name(), fi.get_typename(), is_string ? "<pre>" : "",
209  fi.get_value_string(), is_string ? "</pre>" : "");
210  }
211  *r += " </tr>\n";
212  }
213  r->append_body("</table>\n");
214  r->append_body("<p><a href=\"%s\">Clear detailed</a></p>\n", __baseurl);
215  }
216  }
217 
218 
219  return r;
220  } else {
221  return NULL;
222  }
223 }