]> matita.cs.unibo.it Git - helm.git/commitdiff
ugliness changes:
authorStefano Zacchiroli <zack@upsilon.cc>
Tue, 22 Jun 2004 15:33:17 +0000 (15:33 +0000)
committerStefano Zacchiroli <zack@upsilon.cc>
Tue, 22 Jun 2004 15:33:17 +0000 (15:33 +0000)
- more google like look and feel for query results
- exceptions are no longer rendered in <h1> elements but pretty printed
  inside the standard moogle HTML template
- advanced search status is now rememberd between searches
- added results count
- added result type feedback in results page

helm/searchEngine/html/moogle.html
helm/searchEngine/html/moogle_help.html
helm/searchEngine/html/moogle_init.html
helm/searchEngine/searchEngine.ml

index f608b9d28a0544ec83d92177c01affc569bdf669..dd64296346296e7299a2c73efcb4a08801963fa5 100644 (file)
@@ -2,6 +2,19 @@
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ht="http://www.cs.unibo.it/helm/namespaces/helm-theory" xmlns:helm="http://www.cs.unibo.it/helm" xml:lang="en" lang="en">
 <head>
 <title>Moogle</title>
+<style>
+  div.resultsbar {
+    background-color: #e5ecf9;
+    border-top: solid;
+    border-width: thin;
+    border-color: #3366cc;
+  }
+  td.left { text-align: left }
+  td.right { text-align: right }
+  b.error { color: red }
+  b.query_kind { font-size: large }
+  body { font-family: sans-serif }
+</style>
 </head>
 <body bgcolor="#ffffff">
 <helm:uwobo_form>
    <td> </td>
    <td align="center">
     <font size="-1">
-    <input id="all" type="radio" name="param.advanced" value="no" checked="true" />
-     <label for="all">Simple search</label>
-    <input id="standard" type="radio" name="param.advanced" value="yes" />
-     <label for="standard">Advanced search</label>
+    <input type="radio" name="param.advanced" value="no" @SIMPLE_CHECKED@ />
+    <label>Simple search</label>
+    <input type="radio" name="param.advanced" value="yes" @ADVANCED_CHECKED@ />
+    <label>Advanced search</label>
     </font>
    </td>
    <td> </td>
@@ -47,7 +60,6 @@
    </tr>
   </table>
 </helm:uwobo_form>
-<hr />
 <font size="-1">
 @RESULTS@
 </font>
