source: code/trunk/cli/gemini.ml@ 14

Last change on this file since 14 was 3, checked in by fox, 3 years ago
  • Removed 'txt init'

Format

  • New B32 ID

Index

  • New option: txt index --print
  • Move scheme to peers
  • Replace peer.*.conf files with index packed locations Instead of adding a URL to peers.*.conf, run txt pull <url>

Conversion

  • Rewritten converters
  • txt-convert looks for a .convert.conf containing key: value lines.
  • Specifiable topic-roots from .convert.conf.
  • Added Topics: key, with comma seperated topics.

If set only those topics will appear in the main index and used as topic roots.
Other topics will have sub-indices generated, but won't be listed in the main index.

  • HTML converter header & footer options
  • HTML-index renamed to HTM-index

Internal

  • Change types: uuid:Uuid -> id:string
  • File_store merges identical texts
  • Use peer ID for store path, store peers' texts in .local/share/texts
  • Simple URN resolution for converter

Continue to next feed if parsing one fails

  • Phasing-out Archive, replaced by improved packs
  • Eliminate Bos, Cohttp, lwt, uri, tls, Re, Ptime, dependencies
  • Lock version for Cmdliner, fix dune-project
  • Optional resursive store
  • Improve header_pack
  • Fix recursive mkdir
File size: 3.7 KB
Line 
1let ext = ".gmi"
2
3module GeminiConverter = struct
4 include Converter.Gemini
5 let angled_uri u a = if String.sub u 0 10 <> "urn:txtid:" then
6 angled_uri u a else angled_uri (String.(sub u 10 (length u - 10)) ^ ext) a
7end
8
9let page _conversion text =
10 let open Logarion.Text in
11 "# " ^ text.title
12 ^ "\nAuthors: " ^ Logarion.Person.Set.to_string text.authors
13 ^ "\nDate: " ^ Logarion.Date.(pretty_date @@ listing text.date)
14 ^ let module T = Parsers.Plain_text.Make (GeminiConverter) in
15 "\n" ^ T.of_string text.body ""
16
17let date_index title meta_list =
18 List.fold_left
19 (fun a m ->
20 a ^ "=> " ^ Logarion.Text.short_id m ^ ".gmi " ^
21 Logarion.(Date.(pretty_date (listing m.date)) ^ " " ^ m.title) ^ "\n")
22 ("# " ^ title ^ "\n\n## Posts by date\n\n") meta_list
23
24let to_dated_links ?(limit) meta_list =
25 let meta_list = match limit with
26 | None -> meta_list
27 | Some limit->
28 let rec reduced acc i = function
29 | [] -> acc
30 | h::t -> if i < limit then reduced (h::acc) (i+1) t else acc in
31 List.rev @@ reduced [] 0 meta_list
32 in
33 List.fold_left
34 (fun a m ->
35 a
36 ^ "=> " ^ Logarion.Text.short_id m ^ ".gmi "
37 ^ Logarion.(Date.(pretty_date (listing m.Text.date))) ^ " "
38 ^ m.Logarion.Text.title ^ "\n")
39 "" meta_list
40
41let topic_link root topic =
42 let replaced_space = String.map (function ' '->'+' | x->x) in
43 "=> index." ^ replaced_space root ^ ".gmi " ^ String.capitalize_ascii topic ^ "\n"
44
45let text_item path meta =
46 let open Logarion in
47 "=> " ^ path ^ Text.short_id meta ^ ".gmi "
48 ^ Date.(pretty_date (listing meta.Text.date)) ^ " "
49 ^ meta.Text.title ^ "\n"
50
51let listing_index topic_map topic_roots path metas =
52 let rec item_group topics =
53 List.fold_left (fun acc topic -> acc ^ sub_groups topic ^ items topic) "" topics
54 and sub_groups topic = match Logarion.Topic_set.Map.find_opt topic topic_map with
55 | None -> ""
56 | Some (_, subtopics) -> item_group (Logarion.String_set.elements subtopics)
57 and items topic =
58 let items =
59 let open Logarion in
60 List.fold_left
61 (fun a e ->
62 if String_set.mem topic (String_set.map (Logarion.Topic_set.topic) (Text.set "Topics" e))
63 then text_item path e ^ a else a) "" metas in
64 match items with
65 | "" -> ""
66 | x -> "## " ^ String.capitalize_ascii topic ^ "\n\n" ^ x
67 in
68 item_group topic_roots
69
70let fold_topic_roots topic_roots =
71 let list_item root t = topic_link root t in
72 List.fold_left (fun a x -> a ^ list_item x x) "" (List.rev topic_roots)
73
74let topic_main_index title topic_roots metas =
75 "# " ^ title ^ "\n\n"
76 ^ (if topic_roots <> [] then ("## Main topics\n\n" ^ fold_topic_roots topic_roots) else "")
77 ^ "\n## Latest\n\n" ^ to_dated_links ~limit:10 metas
78 ^ "\n=> index.date.gmi More by date\n"
79
80let topic_sub_index title topic_map topic_root metas =
81 "# " ^ title ^ "\n\n"
82 ^ listing_index topic_map [topic_root] "" metas
83
84let indices r =
85 let open Logarion in
86 let file name = File_store.file (Filename.concat r.Conversion.dir name) in
87 let index_name = try Store.KV.find "Gemini-index" r.kv with Not_found -> "index.gmi" in
88 let title = try Store.KV.find "Title" r.Conversion.kv with Not_found -> "" in
89
90 if index_name <> "" then
91 file index_name (topic_main_index title r.topic_roots r.texts);
92
93 file "index.date.gmi" (date_index title r.texts);
94
95 List.iter
96 (fun topic -> file ("index." ^ topic ^ ".gmi")
97 (topic_sub_index title r.topics topic r.texts))
98 r.topic_roots;
99
100 let base_url = try
101 let _i = Str.(search_forward (regexp "gemini?://[^;]*") (Store.KV.find "Locations" r.kv) 0) in
102 Str.(matched_string (Store.KV.find "Locations" r.kv))
103 with Not_found -> prerr_endline "Missing location for Gemini"; "" in
104 file "gmi.atom" (Atom.feed title r.id base_url "text/gemini" r.texts)
Note: See TracBrowser for help on using the repository browser.