bugs: reunion-00002: idJo consistency check and fixes

parent c5784e56
......@@ -46,6 +46,7 @@
"jsdom": "^16.2.0",
"full-icu": "^1.3.1",
"node-fetch": "^2.6.0",
"node-html-parser": "^1.2.7",
"node-stream-zip": "^1.9.1"
},
"devDependencies": {
......
import glob from "glob"
import { HTMLElement, parse, TextNode } from "node-html-parser"
import fs from "fs-extra"
import { getFiles } from "../file_systems"
import { BasePlugin } from "../bugs"
const remapJo: any = {
RUANR5L15S2017IDS20667: "20172002",
RUANR5L15S2018IDS20817: "20180086",
RUANR5L15S2018IDS20864: "20180121",
RUANR5L15S2018IDS20981: "20180174",
RUANR5L15S2019IDS21507: "20190153",
RUANR5L15S2019IDS21608: "20190218",
RUANR5L15S2020IDS21840: "20200002",
RUANR5L15S2020IDS21841: "20200003",
RUANR5L15S2020IDS21859: "20200001",
RUANR5L15S2020IDS21970: "20200090",
RUANR5L15S2020IDS21983: "20200092",
RUANR5L15S2020IDS22019: "20200117",
RUANR5L15S2020IDS22020: "20200118",
RUANR5L15S2020IDS22021: "20200119",
RUANR5L15S2020IDS22054: "20200134",
RUANR5L15S2020IDS22055: "20200135",
RUANR5L15S2020IDS22056: "20200136",
RUANR5L15S2020IDS22057: "20200137",
RUANR5L15S2020IDS22087: "20200139",
RUANR5L15S2020IDS22089: "20200140",
RUANR5L15S2020IDS22106: "20200125",
}
export class Plugin extends BasePlugin {
cr2filenames: any
date2crs: any
cr2date: any
filename2date: any
constructor(options: any) {
super(options, "reunion-00002")
}
preCheck(): any {
this.filename2date = {}
this.cr2filenames = {}
this.date2crs = {}
this.cr2date = {}
for (const cr of getFiles([`${this.options.cr}/*.asp`])) {
this.cr2filenames[cr] = []
const content: string = fs.readFileSync(cr, { encoding: "utf-8" })
type ParseResult =
| (TextNode & { valid: boolean })
| (HTMLElement & { valid: boolean })
const doc: ParseResult = parse(content)
const root = (doc as unknown) as HTMLElement
let found = false
for (const meta of root.querySelectorAll("meta")) {
if (meta.attributes["name"] == "QUANTIEME_SEANCE") {
const date = meta.attributes["content"]
.split(" ")
.splice(-3)
.join(" ")
if (!(date in this.date2crs)) this.date2crs[date] = []
this.date2crs[date].push(cr)
this.cr2date[cr] = date
found = true
break
}
}
if (!found) {
console.error(`${cr} is missing the meta name="QUANTIEME_SEANCE"`)
}
}
}
check(reunion: any, filename: any): any {
if (
reunion.xsiType != "seance_type" ||
reunion.lieu.code != "AN" ||
reunion.cycleDeVie.etat == "Supprimé" ||
reunion.cycleDeVie.etat == "Annulé"
)
return null
if (this.options.verbose) console.log(`reunion-00002: ${filename}`)
let status = "ok"
let info: any = []
const dateSeance = new Date(
reunion.identifiants.dateSeance.substring(0, 10),
)
const year = dateSeance.toLocaleDateString("fr", { year: "numeric" })
const day = dateSeance.toLocaleDateString("fr", { day: "2-digit" })
const month = dateSeance.toLocaleDateString("fr", { month: "long" })
const dateSeanceString = `${day} ${month} ${year}`
this.filename2date[filename] = dateSeanceString
let idJo
if (
reunion.identifiants == undefined ||
reunion.identifiants.idJo == undefined
) {
const week = 7 * 24 * 60 * 60 * 1000
if (dateSeance >= new Date(new Date().getTime() - week)) {
return null
} else {
idJo = undefined
}
} else {
idJo = reunion.identifiants.idJo
}
if (reunion.uid in remapJo) {
if (idJo == remapJo[reunion.uid]) {
info.push(`idJo already is ${idJo}`)
status = "already-fixed"
} else {
idJo = remapJo[reunion.uid]
status = "will-be-fixed"
}
}
if (idJo == undefined) {
return {
status: "needs-fixing",
info: ["idJo field is missing"],
}
}
const pattern = `${this.options.cr}/*_${idJo}.asp`
const expanded = glob.sync(pattern)
let cr
if (expanded.length > 0) cr = expanded[0]
else cr = undefined
if (cr != undefined) {
this.cr2filenames[cr].push(filename)
if (dateSeanceString != this.cr2date[cr]) {
info.push(
`${cr} meta QUANTIEME_SEANCE contains ${this.cr2date[cr]} instead of the expected ${dateSeanceString}`,
)
status = "needs-fixing"
}
} else {
if (status != "will-be-fixed") {
info.push(`${pattern} does not exist`)
status = "needs-fixing"
}
}
return { status: status, info: info }
}
findCandidates(filename: any): any {
const date = this.filename2date[filename]
if (!(date in this.date2crs)) return []
let candidates = []
for (const cr of this.date2crs[date]) {
if (this.cr2filenames[cr].length > 0)
candidates.push(
`${cr} is not a candidate because it is referenced by ${this.cr2filenames[cr]}`,
)
else candidates.push(`${cr} is a candidate`)
}
return candidates
}
postCheck(analysis: any): any {
for (const filename of Object.keys(analysis)) {
const result = analysis[filename]["reunion-00002"]
if (result == null || result["status"] != "needs-fixing") continue
const info = result["info"].join("")
if (
info.includes("meta QUANTIEME") ||
info.includes("idJo field is missing")
) {
result["info"] = result["info"].concat(this.findCandidates(filename))
}
}
}
fix(reunion: any): any {
if (!(reunion.uid in remapJo)) {
return null
}
const idJo = remapJo[reunion.uid]
const numSeanceJo = String(Number(idJo.substring(5)))
if (
reunion.identifiants.idJo == idJo &&
reunion.identifiants.numSeanceJo == numSeanceJo
)
return false
reunion.identifiants.idJo = idJo
reunion.identifiants.numSeanceJo = numSeanceJo
return true
}
}
......@@ -5,6 +5,7 @@ import fs from "fs-extra"
import { SchemaBugs } from "../../src/bugs"
import { BasePlugin } from "../../src/bugs"
import { Plugin as Dossier00001 } from "../../src/bugs/dossier-00001"
import { Plugin as Reunion00002 } from "../../src/bugs/reunion-00002"
suite("bugs")
......@@ -88,3 +89,38 @@ test("#PluginDossier00001", function() {
assert.equal(bug.fix(content, f), false, f)
}
})
test("#PluginReunion00002", function() {
const bug = new Reunion00002({ cr: "tests/bugs/reunion-00002" })
const d = "tests/bugs/reunion-00002"
for (const expectedStatus of [
"will-be-fixed",
"already-fixed",
"ok",
"needs-fixing",
]) {
const f = `${d}/${expectedStatus}.json`
const content = load(f)
bug.preCheck()
const r = bug.check(content, f)
assert.equal(
r["status"],
expectedStatus,
`${f} returns ${r["status"]} ${r["info"]}`,
)
bug.postCheck({ f: r })
assert.equal(
r["status"],
expectedStatus,
`${f} returns ${r["status"]} ${r["info"]}`,
)
}
{
const f = `${d}/null.json`
const content = load(f)
bug.preCheck()
const r = bug.check(content, f)
assert.equal(r, null, f)
}
})
{
"schemaVersion": "agenda-1.0",
"xsiType": "seance_type",
"uid": "RUANR5L15S2020IDS22089",
"timestampDebut": "2020-02-12T15:00:00.000+01:00",
"timestampFin": "2020-02-12T18:05:00.000+01:00",
"lieu": {
"code": "AN",
"libelleLong": "Assemblée nationale"
},
"cycleDeVie": {
"etat": "Confirmé",
"chrono": {
"creation": "2020-01-20T00:00:00.000+01:00"
}
},
"organeReuniRef": "PO717460",
"sessionRef": "SCR5A2020O1",
"ouverturePresse": true,
"odj": {
"pointsOdj": [
{
"xsiType": "podjSeanceConfPres_type",
"uid": "RUANR5L15S2020IDS22089PT38154",
"cycleDeVie": {
"etat": "Confirmé",
"chrono": {
"creation": "2020-01-20T00:00:00.000+01:00"
}
},
"objet": "Discussion, en deuxième lecture, de la proposition de loi, modifiée par le Sénat, visant à encourager la participation des citoyens aux premiers secours",
"procedure": "procédure de législation en commission-Article 107-1",
"dossiersLegislatifsRefs": [
"DLR5L15N37091"
],
"typePointOdj": "Discussion",
"comiteSecret": false,
"natureTravauxOdj": "ODJPR",
"dateConfPres": "2020-02-12T01:00:00.000+01:00"
},
{
"xsiType": "podjSeanceConfPres_type",
"uid": "RUANR5L15S2020IDS22089PT38155",
"cycleDeVie": {
"etat": "Confirmé",
"chrono": {
"creation": "2020-01-20T00:00:00.000+01:00"
}
},
"objet": "Discussion de la proposition de loi visant à encadrer l'exploitation commerciale de l'image d'enfants de moins de seize ans sur les plateformes en ligne",
"dossiersLegislatifsRefs": [
"DLR5L15N38385"
],
"typePointOdj": "Discussion",
"comiteSecret": false,
"natureTravauxOdj": "ODJPR"
}
]
},
"compteRenduRef": "CRSANR5L15S2020O1N141",
"identifiants": {
"numSeanceJo": "140",
"idJo": "20200140",
"quantieme": "Unique",
"dateSeance": "2020-02-12T01:00:00.000+01:00"
},
"captationVideo": true
}
{
"xsiType": "seance_type",
"uid": "RUANR5L15S2020IDS22005",
"timestampDebut": "2019-12-18T15:00:00.000+01:00",
"lieu": {
"code": "AN",
"libelleLong": "Assemblée nationale"
},
"cycleDeVie": {
"etat": "Confirmé",
"chrono": {
"creation": "2019-11-22T00:00:00.000+01:00"
}
},
"organeReuniRef": "PO717460",
"sessionRef": "SCR5A2020O1",
"ouverturePresse": true,
"odj": {
"pointsOdj": [
{
"xsiType": "podjSeanceConfPres_type",
"uid": "RUANR5L15S2020IDS22005PT37938",
"cycleDeVie": {
"etat": "Confirmé",
"chrono": {
"creation": "2019-11-25T00:00:00.000+01:00"
}
},
"objet": "Suite de la discussion du projet de loi, adopté par le Sénat, relatif à la lutte contre le gaspillage et à l'économie circulaire",
"dossiersLegislatifsRefs": [
"DLR5L15N37641"
],
"typePointOdj": "Suite de la discussion",
"comiteSecret": false,
"natureTravauxOdj": "ODJPR"
}
]
},
"compteRenduRef": "CRSANR5L15S2020O1N109",
"identifiants": {
"numSeanceJo": "113",
"idJo": "20200113",
"quantieme": "Première",
"dateSeance": "2019-12-18T01:00:00.000+01:00"
},
"captationVideo": true
}
{
"xsiType": "reunionInitParlementaire_type",
"uid": "RUANR5L14S2017IDF0092768",
"timestampDebut": "2017-06-20T18:00:00.000+02:00",
"timestampFin": "2017-06-20T21:00:00.000+02:00",
"lieu": {
"code": "SALREU029",
"libelleCourt": "Salon Mars III",
"libelleLong": "Salon Mars III, 101, rue de l'Université"
},
"cycleDeVie": {
"etat": "Annulé",
"chrono": {
"creation": "2017-05-12T12:37:29.000+02:00",
"cloture": "2017-06-16T14:39:10.000+02:00"
}
},
"demandeurs": {
"acteurs": [
{
"nom": "M. Laurent WAUQUIEZ",
"acteurRef": "PA267285"
}
]
},
"typeReunion": "DEP"
}
\ No newline at end of file
{
"xsiType": "seance_type",
"uid": "RUANR5L15S2020IDS22009",
"timestampDebut": "2019-12-19T21:30:00.000+01:00",
"timestampFin": "2019-12-20T01:25:00.000+01:00",
"lieu": {
"code": "AN",
"libelleLong": "Assemblée nationale"
},
"cycleDeVie": {
"etat": "Confirmé",
"chrono": {
"creation": "2019-11-22T00:00:00.000+01:00"
}
},
"organeReuniRef": "PO717460",
"sessionRef": "SCR5A2020O1",
"ouverturePresse": true,
"odj": {
"pointsOdj": [
{
"xsiType": "podjSeanceConfPres_type",
"uid": "RUANR5L15S2020IDS22009PT37944",
"cycleDeVie": {
"etat": "Confirmé",
"chrono": {
"creation": "2019-11-25T00:00:00.000+01:00"
}
},
"objet": "Suite de la discussion du projet de loi, adopté par le Sénat, relatif à la lutte contre le gaspillage et à l'économie circulaire",
"dossiersLegislatifsRefs": [
"DLR5L15N37641"
],
"typePointOdj": "Suite de la discussion",
"comiteSecret": false,
"natureTravauxOdj": "ODJPR"
}
]
},
"compteRenduRef": "CRSANR5L15S2020O1N113",
"identifiants": {
"numSeanceJo": "113",
"idJo": "20200113",
"quantieme": "Troisième",
"dateSeance": "2019-12-19T01:00:00.000+01:00"
},
"captationVideo": true
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"schemaVersion": "agenda-1.0",
"xsiType": "seance_type",
"uid": "RUANR5L15S2020IDS22089",
"timestampDebut": "2020-02-12T15:00:00.000+01:00",
"timestampFin": "2020-02-12T18:05:00.000+01:00",
"lieu": {
"code": "AN",
"libelleLong": "Assemblée nationale"
},
"cycleDeVie": {
"etat": "Confirmé",
"chrono": {
"creation": "2020-01-20T00:00:00.000+01:00"
}
},
"organeReuniRef": "PO717460",
"sessionRef": "SCR5A2020O1",
"ouverturePresse": true,
"odj": {
"pointsOdj": [
{
"xsiType": "podjSeanceConfPres_type",
"uid": "RUANR5L15S2020IDS22089PT38154",
"cycleDeVie": {
"etat": "Confirmé",
"chrono": {
"creation": "2020-01-20T00:00:00.000+01:00"
}
},
"objet": "Discussion, en deuxième lecture, de la proposition de loi, modifiée par le Sénat, visant à encourager la participation des citoyens aux premiers secours",
"procedure": "procédure de législation en commission-Article 107-1",
"dossiersLegislatifsRefs": [
"DLR5L15N37091"
],
"typePointOdj": "Discussion",
"comiteSecret": false,
"natureTravauxOdj": "ODJPR",
"dateConfPres": "2020-02-12T01:00:00.000+01:00"
},
{
"xsiType": "podjSeanceConfPres_type",
"uid": "RUANR5L15S2020IDS22089PT38155",
"cycleDeVie": {
"etat": "Confirmé",
"chrono": {
"creation": "2020-01-20T00:00:00.000+01:00"
}
},
"objet": "Discussion de la proposition de loi visant à encadrer l'exploitation commerciale de l'image d'enfants de moins de seize ans sur les plateformes en ligne",
"dossiersLegislatifsRefs": [
"DLR5L15N38385"
],
"typePointOdj": "Discussion",
"comiteSecret": false,
"natureTravauxOdj": "ODJPR"
}
]
},
"compteRenduRef": "CRSANR5L15S2020O1N141",
"identifiants": {
"numSeanceJo": "141",
"idJo": "20200141",
"quantieme": "Unique",
"dateSeance": "2020-02-12T01:00:00.000+01:00"
},
"captationVideo": true
}
\ No newline at end of file
{
"xsiType": "seance_type",
"uid": "RUANR5L15S2019IDS21272",
"timestampDebut": "2018-10-15T16:00:00.000+02:00",
"timestampFin": "2018-10-15T20:00:00.000+02:00",
"lieu": {
"code": "AN",
"libelleLong": "Assemblée nationale"
},
"cycleDeVie": {
"etat": "Confirmé",
"chrono": {
"creation": "2018-09-24T00:00:00.000+02:00"
}
},
"organeReuniRef": "PO717460",
"sessionRef": "SCR5A2019O1",
"ouverturePresse": true,
"odj": {
"pointsOdj": [
{
"xsiType": "podjSeanceConfPres_type",
"uid": "RUANR5L15S2019IDS21272PT36355",
"cycleDeVie": {
"etat": "Confirmé",
"chrono": {
"creation": "2018-09-24T00:00:00.000+02:00"
}
},
"objet": "Discussion du projet de loi de finances pour 2019 (première partie)",
"dossiersLegislatifsRefs": [
"DLR5L15N36733"
],
"typePointOdj": "Discussion",
"comiteSecret": false,
"natureTravauxOdj": "ODJPR"
}
]
},
"compteRenduRef": "CRSANR5L15S2019O1N017",
"identifiants": {
"numSeanceJo": "17",
"quantieme": "Première",
"dateSeance": "2018-10-15T02:00:00.000+02:00"
},
"captationVideo": true
}
{
"schemaVersion": "agenda-1.0",
"xsiType": "seance_type",
"uid": "RUANR5L15S2020IDS22089",
"timestampDebut": "2020-02-12T15:00:00.000+01:00",
"timestampFin": "2020-02-12T18:05:00.000+01:00",
"lieu": {
"code": "AN",
"libelleLong": "Assemblée nationale"
},
"cycleDeVie": {
"etat": "Confirmé",
"chrono": {
"creation": "2020-01-20T00:00:00.000+01:00"
}
},
"organeReuniRef": "PO717460",
"sessionRef": "SCR5A2020O1",
"ouverturePresse": true,
"odj": {
"pointsOdj": [
{
"xsiType": "podjSeanceConfPres_type",
"uid": "RUANR5L15S2020IDS22089PT38154",
"cycleDeVie": {
"etat": "Confirmé",
"chrono": {
"creation": "2020-01-20T00:00:00.000+01:00"
}
},
"objet": "Discussion, en deuxième lecture, de la proposition de loi, modifiée par le Sénat, visant à encourager la participation des citoyens aux premiers secours",
"procedure": "procédure de législation en commission-Article 107-1",
"dossiersLegislatifsRefs": [
"DLR5L15N37091"
],
"typePointOdj": "Discussion",
"comiteSecret": false,
"natureTravauxOdj": "ODJPR",
"dateConfPres": "2020-02-12T01:00:00.000+01:00"
},
{
"xsiType": "podjSeanceConfPres_type",
"uid": "RUANR5L15S2020IDS22089PT38155",
"cycleDeVie": {
"etat": "Confirmé",
"chrono": {
"creation": "2020-01-20T00:00:00.000+01:00"
}
},
"objet": "Discussion de la proposition de loi visant à encadrer l'exploitation commerciale de l'image d'enfants de moins de seize ans sur les plateformes en ligne",
"dossiersLegislatifsRefs": [
"DLR5L15N38385"
],
"typePointOdj": "Discussion",
"comiteSecret": false,
"natureTravauxOdj": "ODJPR"
}
]
},
"compteRenduRef": "CRSANR5L15S2020O1N141",
"identifiants": {
"numSeanceJo": "141",
"idJo": "20200141",
"quantieme": "Unique",
"dateSeance": "2020-02-12T01:00:00.000+01:00"
},
"captationVideo": true
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment