[1] | 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
|
---|