My agentic slop goes here. Not intended for anyone else!
1open Cmdliner
2
3(** List people command *)
4let list_people env _xdg profile base_url limit hidden =
5 Eio.Switch.run @@ fun sw ->
6
7 let api_key = Keyeio.Profile.get_required profile ~key:"api_key" in
8 let base_url =
9 match base_url with
10 | Some url -> url
11 | None ->
12 Keyeio.Profile.get profile ~key:"base_url"
13 |> Option.value ~default:"https://photos.example.com"
14 in
15
16 try
17 let requests_session = Requests.create ~sw env in
18 let client = Immich.create ~requests_session ~base_url ~api_key in
19 let response = Immich.fetch_people client in
20
21 (* Filter by hidden status if requested *)
22 let people =
23 List.filter (fun (p : Immich.person) ->
24 match hidden with
25 | Some true -> p.is_hidden
26 | Some false -> not p.is_hidden
27 | None -> true
28 ) response.people
29 in
30
31 (* Limit number of results *)
32 let people =
33 match limit with
34 | Some n -> List.filteri (fun i _ -> i < n) people
35 | None -> people
36 in
37
38 Printf.printf "Found %d people (total: %d, visible: %d)\n\n"
39 (List.length people) response.total response.visible;
40
41 List.iteri (fun i (p : Immich.person) ->
42 Printf.printf "%d. %s\n" (i + 1) p.name;
43 Printf.printf " ID: %s\n" p.id;
44 (match p.birth_date with
45 | Some bd -> Printf.printf " Birth date: %s\n" bd
46 | None -> ());
47 Printf.printf " Thumbnail: %s\n" p.thumbnail_path;
48 if p.is_hidden then Printf.printf " [HIDDEN]\n";
49 Printf.printf "\n"
50 ) people;
51 0
52 with exn ->
53 Printf.eprintf "Error: %s\n" (Printexc.to_string exn);
54 1
55
56(** Get a single person by ID *)
57let get_person env _xdg profile base_url person_id =
58 Eio.Switch.run @@ fun sw ->
59
60 let api_key = Keyeio.Profile.get_required profile ~key:"api_key" in
61 let base_url =
62 match base_url with
63 | Some url -> url
64 | None ->
65 Keyeio.Profile.get profile ~key:"base_url"
66 |> Option.value ~default:"https://photos.example.com"
67 in
68
69 try
70 let requests_session = Requests.create ~sw env in
71 let client = Immich.create ~requests_session ~base_url ~api_key in
72 let person = Immich.fetch_person client ~person_id in
73
74 Printf.printf "Person: %s\n" person.name;
75 Printf.printf "ID: %s\n" person.id;
76 (match person.birth_date with
77 | Some bd -> Printf.printf "Birth date: %s\n" bd
78 | None -> ());
79 Printf.printf "Thumbnail: %s\n" person.thumbnail_path;
80 if person.is_hidden then Printf.printf "Status: HIDDEN\n";
81 0
82 with exn ->
83 Printf.eprintf "Error: %s\n" (Printexc.to_string exn);
84 1
85
86(** Search for people by name *)
87let search_people env _xdg profile base_url name =
88 Eio.Switch.run @@ fun sw ->
89
90 let api_key = Keyeio.Profile.get_required profile ~key:"api_key" in
91 let base_url =
92 match base_url with
93 | Some url -> url
94 | None ->
95 Keyeio.Profile.get profile ~key:"base_url"
96 |> Option.value ~default:"https://photos.example.com"
97 in
98
99 try
100 let requests_session = Requests.create ~sw env in
101 let client = Immich.create ~requests_session ~base_url ~api_key in
102 let people = Immich.search_person client ~name in
103
104 Printf.printf "Found %d people matching '%s'\n\n" (List.length people) name;
105
106 List.iteri (fun i (p : Immich.person) ->
107 Printf.printf "%d. %s\n" (i + 1) p.name;
108 Printf.printf " ID: %s\n" p.id;
109 (match p.birth_date with
110 | Some bd -> Printf.printf " Birth date: %s\n" bd
111 | None -> ());
112 Printf.printf " Thumbnail: %s\n" p.thumbnail_path;
113 if p.is_hidden then Printf.printf " [HIDDEN]\n";
114 Printf.printf "\n"
115 ) people;
116 0
117 with exn ->
118 Printf.eprintf "Error: %s\n" (Printexc.to_string exn);
119 1
120
121(** Command-line arguments *)
122
123let base_url_arg =
124 let doc = "Base URL of the Immich instance (overrides profile setting)" in
125 Arg.(value & opt (some string) None & info ["u"; "url"] ~docv:"URL" ~doc)
126
127let limit_arg =
128 let doc = "Maximum number of results to return" in
129 Arg.(value & opt (some int) None & info ["l"; "limit"] ~docv:"N" ~doc)
130
131let hidden_arg =
132 let doc = "Filter by hidden status (true/false)" in
133 Arg.(value & opt (some bool) None & info ["hidden"] ~docv:"BOOL" ~doc)
134
135let person_id_arg =
136 let doc = "ID of the person" in
137 Arg.(required & pos 0 (some string) None & info [] ~docv:"PERSON_ID" ~doc)
138
139let name_arg =
140 let doc = "Name to search for" in
141 Arg.(required & pos 0 (some string) None & info [] ~docv:"NAME" ~doc)
142
143(** Commands *)
144
145let list_cmd =
146 let doc = "List people from Immich" in
147 Eiocmd.run
148 ~info:(Cmd.info "list" ~doc)
149 ~app_name:"immich"
150 ~service:"immich"
151 Term.(const (fun base_url limit hidden env xdg profile ->
152 list_people env xdg profile base_url limit hidden)
153 $ base_url_arg $ limit_arg $ hidden_arg)
154
155let get_cmd =
156 let doc = "Get a person by ID" in
157 Eiocmd.run
158 ~info:(Cmd.info "get" ~doc)
159 ~app_name:"immich"
160 ~service:"immich"
161 Term.(const (fun base_url person_id env xdg profile ->
162 get_person env xdg profile base_url person_id)
163 $ base_url_arg $ person_id_arg)
164
165let search_cmd =
166 let doc = "Search for people by name" in
167 Eiocmd.run
168 ~info:(Cmd.info "search" ~doc)
169 ~app_name:"immich"
170 ~service:"immich"
171 Term.(const (fun base_url name env xdg profile ->
172 search_people env xdg profile base_url name)
173 $ base_url_arg $ name_arg)
174
175(** Main command *)
176
177let main_cmd =
178 let doc = "Immich API client" in
179 let man = [
180 `S Manpage.s_description;
181 `P "$(tname) is a command-line client for the Immich API.";
182 `P "It allows you to list, search, and view people from your Immich instance.";
183 ] in
184 let info = Cmd.info "immich" ~version:"0.1.0" ~doc ~man in
185 Cmd.group info [list_cmd; get_cmd; search_cmd]
186
187let () = exit (Cmd.eval' main_cmd)