113 lines
3.4 KiB
OCaml
113 lines
3.4 KiB
OCaml
let extensions = [ ".md"; ".org" ]
|
|
|
|
open Logarion
|
|
let load f =
|
|
let ic = open_in (Fpath.to_string f) in
|
|
let n = in_channel_length ic in
|
|
let s = Bytes.create n in
|
|
really_input ic s 0 n;
|
|
close_in ic;
|
|
Bytes.to_string s
|
|
|
|
let note path = Lpath.fpath_of_note path |> load |> Note.of_string
|
|
|
|
type t = { repo_path : Lpath.repo_t }
|
|
|
|
let note_filetype name =
|
|
try Fpath.(mem_ext extensions @@ v name) with
|
|
| Invalid_argument _ -> false
|
|
|
|
let to_list ?(order) lens_fn store =
|
|
let repo_path = store.repo_path in
|
|
let cons_valid_meta list path =
|
|
try
|
|
let note = note (Lpath.note_of_basename repo_path path) in
|
|
lens_fn note :: list
|
|
with Note.Syntax_error str -> prerr_endline str; list
|
|
in
|
|
Lpath.string_of_repo repo_path
|
|
|> Sys.readdir
|
|
|> Array.to_list
|
|
|> List.filter note_filetype
|
|
|> List.fold_left cons_valid_meta []
|
|
|> match order with
|
|
| Some fn -> List.fast_sort fn
|
|
| None -> (fun x -> x)
|
|
|
|
let note_with_id store id =
|
|
let repo_path = store.repo_path in
|
|
let note_of_path path = note (Lpath.note_of_basename repo_path path) in
|
|
let with_id path =
|
|
try
|
|
let note = note_of_path path in
|
|
note.Note.meta.Meta.uuid = id
|
|
with Note.Syntax_error str -> prerr_endline str; false
|
|
in
|
|
let notes =
|
|
Lpath.string_of_repo repo_path
|
|
|> Sys.readdir
|
|
|> Array.to_list
|
|
|> List.filter note_filetype
|
|
in
|
|
try Some (note_of_path (List.find with_id notes))
|
|
with Not_found -> None
|
|
|
|
let note_with_alias store alias =
|
|
let repo_path = store.repo_path in
|
|
let cons_valid_meta list path =
|
|
try (note (Lpath.note_of_basename repo_path path)) :: list
|
|
with Note.Syntax_error str -> prerr_endline str; list
|
|
in
|
|
let recency_order a b = Meta.(Date.compare b.date a.date) in
|
|
let notes =
|
|
Lpath.string_of_repo repo_path
|
|
|> Sys.readdir
|
|
|> Array.to_list
|
|
|> List.filter note_filetype
|
|
|> List.fold_left cons_valid_meta []
|
|
|> List.filter (fun note -> Meta.alias note.Note.meta = alias)
|
|
|> List.fast_sort (fun a b -> recency_order a.Note.meta b.Note.meta)
|
|
in
|
|
try Some (List.hd notes)
|
|
with Failure _ -> None
|
|
|
|
let notepath_with_id _store _id = None
|
|
|
|
let store repo_path = { repo_path }
|
|
|
|
module Lwt = struct
|
|
let of_filename f =
|
|
let open Lwt in
|
|
Lwt_io.(open_file ~mode:(Input) f >|= read_lines)
|
|
>|= (fun stream -> Lwt_stream.fold (^) stream "")
|
|
|
|
let with_note store new_note =
|
|
let extension = List.hd extensions in
|
|
let open Lwt in
|
|
let open Lwt.Infix in
|
|
let store =
|
|
let write_note out = Lwt_io.write out (Note.to_string new_note) in
|
|
match notepath_with_id store new_note.Note.meta.Meta.uuid with
|
|
| Some previous_path ->
|
|
let filepath =
|
|
let open Note in
|
|
let open Meta in
|
|
if (note previous_path).meta.title <> new_note.meta.title
|
|
then Lpath.versioned_basename_of_title store.repo_path extension new_note.meta.title
|
|
else previous_path
|
|
in
|
|
Lwt_io.with_file ~mode:Lwt_io.output (Lpath.string_of_note filepath) write_note
|
|
>>= (fun () ->
|
|
if previous_path <> filepath
|
|
then Lwt_unix.unlink @@ Lpath.string_of_note previous_path
|
|
else Lwt.return_unit
|
|
)
|
|
| None ->
|
|
let filepath = Lpath.versioned_basename_of_title store.repo_path extension new_note.meta.title in
|
|
Lwt_io.with_file ~mode:Lwt_io.output (Lpath.string_of_note filepath) write_note
|
|
in
|
|
store >>= (fun () -> return new_note);
|
|
end
|
|
|
|
let with_note = Lwt.with_note
|