Because sweet girls are the best, officially rebranding Logarion to Kosuzu

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

git-svn-id: file:///srv/svn/repo/kosuzu/trunk@73 eb64cd80-c68d-6f47-b6a3-0ada418499da
This commit is contained in:
yakumo.izuru 2024-08-22 16:32:00 +00:00
parent 91069878cf
commit 758d1d6d47
29 changed files with 126 additions and 141 deletions

View File

@ -1,6 +1,6 @@
OS=`uname -s` OS=`uname -s`
MACHINE=`uname -m` 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` COMMIT=`git rev-parse --short HEAD`
PREFIX=/usr/local PREFIX=/usr/local
@ -11,18 +11,21 @@ all:
@dune build @dune build
deps: deps:
@opam install dune ocurl cmdliner msgpck @opam install dune ocurl cmdliner msgpck
cli: txt:
@dune build cli/txt.exe @dune build cmd/txt/txt.exe
clean: clean:
@dune clean @dune clean
dist: dist:
@dune build @dune build
@cp _build/default/cli/txt.exe txt.exe @cp _build/default/cmd/txt/txt.exe txt.exe
@strip 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 @rm txt.exe
txt_init:
@dune build cmd/txt_init/txt_init.exe
install: install:
@dune install --prefix ${PREFIX} @dune install --prefix ${PREFIX}
uninstall: uninstall:
@dune uninstall --prefix ${PREFIX} @dune uninstall --prefix ${PREFIX}
.PHONY: cli .PHONY: txt txt_init

View File

@ -1,16 +1,7 @@
# Logarion ![Kosuzu Motoori](img/FS_Kosuzu2.png)
Text archival and exchange.
# 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 ## Contact
* [Mailing list](https://lists.tildeverse.org/postorius/lists/logarion.lists.tildeverse.org/) * [Mailing list](mailto:kosuzu-dev@chaotic.ninja)
## 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)

View File

@ -11,23 +11,23 @@ let opt_element tag_name content =
module P = Parsers.Plain_text.Make (Converter.Html) module P = Parsers.Plain_text.Make (Converter.Html)
let id txt = "<id>urn:txtid:" ^ Logarion.(txt.Text.id) ^ "</id>\n" let id txt = "<id>urn:txtid:" ^ Kosuzu.(txt.Text.id) ^ "</id>\n"
let title text = "<title>" ^ esc text.Logarion.Text.title ^ "</title>\n" let title text = "<title>" ^ esc text.Kosuzu.Text.title ^ "</title>\n"
let authors text = let authors text =
let u acc addr = acc ^ element "uri" addr in let u acc addr = acc ^ element "uri" addr in
let open Logarion in let open Kosuzu in
let fn txt a = let fn txt a =
a ^ "<author>" ^ (opt_element "name" @@ esc txt.Person.name) a ^ "<author>" ^ (opt_element "name" @@ esc txt.Person.name)
^ (List.fold_left u "" txt.Person.addresses) ^ (List.fold_left u "" txt.Person.addresses)
^ "</author>\n" in ^ "</author>\n" in
Person.Set.fold fn text.Text.authors "" Person.Set.fold fn text.Text.authors ""
let updated txt = let open Logarion in let updated txt = let open Kosuzu in
"<updated>"^ Date.(txt.Text.date |> listing |> rfc_string) ^"</updated>\n" "<updated>"^ Date.(txt.Text.date |> listing |> rfc_string) ^"</updated>\n"
let htm_entry base_url text = let htm_entry base_url text =
let open Logarion in let open Kosuzu in
let u = Text.short_id text in let u = Text.short_id text in
"<entry>\n<link rel=\"alternate\" href=\"" ^ base_url ^ "/" ^ u ^ ".htm\" />\n" "<entry>\n<link rel=\"alternate\" href=\"" ^ base_url ^ "/" ^ u ^ ".htm\" />\n"
^ title text ^ id text ^ updated text ^ authors text ^ title text ^ id text ^ updated text ^ authors text
@ -36,7 +36,7 @@ let htm_entry base_url text =
^ "</entry>\n" ^ "</entry>\n"
let gmi_entry base_url text = let gmi_entry base_url text =
let open Logarion in let open Kosuzu in
let u = Text.short_id text in let u = Text.short_id text in
"<entry>\n<link rel=\"alternate\" href=\"" ^ base_url ^ "/" ^ u ^ ".gmi\" />\n" "<entry>\n<link rel=\"alternate\" href=\"" ^ base_url ^ "/" ^ u ^ ".gmi\" />\n"
^ title text ^ id text ^ updated text ^ authors text ^ title text ^ id text ^ updated text ^ authors text
@ -45,14 +45,14 @@ let gmi_entry base_url text =
^ "</entry>\n" ^ "</entry>\n"
let base_url kv protocol = try 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 let _i = Str.(search_forward (regexp (protocol ^ "://[^;]*")) locs 0) in
Str.(matched_string locs) Str.(matched_string locs)
with Not_found -> Printf.eprintf "Missing location for %s, add it to txt.conf\n" protocol; "" with Not_found -> Printf.eprintf "Missing location for %s, add it to txt.conf\n" protocol; ""
let indices alternate_type c = let indices alternate_type c =
let file name = Logarion.File_store.file (Filename.concat c.Conversion.dir name) in let file name = Kosuzu.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 title = try Kosuzu.Store.KV.find "Title" c.Conversion.kv with Not_found -> "" in
let entry, fname, protocol_regexp = match alternate_type with let entry, fname, protocol_regexp = match alternate_type with
| "text/gemini" -> gmi_entry, "gmi.atom", "gemini" | "text/gemini" -> gmi_entry, "gmi.atom", "gemini"
| "text/html" | _ -> htm_entry, "feed.atom", "https?" | "text/html" | _ -> htm_entry, "feed.atom", "https?"
@ -64,7 +64,7 @@ let indices alternate_type c =
^ title ^ {|</title><link rel="alternate" type="|} ^ alternate_type ^ {|" href="|} ^ title ^ {|</title><link rel="alternate" type="|} ^ alternate_type ^ {|" href="|}
^ base_url ^ {|/" /><link rel="self" type="application/atom+xml" href="|} ^ base_url ^ {|/" /><link rel="self" type="application/atom+xml" href="|}
^ self ^ {|" /><id>urn:txtid:|} ^ c.Conversion.id ^ "</id><updated>" ^ self ^ {|" /><id>urn:txtid:|} ^ c.Conversion.id ^ "</id><updated>"
^ Logarion.Date.now () ^ "</updated>\n" ^ Kosuzu.Date.now () ^ "</updated>\n"
^ List.fold_left (fun acc t -> acc ^ entry base_url t) "" c.texts ^ List.fold_left (fun acc t -> acc ^ entry base_url t) "" c.texts
^ "</feed>" ^ "</feed>"

View File

@ -1,4 +1,4 @@
open Logarion open Kosuzu
let authors r topics_opt = let authors r topics_opt =
let predicates = Archive.(predicate topics topics_opt) in let predicates = Archive.(predicate topics topics_opt) in
let predicate text = List.fold_left (fun a e -> a && e text) true predicates in let predicate text = List.fold_left (fun a e -> a && e text) true predicates in

View File

@ -1,4 +1,4 @@
open Logarion open Kosuzu
module Rel = struct module Rel = struct
@ -60,7 +60,7 @@ type t = {
type fn_t = { type fn_t = {
ext: string; ext: string;
page: (t -> Logarion.Text.t -> string) option; page: (t -> Kosuzu.Text.t -> string) option;
indices: (t -> unit) option; indices: (t -> unit) option;
} }

View File

@ -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 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 let convert cs r (text, files) = match Text.str "Content-Type" text with

View File

@ -3,4 +3,4 @@
(public_name txt) (public_name txt)
(modules txt authors convert conversion edit file index last listing (modules txt authors convert conversion edit file index last listing
new topics html atom gemini peers pull recent unfile) 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))

View File

@ -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 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 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 cmd =
let doc = "Edit a text" in let doc = "Edit a text" in

View File

@ -1,4 +1,4 @@
open Logarion open Kosuzu
let file files = let file files =
let dirs, files = File_store.split_filetypes files in let dirs, files = File_store.split_filetypes files in
let _link_as_named dir file = Unix.link file (Filename.concat dir file) in let _link_as_named dir file = Unix.link file (Filename.concat dir file) in

View File

@ -7,18 +7,18 @@ module GeminiConverter = struct
end end
let page _conversion text = let page _conversion text =
let open Logarion.Text in let open Kosuzu.Text in
"# " ^ text.title "# " ^ text.title
^ "\nAuthors: " ^ Logarion.Person.Set.to_string text.authors ^ "\nAuthors: " ^ Kosuzu.Person.Set.to_string text.authors
^ "\nDate: " ^ Logarion.Date.(pretty_date @@ listing text.date) ^ "\nDate: " ^ Kosuzu.Date.(pretty_date @@ listing text.date)
^ let module T = Parsers.Plain_text.Make (GeminiConverter) in ^ let module T = Parsers.Plain_text.Make (GeminiConverter) in
"\n" ^ T.of_string text.body "" "\n" ^ T.of_string text.body ""
let date_index title meta_list = let date_index title meta_list =
List.fold_left List.fold_left
(fun a m -> (fun a m ->
a ^ "=> " ^ Logarion.Text.short_id m ^ ".gmi " ^ a ^ "=> " ^ Kosuzu.Text.short_id m ^ ".gmi " ^
Logarion.(Date.(pretty_date (listing m.date)) ^ " " ^ m.title) ^ "\n") Kosuzu.(Date.(pretty_date (listing m.date)) ^ " " ^ m.title) ^ "\n")
("# " ^ title ^ "\n\n## Posts by date\n\n") meta_list ("# " ^ title ^ "\n\n## Posts by date\n\n") meta_list
let to_dated_links ?(limit) meta_list = let to_dated_links ?(limit) meta_list =
@ -33,9 +33,9 @@ let to_dated_links ?(limit) meta_list =
List.fold_left List.fold_left
(fun a m -> (fun a m ->
a a
^ "=> " ^ Logarion.Text.short_id m ^ ".gmi " ^ "=> " ^ Kosuzu.Text.short_id m ^ ".gmi "
^ Logarion.(Date.(pretty_date (listing m.Text.date))) ^ " " ^ Kosuzu.(Date.(pretty_date (listing m.Text.date))) ^ " "
^ m.Logarion.Text.title ^ "\n") ^ m.Kosuzu.Text.title ^ "\n")
"" meta_list "" meta_list
let topic_link root topic = let topic_link root topic =
@ -43,7 +43,7 @@ let topic_link root topic =
"=> index." ^ replaced_space root ^ ".gmi " ^ String.capitalize_ascii topic ^ "\n" "=> index." ^ replaced_space root ^ ".gmi " ^ String.capitalize_ascii topic ^ "\n"
let text_item path meta = let text_item path meta =
let open Logarion in let open Kosuzu in
"=> " ^ path ^ Text.short_id meta ^ ".gmi " "=> " ^ path ^ Text.short_id meta ^ ".gmi "
^ Date.(pretty_date (listing meta.Text.date)) ^ " " ^ Date.(pretty_date (listing meta.Text.date)) ^ " "
^ meta.Text.title ^ "\n" ^ meta.Text.title ^ "\n"
@ -51,15 +51,15 @@ let text_item path meta =
let listing_index topic_map topic_roots path metas = let listing_index topic_map topic_roots path metas =
let rec item_group topics = let rec item_group topics =
List.fold_left (fun acc topic -> acc ^ sub_groups topic ^ items topic) "" 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 -> "" | None -> ""
| Some (_, subtopics) -> item_group (Logarion.String_set.elements subtopics) | Some (_, subtopics) -> item_group (Kosuzu.String_set.elements subtopics)
and items topic = and items topic =
let items = let items =
let open Logarion in let open Kosuzu in
List.fold_left List.fold_left
(fun a e -> (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 then text_item path e ^ a else a) "" metas in
match items with 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 "") ^ (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## Latest\n\n" ^ to_dated_links ~limit:10 metas
^ "\n=> index.date.gmi More by date\n\n" ^ "\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 if peers = "" then "" else
List.fold_left (fun a s -> Printf.sprintf "%s=> %s\n" a s) "## Peers\n\n" List.fold_left (fun a s -> Printf.sprintf "%s=> %s\n" a s) "## Peers\n\n"
(Str.split (Str.regexp ";\n") peers) (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 ^ listing_index topic_map [topic_root] "" metas
let indices r = 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 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 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 let title = try Store.KV.find "Title" r.Conversion.kv with Not_found -> "" in

View File

@ -6,7 +6,7 @@ let empty_templates = { header = None; footer = None }
let default_opts = { templates = empty_templates; style = "" } let default_opts = { templates = empty_templates; style = "" }
let init kv = let init kv =
let open Logarion in let open Kosuzu in
let to_string key kv = match Store.KV.find key kv with let to_string key kv = match Store.KV.find key kv with
| fname -> Some (File_store.to_string fname) | fname -> Some (File_store.to_string fname)
| exception Not_found -> None in | exception Not_found -> None in
@ -17,12 +17,12 @@ let init kv =
{ templates = { header; footer}; style } { templates = { header; footer}; style }
let wrap conv htm text_title body = 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 let replace x = let open Str in
global_replace (regexp "{{archive-title}}") site_title x global_replace (regexp "{{archive-title}}") site_title x
|> global_replace (regexp "{{text-title}}") text_title |> global_replace (regexp "{{text-title}}") text_title
in 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") with Not_found -> if Sys.file_exists (Filename.concat conv.Conversion.dir "feed.atom")
then "feed.atom" else "" in then "feed.atom" else "" in
let header = match htm.templates.header with let header = match htm.templates.header with
@ -31,7 +31,7 @@ let wrap conv htm text_title body =
(if feed <> "" then sprintf "<a href='%s' id='feed'>feed</a>" feed else "")) (if feed <> "" then sprintf "<a href='%s' id='feed'>feed</a>" feed else ""))
in in
let footer = match htm.templates.footer with None -> "" | Some x -> replace x in let footer = match htm.templates.footer with None -> "" | Some x -> replace x in
Printf.sprintf "<!DOCTYPE HTML>\n<html>\n<head>\n<link rel=\"icon\" href=\"/favicon.ico\">\n<title>%s%s</title>\n%s\n%s\n<meta name=\"generator\" content=\"Logarion\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n</head>\n<body>\n%s%s%s</body>\n</html>" Printf.sprintf "<!DOCTYPE HTML>\n<html>\n<head>\n<link rel=\"icon\" href=\"/favicon.ico\">\n<title>%s%s</title>\n%s\n%s\n<meta name=\"generator\" content=\"Kosuzu\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n</head>\n<body>\n%s%s%s</body>\n</html>"
text_title (if site_title <> "" then (" &bull; " ^ site_title) else "") text_title (if site_title <> "" then (" &bull; " ^ site_title) else "")
htm.style htm.style
(if feed <> "" then Printf.sprintf "<link rel='alternate' href='%s' type='application/atom+xml'>" feed else "") (if feed <> "" then Printf.sprintf "<link rel='alternate' href='%s' type='application/atom+xml'>" feed else "")
@ -51,7 +51,7 @@ module HtmlConverter = struct
end end
let page htm conversion text = let page htm conversion text =
let open Logarion in let open Kosuzu in
let open Text in let open Text in
let module T = Parsers.Plain_text.Make (HtmlConverter) 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 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 | h::t -> if i < limit then reduced (h::acc) (i+1) t else acc in
List.rev @@ reduced [] 0 meta_list in List.rev @@ reduced [] 0 meta_list in
List.fold_left List.fold_left
(fun a m -> Printf.sprintf "%s <li> %s <a href=\"%s.htm\">%s</a>" a Logarion.(Date.(pretty_date (listing m.Text.date))) (fun a m -> Printf.sprintf "%s <li> %s <a href=\"%s.htm\">%s</a>" a Kosuzu.(Date.(pretty_date (listing m.Text.date)))
(Logarion.Text.short_id m) m.Logarion.Text.title) (Kosuzu.Text.short_id m) m.Kosuzu.Text.title)
"" meta_list "" meta_list
let date_index ?(limit) conv htm meta_list = let date_index ?(limit) conv htm meta_list =
@ -111,7 +111,7 @@ let fold_topic_roots topic_roots =
^ "</ul></nav>" ^ "</ul></nav>"
let fold_topics topic_map topic_roots metas = let fold_topics topic_map topic_roots metas =
let open Logarion in let open Kosuzu in
let rec unordered_list root topic = let rec unordered_list root topic =
List.fold_left (fun a x -> a ^ list_item root x) "<ul>" topic List.fold_left (fun a x -> a ^ list_item root x) "<ul>" topic
^ "</ul>" ^ "</ul>"
@ -128,7 +128,7 @@ and list_item root t =
^ "</ul></nav>" ^ "</ul></nav>"
let text_item path meta = let text_item path meta =
let open Logarion in let open Kosuzu in
"<time>" ^ Date.(pretty_date (listing meta.Text.date)) "<time>" ^ Date.(pretty_date (listing meta.Text.date))
^ {|</time> <a href="|} ^ path ^ Text.short_id meta ^ {|.htm">|} ^ meta.Text.title ^ {|</time> <a href="|} ^ path ^ Text.short_id meta ^ {|.htm">|} ^ meta.Text.title
^ "</a><br>" ^ "</a><br>"
@ -136,15 +136,15 @@ let text_item path meta =
let listing_index topic_map topic_roots path metas = let listing_index topic_map topic_roots path metas =
let rec item_group topics = let rec item_group topics =
List.fold_left (fun acc topic -> acc ^ sub_groups topic ^ items topic) "" 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 -> "" | None -> ""
| Some (_, subtopics) -> item_group (Logarion.String_set.elements subtopics) | Some (_, subtopics) -> item_group (Kosuzu.String_set.elements subtopics)
and items topic = and items topic =
let items = let items =
let open Logarion in let open Kosuzu in
List.fold_left List.fold_left
(fun a e -> (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 then text_item path e ^ a else a) "" metas in
match items with match items with
| "" -> "" | "" -> ""
@ -156,10 +156,10 @@ let topic_main_index conv htm topic_roots metas =
(fold_topic_roots topic_roots (fold_topic_roots topic_roots
^ "<nav><h1>Latest</h1><ul>" ^ to_dated_links ~limit:10 metas ^ "<nav><h1>Latest</h1><ul>" ^ to_dated_links ~limit:10 metas
^ {|</ul></nav><hr><a href="index.date.htm">More by date</a>|} ^ {|</ul></nav><hr><a href="index.date.htm">More by date</a>|}
^ 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 (if peers = "" then "" else
List.fold_left (fun a s -> Printf.sprintf {|%s<li><a href="%s">%s</a>|} a s s) "<h1>Peers</h1><ul>" List.fold_left (fun a s -> Printf.sprintf {|%s<li><a href="%s">%s</a>|} a s s) "<h1>Peers</h1><ul>"
(Str.split (Str.regexp ";\n") (Logarion.Store.KV.find "Peers" conv.kv)) (Str.split (Str.regexp ";\n") (Kosuzu.Store.KV.find "Peers" conv.kv))
^ "</ul>")) ^ "</ul>"))
let topic_sub_index conv htm topic_map topic_root metas = 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) ^ listing_index topic_map [topic_root] "" metas)
let indices htm c = let indices htm c =
let file name = Logarion.File_store.file (Filename.concat c.Conversion.dir name) in let file name = Kosuzu.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 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); 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); file "index.date.htm" (date_index c htm c.texts);
List.iter List.iter

View File

@ -1,4 +1,4 @@
open Logarion open Kosuzu
let text_editor name x = let text_editor name x =
let fname, out = Filename.open_temp_file name "" in 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 "* 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 "* listing of texts with: ID, date, title, authors, topics.";
`P "* list of other text repositories (peers)"; `P "* list of other text repositories (peers)";
`S Manpage.s_environment;
`P "EDITOR - Default editor name";
`S Manpage.s_see_also; `S Manpage.s_see_also;
`P "MessagePack format. https://msgpack.org" ] in `P "MessagePack format. https://msgpack.org" ] in
let info = Cmd.info "index" ~doc ~man in let info = Cmd.info "index" ~doc ~man in

View File

@ -1,4 +1,4 @@
open Logarion open Kosuzu
let last a ((t,_) as pair) = match a with let last a ((t,_) as pair) = match a with
| None -> Some pair | None -> Some pair

View File

@ -1,4 +1,4 @@
open Logarion open Kosuzu
module FS = File_store module FS = File_store
module A = Archive module A = Archive

View File

@ -1,9 +1,9 @@
open Logarion open Kosuzu
open Cmdliner open Cmdliner
let new_txt title topics_opt = let new_txt title topics_opt =
let kv = Logarion.File_store.of_kv_file () in let kv = Kosuzu.File_store.of_kv_file () in
let authors = Person.Set.of_string (try Logarion.Store.KV.find "Authors" kv let authors = Person.Set.of_string (try Kosuzu.Store.KV.find "Authors" kv
with Not_found -> Sys.getenv "USER") in with Not_found -> Sys.getenv "USER") in
let text = { (Text.blank ()) with title; authors } 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 let text = try Text.with_str_set text "Topics" (Option.get topics_opt) with _->text in

View File

@ -1,20 +1,20 @@
let print_peers_of_peer p = 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 [] -> () match Msgpck.to_list p.peers with [] -> ()
| ps -> print_endline @@ | ps -> print_endline @@
List.fold_left (fun a x -> Printf.sprintf "%s %s" a (Msgpck.to_string x)) "peers: " ps 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 print_peer () peer =
let open Logarion.Peers in let open Kosuzu.Peers in
Printf.printf "%s" peer.path; Printf.printf "%s" peer.path;
List.iter (Printf.printf "\t%s\n") peer.pack.info.locations List.iter (Printf.printf "\t%s\n") peer.pack.info.locations
let remove_repo id = 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 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 -> | true ->
let cmd = Printf.sprintf "rm -r %s" repopath in let cmd = Printf.sprintf "rm -r %s" repopath in
Printf.printf "Run: %s ? (y/N) %!" cmd; Printf.printf "Run: %s ? (y/N) %!" cmd;
@ -25,8 +25,8 @@ let remove_repo id =
let peers = function let peers = function
| Some id -> remove_repo id | Some id -> remove_repo id
| None -> | None ->
Printf.printf "Peers in %s\n" Logarion.Peers.text_dir; Printf.printf "Peers in %s\n" Kosuzu.Peers.text_dir;
Logarion.Peers.fold print_peer () Kosuzu.Peers.fold print_peer ()
open Cmdliner open Cmdliner
let remove = Arg.(value & opt (some string) None & info ["remove"] ~docv:"Repository ID" ~doc:"Remove repository texts and from future pulling") let remove = Arg.(value & opt (some string) None & info ["remove"] ~docv:"Repository ID" ~doc:"Remove repository texts and from future pulling")

View File

@ -2,15 +2,6 @@ let writer accum data =
Buffer.add_string accum data; Buffer.add_string accum data;
String.length 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 = let getContent connection url =
Curl.set_url connection url; Curl.set_url connection url;
Curl.perform connection Curl.perform connection
@ -25,8 +16,6 @@ let curl_pull url =
Curl.set_followlocation connection true; Curl.set_followlocation connection true;
Curl.set_url connection url; Curl.set_url connection url;
Curl.perform connection; Curl.perform connection;
(* showContent result;*)
(* showInfo connection;*)
Curl.cleanup connection; Curl.cleanup connection;
Ok result Ok result
with with
@ -38,18 +27,18 @@ let curl_pull url =
Error (Printf.sprintf "Caught exception: %s" s) Error (Printf.sprintf "Caught exception: %s" s)
let newer time id dir = 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 | 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 | exception (Sys_error _) -> true
let print_peers p = let print_peers p =
let open Logarion.Header_pack in let open Kosuzu.Header_pack in
match Msgpck.to_list p.peers with [] -> () match Msgpck.to_list p.peers with [] -> ()
| ps -> print_endline @@ | ps -> print_endline @@
List.fold_left (fun a x -> Printf.sprintf "%s %s" a (Msgpck.to_string x)) "peers: " ps 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 = let print_pull_start width total title dir =
Printf.printf "%*d/%s %s => %s %!" width 0 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_start width total title dir;
print_pull width total 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 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 match curl_pull u with
| Error msg -> Printf.eprintf "Failed getting %s: %s" u msg | Error msg -> Printf.eprintf "Failed getting %s: %s" u msg
| Ok txt -> let txt = Buffer.contents txt in | 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 | Error s -> prerr_endline s
| Ok text -> | Ok text ->
let file = open_out_gen [Open_creat; Open_trunc; Open_wronly] 0o640 (fname dir text) in 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 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 | "" -> Printf.eprintf "\nInvalid id for %s\n" title
| id -> let open Logarion in | id -> let open Kosuzu in
print i; print i;
if newer time id dir if newer time id dir
&& (String_set.empty = filter.topics && (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) || Person.Set.exists (fun t -> List.mem (Person.to_string t) authors) filter.authors)
then pull_text url dir id 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 pull_index url authors_opt topics_opt =
let index_url = Filename.concat url "index.pck" in let index_url = Filename.concat url "index.pck" in
match curl_pull index_url with match curl_pull index_url with
| Error s -> prerr_endline s; false | Error s -> prerr_endline s; false
| Ok body -> | 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 | Error s -> Printf.printf "Error with %s: %s\n" url s; false
| Ok pk when pk.info.id = "" -> | Ok pk when pk.info.id = "" ->
Printf.printf "Empty ID index.pck, skipping %s\n" url; false 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 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 Printf.printf "Index pack contains invalid ID characters, skipping %s\n" url; false
| Ok pk -> | Ok pk ->
let dir = Filename.concat Logarion.Peers.text_dir pk.info.id in let dir = Filename.concat Kosuzu.Peers.text_dir pk.info.id in
Logarion.File_store.with_dir dir; Kosuzu.File_store.with_dir dir;
let file = open_out_gen [Open_creat; Open_trunc; Open_wronly] 0o640 let file = open_out_gen [Open_creat; Open_trunc; Open_wronly] 0o640
(Filename.concat dir "index.pck") in (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 }}); pk with info = { pk.info with locations = url::pk.info.locations }});
close_out file; 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); 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); topics =( match topics_opt with Some s -> String_set.of_string s | None -> String_set.empty);
} in } in
let name = match pk.info.title with "" -> url | title -> title 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 let print = printers (string_of_int @@ Kosuzu.Header_pack.numof_texts pk) name dir in
try Logarion.Header_pack.iteri (per_text url dir filter print) pk; print_newline (); true 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 with Invalid_argument msg -> Printf.printf "\nFailed to parse %s: %s\n%!" url msg; false
let pull_list auths topics = let pull_list auths topics =
Curl.global_init Curl.CURLINIT_GLOBALALL; Curl.global_init Curl.CURLINIT_GLOBALALL;
let pull got_one peer_url = if got_one then got_one else let pull got_one peer_url = if got_one then got_one else
(pull_index peer_url auths topics) in (pull_index peer_url auths topics) in
let open Logarion in let open Kosuzu in
let fold_locations init peer = let fold_locations init peer =
ignore @@ List.fold_left pull init peer.Peers.pack.Header_pack.info.locations; ignore @@ List.fold_left pull init peer.Peers.pack.Header_pack.info.locations;
false false

View File

@ -1,4 +1,4 @@
open Logarion open Kosuzu
module FS = File_store module FS = File_store
module A = Archive module A = Archive

View File

@ -1,4 +1,4 @@
open Logarion open Kosuzu
let topics r authors_opt = let topics r authors_opt =
let predicates = Archive.(predicate authored authors_opt) in let predicates = Archive.(predicate authored authors_opt) in
let predicate text = List.fold_left (fun a e -> a && e text) true predicates in let predicate text = List.fold_left (fun a e -> a && e text) true predicates in

View File

@ -25,7 +25,10 @@ let txt =
`P "orbifx <mailto:fox@orbitalfox.eu>"; `P "orbifx <mailto:fox@orbitalfox.eu>";
`P "Izuru Yakumo <mailto:yakumo.izuru@chaotic.ninja>"; `P "Izuru Yakumo <mailto:yakumo.izuru@chaotic.ninja>";
`S Manpage.s_bugs; `S Manpage.s_bugs;
`P "Please report them at <mailto:logarion-dev@chaotic.ninja>"; ] `P "Please report them at <mailto:kosuzu-dev@chaotic.ninja>";
`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 in
Cmd.group (Cmd.info "txt" ~version:"%%VERSION%%" ~doc ~man) ~default:default_cmd subs Cmd.group (Cmd.info "txt" ~version:"%%VERSION%%" ~doc ~man) ~default:default_cmd subs

