~mro/geohash

fbd81a15734aef8454f6064b66c7ffc911276050 — Marcus Rohrmoser 3 years ago adcd962
- stdout explicit
- -V
5 files changed, 51 insertions(+), 48 deletions(-)

M bin/cgi.ml
M bin/geohash.ml
M bin/shell.ml
M lib/cgi.ml
M test/route_test.ml
M bin/cgi.ml => bin/cgi.ml +20 -19
@@ 23,19 23,19 @@ let globe = "🌐"
open Lib
open Lib.Cgi

let handle_hash req =
let handle_hash oc req =
  match req.path_info |> String.split_on_char '/' with
  | [ ""; hash ] -> (
      match Lib.Geohash.decode hash with
      | Error _ -> error 406 "Cannot decode hash."
      | Error _ -> error oc 406 "Cannot decode hash."
      | Ok ((lat, lon), (dlat, dlon)) ->
          let mime = "text/xml"
          and xslt = "gpx2html.xslt"
          and uri = req |> request_uri
          and base = "http://purl.mro.name/geohash" in
          Printf.printf "%s: %s\n" "Content-Type" mime;
          Printf.printf "\n";
          Printf.printf
          Printf.fprintf oc "%s: %s\n" "Content-Type" mime;
          Printf.fprintf oc "\n";
          Printf.fprintf oc
            "<?xml version='1.0'?><!-- \
             https://www.topografix.com/GPX/1/1/gpx.xsd -->\n\
             <?xml-stylesheet type='text/xsl' href='%s'?>\n\


@@ 54,26 54,27 @@ let handle_hash req =
            (lon -. dlon) (lat +. dlat) (lon +. dlon) lat lon hash req.scheme
            req.host req.server_port uri;
          0)
  | _ -> error 404 "Not found"
  | _ -> error oc 404 "Not found"

