My agentic slop goes here. Not intended for anyone else!
1(** Immiche - Immich API client library *)
2
3open Printf
4
5(** {1 Types} *)
6
7type 'net t_internal = {
8 base_url: string;
9 api_key: string;
10 requests_session: (float Eio.Time.clock_ty Eio.Resource.t, 'net Eio.Net.ty Eio.Resource.t) Requests.t;
11}
12
13type t = [`Generic | `Unix] t_internal
14
15type person = {
16 id: string;
17 name: string;
18 birth_date: string option;
19 thumbnail_path: string;
20 is_hidden: bool;
21}
22
23type people_response = {
24 total: int;
25 visible: int;
26 people: person list;
27}
28
29(** {1 Client Creation} *)
30
31let create ~requests_session ~base_url ~api_key : t =
32 (* Set API key header on the session *)
33 let requests_session = Requests.set_default_header requests_session "x-api-key" api_key in
34 { base_url; api_key; requests_session }
35
36(** {1 JSON Parsing} *)
37
38(* Parse a single person from JSON *)
39let parse_person json =
40 let open Ezjsonm in
41 let id = find json ["id"] |> get_string in
42 let name = find json ["name"] |> get_string in
43 let birth_date =
44 try Some (find json ["birthDate"] |> get_string)
45 with _ -> None
46 in
47 let thumbnail_path = find json ["thumbnailPath"] |> get_string in
48 let is_hidden =
49 try find json ["isHidden"] |> get_bool
50 with _ -> false
51 in
52 { id; name; birth_date; thumbnail_path; is_hidden }
53
54(* Parse people response from JSON *)
55let parse_people_response json =
56 let open Ezjsonm in
57 let total = find json ["total"] |> get_int in
58 let visible = find json ["visible"] |> get_int in
59 let people_json = find json ["people"] in
60 let people = get_list parse_person people_json in
61 { total; visible; people }
62
63(* Parse a list of people from search results *)
64let parse_person_list json =
65 let open Ezjsonm in
66 get_list parse_person json
67
68(** {1 API Functions} *)
69
70let fetch_people { base_url; requests_session; _ } =
71 let open Requests_json_api in
72 let url = base_url / "api/people" in
73 get_json_exn requests_session url parse_people_response
74
75let fetch_person { base_url; requests_session; _ } ~person_id =
76 let open Requests_json_api in
77 let url = base_url / "api/people" / person_id in
78 get_json_exn requests_session url parse_person
79
80let download_thumbnail { base_url; requests_session; _ } ~fs ~person_id ~output_path =
81 try
82 let open Requests_json_api in
83 let url = base_url / "api/people" / person_id / "thumbnail" in
84
85 match get_result requests_session url with
86 | Error (status, _body) ->
87 Error (`Msg (sprintf "HTTP error: %d" status))
88 | Ok img_data ->
89 (* Ensure output directory exists *)
90 let dir = Filename.dirname output_path in
91 if not (Sys.file_exists dir) then
92 Unix.mkdir dir 0o755;
93
94 (* Write the image data to file *)
95 let path = Eio.Path.(fs / output_path) in
96 Eio.Path.save ~create:(`Or_truncate 0o644) path img_data;
97
98 Ok ()
99 with
100 | Failure msg -> Error (`Msg msg)
101 | exn -> Error (`Msg (Printexc.to_string exn))
102
103let search_person { base_url; requests_session; _ } ~name =
104 let open Requests_json_api in
105 let encoded_name = Uri.pct_encode name in
106 let url = sprintf "%s/api/search/person?name=%s" base_url encoded_name in
107 get_json_exn requests_session url parse_person_list