OCaml HTML5 parser/serialiser based on Python's JustHTML

fixes

+93 -82
+17 -34
ocaml-peertube/bin/opeertube.ml
··· 193 193 handle_api_error @@ fun () -> 194 194 Eio_main.run @@ fun env -> 195 195 Eio.Switch.run @@ fun sw -> 196 - let session = Requests.create ~sw env in 197 - let client = Peertube.Client.create ~session ~base_url in 196 + let client = Peertube.Client.create ~sw env ~base_url in 198 197 if all then begin 199 198 let videos = 200 199 Peertube.Client.fetch_all_channel_videos client ?max_pages ··· 226 225 handle_api_error @@ fun () -> 227 226 Eio_main.run @@ fun env -> 228 227 Eio.Switch.run @@ fun sw -> 229 - let session = Requests.create ~sw env in 230 - let client = Peertube.Client.create ~session ~base_url in 228 + let client = Peertube.Client.create ~sw env ~base_url in 231 229 let response = Peertube.Client.list_videos client ~count ~start () in 232 230 Fmt.pr "Showing %d of %d videos (offset %d)@.@." 233 231 (List.length (Peertube.Paginated.data response)) ··· 247 245 handle_api_error @@ fun () -> 248 246 Eio_main.run @@ fun env -> 249 247 Eio.Switch.run @@ fun sw -> 250 - let session = Requests.create ~sw env in 251 - let client = Peertube.Client.create ~session ~base_url in 248 + let client = Peertube.Client.create ~sw env ~base_url in 252 249 let response = Peertube.Client.search_videos client ~query ~count ~start () in 253 250 Fmt.pr "Found %d results for '%s' (showing %d, offset %d)@.@." 254 251 (Peertube.Paginated.total response) ··· 269 266 handle_api_error @@ fun () -> 270 267 Eio_main.run @@ fun env -> 271 268 Eio.Switch.run @@ fun sw -> 272 - let session = Requests.create ~sw env in 273 - let client = Peertube.Client.create ~session ~base_url in 269 + let client = Peertube.Client.create ~sw env ~base_url in 274 270 let video = Peertube.Client.fetch_video_details client ~uuid () in 275 271 print_video ~json video 276 272 ··· 285 281 handle_api_error @@ fun () -> 286 282 Eio_main.run @@ fun env -> 287 283 Eio.Switch.run @@ fun sw -> 288 - let session = Requests.create ~sw env in 289 - let client = Peertube.Client.create ~session ~base_url in 284 + let client = Peertube.Client.create ~sw env ~base_url in 290 285 let video = Peertube.Client.fetch_video_details client ~uuid () in 291 286 match 292 287 Peertube.Client.download_thumbnail client ~video ~output_path:output () ··· 310 305 handle_api_error @@ fun () -> 311 306 Eio_main.run @@ fun env -> 312 307 Eio.Switch.run @@ fun sw -> 313 - let session = Requests.create ~sw env in 314 - let client = Peertube.Client.create ~session ~base_url in 308 + let client = Peertube.Client.create ~sw env ~base_url in 315 309 let response = Peertube.Client.list_channels client ~count ~start () in 316 310 Fmt.pr "Showing %d of %d channels (offset %d)@.@." 317 311 (List.length (Peertube.Paginated.data response)) ··· 331 325 handle_api_error @@ fun () -> 332 326 Eio_main.run @@ fun env -> 333 327 Eio.Switch.run @@ fun sw -> 334 - let session = Requests.create ~sw env in 335 - let client = Peertube.Client.create ~session ~base_url in 328 + let client = Peertube.Client.create ~sw env ~base_url in 336 329 let response = 337 330 Peertube.Client.search_channels client ~query ~count ~start () 338 331 in ··· 355 348 handle_api_error @@ fun () -> 356 349 Eio_main.run @@ fun env -> 357 350 Eio.Switch.run @@ fun sw -> 358 - let session = Requests.create ~sw env in 359 - let client = Peertube.Client.create ~session ~base_url in 351 + let client = Peertube.Client.create ~sw env ~base_url in 360 352 let channel = Peertube.Client.get_channel client ~handle () in 361 353 print_channel ~json channel 362 354 ··· 378 370 handle_api_error @@ fun () -> 379 371 Eio_main.run @@ fun env -> 380 372 Eio.Switch.run @@ fun sw -> 381 - let session = Requests.create ~sw env in 382 - let client = Peertube.Client.create ~session ~base_url in 373 + let client = Peertube.Client.create ~sw env ~base_url in 383 374 let response = Peertube.Client.list_accounts client ~count ~start () in 384 375 Fmt.pr "Showing %d of %d accounts (offset %d)@.@." 385 376 (List.length (Peertube.Paginated.data response)) ··· 399 390 handle_api_error @@ fun () -> 400 391 Eio_main.run @@ fun env -> 401 392 Eio.Switch.run @@ fun sw -> 402 - let session = Requests.create ~sw env in 403 - let client = Peertube.Client.create ~session ~base_url in 393 + let client = Peertube.Client.create ~sw env ~base_url in 404 394 let account = Peertube.Client.get_account client ~handle () in 405 395 print_account ~json account 406 396 ··· 415 405 handle_api_error @@ fun () -> 416 406 Eio_main.run @@ fun env -> 417 407 Eio.Switch.run @@ fun sw -> 418 - let session = Requests.create ~sw env in 419 - let client = Peertube.Client.create ~session ~base_url in 408 + let client = Peertube.Client.create ~sw env ~base_url in 420 409 let response = 421 410 Peertube.Client.get_account_videos client ~count ~start ~handle () 422 411 in ··· 445 434 handle_api_error @@ fun () -> 446 435 Eio_main.run @@ fun env -> 447 436 Eio.Switch.run @@ fun sw -> 448 - let session = Requests.create ~sw env in 449 - let client = Peertube.Client.create ~session ~base_url in 437 + let client = Peertube.Client.create ~sw env ~base_url in 450 438 let response = Peertube.Client.list_playlists client ~count ~start () in 451 439 Fmt.pr "Showing %d of %d playlists (offset %d)@.@." 452 440 (List.length (Peertube.Paginated.data response)) ··· 466 454 handle_api_error @@ fun () -> 467 455 Eio_main.run @@ fun env -> 468 456 Eio.Switch.run @@ fun sw -> 469 - let session = Requests.create ~sw env in 470 - let client = Peertube.Client.create ~session ~base_url in 457 + let client = Peertube.Client.create ~sw env ~base_url in 471 458 let response = 472 459 Peertube.Client.search_playlists client ~query ~count ~start () 473 460 in ··· 490 477 handle_api_error @@ fun () -> 491 478 Eio_main.run @@ fun env -> 492 479 Eio.Switch.run @@ fun sw -> 493 - let session = Requests.create ~sw env in 494 - let client = Peertube.Client.create ~session ~base_url in 480 + let client = Peertube.Client.create ~sw env ~base_url in 495 481 let playlist = Peertube.Client.get_playlist client ~id () in 496 482 print_playlist ~json playlist 497 483 ··· 506 492 handle_api_error @@ fun () -> 507 493 Eio_main.run @@ fun env -> 508 494 Eio.Switch.run @@ fun sw -> 509 - let session = Requests.create ~sw env in 510 - let client = Peertube.Client.create ~session ~base_url in 495 + let client = Peertube.Client.create ~sw env ~base_url in 511 496 let response = 512 497 Peertube.Client.get_playlist_videos client ~count ~start ~id () 513 498 in ··· 549 534 handle_api_error @@ fun () -> 550 535 Eio_main.run @@ fun env -> 551 536 Eio.Switch.run @@ fun sw -> 552 - let session = Requests.create ~sw env in 553 - let client = Peertube.Client.create ~session ~base_url in 537 + let client = Peertube.Client.create ~sw env ~base_url in 554 538 let config = Peertube.Client.get_config client () in 555 539 if json then print_json Peertube.Server_config.jsont config 556 540 else begin ··· 578 562 handle_api_error @@ fun () -> 579 563 Eio_main.run @@ fun env -> 580 564 Eio.Switch.run @@ fun sw -> 581 - let session = Requests.create ~sw env in 582 - let client = Peertube.Client.create ~session ~base_url in 565 + let client = Peertube.Client.create ~sw env ~base_url in 583 566 let stats = Peertube.Client.get_stats client () in 584 567 if json then print_json Peertube.Server_stats.jsont stats 585 568 else begin
+18 -6
ocaml-peertube/lib/peertube.mli
··· 14 14 let () = 15 15 Eio_main.run @@ fun env -> 16 16 Eio.Switch.run @@ fun sw -> 17 - let session = Requests.create ~sw env in 18 - let client = Client.create ~session ~base_url:"https://framatube.org" in 17 + let client = Client.create ~sw env ~base_url:"https://framatube.org" in 19 18 20 19 (* List recent videos *) 21 20 let videos = Client.list_videos client () in ··· 815 814 Functions raise {!Client.Api_error} on HTTP errors. 816 815 817 816 {[ 818 - let client = Client.create ~session ~base_url:"https://framatube.org" in 817 + let client = Client.create ~sw env ~base_url:"https://framatube.org" in 819 818 let videos = Client.list_videos client () in 820 819 ... 821 820 ]} *) ··· 828 827 Encapsulates the HTTP client and base URL for making API requests. In 829 828 future, this may also contain authentication credentials. *) 830 829 831 - val create : session:Requests.t -> base_url:string -> t 832 - (** [create ~session ~base_url] creates a new PeerTube API session. 830 + val create : 831 + ?session:Requests.t -> 832 + sw:Eio.Switch.t -> 833 + < clock : _ Eio.Time.clock 834 + ; net : _ Eio.Net.t 835 + ; fs : Eio.Fs.dir_ty Eio.Path.t 836 + ; .. > -> 837 + base_url:string -> 838 + t 839 + (** [create ?session ~sw env ~base_url] creates a new PeerTube API session. 833 840 834 - @param session HTTP client session from the Requests library 841 + If [session] is not provided, a new HTTP session is created using the 842 + given switch and environment. If [session] is provided, it is reused. 843 + 844 + @param session Optional existing HTTP client session to reuse 845 + @param sw Eio switch for resource management 846 + @param env Eio environment with clock, net, and fs capabilities 835 847 @param base_url 836 848 Base URL of the PeerTube instance (e.g., "https://framatube.org") *) 837 849
+6 -1
ocaml-peertube/lib/peertube_client.ml
··· 3 3 type t = { session : Requests.t; base_url : string } 4 4 (** Session type encapsulating HTTP client and base URL. *) 5 5 6 - let create ~session ~base_url = { session; base_url } 6 + let create ?session ~sw env ~base_url = 7 + let session = match session with 8 + | Some s -> s 9 + | None -> Requests.create ~sw env 10 + in 11 + { session; base_url } 7 12 let base_url t = t.base_url 8 13 let http_session t = t.session 9 14 let log_src = Logs.Src.create "peertube" ~doc:"PeerTube API client"
+16 -3
ocaml-peertube/lib/peertube_client.mli
··· 11 11 Encapsulates the HTTP client and base URL for making API requests. In 12 12 future, this may also contain authentication credentials. *) 13 13 14 - val create : session:Requests.t -> base_url:string -> t 15 - (** [create ~session ~base_url] creates a new PeerTube API session. 14 + val create : 15 + ?session:Requests.t -> 16 + sw:Eio.Switch.t -> 17 + < clock : _ Eio.Time.clock 18 + ; net : _ Eio.Net.t 19 + ; fs : Eio.Fs.dir_ty Eio.Path.t 20 + ; .. > -> 21 + base_url:string -> 22 + t 23 + (** [create ?session ~sw env ~base_url] creates a new PeerTube API session. 24 + 25 + If [session] is not provided, a new HTTP session is created using the 26 + given switch and environment. If [session] is provided, it is reused. 16 27 17 - @param session HTTP client session from the Requests library 28 + @param session Optional existing HTTP client session to reuse 29 + @param sw Eio switch for resource management 30 + @param env Eio environment with clock, net, and fs capabilities 18 31 @param base_url 19 32 Base URL of the PeerTube instance (e.g., "https://framatube.org") *) 20 33
+17 -20
ocaml-requests/lib/signature.ml
··· 409 409 (* Context *) 410 410 (* ========================================================================= *) 411 411 412 - module Context = struct 413 - (** Request context for signature computation. *) 414 - type request_ctx = { 415 - method_ : Method.t; (** The HTTP method *) 416 - uri : Uri.t; (** The request URI *) 417 - headers : Headers.t; (** The request headers *) 418 - } 412 + type request_ctx = { 413 + method_ : Method.t; 414 + uri : Uri.t; 415 + headers : Headers.t; 416 + } 419 417 420 - (** Response context for signature computation. *) 421 - type response_ctx = { 422 - status : int; (** The HTTP status code *) 423 - headers : Headers.t; (** The response headers *) 424 - request : request_ctx option; (** The original request, if available *) 425 - } 418 + type response_ctx = { 419 + status : int; 420 + headers : Headers.t; 421 + request : request_ctx option; 422 + } 426 423 427 - (** Message context (request or response). *) 424 + module Context = struct 428 425 type t = [ 429 - | `Request of request_ctx (** A request context *) 430 - | `Response of response_ctx (** A response context *) 426 + | `Request of request_ctx 427 + | `Response of response_ctx 431 428 ] 432 429 433 430 let request ~method_ ~uri ~headers : t = ··· 517 514 518 515 let resolve_component (ctx : Context.t) (component : Component.t) = 519 516 let get_headers : Context.t -> Headers.t = function 520 - | `Request r -> r.Context.headers 521 - | `Response r -> r.Context.headers 517 + | `Request r -> r.headers 518 + | `Response r -> r.headers 522 519 in 523 520 let get_request_headers : Context.t -> Headers.t option = function 524 - | `Request r -> Some r.Context.headers 525 - | `Response (r : Context.response_ctx) -> Option.map (fun (req : Context.request_ctx) -> req.headers) r.request 521 + | `Request r -> Some r.headers 522 + | `Response (r : response_ctx) -> Option.map (fun (req : request_ctx) -> req.headers) r.request 526 523 in 527 524 match component with 528 525 | `Derived (d, params) ->
+16 -15
ocaml-requests/lib/signature.mli
··· 273 273 274 274 (** {1 Signing Context} *) 275 275 276 - module Context : sig 277 - (** Context for resolving message components. *) 276 + type request_ctx = { 277 + method_ : Method.t; 278 + uri : Uri.t; 279 + headers : Headers.t; 280 + } 281 + (** Request context for signature computation. 282 + Contains the HTTP method, request URI, and request headers. *) 278 283 279 - type request_ctx = { 280 - method_ : Method.t; (** The HTTP method *) 281 - uri : Uri.t; (** The request URI *) 282 - headers : Headers.t; (** The request headers *) 283 - } 284 - (** Request context for signature computation. *) 284 + type response_ctx = { 285 + status : int; 286 + headers : Headers.t; 287 + request : request_ctx option; 288 + } 289 + (** Response context for signature computation. 290 + Contains the HTTP status code, response headers, and optionally the original request. *) 285 291 286 - type response_ctx = { 287 - status : int; (** The HTTP status code *) 288 - headers : Headers.t; (** The response headers *) 289 - request : request_ctx option; (** The original request, if available *) 290 - } 291 - (** Response context for signature computation. *) 292 - 292 + (** Context for resolving message components. *) 293 + module Context : sig 293 294 type t = [ 294 295 | `Request of request_ctx 295 296 | `Response of response_ctx
+1 -1
ocaml-zulip/lib/zulip/channel.mli
··· 121 121 (** Email notification setting. *) 122 122 123 123 val wildcard_mentions_notify : t -> bool option 124 - (** Whether to notify on @all/@everyone mentions. *) 124 + (** Whether to notify on \@all/\@everyone mentions. *) 125 125 126 126 val jsont : t Jsont.t 127 127 (** Jsont codec for subscription. *)
+2 -2
ocaml-zulip/lib/zulip/message_flag.mli
··· 18 18 19 19 type t = 20 20 [ modifiable 21 - | `Mentioned (** User was @-mentioned in the message *) 22 - | `Wildcard_mentioned (** User was mentioned via @all/@everyone *) 21 + | `Mentioned (** User was \@-mentioned in the message *) 22 + | `Wildcard_mentioned (** User was mentioned via \@all/\@everyone *) 23 23 | `Has_alert_word (** Message contains one of user's alert words *) 24 24 | `Historical (** Message predates user joining the stream *) ] 25 25 (** All possible message flags. *)