1 | let extensions = [ ".md"; ".org" ]
|
---|
2 |
|
---|
3 | open Logarion
|
---|
4 | let load f =
|
---|
5 | let ic = open_in (Fpath.to_string f) in
|
---|
6 | let n = in_channel_length ic in
|
---|
7 | let s = Bytes.create n in
|
---|
8 | really_input ic s 0 n;
|
---|
9 | close_in ic;
|
---|
10 | Bytes.to_string s
|
---|
11 |
|
---|
12 | let note path = Lpath.fpath_of_note path |> load |> Note.of_string
|
---|
13 |
|
---|
14 | type t = { repo_path : Lpath.repo_t }
|
---|
15 |
|
---|
16 | let note_filetype name =
|
---|
17 | try Fpath.(mem_ext extensions @@ v name) with
|
---|
18 | | Invalid_argument _ -> false
|
---|
19 |
|
---|
20 | let to_list ?(order) lens_fn store =
|
---|
21 | let repo_path = store.repo_path in
|
---|
22 | let cons_valid_meta list path =
|
---|
23 | try
|
---|
24 | let note = note (Lpath.note_of_basename repo_path path) in
|
---|
25 | lens_fn note :: list
|
---|
26 | with Note.Syntax_error str -> prerr_endline str; list
|
---|
27 | in
|
---|
28 | Lpath.string_of_repo repo_path
|
---|
29 | |> Sys.readdir
|
---|
30 | |> Array.to_list
|
---|
31 | |> List.filter note_filetype
|
---|
32 | |> List.fold_left cons_valid_meta []
|
---|
33 | |> match order with
|
---|
34 | | Some fn -> List.fast_sort fn
|
---|
35 | | None -> (fun x -> x)
|
---|
36 |
|
---|
37 | let note_with_id store id =
|
---|
38 | let repo_path = store.repo_path in
|
---|
39 | let note_of_path path = note (Lpath.note_of_basename repo_path path) in
|
---|
40 | let with_id path =
|
---|
41 | try
|
---|
42 | let note = note_of_path path in
|
---|
43 | note.Note.meta.Meta.uuid = id
|
---|
44 | with Note.Syntax_error str -> prerr_endline str; false
|
---|
45 | in
|
---|
46 | let notes =
|
---|
47 | Lpath.string_of_repo repo_path
|
---|
48 | |> Sys.readdir
|
---|
49 | |> Array.to_list
|
---|
50 | |> List.filter note_filetype
|
---|
51 | in
|
---|
52 | try Some (note_of_path (List.find with_id notes))
|
---|
53 | with Not_found -> None
|
---|
54 |
|
---|
55 | let note_with_alias store alias =
|
---|
56 | let repo_path = store.repo_path in
|
---|
57 | let cons_valid_meta list path =
|
---|
58 | try (note (Lpath.note_of_basename repo_path path)) :: list
|
---|
59 | with Note.Syntax_error str -> prerr_endline str; list
|
---|
60 | in
|
---|
61 | let recency_order a b = Meta.(Date.compare b.date a.date) in
|
---|
62 | let notes =
|
---|
63 | Lpath.string_of_repo repo_path
|
---|
64 | |> Sys.readdir
|
---|
65 | |> Array.to_list
|
---|
66 | |> List.filter note_filetype
|
---|
67 | |> List.fold_left cons_valid_meta []
|
---|
68 | |> List.filter (fun note -> Meta.alias note.Note.meta = alias)
|
---|
69 | |> List.fast_sort (fun a b -> recency_order a.Note.meta b.Note.meta)
|
---|
70 | in
|
---|
71 | try Some (List.hd notes)
|
---|
72 | with Failure _ -> None
|
---|
73 |
|
---|
74 | let notepath_with_id _store _id = None
|
---|
75 |
|
---|
76 | let store repo_path = { repo_path }
|
---|
77 |
|
---|
78 | module Lwt = struct
|
---|
79 | let of_filename f =
|
---|
80 | let open Lwt in
|
---|
81 | Lwt_io.(open_file ~mode:(Input) f >|= read_lines)
|
---|
82 | >|= (fun stream -> Lwt_stream.fold (^) stream "")
|
---|
83 |
|
---|
84 | let with_note store new_note =
|
---|
85 | let extension = List.hd extensions in
|
---|
86 | let open Lwt in
|
---|
87 | let open Lwt.Infix in
|
---|
88 | let store =
|
---|
89 | let write_note out = Lwt_io.write out (Note.to_string new_note) in
|
---|
90 | match notepath_with_id store new_note.Note.meta.Meta.uuid with
|
---|
91 | | Some previous_path ->
|
---|
92 | let filepath =
|
---|
93 | let open Note in
|
---|
94 | let open Meta in
|
---|
95 | if (note previous_path).meta.title <> new_note.meta.title
|
---|
96 | then Lpath.versioned_basename_of_title store.repo_path extension new_note.meta.title
|
---|
97 | else previous_path
|
---|
98 | in
|
---|
99 | Lwt_io.with_file ~mode:Lwt_io.output (Lpath.string_of_note filepath) write_note
|
---|
100 | >>= (fun () ->
|
---|
101 | if previous_path <> filepath
|
---|
102 | then Lwt_unix.unlink @@ Lpath.string_of_note previous_path
|
---|
103 | else Lwt.return_unit
|
---|
104 | )
|
---|
105 | | None ->
|
---|
106 | let filepath = Lpath.versioned_basename_of_title store.repo_path extension new_note.meta.title in
|
---|
107 | Lwt_io.with_file ~mode:Lwt_io.output (Lpath.string_of_note filepath) write_note
|
---|
108 | in
|
---|
109 | store >>= (fun () -> return new_note);
|
---|
110 | end
|
---|
111 |
|
---|
112 | let with_note = Lwt.with_note
|
---|