(* camlp4r ./pa_html.cmo ./def.syn.cmo *)
(* $Id: advSearchOk.ml,v 4.8 2004/12/14 09:30:10 ddr Exp $ *)
(* Copyright (c) 1998-2005 INRIA *)
open Config;
open Def;
open Gutil;
open Util;
value get_number var key env = p_getint env (var ^ "_" ^ key);
value reconstitute_date_dmy conf var =
match get_number var "yyyy" conf.env with
[ Some y ->
match get_number var "mm" conf.env with
[ Some m ->
match get_number var "dd" conf.env with
[ Some d ->
if d >= 1 && d <= 31 && m >= 1 && m <= 12 then
Some {day = d; month = m; year = y; prec = Sure; delta = 0}
else None
| None ->
if m >= 1 && m <= 12 then
Some {day = 0; month = m; year = y; prec = Sure; delta = 0}
else None ]
| None -> Some {day = 0; month = 0; year = y; prec = Sure; delta = 0} ]
| None -> None ]
;
value reconstitute_date conf var =
match reconstitute_date_dmy conf var with
[ Some d -> Some (Dgreg d Dgregorian)
| None -> None ]
;
value name_eq x y = Name.abbrev (Name.lower x) = Name.abbrev (Name.lower y);
value rec skip_spaces x i =
if i = String.length x then i
else if String.unsafe_get x i == ' ' then skip_spaces x (i + 1)
else i
;
value rec skip_no_spaces x i =
if i = String.length x then i
else if String.unsafe_get x i != ' ' then skip_no_spaces x (i + 1)
else i
;
value string_incl x y =
loop 0 where rec loop j_ini =
if j_ini == String.length y then False
else
let rec loop1 i j =
if i == String.length x then
if j == String.length y then True else String.unsafe_get y j == ' '
else if
j < String.length y &&
String.unsafe_get x i == String.unsafe_get y j then
loop1 (i + 1) (j + 1)
else loop (skip_spaces y (skip_no_spaces y j_ini))
in
loop1 0 j_ini
;
value name_incl x y =
let x = Name.abbrev (Name.lower x) in
let y = Name.abbrev (Name.lower y) in
string_incl x y
;
value advanced_search conf base max_answers =
let hs = Hashtbl.create 73 in
let hd = Hashtbl.create 73 in
let gets x =
try Hashtbl.find hs x with
[ Not_found ->
let v =
match p_getenv conf.env x with
[ Some v -> v
| None -> "" ]
in
do { Hashtbl.add hs x v; v } ]
in
let test x cmp =
let y = gets x in
if y = "" then True else cmp y
in
let test_auth p x cmp =
let y = gets x in
if y = "" then True else if fast_auth_age conf p then cmp y else False
in
let test_date p x df =
let (d1, d2) =
try Hashtbl.find hd x with
[ Not_found ->
let v =
(reconstitute_date conf (x ^ "1"),
reconstitute_date conf (x ^ "2"))
in
do { Hashtbl.add hd x v; v } ]
in
match (d1, d2) with
[ (Some d1, Some d2) ->
match df () with
[ Some d when fast_auth_age conf p ->
if d strictly_before d1 then False
else if d2 strictly_before d then False
else True
| _ -> False ]
| (Some d1, _) ->
match df () with
[ Some d when fast_auth_age conf p ->
if d strictly_before d1 then False else True
| _ -> False ]
| (_, Some d2) ->
match df () with
[ Some d when fast_auth_age conf p ->
if d strictly_after d2 then False else True
| _ -> False ]
| _ -> True ]
in
let list = ref [] in
let len = ref 0 in
let test_person p u =
if test "sex"
(fun
[ "M" -> p.sex = Male
| "F" -> p.sex = Female
| _ -> True ]) &&
test_date p "birth" (fun () -> Adef.od_of_codate p.birth) &&
test_date p "bapt" (fun () -> Adef.od_of_codate p.baptism) &&
test_auth p "death"
(fun d ->
match (d, p.death) with
[ ("Dead", NotDead | DontKnowIfDead) -> False
| ("Dead", _) -> True
| ("NotDead", NotDead) -> True
| ("NotDead", _) -> False
| _ -> True ]) &&
test_date p "death"
(fun () ->
match p.death with
[ Death _ cd -> Some (Adef.date_of_cdate cd)
| _ -> None ]) &&
test_date p "burial"
(fun () ->
match p.burial with
[ Buried cod -> Adef.od_of_codate cod
| Cremated cod -> Adef.od_of_codate cod
| _ -> None ]) &&
test "first_name" (fun x -> name_eq x (p_first_name base p)) &&
test "surname" (fun x -> name_eq x (p_surname base p)) &&
test "married"
(fun
[ "Y" -> u.family <> [| |]
| "N" -> u.family = [| |]
| _ -> True ]) &&
test_auth p "birth_place"
(fun x -> name_incl x (sou base p.birth_place)) &&
test_auth p "bapt_place"
(fun x -> name_incl x (sou base p.baptism_place)) &&
test_auth p "death_place"
(fun x -> name_incl x (sou base p.death_place)) &&
test_auth p "burial_place"
(fun x -> name_incl x (sou base p.burial_place)) &&
test_auth p "occu" (fun x -> name_incl x (sou base p.occupation)) then
do {
list.val := [p :: list.val]; incr len;
}
else ()
in
do {
if gets "first_name" <> "" || gets "surname" <> "" then
let (slist, _) =
if gets "first_name" <> "" then
Some.persons_of_fsname conf base base.func.persons_of_first_name.find
(fun x -> x.first_name) (gets "first_name")
else
Some.persons_of_fsname conf base base.func.persons_of_surname.find
(fun x -> x.surname) (gets "surname")
in
let slist = List.fold_right (fun (_, _, l) sl -> l @ sl) slist [] in
List.iter
(fun ip -> test_person (pget conf base ip) (uget conf base ip)) slist
else
for i = 0 to base.data.persons.len - 1 do {
if len.val > max_answers then ()
else
test_person (pget conf base (Adef.iper_of_int i))
(uget conf base (Adef.iper_of_int i))
};
(List.rev list.val, len.val)
}
;
value print_result conf base max_answers (list, len) =
if len > max_answers then do {
Wserver.wprint (fcapitale (ftransl conf "more than %d answers"))
max_answers;
Wserver.wprint "\n";
html_p conf;
}
else if len == 0 then
Wserver.wprint "%s\n" (capitale (transl conf "no match"))
else
tag "ul" begin
List.iter
(fun p ->
do {
html_li conf;
Wserver.wprint "\n%s" (referenced_person_text conf base p);
Wserver.wprint "%s" (Date.short_dates_text conf base p);
})
list;
if len > max_answers then do { html_li conf; Wserver.wprint "...\n"; }
else ();
end
;
value print conf base =
let title _ =
Wserver.wprint "%s" (capitale (transl conf "advanced request"))
in
let max_answers =
match p_getint conf.env "max" with
[ Some n -> n
| None -> 100 ]
in
do {
header conf title;
let list = advanced_search conf base max_answers in
print_result conf base max_answers list;
trailer conf;
}
;