23 #include "clips-webview-processor.h" 25 #include <core/exception.h> 26 #include <core/threading/mutex_locker.h> 27 #include <webview/page_reply.h> 28 #include <webview/file_reply.h> 29 #include <webview/error_reply.h> 30 #include <webview/redirect_reply.h> 31 #include <utils/misc/string_conversions.h> 32 #include <plugins/clips/aspect/clips_env_manager.h> 37 #include <clips/clips.h> 48 clips_router_query(
void *env,
char *logical_name)
50 if (strcmp(logical_name, WERROR) == 0)
return TRUE;
55 clips_router_print(
void *env,
char *logical_name,
char *str)
57 void *rc = GetEnvironmentRouterContext(env);
60 EnvDeactivateRouter(env, (
char *)
"webview-reqproc");
61 EnvPrintRouter(env, logical_name, str);
62 EnvActivateRouter(env, (
char *)
"webview-reqproc");
67 clips_router_exit(
void *env,
int exit_code)
81 clips_env_mgr_ = clips_env_mgr;
85 baseurl_len_ = strlen(baseurl);
99 EnvAddRouterWithContext(clips->cobj(), (
char *)
"webview-reqproc",
112 EnvDeleteRouter(clips->cobj(), (
char *)
"webview-reqproc");
123 errors_.push_back(str);
129 CLIPS::Fact::pointer fact = clips->get_facts();
131 if (fact->index() == index) {
142 if ( strncmp(baseurl_, request->
url().c_str(), baseurl_len_) == 0 ) {
144 std::string env_name = request->
url().substr(baseurl_len_);
145 std::string::size_type slash_pos = env_name.find(
"/", 1);
147 if (slash_pos != std::string::npos) {
148 subpath = env_name.substr(slash_pos);
149 env_name = env_name.substr(1, slash_pos-1);
150 }
else if (env_name.length() > 0) {
152 env_name = env_name.substr(1);
155 std::map<std::string, LockPtr<CLIPS::Environment>> envs =
156 clips_env_mgr_->environments();
158 if (envs.find(env_name) == envs.end()) {
159 if (envs.size() == 1) {
161 return new WebRedirectReply(std::string(baseurl_) +
"/" + envs.begin()->first);
164 *r +=
"<h2>Environment " + env_name +
" not found</h2>\n";
165 if (! envs.empty()) {
166 *r +=
"<p>Choose on of the following existing environments:</p>\n";
168 for (
auto env : envs) {
169 *r += std::string(
"<li><a href=\"") + baseurl_ +
"/" +
170 env.first +
"\">" + env.first +
"</a></li>\n";
174 *r +=
"<p>No environments have been registered.</p>\n";
183 if (subpath ==
"/assert") {
185 enable_error_log(clips);
188 retract_fact(clips, index);
191 clips->assert_fact(request->
post_value(
"fact"));
192 disable_error_log(clips);
193 if (! errors_.empty()) {
195 *r +=
"<h2>CLIPS Fact Assertion</h2>\n";
196 r->
append_body(
"<p><span style=\"color:red\">Asserting '%s' failed:</span>\n<pre>",
198 for (
auto e : errors_) {
202 r->
append_body(
"<p><a href=\"%s\">Back</a></p>", baseurl_);
204 r->
append_body(
"<form action=\"%s/%s/assert\" method=\"post\">" 205 "<input type=\"hidden\" name=\"index\" value=\"%s\">" 206 "New fact: <input type=\"text\" name=\"fact\" value=\"%s\"/>" 207 "<input type=\"submit\" value=\"Assert\" />",
208 baseurl_, env_name.c_str(),
216 }
else if (subpath.find(
"/retract") == 0) {
217 std::string index_str = subpath.substr(9);
220 retract_fact(clips, index);
227 r->set_html_header(
" <link type=\"text/css\" href=\"/static/css/jqtheme/" 228 "jquery-ui.custom.css\" rel=\"stylesheet\" />\n" 229 " <script type=\"text/javascript\" src=\"/static/js/" 230 "jquery.min.js\"></script>\n" 231 " <script type=\"text/javascript\" src=\"/static/js/" 232 "jquery-ui.custom.min.js\"></script>\n");
235 "<style type=\"text/css\">\n" 236 " tr:hover { background-color: #eeeeee; }\n" 237 " :link:hover, :visited:hover { background-color: #bb0000; color: white; }\n" 238 " .envs { margin: 0px; padding: 0px; display: inline; }\n" 239 " .envs li { display: inline; padding-left: 8px; white-space: no-wrap; }\n" 242 if (envs.size() > 1) {
243 *r +=
"Environments: <ul class=\"envs\">\n";
244 for (
auto env : envs) {
245 *r += std::string(
"<li><a href=\"") + baseurl_ +
"/" +
246 env.first +
"\">" + env.first +
"</a></li>\n";
252 *r +=
"<h2>CLIPS Facts</h2>\n";
255 *r +=
"<tr><th>Index</th><th>Fact</th><th>Action</th></tr>\n";
257 CLIPS::Fact::pointer fact = clips->get_facts();
259 CLIPS::Template::pointer tmpl = fact->get_template();
262 OpenStringDestination(clips->cobj(), (
char *)
"ProcPPForm", tmp, 16383);
263 PrintFact(clips->cobj(), (
char *)
"ProcPPForm",
264 (
struct fact *)fact->cobj(), FALSE, FALSE);
265 CloseStringDestination(clips->cobj(), (
char *)
"ProcPPForm");
267 r->append_body(
"<tr><td>f-%li</td><td>%s</td>" 268 "<td><a href=\"%s/%s/retract/%li\">Retract</a></td>" 270 fact->index(), tmp, baseurl_, env_name.c_str(), fact->index());
272 std::string escaped = tmp;
274 while ((pos = escaped.find(
"\"", pos)) != std::string::npos) {
275 escaped.replace(pos, 1,
""");
284 r->append_body(
"<p><form action=\"%s/%s/assert\" method=\"post\">" 285 "<input type=\"hidden\" name=\"index\" value=\"\">" 286 "New fact: <input type=\"text\" name=\"fact\" />" 287 "<input type=\"submit\" value=\"Assert\" /></form></p>",
288 baseurl_, env_name.c_str());
Fawkes library namespace.
ClipsWebRequestProcessor(fawkes::LockPtr< fawkes::CLIPSEnvManager > &clips, fawkes::Logger *logger, const char *baseurl)
Constructor.
virtual fawkes::WebReply * process_request(const fawkes::WebRequest *request)
Process a request.
std::string post_value(std::string &key) const
Get specific POST value.
virtual ~ClipsWebRequestProcessor()
Destructor.
Mutex * objmutex_ptr() const
Get object mutex.
Web request meta data carrier.
static long to_long(std::string s)
Convert string to a long int value.
void append_body(const char *format,...)
Append to body.
const std::string & url() const
Get URL.
void add_error(const char *str)
Add an error string.
Clips web request processor.
Redirect reply for webview.