View File

@ -1,4 +1,4 @@
open Logarion open Kosuzu
let unfile files = let unfile files =
let dirs, files = File_store.split_filetypes files in let dirs, files = File_store.split_filetypes files in

5
cmd/txt_init/dune Normal file
View File

@ -0,0 +1,5 @@
(executable
(name txt_init)
(public_name txt_init)
(modules txt_init)
(libraries kosuzu))

View File

@ -1,4 +1,3 @@
open Logarion
let init_repo = let init_repo =
print_endline "No txt.conf found"; print_endline "No txt.conf found";
print_endline "It's required for the repository name and id."; print_endline "It's required for the repository name and id.";
@ -11,8 +10,8 @@ let init_repo =
let authors = let authors =
print_endline "Authors (format: name <name@email> <http://website>): "; print_endline "Authors (format: name <name@email> <http://website>): ";
input_line stdin in input_line stdin in
Logarion.File_store.file "txt.conf" Kosuzu.File_store.file "txt.conf"
(Printf.sprintf "Id:%s\nTitle: %s\nAuthors: %s\n" (Logarion.Id.generate ()) title authors); (Printf.sprintf "Id:%s\nTitle: %s\nAuthors: %s\n" (Kosuzu.Id.generate ()) title authors);
Logarion.File_store.of_kv_file () Kosuzu.File_store.of_kv_file ()
| _ -> | _ ->
print_endline "Aborting..."; exit 1 print_endline "Aborting..."; exit 1

