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

Last change on this file since 2 was 2, checked in by fox, 3 years ago

Samhain 21

Converter

  • type selection
  • subdir conversion
  • htm extension

Gemini

  • index.gmi
  • topics and latest
  • gmi.atom feed

Add pull (http(s)) operation

  • peers.pub.conf and peers.priv.conf

HTML5 format & fixes by Novaburst
Phony target (thanks Gergely)

May

Basic unit renamed from Note to Text.
New modular text-parser, internal to Logarion, for generic notation parsing. The default input format is now a much plainer text.
Logarion created texts have part of the UUID in filename.
Logarion's index re-written in Messagepack format. Removed indices command. They are generated during convert.

File size: 4.1 KB
Line 
1open Logarion
2module A = Archive.Make (Logarion.File_store)
3
4let convert_modified source dest fn title text =
5 if (try Unix.((stat dest).st_mtime < (stat source).st_mtime) with _-> true)
6 then (File_store.file dest (fn title text); true) else false
7
8let word_fname dir text = dir ^ "/" ^ Text.alias text
9let id_fname dir text = dir ^ "/" ^ Text.short_id text
10
11let writer types dir name (text,store_item) = (* todo: single_parser -> [files] *)
12(* convert_modified store_item idfilename (fun _title -> Text.to_string) text.title text;*)
13 let h = if "htm" = types || "all" = types then
14 convert_modified store_item (id_fname dir text ^ ".htm") Html.page name text
15 else false in
16 let g = if "gmi" = types || "all" = types then
17 convert_modified store_item (id_fname dir text ^ ".gmi") Gemini.page name text
18 else false in
19 h || g
20
21let index_writer types noindex dir archive topic_roots topic_map texts =
22 let name = archive.A.name in
23 let file path = File_store.file (dir ^ path) in
24 file "/index.pck" (Header_pack.pack archive texts);
25 if not noindex && ("htm" = types || "all" = types) then (
26 let index_name = try Store.KV.find "HTML-index" archive.File_store.kv
27 with Not_found -> "index.html" in
28 if index_name <> "" then
29 file ("/"^index_name) (Html.topic_main_index name topic_roots texts);
30 file "/index.date.htm" (Html.date_index name texts);
31 List.iter
32 (fun topic -> file ("/index." ^ topic ^ ".htm")
33 (Html.topic_sub_index name topic_map topic texts))
34 topic_roots;
35 let base_url = try Store.KV.find "HTTP-URL" archive.File_store.kv
36 with Not_found -> prerr_endline "Missing `HTTP-URL:` in config"; "" in
37 file "/feed.atom" (Atom.feed archive.A.name archive.A.id base_url "text/html" texts)
38 );
39 if not noindex && ("gmi" = types || "all" = types) then (
40 let index_name = try Store.KV.find "Gemini-index" archive.File_store.kv
41 with Not_found -> "index.gmi" in
42 if index_name <> "" then
43 file ("/"^index_name) (Gemini.topic_main_index name topic_roots texts);
44 file "/index.date.gmi" (Gemini.date_index name texts);
45 List.iter
46 (fun topic -> file ("/index." ^ topic ^ ".gmi")
47 (Gemini.topic_sub_index name topic_map topic texts))
48 topic_roots;
49 let base_url = try Store.KV.find "GEMINI-URL" archive.File_store.kv
50 with Not_found -> prerr_endline "Missing `GEMINI-URL:` in config"; "" in
51 file "/gmi.atom" (Atom.feed archive.A.name archive.A.id base_url "text/gemini" texts)
52 )
53
54let txt_writer types dir name ((text, _store_item) as r) =
55 match Text.str "Content-Type" text with
56 | "" | "text/plain" -> writer types dir name r
57 | x -> prerr_endline ("Can't convert Content-Type: "^x^" file: " ^text.Text.title); false
58
59let convert_all types noindex dir archive =
60 let name = archive.A.name in
61 let fn (ts,ls,acc) ((elt,_) as r) =
62 (Topic_set.to_map ts (Text.set "topics" elt)),
63 elt::ls, if txt_writer types dir name r then acc+1 else acc in
64 let empty = Topic_set.Map.empty in
65 let topic_map, texts, count = A.(fold ~order:newest fn (empty,[],0) archive) in
66 let topic_roots = Topic_set.roots topic_map in
67 index_writer types noindex dir archive topic_roots topic_map texts;
68 print_endline @@ "Converted: " ^ string_of_int (count)
69 ^ "\nIndexed: " ^ string_of_int (List.length texts);
70 Ok ()
71
72let convert_dir types noindex cmd_dir =
73 let (>>=) = Result.bind in
74 let with_dir dir =
75 Result.map_error (function `Msg m -> m)
76 Logarion.File_store.Directory.(directory dir |> print ~descr:"export" dir) in
77 (A.of_path "."
78 >>= fun archive -> (match cmd_dir with "" -> Error "unspecified export dir" | x -> Ok x)
79 >>= fun dir -> with_dir dir
80 >>= fun _ -> convert_all types noindex dir { archive with store = dir })
81 |> function Ok () -> () | Error x -> prerr_endline x
82
83open Cmdliner
84
85let term =
86 let directory = Arg.(value & pos 0 string "" & info [] ~docv:"target directory" ~doc:"Directory to convert into") in
87 let types = Arg.(value & opt string "all" & info ["t"; "type"] ~docv:"TYPES" ~doc:"Convert to type") in
88 let noindex = Arg.(value & flag & info ["noindex"] ~doc:"don't write an index when converting") in
89 Term.(const convert_dir $ types $ noindex $ directory),
90 Term.info "convert" ~doc:"convert archive" ~man:[ `S "DESCRIPTION"; `P "Convert Logarion archive" ]
Note: See TracBrowser for help on using the repository browser.