index e6252cc28a79ae259dba19fa9ed1a56c7d06ce4a..22bb5412caca53ab92a9133b311c385370e099e5 100644 (file)
@@ -1,85 +1 @@
-<?xml version="1.0"?>
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ht="http://www.cs.unibo.it/helm/namespaces/helm-theory" xmlns:helm="http://www.cs.unibo.it/helm" xml:lang="en" lang="en">
-<head>
-<title>Moogle_help</title>
-</head>
-<body bgcolor="#ffffff">
-<helm:uwobo_form>
-  <helm:hidden_params />
-  <input type="hidden" name="advanced" value="@ADVANCED@"/>
-  <input type="hidden" name="keys" value="S,T1,T2,L,RT,E"/>
-  <table cellspacing="0" cellpadding="0">
-  <tr valign="middle">
-  <td><img src="@SEARCH_ENGINE_URL@/getpage?url=moogle_small.png" alt="moogle" /></td>
-  <td>&#xA0;&#xA0;</td>
-  <td align="center">
-  <input maxLength="256" size="55" name="param.expression" value="@EXPRESSION@" />
-  </td>
-  <td>
-  <input type="submit" value="locate" name="param.action" />
-  <input type="submit" value=" hint " name="param.action" />
-  <input type="submit" value="match" name="param.action" />
-  <input type="submit" value=" elim " name="param.action" />
-  </td>
-  <td>&#xA0;&#xA0;&#xA0;</td>
-  <td>
-   <font size="-2">
-    <a href="@SEARCH_ENGINE_URL@/getpage?url=help.html">Help</a><br />
-    <a href="@SEARCH_ENGINE_URL@/getpage?url=syntax.html">Input Syntax</a>
-   </font>
-  </td>
-  </tr>
-  <tr>
-  </tr>
-  <tr>
-   <td> </td>
-   <td> </td>
-   <td align="center">
-    <font size="-1">
-    <input id="all" type="radio" name="param.advanced" value="no" checked="true" />
-     <label for="all">Simple search</label>
-    <input id="standard" type="radio" name="param.advanced" value="yes" />
-     <label for="standard">Advanced search</label>
-    </font>
-   </td>
-   <td> </td>
-   <td> </td>
-   </tr>
-  </table>
-</helm:uwobo_form>
-<hr />
-
-<ul>
- <input type="submit" value="hint" onclick="location:#hint"/>
- <li><a href ="#lhint">hint</a>
- <li><a href ="#"></a>
- <li><a href ="#"></a>
- <li><a href ="#"></a>
-
-<p>ccccccccccccc</p>
-</ul>
-
-<p>
- <a name = "locate"><input type="submit" value="locate"</a> 
- Locate and display an object by its short name. <br/> 
- For instance 
- locating the identifier "nat" gives you back the definition of 
- natural numbers, and locating "plus" returns several (axiomatic and
- concrete) definitions of the sum.
-</p>
-
-<p>
- <a name = "hint"><input type="submit" value="hint"</a> 
- Given a closed statement G of the form 
- <center>
-  \forall x<sub>1</sub>:T<sub>1</sub>...x<sub>n</sub>:T<sub>n</sub>.body
- </center>
- returns all theorems in the library whose conclusion is a generalization 
- of body, that is all theorems which can be used (as a last step) to prove G
- (for tecnical reasons, the actual result may be a superset of
-  the expected one).
-</p>
-
-</body>
-</html>
-
+<html><body><table align="center"><tr><td><img align="center" src="http://helm.cs.unibo.it/moogle.png" alt="moogle" /></td></tr><tr><td>&nbsp;</td></tr><tr><td align="center"><h2>Coming soon!</h2></td></tr></table></body></html>
index af4c26c2685ac6a456606cabc406f242382ec1b8..feddb620c77350bad458df812620c0a3b0e1c529 100644 (file)
@@ -2,6 +2,9 @@
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ht="http://www.cs.unibo.it/helm/namespaces/helm-theory" xmlns:helm="http://www.cs.unibo.it/helm" xml:lang="en" lang="en">
 <head>
 <title>Moogle</title>
+<style>
+  body { font-family: sans-serif }
+</style>
 </head>
 <body bgcolor="#ffffff">
 <center>