View File

@ -1,16 +1,16 @@
(lang dune 2.0) (lang dune 2.0)
(name logarion) (name kosuzu)
(version 1.4.3) (version 1.4.3)
(license EUPL-1.2) (license EUPL-1.2)
(authors "orbifx <fox@orbitalfox.eu>") (authors "orbifx <fox@orbitalfox.eu>")
(bug_reports "mailto:logarion-dev@chaotic.ninja") (bug_reports "mailto:kosuzu-dev@chaotic.ninja")
(maintainers "Izuru Yakumo <yakumo.izuru@chaotic.ninja>") (maintainers "Izuru Yakumo <yakumo.izuru@chaotic.ninja>")
(homepage "https://suzunaan.chaotic.ninja/logarion/") (homepage "https://suzunaan.chaotic.ninja/kosuzu/")
(source (uri git+https://git.chaotic.ninja/yakumo.izuru/logarion)) (source (uri git+https://git.chaotic.ninja/yakumo.izuru/kosuzu))
(generate_opam_files true) (generate_opam_files true)
(package (package
(name logarion) (name kosuzu)
(synopsis "Texts archival and exchange") (synopsis "Texts archival and exchange")
(depends ocaml dune ocurl msgpck cmdliner)) (depends ocaml dune ocurl msgpck cmdliner))

BIN
img/FS_Kosuzu2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 KiB

View File

@ -1,4 +0,0 @@
(executable
(name init)
(public_name txt_init)
(libraries logarion))

View File

@ -5,8 +5,8 @@ synopsis: "Texts archival and exchange"
maintainer: ["Izuru Yakumo <yakumo.izuru@chaotic.ninja>"] maintainer: ["Izuru Yakumo <yakumo.izuru@chaotic.ninja>"]
authors: ["orbifx <fox@orbitalfox.eu>"] authors: ["orbifx <fox@orbitalfox.eu>"]
license: "EUPL-1.2" license: "EUPL-1.2"
homepage: "https://suzunaan.chaotic.ninja/logarion/" homepage: "https://suzunaan.chaotic.ninja/kosuzu/"
bug-reports: "mailto:logarion-dev@chaotic.ninja" bug-reports: "mailto:kosuzu-dev@chaotic.ninja"
depends: ["ocaml" "dune" "ocurl" "msgpck" "cmdliner"] depends: ["ocaml" "dune" "ocurl" "msgpck" "cmdliner"]
build: [ build: [
["dune" "subst"] {pinned} ["dune" "subst"] {pinned}
@ -22,4 +22,4 @@ build: [
"@doc" {with-doc} "@doc" {with-doc}
] ]
] ]
dev-repo: "git+https://git.chaotic.ninja/yakumo.izuru/logarion" dev-repo: "git+https://git.chaotic.ninja/yakumo.izuru/kosuzu"

View File

@ -1,4 +1,4 @@
(library (library
(name logarion) (name kosuzu)
(public_name logarion) (public_name kosuzu)
(libraries text_parse text_parse.parsers unix str msgpck)) (libraries text_parse text_parse.parsers unix str msgpck))

5
lib/validate.ml Normal file
View File

@ -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