lanonna/pam/bin/httpclient.ml

107 lines
3.4 KiB
OCaml
Raw Normal View History

2024-03-16 09:34:29 +01:00
open Pyops
open Pytypes
open Batteries
2024-04-02 14:38:00 +02:00
open Yojson.Safe
open Config
open Utils
2024-04-23 09:35:10 +02:00
open Pam
2024-03-16 09:34:29 +01:00
2024-04-24 09:45:20 +02:00
let issue_of_json (m_room: Datatypes.MatrixRoom.t) (json): Datatypes.forgejo_issue_data =
2024-04-02 14:38:00 +02:00
let open Yojson.Safe.Util in
let due_date = json |> member "due_date" |> to_option to_string in
2024-04-24 09:45:20 +02:00
let record: Datatypes.forgejo_issue_data = {
2024-04-17 18:18:19 +02:00
url = json |> member "url" |> to_string;
title = json |> member "title" |> to_string;
body = json |> member "body" |> to_string;
matrix_target = m_room;
due_date = due_date
}
in record
2024-03-16 09:34:29 +01:00
2024-04-02 14:38:00 +02:00
let issues_of_json matrix_room json_str =
let open Yojson.Safe.Util in
2024-04-17 18:18:19 +02:00
try
json_str |> from_string |> to_list |> List.map (issue_of_json matrix_room) |> Result.ok
with
| Yojson.Json_error msg -> Error [%string "JSON parsing error: %{msg}"]
module ForgejoUrl = struct
type t = {url: string; page: int}
let from_id repo_id =
{ url = [%string "https://salsa.lezzo.org/api/v1/repos/%{repo_id}/issues?state=open&type=issues&limit=50"];
page = 0 }
let next_page t = {t with page=t.page+1}
let to_string t = [%string "%{t.url}&page=%{t.page#Int}"]
end
2024-04-02 14:38:00 +02:00
2024-04-17 18:18:19 +02:00
type repo_pytuple = {url: ForgejoUrl.t; headers: pyobject}
2024-04-02 14:38:00 +02:00
type http_actor = {requests: pyobject; repos: repo_pytuple StringMap.t}
let make_headers base64_password =
let headers =
[("accept", "application/json");
("authorization", [%string "Basic %{base64_password}"])] in
headers
2024-03-16 09:34:29 +01:00
|> List.map (fun (k, v) -> (k, Py.String.of_string v))
2024-04-02 14:38:00 +02:00
|> Py.Dict.of_bindings_string
2024-03-16 09:34:29 +01:00
2024-04-02 14:38:00 +02:00
let init (repos: Config.repo_data list) =
let _ = Py.initialize () in
let requests = Py.import "requests" in
let urls =
repos
|> List.map (fun {forgejo_id; base64_password; matrix_room} ->
2024-04-17 18:18:19 +02:00
(matrix_room, {url=ForgejoUrl.from_id forgejo_id; headers=make_headers base64_password}))
2024-04-02 14:38:00 +02:00
|> StringMap.of_list
in
{requests=requests; repos=urls}
2024-03-16 09:34:29 +01:00
2024-04-17 18:18:19 +02:00
let pyprint () =
let builtins = Py.Eval.get_builtins () in
let p = Py.Dict.find_string builtins "print" in
Py.Callable.to_function p
let extract_pagination resp =
let key = Py.String.of_string "X-Total-Count" in
resp
.@$("headers")
.&("get") [|key|] (* not really a pydict, so need to use `get` *)
|> Py.Object.to_string
|> int_of_string
2024-04-02 14:38:00 +02:00
let make_get_request {requests; repos} =
2024-03-16 09:34:29 +01:00
let get = Py.Module.get_function_with_keywords requests "get" in
2024-04-17 18:18:19 +02:00
2024-04-24 09:45:20 +02:00
let rec fold_fn (accum: (Datatypes.forgejo_issue_data list)) = function
2024-04-17 18:18:19 +02:00
| [] -> Ok accum
| (m_room_string, {url; headers})::rest ->
let pyurl = url |> ForgejoUrl.to_string |> Py.String.of_string in
let resp = get [|pyurl|] [("headers", headers)] in
2024-04-02 14:38:00 +02:00
let jsontext =
resp.@$("text")
|> Py.String.to_string
in
2024-04-17 18:18:19 +02:00
let _ = print_endline "linea 62" in
let target_items_total = extract_pagination resp in
let _ = print_endline (url |> ForgejoUrl.to_string) in
let _ = print_endline "linea 64" in
2024-04-02 14:38:00 +02:00
let matrix_room = Datatypes.MatrixRoom.make m_room_string in
2024-04-17 18:18:19 +02:00
let issues = issues_of_json matrix_room jsontext in
match issues with
| Error err ->
Error err
| Ok target_issues ->
let n_received = List.length target_issues in
let accum' = target_issues@accum in
let urls =
if n_received <> target_items_total then
(m_room_string, {url=ForgejoUrl.next_page url; headers=headers})::rest
else
rest
in fold_fn accum' urls
in
StringMap.to_list repos
|> fold_fn []