diff --git a/cli/convert.ml b/cli/convert.ml index a288396..7161a84 100644 --- a/cli/convert.ml +++ b/cli/convert.ml @@ -3,70 +3,79 @@ let version = "%%VERSION%%" open Logarion module A = Archive.Make (Logarion.File_store) -let file_when_changed source dest fn title text = - if (try Unix.((stat dest).st_mtime < (stat source).st_mtime) with _-> true) then - File_store.file dest (fn title text) +let convert_modified source dest fn title text = + if (try Unix.((stat dest).st_mtime < (stat source).st_mtime) with _-> true) + then (File_store.file dest (fn title text); true) else false -let writer types dir name acc (text,store_item) = (* todo: single_parser -> [files] *) - let open Logarion in - match Text.(str "Content-Type" text) with - | "" | "text/plain" -> - let filename = dir ^ "/" ^ Text.alias text in -(* let idfilename = dir ^ "/" ^ Id.to_string text.Text.uuid ^ ".txt" in*) -(* file_when_changed store_item idfilename (fun _title -> Text.to_string) text.title text;*) - if "htm" = types || "all" = types then file_when_changed store_item (filename ^ ".htm") (Html.page "") name text; - if "gmi" = types || "all" = types then file_when_changed store_item (filename ^ ".gmi") Gemini.page name text; - (acc + 1) - | x -> prerr_endline ("No converter for Content-Type: " ^ x ^ ", for " ^ text.Text.title); acc +let word_fname dir text = dir ^ "/" ^ Text.alias text +let id_fname dir text = dir ^ "/" ^ String.sub (Id.to_string text.Text.uuid) 0 8 + +let writer types dir name (text,store_item) = (* todo: single_parser -> [files] *) +(* convert_modified store_item idfilename (fun _title -> Text.to_string) text.title text;*) + let h = if "htm" = types || "all" = types then + convert_modified store_item (word_fname dir text ^ ".htm") Html.page name text + else false in + let g = if "gmi" = types || "all" = types then + convert_modified store_item (word_fname dir text ^ ".gmi") Gemini.page name text + else false in + h || g let index_writer types dir archive topic_roots topic_map indexed_texts = - let name = archive.A.name in - let file path = File_store.file (dir ^ path) in - file "/index.pck" (Header_pack.pack archive indexed_texts); - if "htm" = types || "all" = types then ( - file "/index.html" (Html.topic_main_index name topic_roots indexed_texts); - List.iter - (fun topic -> file ("/index." ^ topic ^ ".htm") (Html.topic_sub_index name topic_map topic indexed_texts)) - topic_roots; - file "/index.date.htm" (Html.date_index name indexed_texts); - ); - let base_url = try Store.KV.find "HTTP-URL" archive.File_store.kv - with Not_found -> prerr_endline "Missing `HTTP-URL:` in config"; "" - in - file "/feed.atom" (Atom.feed archive.A.name archive.A.id base_url indexed_texts); - if "gmi" = types || "all" = types then file "/index.date.gmi" (Gemini.date_index name indexed_texts) + let name = archive.A.name in + let file path = File_store.file (dir ^ path) in + file "/index.pck" (Header_pack.pack archive indexed_texts); + if "htm" = types || "all" = types then ( + file "/index.html" (Html.topic_main_index name topic_roots indexed_texts); + List.iter + (fun topic -> file ("/index." ^ topic ^ ".htm") + (Html.topic_sub_index name topic_map topic indexed_texts)) + topic_roots; + file "/index.date.htm" (Html.date_index name indexed_texts); + ); + let base_url = try Store.KV.find "HTTP-URL" archive.File_store.kv + with Not_found -> prerr_endline "Missing `HTTP-URL:` in config"; "" + in + file "/feed.atom" (Atom.feed archive.A.name archive.A.id base_url indexed_texts); + if "gmi" = types || "all" = types then + file "/index.date.gmi" (Gemini.date_index name indexed_texts) + +let txt_writer types dir name ((text, _store_item) as r) = + match Logarion.Text.str "Content-Type" text with + | "" | "text/plain" -> writer types dir name r + | x -> prerr_endline ("Can't convert Content-Type: "^x^" file: " ^text.Text.title); false let convert_all types dir archive = - let name = archive.A.name in - let topic_map, indexed_metas, count = - let topic_map = Logarion.Topic_set.Map.empty in - let fn (ts,ls,acc) ((elt,_) as r) = - Logarion.(Topic_set.to_map ts (Text.set "topics" elt)), elt::ls, writer types dir name acc r in - A.(fold ~order:newest fn (topic_map,[],0) archive) in - let topic_roots = Logarion.Topic_set.roots topic_map in - index_writer types dir archive topic_roots topic_map indexed_metas; - print_endline @@ "Converted: " ^ string_of_int (count) ^ "\nIndexed: " ^ string_of_int (List.length indexed_metas); - Ok () + let name = archive.A.name in + let fn (ts,ls,acc) ((elt,_) as r) = + Logarion.(Topic_set.to_map ts (Text.set "topics" elt)), + elt::ls, if txt_writer types dir name r then acc+1 else acc in + let empty = Logarion.Topic_set.Map.empty in + let topic_map, indexed_metas, count = A.(fold ~order:newest fn (empty,[],0) archive) in + let topic_roots = Logarion.Topic_set.roots topic_map in + index_writer types dir archive topic_roots topic_map indexed_metas; + print_endline @@ "Converted: " ^ string_of_int (count) + ^ "\nIndexed: " ^ string_of_int (List.length indexed_metas); + Ok () let convert_dir types cmd_dir = - let (>>=) = Result.bind in - let with_dir dir = - Result.map_error (function `Msg m -> m) - Logarion.File_store.Directory.(directory dir |> print ~descr:"export" dir) in - (A.of_path "." - >>= fun archive -> (match cmd_dir with "" -> Error "unspecified export dir" | x -> Ok x) - >>= fun dir -> with_dir dir - >>= fun _ -> convert_all types dir { archive with store = dir }) - |> function Ok () -> () | Error x -> prerr_endline x + let (>>=) = Result.bind in + let with_dir dir = + Result.map_error (function `Msg m -> m) + Logarion.File_store.Directory.(directory dir |> print ~descr:"export" dir) in + (A.of_path "." + >>= fun archive -> (match cmd_dir with "" -> Error "unspecified export dir" | x -> Ok x) + >>= fun dir -> with_dir dir + >>= fun _ -> convert_all types dir { archive with store = dir }) + |> function Ok () -> () | Error x -> prerr_endline x open Cmdliner let term = - let directory = Arg.(value & pos 0 string "" - & info [] ~docv:"target directory" ~doc:"Directory to convert into") in - let types = Arg.(value & opt string "all" & info ["t"; "type"] ~docv:"TYPES" ~doc:"Convert to type") in + let directory = Arg.(value & pos 0 string "" + & info [] ~docv:"target directory" ~doc:"Directory to convert into") in + let types = Arg.(value & opt string "all" & info ["t"; "type"] ~docv:"TYPES" ~doc:"Convert to type") in - Term.(const convert_dir $ types $ directory), - Term.info - "convert" ~doc:"convert archive" - ~man:[ `S "DESCRIPTION"; `P "Convert Logarion archive" ] + Term.(const convert_dir $ types $ directory), + Term.info + "convert" ~doc:"convert archive" + ~man:[ `S "DESCRIPTION"; `P "Convert Logarion archive" ] diff --git a/cli/html.ml b/cli/html.ml index af433a9..43540df 100644 --- a/cli/html.ml +++ b/cli/html.ml @@ -9,7 +9,7 @@ let wrap ?(keywords="") (title:string) (subtitle:string) body = let topic_link root topic = {||} ^ String.capitalize_ascii topic ^ "" -let page _topic_roots archive_title text = +let page archive_title text = let open Logarion in let open Text in let module T = Parsers.Plain_text.Make (Converter.Html) in