From 4d12eab0c3d7d76284accc73a8f6bcb5ab1bf32b Mon Sep 17 00:00:00 2001 From: Emmanuel Raviart Date: Fri, 19 May 2023 14:12:43 +0200 Subject: [PATCH] Export function parseDossierLegislatif --- src/lib/index.ts | 1 + src/lib/parsers/dole.ts | 69 ++++++++++++++++++++++++++++++ src/lib/parsers/index.ts | 1 + src/scripts/import_dole.ts | 88 ++++++++------------------------------ 4 files changed, 90 insertions(+), 69 deletions(-) create mode 100644 src/lib/parsers/dole.ts create mode 100644 src/lib/parsers/index.ts diff --git a/src/lib/index.ts b/src/lib/index.ts index 714004d..376357d 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -184,3 +184,4 @@ export { type TmLienTxt, type Versions, } from "./legal" +export { parseDossierLegislatif } from "./parsers" diff --git a/src/lib/parsers/dole.ts b/src/lib/parsers/dole.ts new file mode 100644 index 0000000..719aed2 --- /dev/null +++ b/src/lib/parsers/dole.ts @@ -0,0 +1,69 @@ +import { auditChain, auditRequire, strictAudit } from "@auditors/core" +import assert from "assert" +import { XMLParser } from "fast-xml-parser" +import he from "he" + +import { auditDossierLegislatif } from "$lib/auditors/dole" +import type { DossierLegislatif, XmlHeader } from "$lib/legal" + +const xmlParser = new XMLParser({ + attributeNamePrefix: "@", + ignoreAttributes: false, + stopNodes: [ + "DOSSIER_LEGISLATIF.CONTENU.CONTENU_DOSSIER_1", + "DOSSIER_LEGISLATIF.CONTENU.CONTENU_DOSSIER_2", + "DOSSIER_LEGISLATIF.CONTENU.CONTENU_DOSSIER_3", + "DOSSIER_LEGISLATIF.CONTENU.CONTENU_DOSSIER_4", + "DOSSIER_LEGISLATIF.CONTENU.CONTENU_DOSSIER_5", + "DOSSIER_LEGISLATIF.CONTENU.EXPOSE_MOTIF", + ], + tagValueProcessor: (_tagName, tagValue) => he.decode(tagValue), +}) + +export function parseDossierLegislatif( + filePath: string, + xmlString: string, +): DossierLegislatif | undefined { + try { + const xmlData = xmlParser.parse(xmlString) + for (const [key, element] of Object.entries(xmlData) as [ + string, + DossierLegislatif | XmlHeader, + ][]) { + switch (key) { + case "?xml": { + const xmlHeader = element as XmlHeader + assert.strictEqual(xmlHeader["@encoding"], "UTF-8", filePath) + assert.strictEqual(xmlHeader["@version"], "1.0", filePath) + break + } + case "DOSSIER_LEGISLATIF": { + const [dossierLegislatif, error] = auditChain( + auditDossierLegislatif, + auditRequire, + )(strictAudit, element) as [DossierLegislatif, unknown] + assert.strictEqual( + error, + null, + `Unexpected format for DOSSIER_LEGISLATIF:\n${JSON.stringify( + dossierLegislatif, + null, + 2, + )}\nError:\n${JSON.stringify(error, null, 2)}`, + ) + return dossierLegislatif + } + default: { + console.warn( + `Unexpected root element "${key}" in XML file: ${filePath}`, + ) + return undefined + } + } + } + return undefined + } catch (e) { + console.error("An error occurred while parsing XML file", filePath) + throw e + } +} diff --git a/src/lib/parsers/index.ts b/src/lib/parsers/index.ts new file mode 100644 index 0000000..aea0d1f --- /dev/null +++ b/src/lib/parsers/index.ts @@ -0,0 +1 @@ +export { parseDossierLegislatif } from "./dole" diff --git a/src/scripts/import_dole.ts b/src/scripts/import_dole.ts index afc2b0c..1ea07a5 100644 --- a/src/scripts/import_dole.ts +++ b/src/scripts/import_dole.ts @@ -1,31 +1,13 @@ -import { auditChain, auditRequire, strictAudit } from "@auditors/core" import assert from "assert" -import { XMLParser } from "fast-xml-parser" import fs from "fs-extra" -import he from "he" import path from "path" import type { JSONValue } from "postgres" import sade from "sade" -import { auditDossierLegislatif } from "$lib/auditors/dole" -import type { DossierLegislatif, XmlHeader } from "$lib/legal" +import { parseDossierLegislatif } from "$lib/parsers" import { db } from "$lib/server/databases" import { walkDir } from "$lib/server/file_systems" -const xmlParser = new XMLParser({ - attributeNamePrefix: "@", - ignoreAttributes: false, - stopNodes: [ - "DOSSIER_LEGISLATIF.CONTENU.CONTENU_DOSSIER_1", - "DOSSIER_LEGISLATIF.CONTENU.CONTENU_DOSSIER_2", - "DOSSIER_LEGISLATIF.CONTENU.CONTENU_DOSSIER_3", - "DOSSIER_LEGISLATIF.CONTENU.CONTENU_DOSSIER_4", - "DOSSIER_LEGISLATIF.CONTENU.CONTENU_DOSSIER_5", - "DOSSIER_LEGISLATIF.CONTENU.EXPOSE_MOTIF", - ], - tagValueProcessor: (_tagName, tagValue) => he.decode(tagValue), -}) - async function importDole( dilaDir: string, { resume }: { resume?: string } = {}, @@ -65,57 +47,25 @@ async function importDole( const xmlString: string = await fs.readFile(filePath, { encoding: "utf8", }) - const xmlData = xmlParser.parse(xmlString) - for (const [key, element] of Object.entries(xmlData) as [ - string, - DossierLegislatif | XmlHeader, - ][]) { - switch (key) { - case "?xml": { - const xmlHeader = element as XmlHeader - assert.strictEqual(xmlHeader["@encoding"], "UTF-8", filePath) - assert.strictEqual(xmlHeader["@version"], "1.0", filePath) - break - } - case "DOSSIER_LEGISLATIF": { - const [dossierLegislatif, error] = auditChain( - auditDossierLegislatif, - auditRequire, - )(strictAudit, element) as [DossierLegislatif, unknown] - assert.strictEqual( - error, - null, - `Unexpected format for DOSSIER_LEGISLATIF:\n${JSON.stringify( - dossierLegislatif, - null, - 2, - )}\nError:\n${JSON.stringify(error, null, 2)}`, - ) - await db` - INSERT INTO dossier_legislatif ( - id, - data - ) VALUES ( - ${dossierLegislatif.META.META_COMMUN.ID}, - ${db.json(dossierLegislatif as unknown as JSONValue)} - ) - ON CONFLICT (id) - DO UPDATE SET - data = ${db.json(dossierLegislatif as unknown as JSONValue)} - ` - dossierLegislatifRemainingIds.delete( - dossierLegislatif.META.META_COMMUN.ID, - ) - break - } - default: { - console.warn( - `Unexpected root element "${key}" in XML file: ${filePath}`, - ) - break iterXmlFiles - } - } + const dossierLegislatif = parseDossierLegislatif(filePath, xmlString) + if (dossierLegislatif === undefined) { + break iterXmlFiles } + await db` + INSERT INTO dossier_legislatif ( + id, + data + ) VALUES ( + ${dossierLegislatif.META.META_COMMUN.ID}, + ${db.json(dossierLegislatif as unknown as JSONValue)} + ) + ON CONFLICT (id) + DO UPDATE SET + data = ${db.json(dossierLegislatif as unknown as JSONValue)} + ` + dossierLegislatifRemainingIds.delete( + dossierLegislatif.META.META_COMMUN.ID, + ) } catch (e) { console.error("An error occurred while parsing XML file", filePath) throw e