let handle req =
let handle oc req =
  let mercator_birth = "u154c" and uri = req |> request_uri in
  match req.request_method with
  | "GET" -> (
      match req.path_info with
      | "/about" -> dump_clob "text/xml" Res.doap_rdf
      | "/LICENSE" -> dump_clob "text/plain" Res._LICENSE
      | "/doap2html.xslt" -> dump_clob "text/xml" Res.doap2html_xslt
      | "/gpx2html.xslt" -> dump_clob "text/xml" Res.gpx2html_xslt
      | "" -> uri ^ "/" |> redirect
      | "/about" -> dump_clob oc "text/xml" Res.doap_rdf
      | "/LICENSE" -> dump_clob oc "text/plain" Res._LICENSE
      | "/doap2html.xslt" -> dump_clob oc "text/xml" Res.doap2html_xslt
      | "/gpx2html.xslt" -> dump_clob oc "text/xml" Res.gpx2html_xslt
      | "" -> uri ^ "/" |> redirect oc
      | "/" -> (
          match req.query_string with
          | "" -> uri ^ mercator_birth |> redirect
          | "" -> uri ^ mercator_birth |> redirect oc
          | qs -> (
              match qs |> Route.coord_from_qs with
              | Error (`NoMatch (_, s')) ->
                  error 406 ("Cannot encode coords: '" ^ s' ^ "'")
              | Error (`ConverterFailure _) -> error 406 "Cannot encode coords."
                  error oc 406 ("Cannot encode coords: '" ^ s' ^ "'")
              | Error (`ConverterFailure _) ->
                  error oc 406 "Cannot encode coords."
              | Ok co -> (
                  (* actually logic :-( *)
                  let prec =


@@ 87,7 88,7 @@ let handle req =
                    |> min 12
                  in
                  match co |> Lib.Geohash.encode prec with
                  | Error _ -> error 406 "Cannot encode coords."
                  | Ok hash -> hash |> redirect)))
      | _ -> handle_hash req)
  | _ -> error 405 "Method Not Allowed"
                  | Error _ -> error oc 406 "Cannot encode coords."
                  | Ok hash -> hash |> redirect oc)))
      | _ -> handle_hash oc req)
  | _ -> error oc 405 "Method Not Allowed"

M bin/geohash.ml => bin/geohash.ml +1 -1
@@ 20,6 20,6 @@

let () =
  (match Lib.Cgi.request_from_env () |> Lib.Cgi.consolidate with
  | Ok req -> Cgi.handle req
  | Ok req -> Cgi.handle stdout req
  | Error _ -> Sys.argv |> Array.to_list |> Shell.exec)
  |> exit

M bin/shell.ml => bin/shell.ml +11 -10
@@ 27,21 27,21 @@ let err i msgs =

let to_hash h = Ok [ h; "not implemented yet." ]

let print_version () =
let print_version oc =
  let exe = Filename.basename Sys.executable_name in
  Printf.printf "%s: https://mro.name/%s/v%s, built: %s\n" exe "geohash"
  Printf.fprintf oc "%s: https://mro.name/%s/v%s, built: %s\n" exe "geohash"
    Version.git_sha Version.date;
  0

let print_help () =
let print_help oc =
  let exe = Filename.basename Sys.executable_name in
  Printf.printf
  Printf.fprintf oc
    "\n\
     Convert one lat,lon pair or geohash to gpx with bbox and geohash comment.\n\n\
     Works as a webserver CGI or commandline converter.\n\n\
     If run from commandline:\n\n\
     SYNOPSIS\n\n\
    \  $ %s -v\n\n\
    \  $ %s -V\n\n\
    \  $ %s -h\n\n\
    \  $ %s --doap\n\n\
    \  $ %s 'geo:47.67726,12.47077?z=19'\n\n"


@@ 49,15 49,16 @@ let print_help () =
  0

let exec args =
  let oc = stdout in
  match args |> List.tl with
  | [ "-h" ] | [ "--help" ] -> print_help ()
  | [ "-v" ] | [ "--version" ] -> print_version ()
  | [ "-h" ] | [ "--help" ] -> print_help oc
  | [ "-V" ] | [ "--version" ] -> print_version oc
  | [ "--doap" ] ->
      Printf.printf "%s" Lib.Res.doap_rdf;
      Printf.fprintf oc "%s" Lib.Res.doap_rdf;
      0
  | [ i ] ->
      (i |> to_hash |> function
       | Ok h -> h |> String.concat " -> " |> Printf.printf "%s"
       | Error _ -> "ouch" |> Printf.printf "%s");
       | Ok h -> h |> String.concat " -> " |> Printf.fprintf oc "%s"
       | Error _ -> "ouch" |> Printf.fprintf oc "%s");
      0
  | _ -> err 2 [ "get help with -h" ]

M lib/cgi.ml => lib/cgi.ml +15 -15
@@ 32,29 32,29 @@ module Os = struct
      | None -> failwith ("Cgi: the environment variable " ^ s ^ " is not set"))
end

let redirect url =
let redirect oc url =
  let status = 302
  and reason = "Found"
  and mime = "text/plain; charset=utf-8" in
  Printf.printf "%s: %d %s\n" "Status" status reason;
  Printf.printf "%s: %s\n" "Content-Type" mime;
  Printf.printf "%s: %s\n" "Location" url;
  Printf.printf "\n";
  Printf.printf "%s %s.\n" camel reason;
  Printf.fprintf oc "%s: %d %s\n" "Status" status reason;
  Printf.fprintf oc "%s: %s\n" "Content-Type" mime;
  Printf.fprintf oc "%s: %s\n" "Location" url;
  Printf.fprintf oc "\n";
  Printf.fprintf oc "%s %s.\n" camel reason;
  0

let error status reason =
let error oc status reason =
  let mime = "text/plain; charset=utf-8" in
  Printf.printf "%s: %d %s\n" "Status" status reason;
  Printf.printf "%s: %s\n" "Content-Type" mime;
  Printf.printf "\n";
  Printf.printf "%s %s.\n" camel reason;
  Printf.fprintf oc "%s: %d %s\n" "Status" status reason;
  Printf.fprintf oc "%s: %s\n" "Content-Type" mime;
  Printf.fprintf oc "\n";
  Printf.fprintf oc "%s %s.\n" camel reason;
  0

let dump_clob mime clob =
  Printf.printf "%s: %s\n" "Content-Type" mime;
  Printf.printf "\n";
  Printf.printf "%s" clob;
let dump_clob oc mime clob =
  Printf.fprintf oc "%s: %s\n" "Content-Type" mime;
  Printf.fprintf oc "\n";
  Printf.fprintf oc "%s" clob;
  0

type req_raw = {

M test/route_test.ml => test/route_test.ml +4 -3
@@ 22,10 22,11 @@ open Lib.Route

let test_qs () =
  assert (
    match coord_from_qs "q=1.2,3.4" with Ok (1.2, 3.4) -> true | _ -> false );
    match coord_from_qs "q=1.2,3.4" with Ok (1.2, 3.4) -> true | _ -> false);
  assert (
    match coord_from_qs "q=geo%3A47.5440%2C15.4396%3Fz%3D12" with Ok (47.5440,
    15.4396) -> true | _ -> false ); 
    match coord_from_qs "q=geo%3A47.5440%2C15.4396%3Fz%3D12" with
    | Ok (47.5440, 15.4396) -> true
    | _ -> false);
  match coord_from_qs "q=1.u2 , ; 3.4" with
  | Error (`NoMatch (_, original)) -> assert (original != "")
  | _ -> assert false