From 09fc71c6257ab044e8fda6a52f0db286bc6291c1 Mon Sep 17 00:00:00 2001 From: Denis Merigoux Date: Tue, 6 Sep 2022 18:32:26 +0200 Subject: [PATCH] Differenciating API requests depending on text ID (beginning) --- french_law.opam | 1 + french_law/legifrance_checker/api.ml | 81 ++++++++++++++++++++------- french_law/legifrance_checker/api.mli | 10 +++- french_law/legifrance_checker/main.ml | 13 +++-- 4 files changed, 77 insertions(+), 28 deletions(-) diff --git a/french_law.opam b/french_law.opam index d5a5f7cf..0259bca3 100644 --- a/french_law.opam +++ b/french_law.opam @@ -12,6 +12,7 @@ depends: [ "dune" {>= "2.8"} "ocaml" {>= "4.11.0"} "lwt" {>= "5.6.1"} + "re" {>= "1.9.0"} "cohttp-lwt-unix" {>= "5.0.0"} "cohttp" {>= "5.0.0"} "tls" {>= "0.15.3"} diff --git a/french_law/legifrance_checker/api.ml b/french_law/legifrance_checker/api.ml index 63f6f4db..b97bbc37 100644 --- a/french_law/legifrance_checker/api.ml +++ b/french_law/legifrance_checker/api.ml @@ -98,31 +98,72 @@ let make_request type article = Yojson.Basic.t let run_request (request : (string * string t) t) : Yojson.Basic.t = - let resp, body = Lwt_main.run request in - let body = Lwt_main.run body in - if resp = "200 OK" then ( - try body |> Yojson.Basic.from_string - with Yojson.Basic.Util.Type_error (msg, obj) -> + let try_once () = + let resp, body = Lwt_main.run request in + let body = Lwt_main.run body in + resp, body + in + let handle_once resp body = + if resp = "200 OK" then ( + try body |> Yojson.Basic.from_string + with Yojson.Basic.Util.Type_error (msg, obj) -> + Utils.Cli.error_print + "Error while parsing JSON answer from API: %s\n\ + Specific JSON:\n\ + %s\n\ + Full answer:\n\ + %s" + msg + (Yojson.Basic.to_string obj) + body; + exit (-1)) + else raise (Failure "") + in + let resp, body = try_once () in + try handle_once resp body + with Failure _ -> ( + Utils.Cli.debug_format "Retrying request..."; + let resp, body = try_once () in + try handle_once resp body + with Failure _ -> Utils.Cli.error_print - "Error while parsing JSON answer from API: %s\n\ - Specific JSON:\n\ - %s\n\ - Full answer:\n\ - %s" - msg - (Yojson.Basic.to_string obj) + "The API request went wrong ; status is %s and the body is\n%s" resp body; exit (-1)) - else begin - Utils.Cli.error_print - "The API request went wrong ; status is %s and the body is\n%s" resp body; - exit (-1) - end -let retrieve_article (access_token : string) (article_id : string) : - Yojson.Basic.t = +type article_type = LEGIARTI | CETATEXT | JORFTEXT +type article_id = { id : string; typ : article_type } + +let parse_id (id : string) : article_id = + let legi_rex = + Re.(compile @@ whole_string @@ seq [str "LEGIARTI"; repn digit 12 None]) + in + let ceta_tex = + Re.(compile @@ whole_string @@ seq [str "CETATEXT"; repn digit 12 None]) + in + let jorf_rex = + Re.(compile @@ whole_string @@ seq [str "JORFTEXT"; repn digit 12 None]) + in + let typ = + if Re.execp legi_rex id then LEGIARTI + else if Re.execp ceta_tex id then CETATEXT + else if Re.execp jorf_rex id then JORFTEXT + else + Utils.Errors.raise_error + "LégiFrance ID \"%s\" does not correspond to an ID format recognized \ + by the LégiFrance API" + id + in + { id; typ } + +let retrieve_article (access_token : string) (obj : article_id) : Yojson.Basic.t + = run_request - (make_request access_token "consult/getArticle" ["id", article_id]) + (make_request access_token + (match obj.typ with + | CETATEXT -> "consult/juri" + | _ -> "consult/getArticle") + ["id", obj.id]) let raise_article_parsing_error (json : Yojson.Basic.t) diff --git a/french_law/legifrance_checker/api.mli b/french_law/legifrance_checker/api.mli index 0f3abf56..0b2edb95 100644 --- a/french_law/legifrance_checker/api.mli +++ b/french_law/legifrance_checker/api.mli @@ -31,10 +31,16 @@ val get_token : string -> string -> access_token API *) type article +type article_id -val retrieve_article : access_token -> string -> article +val parse_id : string -> article_id +(** [parse_id id] parses the string representing the LégiFrance object to be + fetched from the API, checks its validity (for instance + ["LEGIARTI000006307920"]) and returns an [object_id]*) + +val retrieve_article : access_token -> article_id -> article (** [retrieve_article token article_id] returns the article from the LegiFrance - API. [article_id] should be of the form ["LEGIARTI000006307920"] *) + API.*) type law_excerpt diff --git a/french_law/legifrance_checker/main.ml b/french_law/legifrance_checker/main.ml index a4d40342..e2f6934e 100644 --- a/french_law/legifrance_checker/main.ml +++ b/french_law/legifrance_checker/main.ml @@ -25,7 +25,8 @@ let check_article_expiration (access_token : Api.access_token) : new_article_version option = match law_heading.Surface.Ast.law_heading_id with | None -> None - | Some article_id -> + | Some heading_id -> + let article_id = Api.parse_id heading_id in let article = Api.retrieve_article access_token article_id in let api_article_expiration_date = Api.get_article_expiration_date article in let msg = @@ -66,8 +67,8 @@ let check_article_expiration type law_article_text = { article_title : string * Utils.Pos.t; text : string; - new_version : string option; - current_version : string option; + new_version : Api.article_id option; + current_version : Api.article_id option; } (** Representation of the text of an article of law *) @@ -80,7 +81,7 @@ module Diff = Diff.Make (String) let compare_article_to_version (access_token : Api.access_token) (text : string) - (version : string) : Diff.t option = + (version : Api.article_id) : Diff.t option = let new_article = Api.retrieve_article access_token version in let new_article_text = Api.get_article_text new_article in let text_to_list text = @@ -219,9 +220,9 @@ let rec traverse_source_code text = children_text; new_version = (match new_version with - | Some (Available version) -> Some version + | Some (Available version) -> Some (Api.parse_id version) | _ -> None); - current_version = law_heading.law_heading_id; + current_version = Option.map Api.parse_id law_heading.law_heading_id; } in if diff then compare_to_versions law_article_text access_token;