Changeset 4 in code for trunk


Ignore:
Timestamp:
May 1, 2022, 5:10:03 PM (3 years ago)
Author:
fox
Message:

Use of text editor when value for index field omitted

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/cli/index.ml

    r3 r4  
    11open Logarion
    22
    3 let index print title authors locations peers dir =
    4         let fname = Filename.concat dir "index.pck" in
    5         let pck = match Header_pack.of_string @@ File_store.to_string fname with
    6         | Error s -> failwith s
    7         | Ok pck -> let info = Header_pack.{ pck.info with
    8                         title = if title <> "" then title else pck.info.title;
    9                         people = if authors <> ""
    10                                 then (String_set.list_of_csv authors) else pck.info.people;
    11                         locations = if locations <> ""
    12                                 then (String_set.list_of_csv locations) else pck.info.locations;
    13                 } in
    14                 Header_pack.{ info; fields;
    15                         texts = of_text_list @@ File_store.fold ~dir
    16                                 (fun a (t,_) -> of_text a t) [];
    17                         peers = if peers <> ""
    18                                 then (str_list @@ String_set.list_of_csv peers) else pck.peers;
    19                 }
     3let text_editor name x =
     4        let fname, out = Filename.open_temp_file name "" in
     5        output_string out x; flush out;
     6        let r = match Unix.system ("$EDITOR " ^ fname) with
     7        | Unix.WEXITED 0 ->
     8                let inp = open_in fname in
     9                let line = input_line inp in
     10                close_in inp; line
     11        | _ -> failwith "Failed launching editor to edit value" in
     12        close_out out;
     13        Unix.unlink fname;
     14        r
     15
     16let text_editor_lines name x =
     17        let fname, out = Filename.open_temp_file name "" in
     18        List.iter (fun s -> output_string out (s ^ "\n")) x; flush out;
     19        let r = match Unix.system ("$EDITOR " ^ fname) with
     20        | Unix.WEXITED 0 ->
     21                let inp = open_in fname in
     22                let lines =
     23                        let rec acc a =
     24                                try let a = String.trim (input_line inp) :: a in acc a
     25                                with End_of_file -> a in
     26                        acc [] in
     27                close_in inp; lines
     28        | _ -> failwith "Failed launching editor to edit value" in
     29        close_out out;
     30        Unix.unlink fname;
     31        r
     32
     33let print_pack pck =
     34        let s ss = String.concat "\n\t" ss in
     35        let open Header_pack in
     36        Printf.printf "Id: %s\nTitle: %s\nAuthors: %s\nLocations:\n\t%s\nPeers:\n\t%s\n"
     37                pck.info.id pck.info.title (String.concat "," pck.info.people)
     38                (s pck.info.locations) (s (to_str_list pck.peers))
     39
     40type t = { dir : string; index_path: string; pck : Header_pack.t }
     41
     42let index r print title auth locs peers =
     43        let edit name index param = if print then index else match param with
     44        | Some "$" -> text_editor name index | Some p -> p
     45        | None -> index in
     46        let edits name index param = if print then index else match param with
     47        | Some "$" -> text_editor_lines name index | Some p -> String_set.list_of_csv p
     48        | None -> index in
     49        let edits_mp name index param = if print then index else match param with
     50        | Some "$" -> Header_pack.str_list (text_editor_lines name (Header_pack.to_str_list index))
     51        | Some p -> Header_pack.str_list (String_set.list_of_csv p)
     52        | None -> index in
     53        let info = Header_pack.{ r.pck.info with
     54                title = edit "Title" r.pck.info.title title;
     55                people = edits "People" r.pck.info.people auth;
     56                locations = edits "Locations" r.pck.info.locations locs;
     57        } in
     58        let pack = Header_pack.{ info; fields;
     59                texts = of_text_list @@ File_store.fold ~dir:r.dir (fun a (t,_) -> of_text a t) [];
     60                peers = edits_mp "Peers" r.pck.peers peers;
     61        } in
     62        if print then print_pack pack
     63        else (File_store.file r.index_path (Header_pack.string pack))
     64
     65let load dir =
     66        let index_path = Filename.concat dir "index.pck" in
     67        let pck = match Header_pack.of_string @@ File_store.to_string index_path with
     68        | Error s -> failwith s | Ok pck -> pck
    2069        | exception (Sys_error _) -> Header_pack.{
    21                 info = {
    22                         version = version; id = Id.generate (); title;
    23                         people = String_set.list_of_csv authors;
    24                         locations = String_set.list_of_csv locations };
     70                info = { version = version; id = Id.generate (); title = ""; people = []; locations = [] };
    2571                fields;
    2672                texts = of_text_list @@ File_store.fold ~dir
    2773                        (fun a (t,_) -> of_text a t) [];
    28                 peers = str_list @@ String_set.list_of_csv peers;
     74                peers = Msgpck.of_list [];
    2975        } in
    30         File_store.file fname (Header_pack.string pck);
    31         let open Header_pack in
    32         let s ss = String.concat "\n\t" ss in
    33         if print then
    34                 Printf.printf "Title: %s\nAuthors: %s\nLocations:\n\t%s\nPeers:\n\t%s\n"
    35                         pck.info.title (String.concat "," pck.info.people)
    36                         (s pck.info.locations) (s (to_str_list pck.peers))
     76        index { dir; index_path; pck }
    3777
    3878open Cmdliner
    3979let term =
    40         let print = Arg.(value & flag & info ["print"] ~doc:"print info") in
    41         let title= Arg.(value & opt string "" & info ["t"; "title"]
     80        let print= Arg.(value & flag & info ["print"] ~doc:"print info") in
     81        let title= Arg.(value & opt ~vopt:(Some "$") (some string) None & info ["t"; "title"]
    4282                ~docv:"string" ~doc:"Title for index") in
    43         let auth = Arg.(value & opt string "" & info ["a"; "authors"]
     83        let auth = Arg.(value & opt ~vopt:(Some "$") (some string) None & info ["a"; "authors"]
    4484                ~docv:"comma-separated names" ~doc:"Index authors") in
    45         let locs = Arg.(value & opt string "" & info ["l"; "locations"]
     85        let locs = Arg.(value & opt ~vopt:(Some "$") (some string) None & info ["l"; "locations"]
    4686                ~docv:"comma-separated URLs" ~doc:"repository URLs") in
    47         let peers= Arg.(value & opt string "" & info ["p"; "peers"]
     87        let peers= Arg.(value & opt ~vopt:(Some "$") (some string) None & info ["p"; "peers"]
    4888                ~docv:"comma-separated URLs" ~doc:"URLs to other known text repositories") in
    49         let dir = Arg.(value & pos 0 string "." & info []
     89        let dir  = Arg.(value & pos 0 string "." & info []
    5090                ~docv:"directory to index") in
    5191        let doc = "Generate an index.pck for texts in a directory" in
    52         Term.(const index $ print $ title $ auth $ locs $ peers $ dir),
     92        Term.(const load $ dir $ print $ title $ auth $ locs $ peers),
    5393                Term.info "index" ~doc
    5494                        ~man:[ `S "DESCRIPTION"; `Pre "An index contains:\n
Note: See TracChangeset for help on using the changeset viewer.