source: code/trunk/cli/convert.ml@ 68

Last change on this file since 68 was 66, checked in by Izuru Yakumo, 8 months ago

Migrate the codebase to the latest revision of Cmdliner

Signed-off-by: Izuru Yakumo <yakumo.izuru@…>

File size: 4.3 KB
RevLine 
[2]1open Logarion
2
[20]3(*TODO: move to converters (style, feed checks)*)
4let is_older s d = try Unix.((stat d).st_mtime < (stat s).st_mtime) with _-> true
[2]5
[3]6let convert cs r (text, files) = match Text.str "Content-Type" text with
7 | "" | "text/plain" ->
8 let source = List.hd files in
9 let dest = Filename.concat r.Conversion.dir (Text.short_id text) in
[43]10 List.fold_left (fun a f ->
11 match f.Conversion.page with None -> false || a
12 | Some page ->
13 let dest = dest ^ f.Conversion.ext in
14 (if is_older source dest || Conversion.Rel.Id_map.mem text.Text.id r.relations
15 then (File_store.file dest (page r text); true) else false)
16 || a)
[3]17 false cs
18 | x -> Printf.eprintf "Can't convert Content-Type: %s file: %s" x text.Text.title; false
[2]19
[3]20let converters types kv =
[19]21 let n = String.split_on_char ',' types in
[3]22 let t = [] in
[19]23 let t = if List.(mem "all" n || mem "htm" n) then (Html.converter kv)::t else t in
24 let t = if List.(mem "all" n || mem "atom" n) then (Atom.converter "text/html")::t else t in
25 let t = if List.(mem "all" n || mem "gmi" n) then (Gemini.converter)::t else t in
26 let t = if List.(mem "all" n || mem "gmi-atom" n) then (Atom.converter "text/gemini")::t else t in
[3]27 t
[2]28
[20]29let directory converters noindex repo =
[42]30 let order = File_store.oldest in
31 let repo =
[43]32 let open Conversion in
33 let rels = File_store.fold ~dir:repo.dir ~order Rel.acc_txt Rel.empty_map in
34 let relations = Peers.fold Rel.acc_pck rels in
35 { repo with relations } in
[42]36 let acc (ts,ls,acc) ((elt,_) as r) = Topic_set.to_map ts (Text.set "topics" elt), elt::ls,
37 if convert converters repo r then acc+1 else acc in
38 let topics, texts, count =
39 File_store.fold ~dir:repo.Conversion.dir ~order acc (Topic_set.Map.empty, [], 0) in
[20]40 let topic_roots = try List.rev @@ String_set.list_of_csv (Store.KV.find "Topics" repo.kv)
[3]41 with Not_found -> Topic_set.roots topics in
[42]42 let repo = Conversion.{ repo with topic_roots; topics; texts = List.rev texts } in
[41]43 if not noindex then
44 List.iter (fun c -> match c.Conversion.indices with None -> () | Some f -> f repo) converters;
[3]45 Printf.printf "Converted: %d Indexed: %d\n" count (List.length texts)
[2]46
[20]47let load_kv dir =
[21]48 let kv = File_store.of_kv_file () in
[20]49 let idx = Filename.concat dir "index.pck" in
50 if not (Sys.file_exists idx) then kv else
51 match Header_pack.of_string @@ File_store.to_string (idx) with
52 | Error s -> prerr_endline s; kv
[15]53 | Ok { info; peers; _ } ->
[20]54 let kv = if Store.KV.mem "Id" kv then kv else Store.KV.add "Id" info.Header_pack.id kv in
[19]55 let kv = if Store.KV.mem "Title" kv then kv else Store.KV.add "Title" info.Header_pack.title kv in
[21]56 let kv = if Store.KV.mem "Locations" kv then kv else Store.KV.add "Locations" (String.concat ";\n" info.Header_pack.locations) kv in
[15]57 let kv = Store.KV.add "Peers" (String.concat ";\n" Header_pack.(to_str_list peers)) kv in
[20]58 kv
59
60let at_path types noindex path = match path with
61 | "" -> prerr_endline "unspecified text file or directory"
[13]62 | path when Sys.file_exists path ->
[20]63 if Sys.is_directory path then (
64 let kv = load_kv path in
65 let repo = { (Conversion.empty ()) with dir = path; kv } in
66 directory (converters types kv) noindex repo
67 ) else (
68 match File_store.to_text path with
69 | Error s -> prerr_endline s
70 | Ok text ->
[39]71 let dir = "." in
[43]72 let open Conversion in
73 let relations = File_store.(fold ~dir ~order:newest Rel.acc_txt Rel.empty_map) in
74 let repo = { (Conversion.empty ()) with dir; kv = load_kv ""; relations } in
[20]75 ignore @@ convert (converters types repo.kv) repo (text, [path])
76 )
[13]77 | path -> Printf.eprintf "Path doesn't exist: %s" path
[2]78
[66]79open Cmdliner
80
81let path = Arg.(value & pos 0 string "" & info [] ~docv:"path" ~doc:"Text file or directory to convert. If directory is provided, it must contain an index.pck (see: txt index)")
82let types = Arg.(value & opt string "all" & info ["t"; "type"] ~docv:"output type" ~doc:"Convert to file type")
83let noindex = Arg.(value & flag & info ["noindex"] ~doc:"Don't create indices in target format")
84
85let convert_t = Term.(const at_path $ types $ noindex $ path)
86
87let cmd =
88 let doc = "Convert texts" in
89 let man = [
90 `S Manpage.s_description;
91 `P "Convert text or indexed texts within a directory to another format.";
92 `P "If path is a directory must contain an index.pck.";
93 `P "Run `txt index` first." ]
94 in
95 let info = Cmd.info "convert" ~version: "%%VERSION%%" ~doc ~man in
96 Cmd.v info convert_t
Note: See TracBrowser for help on using the repository browser.