From 01bf6ca0e26f068b9e469df2c8e45574b64134a5 Mon Sep 17 00:00:00 2001 From: Julien Sagot Date: Tue, 30 Jun 2020 15:30:11 +0200 Subject: [PATCH] Refacto gwpublic scripts --- gwpublic/gwiftitles.ml | 23 --- gwpublic/gwprivate.ml | 29 ---- gwpublic/gwpublic.ml | 27 ---- gwpublic/gwpublic2.ml | 109 -------------- {gwpublic => privacy}/README.MD | 0 {gwpublic => privacy}/gwaccess.ml | 82 ++++------- gwpublic/gwpublic1.ml => privacy/gwpublic.ml | 145 ++++++++++++------- {gwpublic => privacy}/gwpublic2priv.ml | 0 8 files changed, 122 insertions(+), 293 deletions(-) delete mode 100644 gwpublic/gwiftitles.ml delete mode 100644 gwpublic/gwprivate.ml delete mode 100644 gwpublic/gwpublic.ml delete mode 100644 gwpublic/gwpublic2.ml rename {gwpublic => privacy}/README.MD (100%) rename {gwpublic => privacy}/gwaccess.ml (56%) rename gwpublic/gwpublic1.ml => privacy/gwpublic.ml (60%) rename {gwpublic => privacy}/gwpublic2priv.ml (100%) diff --git a/gwpublic/gwiftitles.ml b/gwpublic/gwiftitles.ml deleted file mode 100644 index fd58c6a..0000000 --- a/gwpublic/gwiftitles.ml +++ /dev/null @@ -1,23 +0,0 @@ -open Geneweb -open Def - -let ind = ref "" -let bname = ref "" -let everybody = ref false - -let speclist = - ["-everybody", Arg.Set everybody, "set flag iftitles to everybody [lent!]"; - "-ind", Arg.String (fun x -> ind := x), "individual key"] -let anonfun i = bname := i -let usage = "Usage: gwiftitles [-everybody] [-ind key] base" - -let main () = - Arg.parse speclist anonfun usage; - if !bname = "" then begin Arg.usage speclist usage; exit 2 end; - Secure.set_base_dir (Filename.dirname !bname); - Lock.control_retry - (Mutil.lock_file !bname) ~onerror:Lock.print_error_and_exit @@ fun () -> - if !everybody then Gwaccess.access_everybody IfTitles !bname - else Gwaccess.access_some IfTitles !bname !ind - -let _ = main () diff --git a/gwpublic/gwprivate.ml b/gwpublic/gwprivate.ml deleted file mode 100644 index 77f3080..0000000 --- a/gwpublic/gwprivate.ml +++ /dev/null @@ -1,29 +0,0 @@ -open Geneweb - -let list_ind = ref "" -let ind = ref "" -let bname = ref "" -let everybody = ref false - -let speclist = - ["-everybody", Arg.Set everybody, - "set flag public to everybody [slow option]"; - "-ind", Arg.String (fun x -> ind := x), "individual key"; - "-list-ind", Arg.String (fun s -> list_ind := s), - " file to the list of persons"] -let anonfun i = bname := i -let usage = "Usage: private [-everybody] [-ind key] [-list-ind file] base" - -let main () = - Arg.parse speclist anonfun usage; - if !bname = "" then begin Arg.usage speclist usage; exit 2 end; - Secure.set_base_dir (Filename.dirname !bname); - Lock.control_retry (Mutil.lock_file !bname) - ~onerror:Lock.print_error_and_exit - (fun () -> - if !everybody then Gwaccess.access_everybody Def.Private !bname - else if !list_ind = "" then - Gwaccess.access_some Def.Private !bname !ind - else Gwaccess.access_some_list Def.Private !bname !list_ind) - -let _ = main () diff --git a/gwpublic/gwpublic.ml b/gwpublic/gwpublic.ml deleted file mode 100644 index 73b05ef..0000000 --- a/gwpublic/gwpublic.ml +++ /dev/null @@ -1,27 +0,0 @@ -open Def - -let list_ind = ref "" -let ind = ref "" -let bname = ref "" -let everybody = ref false - -let speclist = - ["-everybody", Arg.Set everybody, - "set flag public to everybody [slow option]"; - "-ind", Arg.String (fun x -> ind := x), "individual key"; - "-list-ind", Arg.String (fun s -> list_ind := s), - " file to the list of persons"] -let anonfun i = bname := i -let usage = "Usage: public [-everybody] [-ind key] [-list-ind file] base" - -let main () = - Arg.parse speclist anonfun usage; - if !bname = "" then begin Arg.usage speclist usage; exit 2 end; - let gcc = Gc.get () in - gcc.Gc.max_overhead <- 100; - Gc.set gcc; - if !everybody then Gwaccess.access_everybody Public !bname - else if !list_ind = "" then Gwaccess.access_some Public !bname !ind - else Gwaccess.access_some_list Public !bname !list_ind - -let _ = main () diff --git a/gwpublic/gwpublic2.ml b/gwpublic/gwpublic2.ml deleted file mode 100644 index 379cc98..0000000 --- a/gwpublic/gwpublic2.ml +++ /dev/null @@ -1,109 +0,0 @@ -open Geneweb -open Def -open Gwdb - -let nb_years_by_gen = 30 - -let change_somebody_access base lim_year trace p year_of_p = - if year_of_p = None && get_access p = IfTitles then - match Gwaccess.find_dated_ancestor base p with - Some (a, year, nb_gen) -> - let acc = - if year + nb_gen * nb_years_by_gen > lim_year then IfTitles - else Public - in - let gp = {(gen_person_of_person p) with access = acc} in - patch_person base gp.key_index gp; - if trace && acc <> IfTitles then - begin - Printf.printf "%s -> " (Gutil.designation base p); - if acc = Private then Printf.printf "private" else Printf.printf "public"; - Printf.printf " (anc %d gen %s year %d)" nb_gen - (Gutil.designation base a) year; - Printf.printf "\n"; - flush stdout; - Some acc - end - else None - | None -> None - else None - -let public_all bname lim_year trace = - let base = Gwdb.open_base bname in - let () = load_ascends_array base in - let () = load_couples_array base in - Consang.check_noloop base - (function - OwnAncestor p -> - Printf.printf "I cannot deal this database.\n"; - Printf.printf "%s is his own ancestors\n" (Gutil.designation base p); - flush stdout; - exit 2 - | _ -> assert false); - let n = nb_of_persons base in - let changes = ref false in - ProgrBar.start (); - Gwdb.Collection.iteri begin fun i p -> - ProgrBar.run i n; - if Gwaccess.oldest_year_of p = None && get_access p = IfTitles then - match change_somebody_access base lim_year trace p (Gwaccess.oldest_year_of p) with - | Some _ -> changes := true - | None -> - let fama = get_family p in - let rec loop i = - if i = Array.length fama then () - else - let ifam = fama.(i) in - let isp = Gutil.spouse (get_iper p) (foi base ifam) in - let sp = poi base isp in - let year_of_sp = Gwaccess.oldest_year_of sp in - let acc_opt = - match year_of_sp with - Some year -> - Some (if year > lim_year then IfTitles else Public) - | None -> - change_somebody_access base lim_year trace sp year_of_sp - in - match acc_opt with - Some acc -> - let gp = {(gen_person_of_person p) with access = acc} in - patch_person base gp.key_index gp; - changes := true; - if trace && acc <> IfTitles then - begin - Printf.printf "%s -> " (Gutil.designation base p); - if acc = Private then Printf.printf "private" - else Printf.printf "public"; - Printf.printf " (inherited from spouse %s)" - (Gutil.designation base sp); - Printf.printf "\n"; - flush stdout - end - | None -> loop (i + 1) - in - loop 0 - end (Gwdb.persons base) ; - if !changes then commit_patches base; - ProgrBar.finish () - -let lim_year = ref 1900 -let trace = ref false -let bname = ref "" - -let speclist = - ["-y", Arg.Int (fun i -> lim_year := i), - "limit year (default = " ^ string_of_int !lim_year ^ ")"; - "-t", Arg.Set trace, "trace changed persons"] -let anonfun i = bname := i -let usage = "Usage: public [-y #] [-t] base" - -let main () = - Arg.parse speclist anonfun usage; - if !bname = "" then begin Arg.usage speclist usage; exit 2 end; - Secure.set_base_dir (Filename.dirname !bname) ; - Lock.control_retry - (Mutil.lock_file !bname) - ~onerror:Lock.print_error_and_exit - (fun () -> public_all !bname !lim_year !trace) - -let _ = main () diff --git a/gwpublic/README.MD b/privacy/README.MD similarity index 100% rename from gwpublic/README.MD rename to privacy/README.MD diff --git a/gwpublic/gwaccess.ml b/privacy/gwaccess.ml similarity index 56% rename from gwpublic/gwaccess.ml rename to privacy/gwaccess.ml index 5a2da83..c6e481e 100644 --- a/gwpublic/gwaccess.ml +++ b/privacy/gwaccess.ml @@ -1,31 +1,36 @@ -open Geneweb -open Gwdb +let open Def in +let open Gwdb in + +let date_of_death = function + | Death (_, cd) -> Some (Adef.date_of_cdate cd) + | _ -> None +in (** [oldest_year_of p] Find a year in [[ birth ; baptism ; death ]]. *) let oldest_year_of p = - let open Def in match Adef.od_of_cdate (get_birth p) with | Some (Dgreg (d, _)) -> Some d.year | _ -> match Adef.od_of_cdate (get_baptism p) with | Some (Dgreg (d, _)) -> Some d.year - | _ -> match Date.date_of_death (get_death p) with + | _ -> match date_of_death (get_death p) with | Some (Dgreg (d, _)) -> Some d.year | _ -> None +in (** [most_recent_year_of p] Find a year in [[ death ; baptism ; birth ]]. *) let most_recent_year_of p = - let open Def in - match Date.date_of_death (get_death p) with + match date_of_death (get_death p) with | Some (Dgreg (d, _)) -> Some d.year | _ -> match Adef.od_of_cdate (get_baptism p) with | Some (Dgreg (d, _)) -> Some d.year | _ -> match Adef.od_of_cdate (get_birth p) with | Some (Dgreg (d, _)) -> Some d.year | _ -> None +in let find_dated_ancestor base p = let mark = Gwdb.iper_marker (Gwdb.ipers base) false in @@ -65,58 +70,27 @@ let find_dated_ancestor base p = loop_ind anc_list in loop 1 [get_iper p] +in -let input_person file = - let pl = ref [] in - begin match (try Some (open_in file) with Sys_error _ -> None) with - Some ic -> - begin try - while true do let line = input_line ic in pl := line :: !pl done - with End_of_file -> () - end; - close_in ic - | None -> Printf.eprintf "Error while opening file %s\n" file; flush stderr - end; - List.rev !pl - -let access_everybody access bname = - let base = Gwdb.open_base bname in +let access_everybody access base = Gwdb.Collection.iter begin fun p -> if get_access p <> access then let p = {(gen_person_of_person p) with Def.access = access} in patch_person base p.Def.key_index p - end (Gwdb.persons base) ; - commit_patches base + end (Gwdb.persons base) +in -let access_some access bname key = - let base = Gwdb.open_base bname in - match Gutil.person_ht_find_all base key with - [ip] -> - let p = poi base ip in - if get_access p <> access then - begin let p = {(gen_person_of_person p) with Def.access = access} in - patch_person base p.Def.key_index p - end; - commit_patches base - | _ -> - match Gutil.person_of_string_dot_key base key with - Some ip -> - let p = poi base ip in - if get_access p <> access then - begin let p = - {(gen_person_of_person p) with Def.access = access} - in - patch_person base p.Def.key_index p - end; - commit_patches base - | None -> Printf.eprintf "Bad key %s\n" key; flush stderr - -let access_some_list access bname file = - if Sys.file_exists file then - let pl = input_person file in List.iter (access_some access bname) pl - else - begin - Printf.eprintf "File does not exist : %s\n" file; - flush stderr; - exit 2 +let access_some access base key = + match + match Gutil.person_ht_find_all base key with + | [ip] -> Some ip + | _ -> Gutil.person_of_string_dot_key base key + with + | Some ip -> + let p = poi base ip in + if get_access p <> access then begin + let p = { (gen_person_of_person p) with Def.access = access } in + patch_person base p.Def.key_index p end + | None -> Printf.eprintf "Bad key %s\n" key ; flush stderr +in diff --git a/gwpublic/gwpublic1.ml b/privacy/gwpublic.ml similarity index 60% rename from gwpublic/gwpublic1.ml rename to privacy/gwpublic.ml index 35340e9..b6e413e 100644 --- a/gwpublic/gwpublic1.ml +++ b/privacy/gwpublic.ml @@ -1,22 +1,32 @@ -open Geneweb -open Def -open Gwdb +let open Def in +let open Gwdb in (** This script is used to set people old enough privacy to [Public]. *) (** Set privacy of persons older than X years as [Public]. Set the ancestors and descendants with no dates [Public] as well (counting 3 generations by century for descendants). *) +(** You can also use this script to manually set access of a person list + using keys. +*) + +let nb_gen_by_century = 3 in -let nb_gen_by_century = 3 +let trace = ref false in -let changes = ref false +let if_trace base p acc = + if !trace then + Printf.printf "%s -> %s\n%!" + (Gutil.designation base p) + (if acc = Private then "private" else "public") +in (** Compute the number of (descending) generation to be considered as old starting from [p] included. i.e. [0] means that [p] is not considered old. *) let compute_ndgen treshold y = (treshold - y) * nb_gen_by_century / 100 +in (** Recursively mark descendants and spouses as old, as long as a date allow you to do so, or until @@ -28,7 +38,7 @@ let mark_descendants base scanned old treshold = let p_key_index = get_iper p in if Gwdb.Marker.get scanned p_key_index < ndgen then begin (* If we did not already scanned with ndgen >= current ndgen *) - let ndgen = match Gwaccess.most_recent_year_of p with + let ndgen = match most_recent_year_of p with | Some y -> (* We have a date: we do not want to scan this person again with a higher ndgen *) Gwdb.Marker.set scanned p_key_index max_int ; @@ -49,7 +59,7 @@ let mark_descendants base scanned old treshold = let ndgen'' = Opt.map_default ndgen (compute_ndgen treshold) - (Gwaccess.most_recent_year_of (poi base sp)) + (most_recent_year_of (poi base sp)) in if ndgen'' > 0 then begin Gwdb.Marker.set old sp true ; @@ -63,13 +73,14 @@ let mark_descendants base scanned old treshold = end in loop +in let mark_ancestors base scanned treshold = let rec loop p = let i = get_iper p in if not @@ Gwdb.Marker.get scanned i then begin Gwdb.Marker.set scanned i true ; - begin match Gwaccess.oldest_year_of p with + begin match oldest_year_of p with | Some y when y >= treshold -> Printf.eprintf "Problem of date ! %s %d\n" (Gutil.designation base p) y; flush stderr @@ -78,9 +89,9 @@ let mark_ancestors base scanned treshold = && not (is_quest_string (get_first_name p)) && not (is_quest_string (get_surname p)) then begin + if_trace base p Public ; let p = {(gen_person_of_person p) with access = Public} in patch_person base p.key_index p ; - changes := true end end ; Opt.iter @@ -92,9 +103,9 @@ let mark_ancestors base scanned treshold = end in loop +in -let public_all ~mem bname treshold = - let base = Gwdb.open_base bname in +let public_all ~mem base treshold = if not mem then begin load_persons_array base ; load_ascends_array base ; @@ -134,50 +145,82 @@ let public_all ~mem bname treshold = clear_persons_array base ; clear_ascends_array base ; clear_couples_array base ; - end ; - if !changes then commit_patches base + end +in -let public_some bname treshold key = - let base = Gwdb.open_base bname in - let ip = match Gutil.person_ht_find_all base key with - | [ip] -> ip - | _ -> match Gutil.person_of_string_dot_key base key with - | Some ip -> ip - | None -> Printf.eprintf "Bad key %s\n" key; flush stderr; exit 2 - in - let p = poi base ip in - let scanned = Gwdb.iper_marker (Gwdb.ipers base) false in - let () = load_ascends_array base in - let () = load_couples_array base in - mark_ancestors base scanned treshold p; - let () = clear_ascends_array base in - let () = clear_couples_array base in - if !changes then commit_patches base +let treshold = ref None in +let access = ref None in +let default_treshold = 1900 in +let ind = ref [] in +let bname = ref "" in +let everybody = ref false in +let mem = ref false in -let treshold = ref 1900 -let ind = ref "" -let bname = ref "" -let everybody = ref false -let mem = ref false +let aux v () = + assert (!access = None) ; + access := Some v +in let speclist = - ["-y", Arg.Int (fun i -> treshold := i), - "treshold year. Anybody born before this year is considered old (default = " ^ string_of_int !treshold ^ ")"; - "-everybody", Arg.Set everybody, "set flag public to everybody."; - "-ind", Arg.String (fun x -> ind := x), "individual key. Process only this individual and its ancestors."; - "-mem", Arg.Set mem, "save memory (slower)"; - ] -let anonfun i = bname := i -let usage = "Usage: public1 [-everybody] [-mem] [-y #] [-ind key] base" + [ ( "-y" + , Arg.Int (fun i -> treshold := Some i) + , " Treshold year. Anybody born before this year is considered old (default = " + ^ string_of_int default_treshold ^ ")" + ) + ; ( "-everybody" + , Arg.Set everybody + , " Process the whole database." + ) + ; ( "-ind" + , Arg.String (fun x -> ind := x :: !ind) + , " Process this individual and its ancestors." + ) + ; ( "-list-ind" + , Arg.String begin fun s -> + let ic = open_in s in + try while true do ind := (input_line ic) :: !ind done + with End_of_file -> () + end + , " Process the list of persons contained in (one key per line)." + ) + ; ( "-mem", Arg.Set mem, " Save memory (slower)." ) + ; ( "-public", Arg.Unit (aux Public), " Set individuals access to Public." ) + ; ( "-private", Arg.Unit (aux Private), " Set individuals access to Private." ) + ; ( "-iftitle", Arg.Unit (aux IfTitles), " Set individuals access to IfTitle." ) + ; ( "-trace", Arg.Set trace, " Trace changes." ) + ] |> Arg.align +in -let () = - Arg.parse speclist anonfun usage; - if !bname = "" then begin Arg.usage speclist usage ; exit 2 end ; +let anonfun i = bname := i in + +let usage = + "Usage: cat gwacces.ml gwpublic.ml | GWREPL_PPF=/dev/null GW_NOPROMPT=1 " + ^ Sys.argv.(0) ^ " [OPTS] /path/to/base.gwb" +in + +let main () = + Arg.parse speclist anonfun usage ; + let usage () = Arg.usage speclist usage ; exit 2 in + if !bname = "" then usage () ; Secure.set_base_dir (Filename.dirname !bname); Lock.control_retry (Mutil.lock_file !bname) ~onerror:Lock.print_error_and_exit @@ fun () -> - if !everybody then - if !ind <> "" then failwith "-everybody and -ind options are mutually exclusive" - else if !treshold <> 1900 then failwith "-everybody and -y options are mutually exclusive" - else Gwaccess.access_everybody Def.Public !bname - else if !ind = "" then public_all ~mem:!mem !bname !treshold - else public_some !bname !treshold !ind + let base = Gwdb.open_base !bname in + begin match !treshold, !everybody, !ind, !access with + | Some _, true, _, _ + | Some _, _, _ :: _, _ -> + prerr_endline "-everybody, -ind/-list-ind and -y options are mutually exclusive" ; + usage () + | None, true, _, None + | None, _, _ :: _, None -> + prerr_endline "missing -public, -private or -iftitle option" ; + usage () + | Some y, _, _, _ -> public_all ~mem:!mem base y + | None, false, [], None -> public_all ~mem:!mem base default_treshold + | _, true, _, Some access -> access_everybody access base + | _, _, ind, Some access -> List.iter (access_some access base) ind + end ; + Gwdb.commit_patches base ; +in + +main () +;; diff --git a/gwpublic/gwpublic2priv.ml b/privacy/gwpublic2priv.ml similarity index 100% rename from gwpublic/gwpublic2priv.ml rename to privacy/gwpublic2priv.ml