diff --git a/Makefile b/Makefile index 8d97c88..1baf879 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ OS=`uname -s` MACHINE=`uname -m` -DATE=`date -r _build/default/cli/txt.exe +%Y%m%d` +DATE=`date -r _build/default/cmd/txt/txt.exe +%Y%m%d` COMMIT=`git rev-parse --short HEAD` PREFIX=/usr/local @@ -11,18 +11,21 @@ all: @dune build deps: @opam install dune ocurl cmdliner msgpck -cli: - @dune build cli/txt.exe +txt: + @dune build cmd/txt/txt.exe clean: @dune clean dist: @dune build - @cp _build/default/cli/txt.exe txt.exe + @cp _build/default/cmd/txt/txt.exe txt.exe @strip txt.exe - @tar czvf "logarion-${OS}-${MACHINE}-${DATE}-${COMMIT}" txt.exe readme.txt + @tar czvf "kosuzu-${OS}-${MACHINE}-${DATE}-${COMMIT}" txt.exe readme.txt @rm txt.exe + +txt_init: + @dune build cmd/txt_init/txt_init.exe install: @dune install --prefix ${PREFIX} uninstall: @dune uninstall --prefix ${PREFIX} -.PHONY: cli +.PHONY: txt txt_init diff --git a/README.md b/README.md index b6bc181..18e7a79 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,7 @@ -# Logarion -Text archival and exchange. +![Kosuzu Motoori](img/FS_Kosuzu2.png) + +# Kosuzu +Text archival and exchange, named after [Kosuzu Motoori](https://en.touhouwiki.net/wiki/Kosuzu_Motoori) from [Forbidden Scrollery](https://en.touhouwiki.net/wiki/Forbidden_Scrollery). ## Contact -* [Mailing list](https://lists.tildeverse.org/postorius/lists/logarion.lists.tildeverse.org/) - -## References -* [Building from source](https://logarion.chaotic.ninja/9egbae.htm) -* [Creating texts & publishing on the net](https://logarion.chaotic.ninja/hvhhwf.htm) -* [Exploring & pulling texts from Logarion repositories](https://logarion.chaotic.ninja/3sqd84.htm) -* [Header format](https://logarion.chaotic.ninja/d41e68.htm) -* [Txt uniform resource names](https://logarion.chaotic.ninja/h1a9tg.htm) - -## Maintainers -* orbifx (original author, former maintainer) -* Izuru Yakumo (contributor, current maintainer) +* [Mailing list](mailto:kosuzu-dev@chaotic.ninja) diff --git a/cli/atom.ml b/cmd/txt/atom.ml similarity index 82% rename from cli/atom.ml rename to cmd/txt/atom.ml index 02cfe7d..aab1b53 100644 --- a/cli/atom.ml +++ b/cmd/txt/atom.ml @@ -11,23 +11,23 @@ let opt_element tag_name content = module P = Parsers.Plain_text.Make (Converter.Html) -let id txt = "urn:txtid:" ^ Logarion.(txt.Text.id) ^ "\n" -let title text = "" ^ esc text.Logarion.Text.title ^ "\n" +let id txt = "urn:txtid:" ^ Kosuzu.(txt.Text.id) ^ "\n" +let title text = "" ^ esc text.Kosuzu.Text.title ^ "\n" let authors text = let u acc addr = acc ^ element "uri" addr in - let open Logarion in + let open Kosuzu in let fn txt a = a ^ "" ^ (opt_element "name" @@ esc txt.Person.name) ^ (List.fold_left u "" txt.Person.addresses) ^ "\n" in Person.Set.fold fn text.Text.authors "" -let updated txt = let open Logarion in +let updated txt = let open Kosuzu in ""^ Date.(txt.Text.date |> listing |> rfc_string) ^"\n" let htm_entry base_url text = - let open Logarion in + let open Kosuzu in let u = Text.short_id text in "\n\n" ^ title text ^ id text ^ updated text ^ authors text @@ -36,7 +36,7 @@ let htm_entry base_url text = ^ "\n" let gmi_entry base_url text = - let open Logarion in + let open Kosuzu in let u = Text.short_id text in "\n\n" ^ title text ^ id text ^ updated text ^ authors text @@ -45,14 +45,14 @@ let gmi_entry base_url text = ^ "\n" let base_url kv protocol = try - let locs = Logarion.Store.KV.find "Locations" kv in + let locs = Kosuzu.Store.KV.find "Locations" kv in let _i = Str.(search_forward (regexp (protocol ^ "://[^;]*")) locs 0) in Str.(matched_string locs) with Not_found -> Printf.eprintf "Missing location for %s, add it to txt.conf\n" protocol; "" let indices alternate_type c = - let file name = Logarion.File_store.file (Filename.concat c.Conversion.dir name) in - let title = try Logarion.Store.KV.find "Title" c.Conversion.kv with Not_found -> "" in + let file name = Kosuzu.File_store.file (Filename.concat c.Conversion.dir name) in + let title = try Kosuzu.Store.KV.find "Title" c.Conversion.kv with Not_found -> "" in let entry, fname, protocol_regexp = match alternate_type with | "text/gemini" -> gmi_entry, "gmi.atom", "gemini" | "text/html" | _ -> htm_entry, "feed.atom", "https?" @@ -64,7 +64,7 @@ let indices alternate_type c = ^ title ^ {|urn:txtid:|} ^ c.Conversion.id ^ "" - ^ Logarion.Date.now () ^ "\n" + ^ Kosuzu.Date.now () ^ "\n" ^ List.fold_left (fun acc t -> acc ^ entry base_url t) "" c.texts ^ "" diff --git a/cli/authors.ml b/cmd/txt/authors.ml similarity index 98% rename from cli/authors.ml rename to cmd/txt/authors.ml index bf7f70d..6fd77cc 100644 --- a/cli/authors.ml +++ b/cmd/txt/authors.ml @@ -1,4 +1,4 @@ -open Logarion +open Kosuzu let authors r topics_opt = let predicates = Archive.(predicate topics topics_opt) in let predicate text = List.fold_left (fun a e -> a && e text) true predicates in diff --git a/cli/conversion.ml b/cmd/txt/conversion.ml similarity index 97% rename from cli/conversion.ml rename to cmd/txt/conversion.ml index 22672c8..12f74aa 100644 --- a/cli/conversion.ml +++ b/cmd/txt/conversion.ml @@ -1,4 +1,4 @@ -open Logarion +open Kosuzu module Rel = struct @@ -60,7 +60,7 @@ type t = { type fn_t = { ext: string; - page: (t -> Logarion.Text.t -> string) option; + page: (t -> Kosuzu.Text.t -> string) option; indices: (t -> unit) option; } diff --git a/cli/convert.ml b/cmd/txt/convert.ml similarity index 98% rename from cli/convert.ml rename to cmd/txt/convert.ml index 51daeeb..4ee7de2 100644 --- a/cli/convert.ml +++ b/cmd/txt/convert.ml @@ -1,6 +1,5 @@ -open Logarion +open Kosuzu -(*TODO: move to converters (style, feed checks)*) let is_older s d = try Unix.((stat d).st_mtime < (stat s).st_mtime) with _-> true let convert cs r (text, files) = match Text.str "Content-Type" text with diff --git a/cli/dune b/cmd/txt/dune similarity index 65% rename from cli/dune rename to cmd/txt/dune index c5f9ea1..471ab7f 100644 --- a/cli/dune +++ b/cmd/txt/dune @@ -3,4 +3,4 @@ (public_name txt) (modules txt authors convert conversion edit file index last listing new topics html atom gemini peers pull recent unfile) - (libraries text_parse.converter text_parse.parsers logarion msgpck curl str cmdliner)) + (libraries text_parse.converter text_parse.parsers kosuzu msgpck curl str cmdliner)) diff --git a/cli/edit.ml b/cmd/txt/edit.ml similarity index 88% rename from cli/edit.ml rename to cmd/txt/edit.ml index b830e32..298e52c 100644 --- a/cli/edit.ml +++ b/cmd/txt/edit.ml @@ -7,7 +7,7 @@ let number = Arg.(value & opt (some int) None & info ["n"] ~docv: "number" ~doc: let authed = Arg.(value & opt (some string) None & info ["authored"] ~docv: "Comma-separated names" ~doc: "Texts by authors") let topics = Arg.(value & opt (some string) None & info ["topics"] ~docv: "Comma-separated topics" ~doc: "Texts by topics") -let edit_t = Term.(const (Logarion.Archive.apply_sys_util "EDITOR" "nano") $ recurse $ time $ reverse $ number $ authed $ topics $ id) +let edit_t = Term.(const (Kosuzu.Archive.apply_sys_util "EDITOR" "nano") $ recurse $ time $ reverse $ number $ authed $ topics $ id) let cmd = let doc = "Edit a text" in diff --git a/cli/file.ml b/cmd/txt/file.ml similarity index 98% rename from cli/file.ml rename to cmd/txt/file.ml index 808018e..cea07c8 100644 --- a/cli/file.ml +++ b/cmd/txt/file.ml @@ -1,4 +1,4 @@ -open Logarion +open Kosuzu let file files = let dirs, files = File_store.split_filetypes files in let _link_as_named dir file = Unix.link file (Filename.concat dir file) in diff --git a/cli/gemini.ml b/cmd/txt/gemini.ml similarity index 77% rename from cli/gemini.ml rename to cmd/txt/gemini.ml index e083f81..e2136c3 100644 --- a/cli/gemini.ml +++ b/cmd/txt/gemini.ml @@ -7,18 +7,18 @@ module GeminiConverter = struct end let page _conversion text = - let open Logarion.Text in + let open Kosuzu.Text in "# " ^ text.title - ^ "\nAuthors: " ^ Logarion.Person.Set.to_string text.authors - ^ "\nDate: " ^ Logarion.Date.(pretty_date @@ listing text.date) + ^ "\nAuthors: " ^ Kosuzu.Person.Set.to_string text.authors + ^ "\nDate: " ^ Kosuzu.Date.(pretty_date @@ listing text.date) ^ let module T = Parsers.Plain_text.Make (GeminiConverter) in "\n" ^ T.of_string text.body "" let date_index title meta_list = List.fold_left (fun a m -> - a ^ "=> " ^ Logarion.Text.short_id m ^ ".gmi " ^ - Logarion.(Date.(pretty_date (listing m.date)) ^ " " ^ m.title) ^ "\n") + a ^ "=> " ^ Kosuzu.Text.short_id m ^ ".gmi " ^ + Kosuzu.(Date.(pretty_date (listing m.date)) ^ " " ^ m.title) ^ "\n") ("# " ^ title ^ "\n\n## Posts by date\n\n") meta_list let to_dated_links ?(limit) meta_list = @@ -33,9 +33,9 @@ let to_dated_links ?(limit) meta_list = List.fold_left (fun a m -> a - ^ "=> " ^ Logarion.Text.short_id m ^ ".gmi " - ^ Logarion.(Date.(pretty_date (listing m.Text.date))) ^ " " - ^ m.Logarion.Text.title ^ "\n") + ^ "=> " ^ Kosuzu.Text.short_id m ^ ".gmi " + ^ Kosuzu.(Date.(pretty_date (listing m.Text.date))) ^ " " + ^ m.Kosuzu.Text.title ^ "\n") "" meta_list let topic_link root topic = @@ -43,7 +43,7 @@ let topic_link root topic = "=> index." ^ replaced_space root ^ ".gmi " ^ String.capitalize_ascii topic ^ "\n" let text_item path meta = - let open Logarion in + let open Kosuzu in "=> " ^ path ^ Text.short_id meta ^ ".gmi " ^ Date.(pretty_date (listing meta.Text.date)) ^ " " ^ meta.Text.title ^ "\n" @@ -51,15 +51,15 @@ let text_item path meta = let listing_index topic_map topic_roots path metas = let rec item_group topics = List.fold_left (fun acc topic -> acc ^ sub_groups topic ^ items topic) "" topics - and sub_groups topic = match Logarion.Topic_set.Map.find_opt topic topic_map with + and sub_groups topic = match Kosuzu.Topic_set.Map.find_opt topic topic_map with | None -> "" - | Some (_, subtopics) -> item_group (Logarion.String_set.elements subtopics) + | Some (_, subtopics) -> item_group (Kosuzu.String_set.elements subtopics) and items topic = let items = - let open Logarion in + let open Kosuzu in List.fold_left (fun a e -> - if String_set.mem topic (String_set.map (Logarion.Topic_set.topic) (Text.set "Topics" e)) + if String_set.mem topic (String_set.map (Kosuzu.Topic_set.topic) (Text.set "Topics" e)) then text_item path e ^ a else a) "" metas in match items with | "" -> "" @@ -76,7 +76,7 @@ let topic_main_index r title topic_roots metas = ^ (if topic_roots <> [] then ("## Main topics\n\n" ^ fold_topic_roots topic_roots) else "") ^ "\n## Latest\n\n" ^ to_dated_links ~limit:10 metas ^ "\n=> index.date.gmi More by date\n\n" - ^ let peers = Logarion.Store.KV.find "Peers" r.Conversion.kv in + ^ let peers = Kosuzu.Store.KV.find "Peers" r.Conversion.kv in if peers = "" then "" else List.fold_left (fun a s -> Printf.sprintf "%s=> %s\n" a s) "## Peers\n\n" (Str.split (Str.regexp ";\n") peers) @@ -86,7 +86,7 @@ let topic_sub_index title topic_map topic_root metas = ^ listing_index topic_map [topic_root] "" metas let indices r = - let open Logarion in + let open Kosuzu in let file name = File_store.file (Filename.concat r.Conversion.dir name) in let index_name = try Store.KV.find "Gemini-index" r.kv with Not_found -> "index.gmi" in let title = try Store.KV.find "Title" r.Conversion.kv with Not_found -> "" in diff --git a/cli/html.ml b/cmd/txt/html.ml similarity index 86% rename from cli/html.ml rename to cmd/txt/html.ml index 546873c..7fec0d6 100644 --- a/cli/html.ml +++ b/cmd/txt/html.ml @@ -6,7 +6,7 @@ let empty_templates = { header = None; footer = None } let default_opts = { templates = empty_templates; style = "" } let init kv = - let open Logarion in + let open Kosuzu in let to_string key kv = match Store.KV.find key kv with | fname -> Some (File_store.to_string fname) | exception Not_found -> None in @@ -17,12 +17,12 @@ let init kv = { templates = { header; footer}; style } let wrap conv htm text_title body = - let site_title = try Logarion.Store.KV.find "Title" conv.Conversion.kv with Not_found -> "" in + let site_title = try Kosuzu.Store.KV.find "Title" conv.Conversion.kv with Not_found -> "" in let replace x = let open Str in global_replace (regexp "{{archive-title}}") site_title x |> global_replace (regexp "{{text-title}}") text_title in - let feed = try Logarion.Store.KV.find "HTM-feed" conv.Conversion.kv + let feed = try Kosuzu.Store.KV.find "HTM-feed" conv.Conversion.kv with Not_found -> if Sys.file_exists (Filename.concat conv.Conversion.dir "feed.atom") then "feed.atom" else "" in let header = match htm.templates.header with @@ -31,7 +31,7 @@ let wrap conv htm text_title body = (if feed <> "" then sprintf "feed" feed else "")) in let footer = match htm.templates.footer with None -> "" | Some x -> replace x in - Printf.sprintf "\n\n\n\n%s%s\n%s\n%s\n\n\n\n\n\n%s%s%s\n" + Printf.sprintf "\n\n\n\n%s%s\n%s\n%s\n\n\n\n\n\n%s%s%s\n" text_title (if site_title <> "" then (" • " ^ site_title) else "") htm.style (if feed <> "" then Printf.sprintf "" feed else "") @@ -51,7 +51,7 @@ module HtmlConverter = struct end let page htm conversion text = - let open Logarion in + let open Kosuzu in let open Text in let module T = Parsers.Plain_text.Make (HtmlConverter) in let sep_append ?(sep=", ") a x = match a,x with "",_ -> x | _, "" -> a | _ -> a ^ sep ^ x in @@ -95,8 +95,8 @@ let to_dated_links ?(limit) meta_list = | h::t -> if i < limit then reduced (h::acc) (i+1) t else acc in List.rev @@ reduced [] 0 meta_list in List.fold_left - (fun a m -> Printf.sprintf "%s
  • %s %s" a Logarion.(Date.(pretty_date (listing m.Text.date))) - (Logarion.Text.short_id m) m.Logarion.Text.title) + (fun a m -> Printf.sprintf "%s
  • %s %s" a Kosuzu.(Date.(pretty_date (listing m.Text.date))) + (Kosuzu.Text.short_id m) m.Kosuzu.Text.title) "" meta_list let date_index ?(limit) conv htm meta_list = @@ -111,7 +111,7 @@ let fold_topic_roots topic_roots = ^ "" let fold_topics topic_map topic_roots metas = - let open Logarion in + let open Kosuzu in let rec unordered_list root topic = List.fold_left (fun a x -> a ^ list_item root x) "" @@ -128,7 +128,7 @@ and list_item root t = ^ "" let text_item path meta = - let open Logarion in + let open Kosuzu in " |} ^ meta.Text.title ^ "
    " @@ -136,15 +136,15 @@ let text_item path meta = let listing_index topic_map topic_roots path metas = let rec item_group topics = List.fold_left (fun acc topic -> acc ^ sub_groups topic ^ items topic) "" topics - and sub_groups topic = match Logarion.Topic_set.Map.find_opt topic topic_map with + and sub_groups topic = match Kosuzu.Topic_set.Map.find_opt topic topic_map with | None -> "" - | Some (_, subtopics) -> item_group (Logarion.String_set.elements subtopics) + | Some (_, subtopics) -> item_group (Kosuzu.String_set.elements subtopics) and items topic = let items = - let open Logarion in + let open Kosuzu in List.fold_left (fun a e -> - if String_set.mem topic (String_set.map (Logarion.Topic_set.topic) (Text.set "Topics" e)) + if String_set.mem topic (String_set.map (Kosuzu.Topic_set.topic) (Text.set "Topics" e)) then text_item path e ^ a else a) "" metas in match items with | "" -> "" @@ -156,10 +156,10 @@ let topic_main_index conv htm topic_roots metas = (fold_topic_roots topic_roots ^ "
    More by date|} -^ let peers = try Logarion.Store.KV.find "Peers" conv.kv with Not_found -> "" in +^ let peers = try Kosuzu.Store.KV.find "Peers" conv.kv with Not_found -> "" in (if peers = "" then "" else List.fold_left (fun a s -> Printf.sprintf {|%s
  • %s|} a s s) "

    Peers

    ")) let topic_sub_index conv htm topic_map topic_root metas = @@ -168,8 +168,8 @@ let topic_sub_index conv htm topic_map topic_root metas = ^ listing_index topic_map [topic_root] "" metas) let indices htm c = - let file name = Logarion.File_store.file (Filename.concat c.Conversion.dir name) in - let index_name = try Logarion.Store.KV.find "HTM-index" c.Conversion.kv with Not_found -> "index.html" in + let file name = Kosuzu.File_store.file (Filename.concat c.Conversion.dir name) in + let index_name = try Kosuzu.Store.KV.find "HTM-index" c.Conversion.kv with Not_found -> "index.html" in if index_name <> "" then file index_name (topic_main_index c htm c.topic_roots c.texts); file "index.date.htm" (date_index c htm c.texts); List.iter diff --git a/cli/index.ml b/cmd/txt/index.ml similarity index 97% rename from cli/index.ml rename to cmd/txt/index.ml index cf0a34b..a5fd2ed 100644 --- a/cli/index.ml +++ b/cmd/txt/index.ml @@ -1,4 +1,4 @@ -open Logarion +open Kosuzu let text_editor name x = let fname, out = Filename.open_temp_file name "" in @@ -85,6 +85,8 @@ let cmd = `P "* n info section with: title for the index, the authors, locations (URLs) the texts can be accessed."; `P "* listing of texts with: ID, date, title, authors, topics."; `P "* list of other text repositories (peers)"; + `S Manpage.s_environment; + `P "EDITOR - Default editor name"; `S Manpage.s_see_also; `P "MessagePack format. https://msgpack.org" ] in let info = Cmd.info "index" ~doc ~man in diff --git a/cli/last.ml b/cmd/txt/last.ml similarity index 98% rename from cli/last.ml rename to cmd/txt/last.ml index 07c8fb9..b5bf31e 100644 --- a/cli/last.ml +++ b/cmd/txt/last.ml @@ -1,4 +1,4 @@ -open Logarion +open Kosuzu let last a ((t,_) as pair) = match a with | None -> Some pair diff --git a/cli/listing.ml b/cmd/txt/listing.ml similarity index 99% rename from cli/listing.ml rename to cmd/txt/listing.ml index 4b0db15..fefd3a6 100644 --- a/cli/listing.ml +++ b/cmd/txt/listing.ml @@ -1,4 +1,4 @@ -open Logarion +open Kosuzu module FS = File_store module A = Archive diff --git a/cli/new.ml b/cmd/txt/new.ml similarity index 87% rename from cli/new.ml rename to cmd/txt/new.ml index 2a4bc4c..73f4ebe 100644 --- a/cli/new.ml +++ b/cmd/txt/new.ml @@ -1,9 +1,9 @@ -open Logarion +open Kosuzu open Cmdliner let new_txt title topics_opt = - let kv = Logarion.File_store.of_kv_file () in - let authors = Person.Set.of_string (try Logarion.Store.KV.find "Authors" kv + let kv = Kosuzu.File_store.of_kv_file () in + let authors = Person.Set.of_string (try Kosuzu.Store.KV.find "Authors" kv with Not_found -> Sys.getenv "USER") in let text = { (Text.blank ()) with title; authors } in let text = try Text.with_str_set text "Topics" (Option.get topics_opt) with _->text in diff --git a/cli/peers.ml b/cmd/txt/peers.ml similarity index 74% rename from cli/peers.ml rename to cmd/txt/peers.ml index 1279f67..25753b4 100644 --- a/cli/peers.ml +++ b/cmd/txt/peers.ml @@ -1,20 +1,20 @@ let print_peers_of_peer p = - let open Logarion.Header_pack in + let open Kosuzu.Header_pack in match Msgpck.to_list p.peers with [] -> () | ps -> print_endline @@ List.fold_left (fun a x -> Printf.sprintf "%s %s" a (Msgpck.to_string x)) "peers: " ps -type filter_t = { authors: Logarion.Person.Set.t; topics: Logarion.String_set.t } +type filter_t = { authors: Kosuzu.Person.Set.t; topics: Kosuzu.String_set.t } let print_peer () peer = - let open Logarion.Peers in + let open Kosuzu.Peers in Printf.printf "%s" peer.path; List.iter (Printf.printf "\t%s\n") peer.pack.info.locations let remove_repo id = - let repopath = Filename.concat Logarion.Peers.text_dir id in + let repopath = Filename.concat Kosuzu.Peers.text_dir id in match Sys.is_directory repopath with - | false -> Printf.eprintf "No repository %s in %s" id Logarion.Peers.text_dir + | false -> Printf.eprintf "No repository %s in %s" id Kosuzu.Peers.text_dir | true -> let cmd = Printf.sprintf "rm -r %s" repopath in Printf.printf "Run: %s ? (y/N) %!" cmd; @@ -25,8 +25,8 @@ let remove_repo id = let peers = function | Some id -> remove_repo id | None -> - Printf.printf "Peers in %s\n" Logarion.Peers.text_dir; - Logarion.Peers.fold print_peer () + Printf.printf "Peers in %s\n" Kosuzu.Peers.text_dir; + Kosuzu.Peers.fold print_peer () open Cmdliner let remove = Arg.(value & opt (some string) None & info ["remove"] ~docv:"Repository ID" ~doc:"Remove repository texts and from future pulling") diff --git a/cli/pull.ml b/cmd/txt/pull.ml similarity index 73% rename from cli/pull.ml rename to cmd/txt/pull.ml index 802fc48..7b5766f 100644 --- a/cli/pull.ml +++ b/cmd/txt/pull.ml @@ -2,15 +2,6 @@ let writer accum data = Buffer.add_string accum data; String.length data -let showContent content = - Printf.printf "%s" (Buffer.contents content); - flush stdout - -let showInfo connection = - Printf.printf "Time: %f for: %s\n" - (Curl.get_totaltime connection) - (Curl.get_effectiveurl connection) - let getContent connection url = Curl.set_url connection url; Curl.perform connection @@ -25,8 +16,6 @@ let curl_pull url = Curl.set_followlocation connection true; Curl.set_url connection url; Curl.perform connection; -(* showContent result;*) -(* showInfo connection;*) Curl.cleanup connection; Ok result with @@ -38,18 +27,18 @@ let curl_pull url = Error (Printf.sprintf "Caught exception: %s" s) let newer time id dir = - match Logarion.File_store.to_text @@ Filename.(concat dir (Logarion.Id.short id) ^ ".txt") with + match Kosuzu.File_store.to_text @@ Filename.(concat dir (Kosuzu.Id.short id) ^ ".txt") with | Error x -> prerr_endline x; true - | Ok txt -> time > (Logarion.(Header_pack.date (Date.listing txt.date))) + | Ok txt -> time > (Kosuzu.(Header_pack.date (Date.listing txt.date))) | exception (Sys_error _) -> true let print_peers p = - let open Logarion.Header_pack in + let open Kosuzu.Header_pack in match Msgpck.to_list p.peers with [] -> () | ps -> print_endline @@ List.fold_left (fun a x -> Printf.sprintf "%s %s" a (Msgpck.to_string x)) "peers: " ps -type filter_t = { authors: Logarion.Person.Set.t; topics: Logarion.String_set.t } +type filter_t = { authors: Kosuzu.Person.Set.t; topics: Kosuzu.String_set.t } let print_pull_start width total title dir = Printf.printf "%*d/%s %s => %s %!" width 0 total title dir @@ -62,14 +51,14 @@ let printers total title dir = print_pull_start width total title dir; print_pull width total -let fname dir text = Filename.concat dir (Logarion.Text.short_id text ^ ".txt") +let fname dir text = Filename.concat dir (Kosuzu.Text.short_id text ^ ".txt") let pull_text url dir id = - let u = Filename.concat url ((Logarion.Id.short id) ^ ".txt") in + let u = Filename.concat url ((Kosuzu.Id.short id) ^ ".txt") in match curl_pull u with | Error msg -> Printf.eprintf "Failed getting %s: %s" u msg | Ok txt -> let txt = Buffer.contents txt in - match Logarion.Text.of_string txt with + match Kosuzu.Text.of_string txt with | Error s -> prerr_endline s | Ok text -> let file = open_out_gen [Open_creat; Open_trunc; Open_wronly] 0o640 (fname dir text) in @@ -77,7 +66,7 @@ let pull_text url dir id = let per_text url dir filter print i id time title authors topics _refs _reps = match id with | "" -> Printf.eprintf "\nInvalid id for %s\n" title - | id -> let open Logarion in + | id -> let open Kosuzu in print i; if newer time id dir && (String_set.empty = filter.topics @@ -86,48 +75,41 @@ let per_text url dir filter print i id time title authors topics _refs _reps = m || Person.Set.exists (fun t -> List.mem (Person.to_string t) authors) filter.authors) then pull_text url dir id -(*TODO: integrate in lib*) -let validate_id_length s = String.length s <= 32 -let validate_id_chars s = try - String.iter (function 'a'..'z'|'A'..'Z'|'0'..'9'-> () | _ -> raise (Invalid_argument "")) s; - true - with Invalid_argument _ -> false - let pull_index url authors_opt topics_opt = let index_url = Filename.concat url "index.pck" in match curl_pull index_url with | Error s -> prerr_endline s; false | Ok body -> - match Logarion.Header_pack.of_string (Buffer.contents body) with + match Kosuzu.Header_pack.of_string (Buffer.contents body) with | Error s -> Printf.printf "Error with %s: %s\n" url s; false | Ok pk when pk.info.id = "" -> Printf.printf "Empty ID index.pck, skipping %s\n" url; false - | Ok pk when not (validate_id_length pk.info.id) -> + | Ok pk when not (Kosuzu.Validate.validate_id_length pk.info.id) -> Printf.printf "Index pack ID longer than 32 characters, skipping %s\n" url; false - | Ok pk when not (validate_id_chars pk.info.id) -> + | Ok pk when not (Kosuzu.Validate.validate_id_chars pk.info.id) -> Printf.printf "Index pack contains invalid ID characters, skipping %s\n" url; false | Ok pk -> - let dir = Filename.concat Logarion.Peers.text_dir pk.info.id in - Logarion.File_store.with_dir dir; + let dir = Filename.concat Kosuzu.Peers.text_dir pk.info.id in + Kosuzu.File_store.with_dir dir; let file = open_out_gen [Open_creat; Open_trunc; Open_wronly] 0o640 (Filename.concat dir "index.pck") in - output_string file ( Logarion.Header_pack.string { + output_string file ( Kosuzu.Header_pack.string { pk with info = { pk.info with locations = url::pk.info.locations }}); close_out file; - let filter = let open Logarion in { + let filter = let open Kosuzu in { authors = (match authors_opt with Some s -> Person.Set.of_string s | None -> Person.Set.empty); topics =( match topics_opt with Some s -> String_set.of_string s | None -> String_set.empty); } in let name = match pk.info.title with "" -> url | title -> title in - let print = printers (string_of_int @@ Logarion.Header_pack.numof_texts pk) name dir in - try Logarion.Header_pack.iteri (per_text url dir filter print) pk; print_newline (); true + let print = printers (string_of_int @@ Kosuzu.Header_pack.numof_texts pk) name dir in + try Kosuzu.Header_pack.iteri (per_text url dir filter print) pk; print_newline (); true with Invalid_argument msg -> Printf.printf "\nFailed to parse %s: %s\n%!" url msg; false let pull_list auths topics = Curl.global_init Curl.CURLINIT_GLOBALALL; let pull got_one peer_url = if got_one then got_one else (pull_index peer_url auths topics) in - let open Logarion in + let open Kosuzu in let fold_locations init peer = ignore @@ List.fold_left pull init peer.Peers.pack.Header_pack.info.locations; false diff --git a/cli/recent.ml b/cmd/txt/recent.ml similarity index 98% rename from cli/recent.ml rename to cmd/txt/recent.ml index acdd42c..3b46085 100644 --- a/cli/recent.ml +++ b/cmd/txt/recent.ml @@ -1,4 +1,4 @@ -open Logarion +open Kosuzu module FS = File_store module A = Archive diff --git a/cli/topics.ml b/cmd/txt/topics.ml similarity index 98% rename from cli/topics.ml rename to cmd/txt/topics.ml index 36ebe6d..9c2c936 100644 --- a/cli/topics.ml +++ b/cmd/txt/topics.ml @@ -1,4 +1,4 @@ -open Logarion +open Kosuzu let topics r authors_opt = let predicates = Archive.(predicate authored authors_opt) in let predicate text = List.fold_left (fun a e -> a && e text) true predicates in diff --git a/cli/txt.ml b/cmd/txt/txt.ml similarity index 72% rename from cli/txt.ml rename to cmd/txt/txt.ml index df8677f..a105d3c 100644 --- a/cli/txt.ml +++ b/cmd/txt/txt.ml @@ -25,7 +25,10 @@ let txt = `P "orbifx "; `P "Izuru Yakumo "; `S Manpage.s_bugs; - `P "Please report them at "; ] + `P "Please report them at "; + `S Manpage.s_see_also; + `P "This program is named after Kosuzu Motoori from Touhou Suzunaan: Forbidden Scrollery"; + `P "https://en.touhouwiki.net/wiki/Forbidden_Scrollery" ] in Cmd.group (Cmd.info "txt" ~version:"%%VERSION%%" ~doc ~man) ~default:default_cmd subs diff --git a/cli/unfile.ml b/cmd/txt/unfile.ml similarity index 98% rename from cli/unfile.ml rename to cmd/txt/unfile.ml index dc43ad3..7d29aef 100644 --- a/cli/unfile.ml +++ b/cmd/txt/unfile.ml @@ -1,4 +1,4 @@ -open Logarion +open Kosuzu let unfile files = let dirs, files = File_store.split_filetypes files in diff --git a/cmd/txt_init/dune b/cmd/txt_init/dune new file mode 100644 index 0000000..6090b4e --- /dev/null +++ b/cmd/txt_init/dune @@ -0,0 +1,5 @@ +(executable + (name txt_init) + (public_name txt_init) + (modules txt_init) + (libraries kosuzu)) diff --git a/init/init.ml b/cmd/txt_init/txt_init.ml similarity index 79% rename from init/init.ml rename to cmd/txt_init/txt_init.ml index d1436d4..015ee05 100644 --- a/init/init.ml +++ b/cmd/txt_init/txt_init.ml @@ -1,4 +1,3 @@ -open Logarion let init_repo = print_endline "No txt.conf found"; print_endline "It's required for the repository name and id."; @@ -11,8 +10,8 @@ let init_repo = let authors = print_endline "Authors (format: name ): "; input_line stdin in - Logarion.File_store.file "txt.conf" - (Printf.sprintf "Id:%s\nTitle: %s\nAuthors: %s\n" (Logarion.Id.generate ()) title authors); - Logarion.File_store.of_kv_file () + Kosuzu.File_store.file "txt.conf" + (Printf.sprintf "Id:%s\nTitle: %s\nAuthors: %s\n" (Kosuzu.Id.generate ()) title authors); + Kosuzu.File_store.of_kv_file () | _ -> print_endline "Aborting..."; exit 1 diff --git a/dune-project b/dune-project index af181fc..6603f46 100644 --- a/dune-project +++ b/dune-project @@ -1,16 +1,16 @@ (lang dune 2.0) -(name logarion) +(name kosuzu) (version 1.4.3) (license EUPL-1.2) (authors "orbifx ") -(bug_reports "mailto:logarion-dev@chaotic.ninja") +(bug_reports "mailto:kosuzu-dev@chaotic.ninja") (maintainers "Izuru Yakumo ") -(homepage "https://suzunaan.chaotic.ninja/logarion/") -(source (uri git+https://git.chaotic.ninja/yakumo.izuru/logarion)) +(homepage "https://suzunaan.chaotic.ninja/kosuzu/") +(source (uri git+https://git.chaotic.ninja/yakumo.izuru/kosuzu)) (generate_opam_files true) (package - (name logarion) + (name kosuzu) (synopsis "Texts archival and exchange") (depends ocaml dune ocurl msgpck cmdliner)) diff --git a/img/FS_Kosuzu2.png b/img/FS_Kosuzu2.png new file mode 100644 index 0000000..f9373f8 Binary files /dev/null and b/img/FS_Kosuzu2.png differ diff --git a/init/dune b/init/dune deleted file mode 100644 index 04e2cbd..0000000 --- a/init/dune +++ /dev/null @@ -1,4 +0,0 @@ -(executable - (name init) -(public_name txt_init) -(libraries logarion)) diff --git a/logarion.opam b/kosuzu.opam similarity index 74% rename from logarion.opam rename to kosuzu.opam index 9e6d99d..550e165 100644 --- a/logarion.opam +++ b/kosuzu.opam @@ -5,8 +5,8 @@ synopsis: "Texts archival and exchange" maintainer: ["Izuru Yakumo "] authors: ["orbifx "] license: "EUPL-1.2" -homepage: "https://suzunaan.chaotic.ninja/logarion/" -bug-reports: "mailto:logarion-dev@chaotic.ninja" +homepage: "https://suzunaan.chaotic.ninja/kosuzu/" +bug-reports: "mailto:kosuzu-dev@chaotic.ninja" depends: ["ocaml" "dune" "ocurl" "msgpck" "cmdliner"] build: [ ["dune" "subst"] {pinned} @@ -22,4 +22,4 @@ build: [ "@doc" {with-doc} ] ] -dev-repo: "git+https://git.chaotic.ninja/yakumo.izuru/logarion" +dev-repo: "git+https://git.chaotic.ninja/yakumo.izuru/kosuzu" diff --git a/lib/dune b/lib/dune index 4ec3169..119bdd5 100644 --- a/lib/dune +++ b/lib/dune @@ -1,4 +1,4 @@ (library - (name logarion) - (public_name logarion) + (name kosuzu) + (public_name kosuzu) (libraries text_parse text_parse.parsers unix str msgpck)) diff --git a/lib/validate.ml b/lib/validate.ml new file mode 100644 index 0000000..5ee17bd --- /dev/null +++ b/lib/validate.ml @@ -0,0 +1,5 @@ +let validate_id_length s = String.length s <= 32 +let validate_id_chars s = try + String.iter (function 'a'..'z'|'A'..'Z'|'0'..'9'-> () | _ -> raise (Invalid_argument "")) s; + true + with Invalid_argument _ -> false