Files
Geneweb/lib/historyDiffDisplay.ml
2024-03-05 22:01:20 +01:00

962 lines
37 KiB
OCaml

(* Copyright (c) 1998-2007 INRIA *)
open Config
open Def
open Gwdb
open TemplAst
open Util
open HistoryDiff
let escape_html s = (Util.escape_html s :> Adef.safe_string)
let print_clean conf =
match p_getenv conf.env "f" with
| Some f when f <> "" ->
let title _ =
transl conf "clean history"
|> Utf8.capitalize_fst |> Output.print_sstring conf
in
Hutil.header conf title;
Hutil.print_link_to_welcome conf true;
Util.gen_print_tips conf
("select the input you want to erase from the history" |> transl conf
|> Utf8.capitalize_fst |> Adef.safe);
let history = load_person_history conf f in
Output.print_sstring conf {|<form method="post" action="|};
Output.print_sstring conf conf.command;
Output.print_sstring conf "\">";
Util.hidden_input conf "m" ("HIST_CLEAN_OK" |> Adef.encoded);
Util.hidden_input conf "f" (Mutil.encode f);
Output.print_sstring conf "<ul>";
let rec loop i = function
| [] -> ()
| gr :: l ->
Output.print_sstring conf "<li><label>";
Output.print_sstring conf {|<input type="checkbox" name="i|};
Output.print_sstring conf (string_of_int i);
Output.print_sstring conf {|" value="on">|};
Output.print_string conf gr.date;
Output.print_sstring conf {| |};
Output.print_string conf gr.HistoryDiff.wizard;
Output.print_sstring conf "</label></li>";
loop (i + 1) l
in
loop 0 history;
Output.print_sstring conf
{|</ul><button type="submit" class="btn btn-primary btn-lg">|};
transl_nth conf "validate/delete" 0
|> Utf8.capitalize_fst |> Output.print_sstring conf;
Output.print_sstring conf "</button></form>";
Hutil.trailer conf
| _ -> Hutil.incorrect_request conf
(* ************************************************************************ *)
(* [Fonc] print_clean_ok : config -> unit *)
(* ************************************************************************ *)
(** [Description] : Ré-écrit le fichier historique lié à une personne en
ayant supprimé les entrées non désirées.
[Args] :
- conf : configuration de la base
[Retour] : Néant
[Rem] : Exporté en clair hors de ce module. *)
let print_clean_ok conf =
let rec clean_history i history new_history =
match history with
| [] -> new_history
| gr :: l ->
let lab = "i" ^ string_of_int i in
if p_getenv conf.env lab = Some "on" then
clean_history (i + 1) l new_history
else clean_history (i + 1) l (gr :: new_history)
in
match p_getenv conf.env "f" with
| Some f when f <> "" ->
let title _ =
transl conf "history cleaned"
|> Utf8.capitalize_fst |> Output.print_sstring conf
in
Hutil.header conf title;
Hutil.print_link_to_welcome conf true;
let history = load_person_history conf f in
let new_history = clean_history 0 history [] in
let fname = history_path conf f in
(if new_history = [] then Mutil.rm fname
else
let ext_flags =
[ Open_wronly; Open_trunc; Open_creat; Open_binary; Open_nonblock ]
in
match
try Some (Secure.open_out_gen ext_flags 0o644 fname)
with Sys_error _ -> None
with
| Some oc ->
List.iter (fun v -> output_value oc (v : gen_record)) new_history;
close_out oc
| None -> ());
Hutil.trailer conf
| _ -> Hutil.incorrect_request conf
(**/**) (* Template *)
let person_of_gen_p_key base gen_p =
match person_of_key base gen_p.first_name gen_p.surname gen_p.occ with
| Some ip -> poi base ip
| None -> Gwdb.empty_person base Gwdb.dummy_iper
(* N'est pas forcément très précis. En effet, on enregistre que *)
(* les ipers. Or lors d'un nettoyage de la base, il se peut que *)
(* ces ipers changent. On peut donc pointer vers une autre persone. *)
let person_of_iper conf base ip =
try
let p = pget conf base ip in
if authorized_age conf base p then gen_person_text conf base p
else Adef.safe ""
with _ -> Adef.safe ""
let person_of_iper_array conf base ipl =
(Array.fold_right
(fun ip acc ->
let x = person_of_iper conf base ip in
if (x :> string) = "" then acc else x :: acc)
ipl []
: Adef.safe_string list
:> string list)
|> String.concat ", " |> Adef.safe
let string_of_cdate conf cod =
match Date.od_of_cdate cod with
| Some d -> DateDisplay.string_slash_of_date conf d
| None -> Adef.safe ""
let string_of_death conf death =
match Date.date_of_death death with
| Some cd -> DateDisplay.string_slash_of_date conf cd
| None -> Adef.safe ""
let string_of_burial conf burial =
match burial with
| Buried cod | Cremated cod -> string_of_cdate conf cod
| UnknownBurial -> Adef.safe ""
let string_of_title conf titles : Adef.safe_string =
let string_of_t_name t =
match t.t_name with Tname s -> escape_html s | _ -> Adef.safe ""
in
let one_title t =
let name = escape_html (t.t_ident ^ " " ^ t.t_place) in
let name = if (name :> string) = " " then Adef.safe "" else name in
let dates =
string_of_cdate conf t.t_date_start
^^^ "-"
^<^ string_of_cdate conf t.t_date_end
in
let dates =
if (dates :> string) = "-" then Adef.safe "" else "(" ^<^ dates ^>^ ")"
in
let nth =
let t_name = string_of_t_name t in
if (t_name :> string) = "" then
Adef.safe (if t.t_nth = 0 then "" else string_of_int t.t_nth)
else t_name ^>^ " " ^ string_of_int t.t_nth
in
let nth =
if (nth :> string) = "" then Adef.safe "" else "[" ^<^ nth ^>^ "]"
in
name
^^^ (if (name :> string) = "" then "" else " ")
^<^ nth
^^^ (if (nth :> string) = "" then "" else " ")
^<^ dates
in
List.fold_left
(fun (acc : Adef.safe_string) t ->
if (acc :> string) = "" then one_title t else acc ^^^ ", " ^<^ one_title t)
(Adef.safe "") titles
let string_of_related conf base ip related : Adef.safe_string =
List.fold_right
(fun ic acc ->
let p = person_of_iper conf base ip in
if (p :> string) = "" then acc
else
let c = try pget conf base ic with _ -> Gwdb.empty_person base ic in
let rel =
let rec loop rp =
match rp with
| [] -> Adef.safe ""
| r :: l -> (
match r.r_fath with
| Some ifath when ifath = ip ->
Util.rchild_type_text conf r.r_type 2
| _ -> loop l)
in
loop (get_rparents c)
in
(Utf8.capitalize_fst (rel : Adef.safe_string :> string)
^<^ transl conf ":" ^<^ p)
:: acc)
related []
|> (fun s -> String.concat ", " (s :> string list))
|> Adef.safe
let string_of_rparents conf base rparents : Adef.safe_string =
List.fold_right
(fun rp accu ->
match (rp.r_fath, rp.r_moth) with
| Some ip1, Some ip2 -> (
let rel =
(Util.relation_type_text conf rp.r_type 2
: Adef.safe_string
:> string)
|> Utf8.capitalize_fst
in
let fath = person_of_iper conf base ip1 in
let moth = person_of_iper conf base ip2 in
match ((fath :> string), (moth :> string)) with
| "", "" -> accu
| _, "" -> (rel ^<^ transl conf ":" ^<^ fath) :: accu
| "", _ -> (rel ^<^ transl conf ":" ^<^ moth) :: accu
| _, _ -> (rel ^<^ transl conf ":" ^<^ fath ^^^ ", " ^<^ moth) :: accu
)
| Some ip, None ->
let p = person_of_iper conf base ip in
if (p :> string) = "" then accu
else
(Utf8.capitalize_fst
(Util.relation_type_text conf rp.r_type 2
: Adef.safe_string
:> string)
^<^ transl conf ":" ^<^ p)
:: accu
| None, Some ip ->
let p = person_of_iper conf base ip in
if (p :> string) = "" then accu
else
(Utf8.capitalize_fst
(Util.relation_type_text conf rp.r_type 2
: Adef.safe_string
:> string)
^<^ transl conf ":" ^<^ p)
:: accu
| None, None -> accu)
rparents []
|> (fun s -> String.concat ", " (s : Adef.safe_string list :> string list))
|> Adef.safe
let string_of_marriage conf marriage =
let s =
match marriage with
| NotMarried | NoSexesCheckNotMarried -> "with"
| Married | NoSexesCheckMarried -> "married"
| Engaged -> "engaged"
| NoMention | MarriageBann | MarriageContract | MarriageLicense | Pacs
| Residence ->
"with"
in
Adef.safe (transl conf s)
let string_of_divorce conf divorce =
match divorce with
| NotDivorced -> "" |> Adef.safe
| Divorced cod -> transl conf "divorced" ^<^ " " ^<^ string_of_cdate conf cod
| Separated -> transl conf "separated" |> Adef.safe
let string_of_event_witness conf base witnesses =
Array.fold_right
(fun (ip, wk) accu ->
let witn = person_of_iper conf base ip in
let kind = Util.string_of_witness_kind conf (get_sex @@ poi base ip) wk in
if (witn :> string) = "" then (kind ^^^ transl conf ":" ^<^ witn) :: accu
else accu)
witnesses []
|> fun s ->
String.concat ", " (s : Adef.safe_string list :> string list) |> Adef.safe
let string_of_epers_name conf epers_name =
match epers_name with
| Epers_Birth -> Adef.safe @@ Utf8.capitalize_fst (transl conf "birth")
| Epers_Baptism -> Adef.safe @@ Utf8.capitalize_fst (transl conf "baptism")
| Epers_Death -> Adef.safe @@ Utf8.capitalize_fst (transl conf "death")
| Epers_Burial -> Adef.safe @@ Utf8.capitalize_fst (transl conf "burial")
| Epers_Cremation ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "cremation")
| Epers_Accomplishment ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "accomplishment")
| Epers_Acquisition ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "acquisition")
| Epers_Adhesion -> Adef.safe @@ Utf8.capitalize_fst (transl conf "adhesion")
| Epers_BaptismLDS ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "baptismLDS")
| Epers_BarMitzvah ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "bar mitzvah")
| Epers_BatMitzvah ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "bat mitzvah")
| Epers_Benediction ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "benediction")
| Epers_ChangeName ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "change name")
| Epers_Circumcision ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "circumcision")
| Epers_Confirmation ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "confirmation")
| Epers_ConfirmationLDS ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "confirmation LDS")
| Epers_Decoration ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "decoration")
| Epers_DemobilisationMilitaire ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "demobilisationMilitaire")
| Epers_Diploma -> Adef.safe @@ Utf8.capitalize_fst (transl conf "diploma")
| Epers_Distinction ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "distinction")
| Epers_Dotation -> Adef.safe @@ Utf8.capitalize_fst (transl conf "dotation")
| Epers_DotationLDS ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "dotationLDS")
| Epers_Education ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "education")
| Epers_Election -> Adef.safe @@ Utf8.capitalize_fst (transl conf "election")
| Epers_Emigration ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "emigration")
| Epers_Excommunication ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "excommunication")
| Epers_FamilyLinkLDS ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "familyLinkLDS")
| Epers_FirstCommunion ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "firstCommunion")
| Epers_Funeral -> Adef.safe @@ Utf8.capitalize_fst (transl conf "funeral")
| Epers_Graduate -> Adef.safe @@ Utf8.capitalize_fst (transl conf "graduate")
| Epers_Hospitalisation ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "hospitalisation")
| Epers_Illness -> Adef.safe @@ Utf8.capitalize_fst (transl conf "illness")
| Epers_Immigration ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "immigration")
| Epers_ListePassenger ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "listePassenger")
| Epers_MilitaryDistinction ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "militaryDistinction")
| Epers_MilitaryPromotion ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "militaryPromotion")
| Epers_MilitaryService ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "militaryService")
| Epers_MobilisationMilitaire ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "mobilisationMilitaire")
| Epers_Naturalisation ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "naturalisation")
| Epers_Occupation ->
Adef.safe
@@ Utf8.capitalize_fst (transl_nth conf "occupation/occupations" 0)
| Epers_Ordination ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "ordination")
| Epers_Property -> Adef.safe @@ Utf8.capitalize_fst (transl conf "property")
| Epers_Recensement ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "recensement")
| Epers_Residence ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "residence")
| Epers_Retired -> Adef.safe @@ Utf8.capitalize_fst (transl conf "retired")
| Epers_ScellentChildLDS ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "scellentChildLDS")
| Epers_ScellentParentLDS ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "scellentParentLDS")
| Epers_ScellentSpouseLDS ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "scellentSpouseLDS")
| Epers_VenteBien ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "venteBien")
| Epers_Will -> Adef.safe @@ Utf8.capitalize_fst (transl conf "will")
| Epers_Name n ->
Adef.safe
@@ Utf8.capitalize_fst (escape_html n : Adef.safe_string :> string)
let string_of_efam_name conf efam_name =
match efam_name with
| Efam_Marriage ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "marriage event")
| Efam_NoMarriage ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "no marriage event")
| Efam_NoMention ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "no mention")
| Efam_Engage -> Adef.safe @@ Utf8.capitalize_fst (transl conf "engage event")
| Efam_Divorce ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "divorce event")
| Efam_Separated ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "separate event")
| Efam_Annulation ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "annulation")
| Efam_MarriageBann ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "marriage bann")
| Efam_MarriageContract ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "marriage contract")
| Efam_MarriageLicense ->
Adef.safe @@ Utf8.capitalize_fst (transl conf "marriage licence")
| Efam_PACS -> Adef.safe @@ Utf8.capitalize_fst (transl conf "PACS")
| Efam_Residence -> Adef.safe @@ Utf8.capitalize_fst (transl conf "residence")
| Efam_Name n ->
Adef.safe
@@ Utf8.capitalize_fst (escape_html n : Adef.safe_string :> string)
(* ************************************************************************ *)
(* [Fonc] highlight_diff : char array -> bool array -> string *)
(* ************************************************************************ *)
(** [Description] : Converti un tableau de char en string, avec les parties
modifiées encadrées par des balises <span>.
[Args] :
- arr : tableau à convertir
- diff_arr : tableau des différences
[Retour] :
- string
[Rem] : Non exporté en clair hors de ce module. *)
let highlight_diff arr diff_arr =
let rec loop i s =
if i >= Array.length arr then s
else if diff_arr.(i) then (
let j = ref i in
let accu = ref s in
accu := !accu ^ "<span class=\"mark\">";
while !j < Array.length diff_arr && diff_arr.(!j) do
accu := !accu ^ Printf.sprintf "%c" arr.(!j);
incr j
done;
accu := !accu ^ "</span>";
loop !j !accu)
else loop (i + 1) (s ^ Printf.sprintf "%c" arr.(i))
in
loop 0 ""
(* ************************************************************************ *)
(* [Fonc] array_of_string : string -> char array *)
(* ************************************************************************ *)
(** [Description] : Converti une string en tableau de char afin de pouvoir
faire un diff.
[Args] :
- s : string à convertir
[Retour] :
- char array
[Rem] : Non exporté en clair hors de ce module. *)
let array_of_string s =
let s = (s :> string) in
let len = String.length s in
let a = Array.make len ' ' in
let rec loop i =
if i = len then a
else (
a.(i) <- s.[i];
loop (i + 1))
in
loop 0
let diff_string (before : Adef.safe_string) (after : Adef.safe_string) :
Adef.safe_string * Adef.safe_string =
if before = after then (before, after)
else if (before :> string) = "" then
(before, "<span class=\"mark\">" ^<^ after ^>^ "</span>")
else if (after :> string) = "" then
("<span class=\"mark\">" ^<^ before ^>^ "</span>", after)
else
let aa = array_of_string (after :> string) in
let bb = array_of_string (before :> string) in
let bef_d, aft_d = Difference.f bb aa in
let bef_s = highlight_diff bb bef_d in
let aft_s = highlight_diff aa aft_d in
(Adef.safe bef_s, Adef.safe aft_s)
type 'a env =
| Vfam of
(iper, ifam, string) gen_family option
* (iper, ifam, string) gen_family option
* bool
| Vchild of iper array option * iper array option
| Vfevent of
(iper, string) gen_fam_event option
* (iper, string) gen_fam_event option
* bool
| Vpevent of
(iper, string) gen_pers_event option
* (iper, string) gen_pers_event option
| Vint of int
| Vstring of string
| Vother of 'a
| Vnone
let get_env v env = try List.assoc v env with Not_found -> Vnone
let get_vother = function Vother x -> Some x | _ -> None
let set_vother x = Vother x
let str_val x = VVstring x
let safe_val (x : Adef.safe_string) = VVstring (x :> string)
let rec eval_var conf base env (bef, aft, p_auth) _loc sl =
try eval_simple_var conf base env (bef, aft, p_auth) sl
with Not_found -> eval_compound_var conf base env (bef, aft, p_auth) sl
and eval_simple_var conf base env (bef, aft, p_auth) :
string list -> 'a expr_val = function
| [ s ] -> eval_simple_str_var conf base env (bef, aft, p_auth) s
| _ -> raise Not_found
and eval_compound_var conf base env (bef, aft, p_auth) sl : 'b expr_val =
let loop = function
| [ s ] -> eval_simple_str_var conf base env (bef, aft, p_auth) s
| [ "evar"; s ] -> (
match p_getenv conf.env s with
| Some s -> safe_val (escape_html s)
| None -> str_val "")
| "before" :: sl ->
fst (eval_gen_record conf base env (bef, aft, p_auth) sl)
| "after" :: sl -> snd (eval_gen_record conf base env (bef, aft, p_auth) sl)
| _ -> raise Not_found
in
loop sl
and eval_gen_record conf base env (bef, aft, p_auth) :
string list -> 'a expr_val * 'b expr_val = function
| [ "date" ] -> (safe_val bef.date, safe_val aft.date)
| [ "wizard" ] ->
(safe_val bef.HistoryDiff.wizard, safe_val aft.HistoryDiff.wizard)
| [ s ] -> eval_str_gen_record conf base env (bef, aft, p_auth) s
| _ -> raise Not_found
and eval_str_gen_record conf base env (bef, aft, p_auth) :
string -> 'a expr_val * 'b expr_val =
let diff_string a b =
let a, b = diff_string a b in
(safe_val a, safe_val b)
in
let aux g =
if p_auth then
diff_string (g bef :> Adef.safe_string) (g aft :> Adef.safe_string)
else (str_val "", str_val "")
in
let aux' m_auth bef aft f =
if p_auth && m_auth then
match (bef, aft) with
| Some b, Some a -> diff_string (f conf b) (f conf a)
| None, Some a -> (str_val "", safe_val (f conf a))
| Some b, None -> (safe_val (f conf b), str_val "")
| None, None -> (str_val "", str_val "")
else (str_val "", str_val "")
in
function
| "first_name" -> aux (fun x -> Util.escape_html x.gen_p.first_name)
| "surname" -> aux (fun x -> Util.escape_html x.gen_p.surname)
| "occ" -> aux (fun x -> Adef.safe @@ string_of_int x.gen_p.occ)
| "image" ->
if not conf.no_image then aux (fun x -> Util.escape_html x.gen_p.image)
else (str_val "", str_val "")
| "public_name" -> aux (fun x -> Util.escape_html x.gen_p.public_name)
| "qualifiers" ->
aux (fun x -> Util.escape_html @@ String.concat ", " x.gen_p.qualifiers)
| "aliases" ->
aux (fun x -> Util.escape_html @@ String.concat ", " x.gen_p.aliases)
| "first_names_aliases" ->
aux (fun x ->
Util.escape_html @@ String.concat ", " x.gen_p.first_names_aliases)
| "surnames_aliases" ->
aux (fun x ->
Util.escape_html @@ String.concat ", " x.gen_p.surnames_aliases)
| "titles" -> aux (fun x -> string_of_title conf x.gen_p.titles)
| "relations" ->
aux (fun x ->
let r =
string_of_related conf base x.gen_p.key_index x.gen_p.related
in
let rp = string_of_rparents conf base x.gen_p.rparents in
if (r :> string) = "" then rp else r ^^^ ". " ^<^ rp)
| "occupation" -> aux (fun x -> Util.safe_html x.gen_p.occupation)
| "sex" ->
aux (fun x ->
Util.index_of_sex x.gen_p.sex
|> transl_nth conf "male/female/neuter"
|> Adef.safe)
| "access" ->
aux (fun x ->
match x.gen_p.access with
| IfTitles -> transl_nth conf "iftitles/public/private" 0 |> Adef.safe
| Public -> transl_nth conf "iftitles/public/private" 1 |> Adef.safe
| Private -> transl_nth conf "iftitles/public/private" 2 |> Adef.safe)
| "birth" -> aux (fun x -> string_of_cdate conf x.gen_p.birth)
| "birth_place" -> aux (fun x -> Util.escape_html x.gen_p.birth_place)
| "birth_note" -> aux (fun x -> Util.escape_html x.gen_p.birth_note)
| "birth_src" -> aux (fun x -> Util.escape_html x.gen_p.birth_src)
| "baptism" -> aux (fun x -> string_of_cdate conf x.gen_p.baptism)
| "baptism_place" -> aux (fun x -> Util.escape_html x.gen_p.baptism_place)
| "baptism_note" -> aux (fun x -> Util.escape_html x.gen_p.baptism_note)
| "baptism_src" -> aux (fun x -> Util.escape_html x.gen_p.baptism_src)
| "death" -> aux (fun x -> string_of_death conf x.gen_p.death)
| "death_place" -> aux (fun x -> Util.escape_html x.gen_p.death_place)
| "death_note" -> aux (fun x -> Util.escape_html x.gen_p.death_note)
| "death_src" -> aux (fun x -> Util.escape_html x.gen_p.death_src)
| "burial" -> aux (fun x -> string_of_burial conf x.gen_p.burial)
| "burial_place" -> aux (fun x -> Util.escape_html x.gen_p.burial_place)
| "burial_note" -> aux (fun x -> Util.escape_html x.gen_p.burial_note)
| "burial_src" -> aux (fun x -> Util.escape_html x.gen_p.burial_src)
| "pevent_name" -> (
match get_env "pevent" env with
| Vpevent (bef, aft) ->
aux' true bef aft (fun conf x ->
string_of_epers_name conf x.epers_name)
| _ -> raise Not_found)
| "pevent_date" -> (
match get_env "pevent" env with
| Vpevent (bef, aft) ->
aux' true bef aft (fun conf x -> string_of_cdate conf x.epers_date)
| _ -> raise Not_found)
| "pevent_place" -> (
match get_env "pevent" env with
| Vpevent (bef, aft) ->
aux' true bef aft (fun _ x -> escape_html x.epers_place)
| _ -> raise Not_found)
| "pevent_note" -> (
match get_env "pevent" env with
| Vpevent (bef, aft) ->
aux' (not conf.no_note) bef aft (fun _ x -> escape_html x.epers_note)
| _ -> raise Not_found)
| "pevent_src" -> (
match get_env "pevent" env with
| Vpevent (bef, aft) ->
aux' true bef aft (fun _ x -> escape_html x.epers_src)
| _ -> raise Not_found)
| "pevent_witness" -> (
match get_env "pevent" env with
| Vpevent (bef, aft) ->
aux' true bef aft (fun conf x ->
string_of_event_witness conf base x.epers_witnesses)
| _ -> raise Not_found)
| "notes" ->
if not conf.no_note then aux (fun x -> Util.escape_html x.gen_p.notes)
else (str_val "", str_val "")
| "psources" -> aux (fun x -> Util.escape_html x.gen_p.psources)
| "spouse" -> (
match get_env "fam" env with
| Vfam (_f_bef, _f_aft, m_auth) ->
if m_auth then
(eval_string_env "spouse_bef" env, eval_string_env "spouse_aft" env)
else (str_val "", str_val "")
| _ -> raise Not_found)
| "marriage" -> (
match get_env "fam" env with
| Vfam (bef, aft, m_auth) ->
aux' m_auth bef aft (fun conf x -> string_of_cdate conf x.marriage)
| _ -> raise Not_found)
| "marriage_place" -> (
match get_env "fam" env with
| Vfam (bef, aft, m_auth) ->
aux' m_auth bef aft (fun _ x -> escape_html x.marriage_place)
| _ -> raise Not_found)
| "marriage_src" -> (
match get_env "fam" env with
| Vfam (bef, aft, m_auth) ->
aux' m_auth bef aft (fun _ x -> escape_html x.marriage_src)
| _ -> raise Not_found)
| "witnesses" -> (
match get_env "fam" env with
| Vfam (bef, aft, m_auth) ->
aux' m_auth bef aft (fun conf x ->
person_of_iper_array conf base x.witnesses)
| _ -> raise Not_found)
| "marriage_type" -> (
match get_env "fam" env with
| Vfam (bef, aft, m_auth) ->
aux' m_auth bef aft (fun conf x -> string_of_marriage conf x.relation)
| _ -> raise Not_found)
| "divorce" -> (
match get_env "fam" env with
| Vfam (bef, aft, m_auth) ->
aux' m_auth bef aft (fun conf x -> string_of_divorce conf x.divorce)
| _ -> raise Not_found)
| "fevent_name" -> (
match get_env "fevent" env with
| Vfevent (bef, aft, m_auth) ->
aux' m_auth bef aft (fun conf x ->
string_of_efam_name conf x.efam_name)
| _ -> raise Not_found)
| "fevent_date" -> (
match get_env "fevent" env with
| Vfevent (bef, aft, m_auth) ->
aux' m_auth bef aft (fun conf x -> string_of_cdate conf x.efam_date)
| _ -> raise Not_found)
| "fevent_place" -> (
match get_env "fevent" env with
| Vfevent (bef, aft, m_auth) ->
aux' m_auth bef aft (fun _ x -> escape_html x.efam_place)
| _ -> raise Not_found)
| "fevent_note" -> (
match get_env "fevent" env with
| Vfevent (bef, aft, m_auth) ->
aux' (m_auth && not conf.no_note) bef aft (fun _ x ->
escape_html x.efam_note)
| _ -> raise Not_found)
| "fevent_src" -> (
match get_env "fevent" env with
| Vfevent (bef, aft, m_auth) ->
aux' m_auth bef aft (fun _ x -> escape_html x.efam_src)
| _ -> raise Not_found)
| "fevent_witness" -> (
match get_env "fevent" env with
| Vfevent (bef, aft, m_auth) ->
aux' m_auth bef aft (fun conf x ->
string_of_event_witness conf base x.efam_witnesses)
| _ -> raise Not_found)
| "comment" -> (
match get_env "fam" env with
| Vfam (bef, aft, m_auth) ->
aux' (m_auth && not conf.no_note) bef aft (fun _ x ->
escape_html x.comment)
| _ -> raise Not_found)
| "origin_file" -> (
match get_env "fam" env with
| Vfam (bef, aft, m_auth) ->
aux' m_auth bef aft (fun _ x -> escape_html x.origin_file)
| _ -> raise Not_found)
| "fsources" -> (
match get_env "fam" env with
| Vfam (bef, aft, m_auth) ->
aux' m_auth bef aft (fun _ x -> escape_html x.fsources)
| _ -> raise Not_found)
| "children" -> (
match get_env "fam" env with
| Vfam (_, _, m_auth) ->
if m_auth then
match get_env "child" env with
| Vchild (bef, aft) ->
aux' true bef aft (fun conf -> person_of_iper_array conf base)
| _ -> raise Not_found
else (str_val "", str_val "")
| _ -> raise Not_found)
| _ -> raise Not_found
and eval_simple_str_var conf base env (bef, aft, p_auth) : string -> 'a expr_val
= function
| "acces" ->
person_of_gen_p_key base aft.gen_p
|> acces conf base
|> (safe_val :> Adef.escaped_string -> 'a expr_val)
| "date" -> eval_string_env "date" env
| "history_len" -> eval_int_env "history_len" env
| "line" -> eval_int_env "line" env
| "nb_families" ->
max (List.length bef.gen_f) (List.length aft.gen_f)
|> string_of_int |> str_val
| "person" ->
if p_auth then
person_of_gen_p_key base aft.gen_p
|> Util.gen_person_text conf base
|> safe_val
else eval_string_env "history_file" env
| "wizard" -> eval_string_env "wizard" env
| _ -> raise Not_found
and eval_string_env s env =
match get_env s env with
| Vstring s -> str_val s (* FIXME? *)
| _ -> raise Not_found
and eval_int_env s env =
match get_env s env with
| Vint i -> str_val (string_of_int i)
| _ -> raise Not_found
let print_foreach conf base print_ast _eval_expr =
let rec print_foreach env xx _loc s sl _el al =
match s :: sl with
| [ "family" ] -> print_foreach_family env xx al
| [ "fevent" ] -> print_foreach_fevent env xx al
| [ "pevent" ] -> print_foreach_pevent env xx al
| [ "history_line" ] -> print_foreach_history_line env xx al
| _ -> raise Not_found
and print_foreach_family env xx al =
let bef, aft, p_auth = xx in
let rec loop bef_f bef_c aft_f aft_c =
match (bef_f, aft_f) with
| [], [] -> ()
| [], gen_f :: l ->
let fam = foi base gen_f.fam_index in
let isp = Gutil.spouse aft.gen_p.key_index fam in
let sp = person_of_iper conf base isp in
let m_auth = authorized_age conf base (poi base isp) && p_auth in
let vfam = Vfam (None, Some gen_f, m_auth) in
let vchild, c =
match (bef_c, aft_c) with
| [], gen_c :: l -> (Vchild (None, Some gen_c), l)
| _ -> (* pas normal*) (Vchild (None, None), [])
in
let env =
("fam", vfam) :: ("spouse_bef", Vstring "")
:: ("spouse_aft", Vstring (sp :> string))
:: ("child", vchild) :: env
in
List.iter (print_ast env xx) al;
loop [] bef_c l c
| gen_f :: l, [] ->
let fam = foi base gen_f.fam_index in
let isp = Gutil.spouse aft.gen_p.key_index fam in
let sp = person_of_iper conf base isp in
let m_auth = authorized_age conf base (poi base isp) && p_auth in
let vfam = Vfam (Some gen_f, None, m_auth) in
let vchild, c =
match (bef_c, aft_c) with
| gen_c :: l, [] -> (Vchild (Some gen_c, None), l)
| _ -> (* pas normal*) (Vchild (None, None), [])
in
let env =
("fam", vfam)
:: ("spouse_bef", Vstring (sp :> string))
:: ("spouse_aft", Vstring "") :: ("child", vchild) :: env
in
List.iter (print_ast env xx) al;
loop l c [] aft_c
| gen_f1 :: l1, gen_f2 :: l2 ->
let fam = foi base gen_f2.fam_index in
let isp1 = Gutil.spouse bef.gen_p.key_index fam in
let isp2 = Gutil.spouse aft.gen_p.key_index fam in
let sp1 = person_of_iper conf base isp1 in
let sp2 = person_of_iper conf base isp2 in
let m_auth = authorized_age conf base (poi base isp2) && p_auth in
let vfam = Vfam (Some gen_f1, Some gen_f2, m_auth) in
let vchild, c1, c2 =
match (bef_c, aft_c) with
| gen_c1 :: l1, gen_c2 :: l2 ->
(Vchild (Some gen_c1, Some gen_c2), l1, l2)
| _ -> (* pas normal*) (Vchild (None, None), [], [])
in
let env =
("fam", vfam)
:: ("spouse_bef", Vstring (sp1 :> string))
:: ("spouse_aft", Vstring (sp2 :> string))
:: ("child", vchild) :: env
in
List.iter (print_ast env xx) al;
loop l1 c1 l2 c2
in
loop bef.gen_f bef.gen_c aft.gen_f aft.gen_c
and print_foreach_fevent env xx al =
let rec loop m_auth bef_fevents aft_fevents =
match (bef_fevents, aft_fevents) with
| [], [] -> ()
| [], aft_evt :: l ->
let env = ("fevent", Vfevent (None, Some aft_evt, m_auth)) :: env in
List.iter (print_ast env xx) al;
loop m_auth [] l
| bef_evt :: l, [] ->
let env = ("fevent", Vfevent (Some bef_evt, None, m_auth)) :: env in
List.iter (print_ast env xx) al;
loop m_auth l []
| bef_evt :: l1, aft_evt :: l2 ->
let env =
("fevent", Vfevent (Some bef_evt, Some aft_evt, m_auth)) :: env
in
List.iter (print_ast env xx) al;
loop m_auth l1 l2
in
match get_env "fam" env with
| Vfam (bef, aft, m_auth) -> (
match (bef, aft) with
| Some b, Some a -> loop m_auth b.fevents a.fevents
| None, Some a -> loop m_auth [] a.fevents
| Some b, None -> loop m_auth b.fevents []
| None, None -> ())
| _ -> ()
and print_foreach_pevent env xx al =
let bef, aft, _p_auth = xx in
let rec loop bef_pevents aft_pevents =
match (bef_pevents, aft_pevents) with
| [], [] -> ()
| [], aft_evt :: l ->
let env = ("pevent", Vpevent (None, Some aft_evt)) :: env in
List.iter (print_ast env xx) al;
loop [] l
| bef_evt :: l, [] ->
let env = ("pevent", Vpevent (Some bef_evt, None)) :: env in
List.iter (print_ast env xx) al;
loop l []
| bef_evt :: l1, aft_evt :: l2 ->
let env = ("pevent", Vpevent (Some bef_evt, Some aft_evt)) :: env in
List.iter (print_ast env xx) al;
loop l1 l2
in
loop bef.gen_p.pevents aft.gen_p.pevents
and print_foreach_history_line env xx al =
match get_env "history_file" env with
| Vstring fname ->
let history = load_person_history conf fname in
let rec loop i list =
match list with
| [] -> ()
| gr :: l ->
let env =
("line", Vint i)
:: ("date", Vstring (gr.date : Adef.safe_string :> string))
:: ( "wizard",
Vstring
(gr.HistoryDiff.wizard : Adef.safe_string :> string) )
:: env
in
List.iter (print_ast env xx) al;
loop (i + 1) l
in
loop 0 history
| _ -> ()
in
print_foreach
let eval_predefined_apply conf _env f vl =
let vl = List.map (function VVstring s -> s | _ -> raise Not_found) vl in
match (f, vl) with
| "transl_date", [ date_txt ] -> (
(* date_tpl = "0000-00-00 00:00:00" *)
try
let year = int_of_string (String.sub date_txt 0 4) in
let month = int_of_string (String.sub date_txt 5 2) in
let day = int_of_string (String.sub date_txt 8 2) in
let date =
Dgreg ({ day; month; year; prec = Sure; delta = 0 }, Dgregorian)
in
let time = String.sub date_txt 11 8 in
DateDisplay.string_of_date conf date ^>^ ", " ^ time
with Failure _ -> escape_html date_txt)
| _ -> raise Not_found
let print conf base =
match p_getenv conf.env "t" with
| Some ("SUM" | "DIFF") -> (
match p_getenv conf.env "f" with
| Some file when file <> "" ->
let history = load_person_history conf file in
let len = List.length history in
let before, after =
match (p_getint conf.env "old", p_getint conf.env "new") with
| Some o, Some n ->
let o =
if o < 0 then 0 else if o > len - 1 then len - 1 else o
in
let n =
if n < 0 then 0 else if n > len - 1 then len - 1 else n
in
(o, n)
| _ -> (0, 0)
in
let before = List.nth history before in
let after = List.nth history after in
let p = person_of_gen_p_key base after.gen_p in
let p_auth = authorized_age conf base p in
let env =
[ ("history_file", Vstring file); ("history_len", Vint len) ]
in
let eval_predefined_apply _env f vl =
(eval_predefined_apply conf _env f vl :> string)
in
Hutil.interp conf "updhist_diff"
{
Templ.eval_var = eval_var conf base;
Templ.eval_transl = (fun _ -> Templ.eval_transl conf);
Templ.eval_predefined_apply;
Templ.get_vother;
Templ.set_vother;
Templ.print_foreach = print_foreach conf base;
}
env (before, after, p_auth)
| _ -> Hutil.incorrect_request conf)
| _ -> Hutil.incorrect_request conf