index e52d0aa35da4d3f15ed5275f0f0bdc77ff86a9d2..1f45fe67c8424f6b075f24676d17b404e16792e3 100644 (file)
@@ -1,4 +1,4 @@
-(* Copyright (C) 2002, HELM Team.
+(* Copyright (C) 2002-2004, HELM Team.
  * 
  * This file is part of HELM, an Hypertextual, Electronic
  * Library of Mathematics, developed at the Computer Science
@@ -28,16 +28,16 @@ module U = MQGUtil
 module G = MQueryGenerator
 module C = MQIConn
 
-open Http_types ;;
+open Http_types
 
-let debug = true;;
-let debug_print s = if debug then prerr_endline s;;
-Http_common.debug := true;;
-(* Http_common.debug := true;; *)
+let debug = true
+let debug_print s = if debug then prerr_endline s
+let _ = Http_common.debug := true
+(* let _ = Http_common.debug := false *)
 
-open Printf;;
+open Printf
 
-let daemon_name = "Search Engine";;
+let daemon_name = "Search Engine"
 
 let string_tail s =
   let len = String.length s in
@@ -47,45 +47,40 @@ let string_tail s =
 let _ =
  let configuration_file = "/projects/helm/etc/searchEngine.conf.xml" in
   Helm_registry.load_from configuration_file
-;;
 
-let port = Helm_registry.get_int "search_engine.port";;
+let port = Helm_registry.get_int "search_engine.port"
 
-let pages_dir = Helm_registry.get "search_engine.html_dir";;
+let pages_dir = Helm_registry.get "search_engine.html_dir"
 
   (** accepted HTTP servers for ask_uwobo method forwarding *)
-let valid_servers= Helm_registry.get_string_list "search_engine.valid_servers";;
+let valid_servers= Helm_registry.get_string_list "search_engine.valid_servers"
 
-let interactive_user_uri_choice_TPL = pages_dir ^ "/moogle_chat1.html";;
-let interactive_interpretation_choice_TPL = pages_dir ^ "/moogle_chat2.html";;
-let constraints_choice_TPL = pages_dir ^ "/moogle_constraints_choice.html";;
-(* let final_results_TPL = pages_dir ^ "/templateambigpdq3.html";; *)
-let start_TPL = pages_dir ^ "/moogle.html";; 
-let final_results_TPL = pages_dir ^ "/moogle.html";;  
+let interactive_user_uri_choice_TPL = pages_dir ^ "/moogle_chat1.html"
+let interactive_interpretation_choice_TPL = pages_dir ^ "/moogle_chat2.html"
+let constraints_choice_TPL = pages_dir ^ "/moogle_constraints_choice.html"
+let moogle_TPL = pages_dir ^ "/moogle.html"
 
 let my_own_url =
  let ic = Unix.open_process_in "hostname -f" in
  let hostname = input_line ic in
  ignore (Unix.close_process_in ic);
  sprintf "http://%s:%d" hostname port
-;;
 
 exception Chat_unfinished
 exception Invalid_action of string  (* invalid action for "/search" method *)
+exception Unbound_identifier of string
 
 let javascript_quote s =
  let rex = Pcre.regexp "'" in
  let rex' = Pcre.regexp "\"" in
   Pcre.replace ~rex ~templ:"\\'"
    (Pcre.replace ~rex:rex' ~templ:"\\\"" s)
-;;
 
   (* build a bool from a 1-character-string *)
 let bool_of_string' = function
   | "0" -> false
   | "1" -> true
   | s -> failwith ("Can't parse a boolean from string: " ^ s)
-;;
 
   (* build an int option from a string *)
 let int_of_string' = function
@@ -95,7 +90,6 @@ let int_of_string' = function
         Some (int_of_string s)
       with Failure "int_of_string" ->
         failwith ("Can't parse an int option from string: " ^ s)
-;;
 
   (* HTML pretty printers for mquery_generator types *)
 
@@ -108,22 +102,27 @@ let html_of_r_obj (pos, uri) =
         (U.text_of_depth pos "")
     else
       "<input type=\"hidden\" name=\"obj_depth\" />")
-;;
 
 let html_of_r_rel pos =
   sprintf
     "<tr><td><input type='checkbox' name='constr_rel' checked='on'/></td><td>%s</td><td><input name='rel_depth' size='2' type='text' value='%s' /></td></tr>"
     (U.text_of_position (pos:>T.full_position)) (U.text_of_depth (pos:>T.full_position) "")
-;;
 
 let html_of_r_sort (pos, sort) =
   sprintf
     "<tr><td><input type='checkbox' name='constr_sort' checked='on'/></td><td>%s</td><td>%s</td><td><input name='sort_depth' size='2' type='text' value='%s'/></td></tr>"
     (U.text_of_sort sort) (U.text_of_position (pos:>T.full_position)) (U.text_of_depth (pos:>T.full_position) "")
-;;
+
+let query_of_req (req: Http_types.request) =
+  match req#path with
+  | "/elim" -> "Elim"
+  | "/match" -> "Match"
+  | "/hint" -> "Hint"
+  | "/locate" -> "Locate"
+  | _ -> assert false
 
   (** pretty print a MathQL query result to an HELM theory file *)
-let theory_of_result result =
+let theory_of_result req result =
  let results_no = List.length result in
   if results_no > 0 then
    let mode = if results_no > 10 then "linkonly" else "typeonly" in
@@ -132,17 +131,42 @@ let theory_of_result result =
      List.fold_right
       (fun uri i ->
         decr idx ;
-        "<tr><td valign=\"top\">" ^ string_of_int !idx ^ ".</td><td><ht:OBJECT uri=\"" ^ uri ^ "\" mode=\"" ^ mode ^ "\"/></td></tr>" ^  i
-      ) result ""
+        sprintf
+          "<tr>
+           <td valign=\"top\">%d.</td>
+           <td><ht:OBJECT uri=\"%s\" mode=\"%s\"/></td>
+           </tr>%s"
+          !idx uri mode i)
+      result ""
    in
-    "<b><font size=\"+1\">Query Results:</font></b><table xmlns:ht=\"http://www.cs.unibo.it/helm/namespaces/helm-theory\">" ^ results ^ "</table>"
+   sprintf
+    "<div class='resultsbar'>
+      <table width='100%%'>
+       <tr>
+        <td class='left'><b class='query_kind'>%s</b></td>
+        <td class='right'><b>%d</b> result%s found</td>
+       </tr>
+      </table>
+     </div>
+     <br />
+     <div>
+      <table xmlns:ht=\"http://www.cs.unibo.it/helm/namespaces/helm-theory\">%s</table>
+     </div>"
+    (query_of_req req)
+    results_no (if results_no > 1 then "s" else "") results
   else
-    "<b><font size=\"+1\">Query Results:</font></b><p>No results found!</p>"
-;;
-
-let pp_result result =
- "<html xmlns:ht=\"http://www.cs.unibo.it/helm/namespaces/helm-theory\">\n<head><title>Query Results</title><style> A { text-decoration: none } </style></head>\n<body>" ^ theory_of_result result ^ "</body></html>"
-;;
+    "<div class='resultsbar'>no results found</div>"
+
+let pp_result req result =
+ sprintf
+   "<html xmlns:ht=\"http://www.cs.unibo.it/helm/namespaces/helm-theory\">
+     <head>
+      <title>Query results</title>
+      <style> A { text-decoration: none } </style>
+     </head>
+     <body>%s</body>
+    </html>"
+   (theory_of_result req result)
 
   (** chain application of Pcre substitutions *)
 let rec apply_substs substs line =
@@ -164,17 +188,15 @@ let fold_file f init fname =
   (** iter like function on files *)
 let iter_file f = fold_file (fun _ line -> f line) ()
 
-let (expression_tag_RE,
-     action_tag_RE,
-     advanced_tag_RE,
+let (expression_tag_RE, action_tag_RE, advanced_tag_RE,
+     advanced_checked_RE, simple_checked_RE,
      title_tag_RE, no_choices_tag_RE, current_choices_tag_RE,  
      choices_tag_RE, msg_tag_RE, id_to_uris_RE, id_RE, iden_tag_RE,
      interpretations_RE, interpretations_labels_RE, results_RE, new_aliases_RE,
      form_RE, variables_initialization_RE, search_engine_url_RE)
   =
-  (Pcre.regexp "@EXPRESSION@", 
-   Pcre.regexp "@ACTION@", 
-   Pcre.regexp "@ADVANCED@",
+  (Pcre.regexp "@EXPRESSION@", Pcre.regexp "@ACTION@", Pcre.regexp "@ADVANCED@",
+   Pcre.regexp "@ADVANCED_CHECKED@", Pcre.regexp "@SIMPLE_CHECKED@",
    Pcre.regexp "@TITLE@", Pcre.regexp "@NO_CHOICES@",  
    Pcre.regexp "@CURRENT_CHOICES@",
    Pcre.regexp "@CHOICES@", Pcre.regexp "@MSG@",
@@ -184,14 +206,15 @@ let (expression_tag_RE,
    Pcre.regexp "@VARIABLES_INITIALIZATION@", Pcre.regexp "@SEARCH_ENGINE_URL@")
 let server_and_port_url_RE = Pcre.regexp "^http://([^/]+)/.*$"
 
-let pp_error = sprintf "<html><body><h1>Error: %s</h1></body></html>";;
+(* let pp_error = sprintf "<html><body><h1>Error: %s</h1></body></html>" *)
+let pp_error title msg =
+  sprintf "<hr size='1' /><div><b class='error'>%s:</b> %s</div>" title msg
 
 let bad_request body outchan =
   Http_daemon.respond_error ~code:(`Status (`Client_error `Bad_request)) ~body
     outchan
-;;
 
-let contype = "Content-Type", "text/html";;
+let contype = "Content-Type", "text/html"
 
 (* SEARCH ENGINE functions *)
 
@@ -214,7 +237,6 @@ let get_constraints term =
       (Some CGMatchConclusion.universe), 
       (List.nth list_of_must block, [], []), (Some only, None, None)
     | _ -> assert false
-;;
 
 (*
   format:
@@ -287,7 +309,6 @@ let add_user_constraints ~constraints
       in
       (must', only')
   | _ -> failwith ("Can't parse constraint string: " ^ constraints)
-in
 
 let send_results results
   ?(id_to_uris = DisambiguatingParser.EnvironmentP3.of_string "") 
@@ -296,9 +317,14 @@ let send_results results
   Http_daemon.send_basic_headers ~code:(`Code 200) outchan ;
   Http_daemon.send_header "Content-Type" "text/xml" outchan;
   Http_daemon.send_CRLF outchan ;
+  let results_string =
+    match results with
+    | `Results r -> theory_of_result req r
+    | `Error msg -> msg
+  in
   let subst =
     (search_engine_url_RE, my_own_url) ::
-    (results_RE, theory_of_result results)::
+    (results_RE, results_string)::
     (advanced_tag_RE, req#param "advanced")::
     (expression_tag_RE, req#param "expression")::
     (List.map
@@ -306,23 +332,28 @@ let send_results results
         let key' = (Pcre.extract ~pat:"param\\.(.*)" key).(1) in
         Pcre.regexp ("@" ^ key' ^ "@"), value)
       (List.filter
-             (fun (key,_) as p-> Pcre.pmatch ~pat:"^param\\." key)
-             req#params))
-    in
-    iter_file
-      (fun line ->
-        let new_aliases =
-          DisambiguatingParser.EnvironmentP3.to_string id_to_uris
-        in
-        let processed_line =
-          apply_substs
-            (* CSC: Bug here: this is a string, not an array! *)
-            ((new_aliases_RE, "'" ^ javascript_quote new_aliases ^ "'")::subst) 
-            line
-        in
-        output_string outchan (processed_line ^ "\n"))
-      final_results_TPL
-in
+        (fun (key,_) as p-> Pcre.pmatch ~pat:"^param\\." key)
+        req#params)) @
+    (if req#param "advanced" = "no" then
+      [ simple_checked_RE, "checked='true'";
+        advanced_checked_RE, "" ]
+    else
+      [ simple_checked_RE, "";
+        advanced_checked_RE, "checked='true'" ])
+  in
+  iter_file
+    (fun line ->
+      let new_aliases =
+        DisambiguatingParser.EnvironmentP3.to_string id_to_uris
+      in
+      let processed_line =
+        apply_substs
+          (* CSC: Bug here: this is a string, not an array! *)
+          ((new_aliases_RE, "'" ^ javascript_quote new_aliases ^ "'")::subst) 
+          line
+      in
+      output_string outchan (processed_line ^ "\n"))
+    moogle_TPL
 
 let exec_action mqi_handle (req: Http_types.request) outchan =
   let term_string = req#param "expression" in
@@ -453,7 +484,9 @@ let exec_action mqi_handle (req: Http_types.request) outchan =
               raise Chat_unfinished
 
       let input_or_locate_uri ~title ?id () =
-        assert false
+        match id with
+        | Some id -> raise (Unbound_identifier id)
+        | None -> assert false
 
     end
   in
@@ -482,7 +515,7 @@ let exec_action mqi_handle (req: Http_types.request) outchan =
       | _ -> assert false
     in
     let results = List.map snd (Match_concl.cmatch dbd term') in
-    send_results results ~id_to_uris:id_to_uris' req outchan
+    send_results (`Results results) ~id_to_uris:id_to_uris' req outchan
   else
   let must'', only' =
     (try
@@ -568,8 +601,8 @@ let exec_action mqi_handle (req: Http_types.request) outchan =
     G.query_of_constraints universe must'' only'
   in
   let results = MQueryInterpreter.execute mqi_handle query in 
-  send_results (List.map fst results) ~id_to_uris:id_to_uris' req outchan
-in
+  send_results (`Results (List.map fst results))
+    ~id_to_uris:id_to_uris' req outchan
 
 (* HTTP DAEMON CALLBACK *)
 
@@ -577,7 +610,6 @@ let build_dynamic_uri url params =
   let p = 
     String.concat "&" (List.map  (fun (key,value) -> (key ^ "=" ^ (Netencoding.Url.encode value))) params) in
   url ^ "?" ^ p
-in
 
 let build_uwobo_request (req: Http_types.request) outchan =
   prerr_endline ("ECCOLO: " ^ req#param "param.SEARCH_ENGINE_URL");
@@ -598,10 +630,8 @@ let build_uwobo_request (req: Http_types.request) outchan =
       outchan
   else
     Http_daemon.respond
-      ~body:(pp_error ("Untrusted UWOBO server: " ^ server_and_port ^
-      (String.concat "\n" valid_servers)))
+      ~body:(pp_error "Untrusted UWOBO server" server_and_port)
       outchan
-in
 
 let proxy url outchan =
   let server_and_port =
@@ -614,9 +644,8 @@ let proxy url outchan =
       outchan
   else
     Http_daemon.respond
-      ~body:(pp_error ("Untrusted UWOBO server: " ^ server_and_port))
+      ~body:(pp_error "Untrusted UWOBO server" server_and_port)
       outchan
-in
 
 let callback mqi_handle (req: Http_types.request) outchan =
   try
@@ -632,28 +661,28 @@ let callback mqi_handle (req: Http_types.request) outchan =
             (Pcre.replace ~pat:"^\\s*" initial_expression)
         in
         if expression = "" then
-          send_results [] req outchan
+          send_results (`Results []) req outchan
         else
           let results =
             let query = G.locate expression in
              MQueryInterpreter.execute mqi_handle query
           in
-          send_results (List.map fst results) req outchan
+          send_results (`Results (List.map fst results)) req outchan
     | "/execute" ->
         let query_string = req#param "query" in
         let lexbuf = Lexing.from_string query_string in
         let query = MQueryUtil.query_of_text lexbuf in
         let result = MQueryInterpreter.execute mqi_handle query in
-        let result_string = pp_result (List.map fst result) in
+        let result_string = pp_result req (List.map fst result) in
         Http_daemon.respond ~body:result_string ~headers:[contype] outchan
-(*  Http_daemon.respond ~headers:[contype] ~body:(pp_result result) outchan *)
+(*  Http_daemon.respond ~headers:[contype] ~body:(pp_result req result) outchan *)
     | "/unreferred" ->
         let target = req#param "target" in
         let source = req#param "source" in
         let query = G.unreferred target source in
         let result = MQueryInterpreter.execute mqi_handle query in
         Http_daemon.respond ~headers:[contype]
-          ~body:(pp_result (List.map fst result)) outchan
+          ~body:(pp_result req (List.map fst result)) outchan
     | "/getpage" ->
         (* TODO implement "is_permitted" *)
         let _ = prerr_endline 
@@ -699,10 +728,7 @@ let callback mqi_handle (req: Http_types.request) outchan =
         | page -> Http_daemon.respond_forbidden ~url:page outchan))
     (* OLD | "/ask_uwobo" -> proxy (req#param "url") outchan *)
     | "/ask_uwobo" -> build_uwobo_request req outchan
-    | "/hint"
-    | "/match"
-    | "/elim" ->
-        exec_action mqi_handle req outchan
+    | "/hint" | "/match" | "/elim" -> exec_action mqi_handle req outchan
     | invalid_request ->
         Http_daemon.respond_error ~code:(`Status (`Client_error `Bad_request))
           outchan);
@@ -711,17 +737,24 @@ let callback mqi_handle (req: Http_types.request) outchan =
   | Chat_unfinished -> prerr_endline "Chat unfinished, Try again!"
   | Http_types.Param_not_found attr_name ->
       bad_request (sprintf "Parameter '%s' is missing" attr_name) outchan
-  | exc ->
-      let msg = sprintf "Uncaught exception: %s" (Printexc.to_string exc) in
-       debug_print msg ;
-       Http_daemon.respond ~body:(pp_error msg) outchan
-in
-printf "%s started and listening on port %d\n" daemon_name port;
-printf "Current directory is %s\n" (Sys.getcwd ());
-printf "HTML directory is %s\n" pages_dir;
-flush stdout;
-Unix.putenv "http_proxy" "";
-let mqi_handle = C.init ~log:debug_print () in
-Http_daemon.start' ~port (callback mqi_handle);
-C.close mqi_handle;
-printf "%s is terminating, bye!\n" daemon_name
+  | CicTextualParser2.Parse_error msg ->
+      send_results (`Error (pp_error "Parse_error" msg)) req outchan
+  | Unbound_identifier id ->
+      send_results (`Error (pp_error "Unbound identifier" id)) req outchan
+  | exn ->
+      let exn_string = Printexc.to_string exn in
+      debug_print exn_string;
+      let msg = pp_error "Uncaught exception" exn_string in
+      send_results (`Error msg) req outchan
+
+let _ =
+  printf "%s started and listening on port %d\n" daemon_name port;
+  printf "Current directory is %s\n" (Sys.getcwd ());
+  printf "HTML directory is %s\n" pages_dir;
+  flush stdout;
+  Unix.putenv "http_proxy" "";
+  let mqi_handle = C.init ~log:debug_print () in
+  Http_daemon.start' ~port (callback mqi_handle);
+  C.close mqi_handle;
+  printf "%s is terminating, bye!\n" daemon_name
+