@tricoteuses/senat 2.20.21 → 2.20.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/lib/loaders.d.ts +2 -1
- package/lib/loaders.js +48 -3
- package/lib/model/dosleg.d.ts +1 -2
- package/lib/model/dosleg.js +183 -114
- package/lib/parsers/texte.d.ts +7 -0
- package/lib/parsers/texte.js +228 -0
- package/lib/scripts/convert_data.js +87 -62
- package/lib/scripts/data-download.js +4 -1
- package/lib/scripts/retrieve_documents.d.ts +2 -1
- package/lib/scripts/retrieve_documents.js +124 -192
- package/lib/scripts/shared/cli_helpers.d.ts +10 -0
- package/lib/scripts/shared/cli_helpers.js +12 -0
- package/lib/scripts/test_iter_load.js +11 -22
- package/package.json +5 -7
|
@@ -4,17 +4,12 @@ import fs from "fs-extra";
|
|
|
4
4
|
import { DateTime } from "luxon";
|
|
5
5
|
import path from "path";
|
|
6
6
|
import { DATA_ORIGINAL_FOLDER, DATA_TRANSFORMED_FOLDER, iterLoadSenatDossiersLegislatifsRapportUrls, iterLoadSenatDossiersLegislatifsTexteUrls, RAPPORT_FOLDER, TEXTE_FOLDER, } from "../loaders";
|
|
7
|
-
import { parseExposeDesMotifs, parseTexte, parseTexteFromFile } from "../
|
|
7
|
+
import { parseExposeDesMotifs, parseTexte, parseTexteFromFile } from "../parsers/texte";
|
|
8
8
|
import { getSessionsFromStart, UNDEFINED_SESSION } from "../types/sessions";
|
|
9
9
|
import { commonOptions } from "./shared/cli_helpers";
|
|
10
10
|
import { ensureAndClearDir, fetchWithRetry, isOptionEmptyOrHasValue } from "./shared/util";
|
|
11
11
|
const optionsDefinitions = [
|
|
12
12
|
...commonOptions,
|
|
13
|
-
{
|
|
14
|
-
help: "parse and convert documents into JSON (textes only for now, requires format xml)",
|
|
15
|
-
name: "parseDocuments",
|
|
16
|
-
type: Boolean,
|
|
17
|
-
},
|
|
18
13
|
{
|
|
19
14
|
alias: "F",
|
|
20
15
|
help: "formats of documents to retrieve (xml/html/pdf for textes, html/pdf for rapports); leave empty for all",
|
|
@@ -38,205 +33,142 @@ const options = commandLineArgs(optionsDefinitions);
|
|
|
38
33
|
const textDecoder = new TextDecoder("utf8");
|
|
39
34
|
const today = DateTime.now();
|
|
40
35
|
function isDocumentRecent(documentDate, daysThreshold) {
|
|
41
|
-
if (!documentDate)
|
|
36
|
+
if (!documentDate)
|
|
42
37
|
return false;
|
|
43
|
-
}
|
|
44
38
|
const docDate = DateTime.fromISO(documentDate);
|
|
45
|
-
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
|
-
const daysDiff = today.diff(docDate, "days").days;
|
|
49
|
-
return daysDiff <= daysThreshold;
|
|
39
|
+
return docDate.isValid && today.diff(docDate, "days").days <= daysThreshold;
|
|
50
40
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (options
|
|
57
|
-
|
|
41
|
+
function shouldDownload(filePath, docDate, options) {
|
|
42
|
+
if (options.force)
|
|
43
|
+
return true;
|
|
44
|
+
if (!fs.existsSync(filePath))
|
|
45
|
+
return true;
|
|
46
|
+
if (options.onlyRecent !== undefined) {
|
|
47
|
+
return isDocumentRecent(docDate, options.onlyRecent);
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
async function downloadDocument(documentUrl, verbose) {
|
|
52
|
+
if (verbose) {
|
|
53
|
+
console.log(`Downloading document ${documentUrl}…`);
|
|
58
54
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
fs.ensureDirSync(texteDir);
|
|
66
|
-
let exposeDesMotifsContent = null;
|
|
67
|
-
if (texteMetadata.url_expose_des_motifs) {
|
|
68
|
-
exposeDesMotifsContent = await downloadExposeDesMotifs(texteDir, texteMetadata.name, String(texteMetadata.url_expose_des_motifs));
|
|
69
|
-
}
|
|
70
|
-
if (isOptionEmptyOrHasValue(options["formats"], "xml")) {
|
|
71
|
-
const textePath = path.join(texteDir, `${texteMetadata.name}.xml`);
|
|
72
|
-
let texteBuffer = null;
|
|
73
|
-
// Check if document should be skipped based on onlyRecent option
|
|
74
|
-
const shouldSkip = !options["force"] &&
|
|
75
|
-
fs.existsSync(textePath) &&
|
|
76
|
-
(options["only-recent"] === undefined || !isDocumentRecent(texteMetadata.date, options["only-recent"]));
|
|
77
|
-
if (shouldSkip) {
|
|
78
|
-
if (!options["silent"]) {
|
|
79
|
-
console.info(`Already downloaded texte ${textePath}…`);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
texteBuffer = await downloadDocument(texteMetadata.url_xml.toString());
|
|
84
|
-
if (!texteBuffer) {
|
|
85
|
-
texteUrlsNotFoundOrError.push(texteMetadata.url_xml);
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
fs.writeFileSync(textePath, Buffer.from(texteBuffer));
|
|
89
|
-
retrievedTextesCount++;
|
|
90
|
-
}
|
|
91
|
-
if (options["parseDocuments"]) {
|
|
92
|
-
const parsedTexte = await parseDocument(texteMetadata.session, transformedTextesDir, textePath, texteMetadata.name, texteBuffer, exposeDesMotifsContent);
|
|
93
|
-
if (!parsedTexte) {
|
|
94
|
-
texteUrlsParseError.push(texteMetadata.url_xml);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
if (isOptionEmptyOrHasValue(options["formats"], "html")) {
|
|
99
|
-
const textePath = path.join(texteDir, `${texteMetadata.name}.html`);
|
|
100
|
-
// Check if document should be skipped based on onlyRecent option
|
|
101
|
-
const shouldSkip = !options["force"] &&
|
|
102
|
-
fs.existsSync(textePath) &&
|
|
103
|
-
(options["only-recent"] === undefined || !isDocumentRecent(texteMetadata.date, options["only-recent"]));
|
|
104
|
-
if (shouldSkip) {
|
|
105
|
-
if (!options["silent"]) {
|
|
106
|
-
console.info(`Already downloaded texte ${textePath}…`);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
const texteBuffer = await downloadDocument(texteMetadata.url_html.toString());
|
|
111
|
-
if (!texteBuffer) {
|
|
112
|
-
texteUrlsNotFoundOrError.push(texteMetadata.url_html);
|
|
113
|
-
continue;
|
|
114
|
-
}
|
|
115
|
-
fs.writeFileSync(textePath, Buffer.from(texteBuffer));
|
|
116
|
-
retrievedTextesCount++;
|
|
55
|
+
try {
|
|
56
|
+
const response = await fetchWithRetry(documentUrl);
|
|
57
|
+
if (!response.ok) {
|
|
58
|
+
if (response.status === 404) {
|
|
59
|
+
if (verbose) {
|
|
60
|
+
console.warn(`Document ${documentUrl} not found`);
|
|
117
61
|
}
|
|
118
62
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const shouldSkip = !options["force"] &&
|
|
123
|
-
fs.existsSync(textePath) &&
|
|
124
|
-
(options["only-recent"] === undefined || !isDocumentRecent(texteMetadata.date, options["only-recent"]));
|
|
125
|
-
if (shouldSkip) {
|
|
126
|
-
if (!options["silent"]) {
|
|
127
|
-
console.info(`Already downloaded texte ${textePath}…`);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
const texteBuffer = await downloadDocument(texteMetadata.url_pdf.toString());
|
|
132
|
-
if (!texteBuffer) {
|
|
133
|
-
texteUrlsNotFoundOrError.push(texteMetadata.url_pdf);
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
136
|
-
fs.writeFileSync(textePath, Buffer.from(texteBuffer));
|
|
137
|
-
retrievedTextesCount++;
|
|
63
|
+
else {
|
|
64
|
+
if (verbose) {
|
|
65
|
+
console.error(`An error occurred while retrieving document ${documentUrl}: ${response.status}`);
|
|
138
66
|
}
|
|
139
67
|
}
|
|
68
|
+
return null;
|
|
140
69
|
}
|
|
70
|
+
return response.arrayBuffer();
|
|
141
71
|
}
|
|
142
|
-
|
|
143
|
-
console.
|
|
144
|
-
|
|
145
|
-
if (options["parseDocuments"]) {
|
|
146
|
-
console.log(`${texteUrlsParseError.length} textes failed to be parsed with URLs ${texteUrlsParseError.join(", ")}`);
|
|
147
|
-
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
console.error(error.message);
|
|
74
|
+
return null;
|
|
148
75
|
}
|
|
149
76
|
}
|
|
150
|
-
async function
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
fs.writeFileSync(rapportPath, Buffer.from(rapportBuffer));
|
|
178
|
-
retrievedRapportsCount++;
|
|
179
|
-
}
|
|
180
|
-
if (isOptionEmptyOrHasValue(options["formats"], "pdf")) {
|
|
181
|
-
const rapportPath = path.join(rapportDir, `${rapportMetadata.name}.pdf`);
|
|
182
|
-
// Check if document should be skipped based on onlyRecent option
|
|
183
|
-
const shouldSkip = !options["force"] &&
|
|
184
|
-
fs.existsSync(rapportPath) &&
|
|
185
|
-
(options["only-recent"] === undefined || !isDocumentRecent(rapportMetadata.date, options["only-recent"]));
|
|
186
|
-
if (shouldSkip) {
|
|
187
|
-
if (!options["silent"]) {
|
|
188
|
-
console.info(`Already downloaded rapport ${rapportPath}…`);
|
|
189
|
-
}
|
|
190
|
-
continue;
|
|
191
|
-
}
|
|
192
|
-
const rapportBuffer = await downloadDocument(rapportMetadata.url_pdf.toString());
|
|
193
|
-
if (!rapportBuffer) {
|
|
194
|
-
rapportUrlsNotFoundOrError.push(rapportMetadata.url_pdf);
|
|
195
|
-
continue;
|
|
196
|
-
}
|
|
197
|
-
fs.writeFileSync(rapportPath, Buffer.from(rapportBuffer));
|
|
198
|
-
retrievedRapportsCount++;
|
|
77
|
+
async function processDocument(url, destPath, docDate, options) {
|
|
78
|
+
if (!shouldDownload(destPath, docDate, options)) {
|
|
79
|
+
if (options.verbose)
|
|
80
|
+
console.info(`Already downloaded ${destPath}…`);
|
|
81
|
+
return { success: true, skipped: true, buffer: null };
|
|
82
|
+
}
|
|
83
|
+
const arrayBuffer = await downloadDocument(url, options.verbose);
|
|
84
|
+
if (!arrayBuffer) {
|
|
85
|
+
return { success: false, skipped: false, buffer: null };
|
|
86
|
+
}
|
|
87
|
+
const buffer = Buffer.from(arrayBuffer);
|
|
88
|
+
await fs.outputFile(destPath, buffer);
|
|
89
|
+
return { success: true, skipped: false, buffer };
|
|
90
|
+
}
|
|
91
|
+
export async function processTexte(texteMetadata, originalTextesDir, transformedTextesDir, options) {
|
|
92
|
+
const texteDir = path.join(originalTextesDir, `${texteMetadata.session ?? UNDEFINED_SESSION}`, texteMetadata.name);
|
|
93
|
+
let exposeDesMotifsContent = null;
|
|
94
|
+
if (texteMetadata.url_expose_des_motifs) {
|
|
95
|
+
const exposePath = path.join(texteDir, `${texteMetadata.name}-expose.html`);
|
|
96
|
+
const res = await processDocument(texteMetadata.url_expose_des_motifs.toString(), exposePath, texteMetadata.date, options);
|
|
97
|
+
if (res.buffer) {
|
|
98
|
+
exposeDesMotifsContent = res.buffer;
|
|
99
|
+
}
|
|
100
|
+
else if (res.skipped && options.parseDocuments) {
|
|
101
|
+
if (await fs.pathExists(exposePath)) {
|
|
102
|
+
exposeDesMotifsContent = await fs.readFile(exposePath);
|
|
199
103
|
}
|
|
200
104
|
}
|
|
201
105
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
106
|
+
const formats = [
|
|
107
|
+
{ type: "xml", url: texteMetadata.url_xml, isParseTarget: true },
|
|
108
|
+
{ type: "html", url: texteMetadata.url_html, isParseTarget: false },
|
|
109
|
+
{ type: "pdf", url: texteMetadata.url_pdf, isParseTarget: false },
|
|
110
|
+
];
|
|
111
|
+
for (const format of formats) {
|
|
112
|
+
if (!isOptionEmptyOrHasValue(options.formats, format.type))
|
|
113
|
+
continue;
|
|
114
|
+
const destPath = path.join(texteDir, `${texteMetadata.name}.${format.type}`);
|
|
115
|
+
const result = await processDocument(format.url.toString(), destPath, texteMetadata.date, options);
|
|
116
|
+
// Specific logic: Parsing (Only applies to XML)
|
|
117
|
+
if (format.isParseTarget && options.parseDocuments) {
|
|
118
|
+
await parseDocument(texteMetadata.session, transformedTextesDir, destPath, texteMetadata.name, result.buffer, exposeDesMotifsContent, options);
|
|
119
|
+
}
|
|
205
120
|
}
|
|
206
121
|
}
|
|
207
|
-
async function
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
122
|
+
export async function processRapport(rapportMetadata, originalRapportsDir, options) {
|
|
123
|
+
const rapportDir = path.join(originalRapportsDir, `${rapportMetadata.session ?? UNDEFINED_SESSION}`, rapportMetadata.name);
|
|
124
|
+
const formats = [
|
|
125
|
+
{ type: "html", url: rapportMetadata.url_html },
|
|
126
|
+
{ type: "pdf", url: rapportMetadata.url_pdf },
|
|
127
|
+
];
|
|
128
|
+
for (const format of formats) {
|
|
129
|
+
if (!isOptionEmptyOrHasValue(options["formats"], format.type))
|
|
130
|
+
continue;
|
|
131
|
+
const destPath = path.join(rapportDir, `${rapportMetadata.name}.${format.type}`);
|
|
132
|
+
await processDocument(format.url.toString(), destPath, rapportMetadata.date, options);
|
|
211
133
|
}
|
|
212
|
-
const exposeDesMotifsPath = path.join(texteDir, `${texteName}-expose.html`);
|
|
213
|
-
fs.writeFileSync(exposeDesMotifsPath, Buffer.from(content));
|
|
214
|
-
return content;
|
|
215
134
|
}
|
|
216
|
-
async function
|
|
217
|
-
|
|
218
|
-
|
|
135
|
+
async function retrieveTextes(dataDir, sessions) {
|
|
136
|
+
const originalTextesDir = path.join(dataDir, TEXTE_FOLDER, DATA_ORIGINAL_FOLDER);
|
|
137
|
+
const transformedTextesDir = path.join(dataDir, TEXTE_FOLDER, DATA_TRANSFORMED_FOLDER);
|
|
138
|
+
if (options["parseDocuments"]) {
|
|
139
|
+
ensureAndClearDir(transformedTextesDir);
|
|
219
140
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
141
|
+
const dlOptions = {
|
|
142
|
+
force: options["force"],
|
|
143
|
+
silent: options["silent"],
|
|
144
|
+
verbose: options["verbose"],
|
|
145
|
+
onlyRecent: options["only-recent"],
|
|
146
|
+
formats: options["formats"],
|
|
147
|
+
parseDocuments: options["parseDocuments"],
|
|
148
|
+
};
|
|
149
|
+
for (const session of sessions) {
|
|
150
|
+
for (const { item: texteMetadata } of iterLoadSenatDossiersLegislatifsTexteUrls(dataDir, session)) {
|
|
151
|
+
await processTexte(texteMetadata, originalTextesDir, transformedTextesDir, dlOptions);
|
|
230
152
|
}
|
|
231
|
-
return response.arrayBuffer();
|
|
232
153
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
154
|
+
}
|
|
155
|
+
async function retrieveRapports(dataDir, sessions) {
|
|
156
|
+
const originalRapportsDir = path.join(dataDir, RAPPORT_FOLDER, DATA_ORIGINAL_FOLDER);
|
|
157
|
+
const dlOptions = {
|
|
158
|
+
force: options["force"],
|
|
159
|
+
silent: options["silent"],
|
|
160
|
+
verbose: options["verbose"],
|
|
161
|
+
onlyRecent: options["only-recent"],
|
|
162
|
+
formats: options["formats"],
|
|
163
|
+
};
|
|
164
|
+
for (const session of sessions) {
|
|
165
|
+
for (const { item: rapportMetadata } of iterLoadSenatDossiersLegislatifsRapportUrls(dataDir, session)) {
|
|
166
|
+
await processRapport(rapportMetadata, originalRapportsDir, dlOptions);
|
|
167
|
+
}
|
|
236
168
|
}
|
|
237
169
|
}
|
|
238
|
-
async function parseDocument(session, transformedTextesDir, textePath, texteName, texteBuffer, exposeDesMotifs = null) {
|
|
239
|
-
if (
|
|
170
|
+
async function parseDocument(session, transformedTextesDir, textePath, texteName, texteBuffer, exposeDesMotifs = null, options = {}) {
|
|
171
|
+
if (options.verbose) {
|
|
240
172
|
console.log(`Parsing texte ${textePath}…`);
|
|
241
173
|
}
|
|
242
174
|
let parsedTexte;
|
|
@@ -247,19 +179,17 @@ async function parseDocument(session, transformedTextesDir, textePath, texteName
|
|
|
247
179
|
else {
|
|
248
180
|
parsedTexte = await parseTexteFromFile(textePath);
|
|
249
181
|
}
|
|
250
|
-
if (!parsedTexte)
|
|
182
|
+
if (!parsedTexte)
|
|
251
183
|
return null;
|
|
252
|
-
}
|
|
253
184
|
if (exposeDesMotifs) {
|
|
254
|
-
if (
|
|
185
|
+
if (options.verbose) {
|
|
255
186
|
console.log("Parsing exposé des motifs…");
|
|
256
187
|
}
|
|
257
188
|
const exposeDesMotifsHtml = textDecoder.decode(exposeDesMotifs);
|
|
258
189
|
parsedTexte.exposeDesMotifs = parseExposeDesMotifs(exposeDesMotifsHtml);
|
|
259
190
|
}
|
|
260
191
|
const transformedTexteDir = path.join(transformedTextesDir, `${session ?? UNDEFINED_SESSION}`, texteName);
|
|
261
|
-
fs.
|
|
262
|
-
fs.writeJSONSync(path.join(transformedTexteDir, `${texteName}.json`), parsedTexte, { spaces: 2 });
|
|
192
|
+
await fs.outputJSON(path.join(transformedTexteDir, `${texteName}.json`), parsedTexte, { spaces: 2 });
|
|
263
193
|
return parsedTexte;
|
|
264
194
|
}
|
|
265
195
|
async function main() {
|
|
@@ -277,9 +207,11 @@ async function main() {
|
|
|
277
207
|
console.timeEnd("documents processing time");
|
|
278
208
|
}
|
|
279
209
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
210
|
+
if (process.argv[1].endsWith("retrieve_documents.ts")) {
|
|
211
|
+
main()
|
|
212
|
+
.then(() => process.exit(0))
|
|
213
|
+
.catch((error) => {
|
|
214
|
+
console.log(error);
|
|
215
|
+
process.exit(1);
|
|
216
|
+
});
|
|
217
|
+
}
|
|
@@ -64,6 +64,16 @@ export declare const pullOption: {
|
|
|
64
64
|
name: string;
|
|
65
65
|
type: BooleanConstructor;
|
|
66
66
|
};
|
|
67
|
+
export declare const fetchDocumentsOption: {
|
|
68
|
+
help: string;
|
|
69
|
+
name: string;
|
|
70
|
+
type: BooleanConstructor;
|
|
71
|
+
};
|
|
72
|
+
export declare const parseDocumentsOption: {
|
|
73
|
+
help: string;
|
|
74
|
+
name: string;
|
|
75
|
+
type: BooleanConstructor;
|
|
76
|
+
};
|
|
67
77
|
export declare const commonOptions: ({
|
|
68
78
|
defaultOption: boolean;
|
|
69
79
|
help: string;
|
|
@@ -64,6 +64,16 @@ export const pullOption = {
|
|
|
64
64
|
name: "pull",
|
|
65
65
|
type: Boolean,
|
|
66
66
|
};
|
|
67
|
+
export const fetchDocumentsOption = {
|
|
68
|
+
help: "download documents",
|
|
69
|
+
name: "fetchDocuments",
|
|
70
|
+
type: Boolean,
|
|
71
|
+
};
|
|
72
|
+
export const parseDocumentsOption = {
|
|
73
|
+
help: "parse documents",
|
|
74
|
+
name: "parseDocuments",
|
|
75
|
+
type: Boolean,
|
|
76
|
+
};
|
|
67
77
|
export const commonOptions = [
|
|
68
78
|
categoriesOption,
|
|
69
79
|
dataDirDefaultOption,
|
|
@@ -76,4 +86,6 @@ export const commonOptions = [
|
|
|
76
86
|
commitOption,
|
|
77
87
|
remoteOption,
|
|
78
88
|
pullOption,
|
|
89
|
+
fetchDocumentsOption,
|
|
90
|
+
parseDocumentsOption,
|
|
79
91
|
];
|
|
@@ -1,29 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { iterLoadSenatAmendements, iterLoadSenatDossiersLegislatifs } from "../loaders";
|
|
2
2
|
import commandLineArgs from "command-line-args";
|
|
3
3
|
import { dataDirDefaultOption } from "./shared/cli_helpers";
|
|
4
4
|
const optionsDefinitions = [dataDirDefaultOption];
|
|
5
5
|
const options = commandLineArgs(optionsDefinitions);
|
|
6
|
-
const noValidation = false;
|
|
7
6
|
const session = 2024;
|
|
8
|
-
const
|
|
9
|
-
for (const { item:
|
|
10
|
-
|
|
7
|
+
const sinceCommit = undefined;
|
|
8
|
+
for (const { item: amendement, filePathFromDataset } of iterLoadSenatAmendements(options["dataDir"], session, {
|
|
9
|
+
log: true,
|
|
10
|
+
sinceCommit: sinceCommit,
|
|
11
|
+
})) {
|
|
12
|
+
console.log(amendement["numero"]);
|
|
11
13
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
session,
|
|
17
|
-
{ noValidation: noValidation },
|
|
18
|
-
)) {
|
|
19
|
-
console.log(amendement["numero"])
|
|
14
|
+
for (const { item: dossierLegislatif } of iterLoadSenatDossiersLegislatifs(options["dataDir"], session, {
|
|
15
|
+
sinceCommit: sinceCommit,
|
|
16
|
+
})) {
|
|
17
|
+
console.log(dossierLegislatif["numero"]);
|
|
20
18
|
}
|
|
21
|
-
|
|
22
|
-
for (const { item: dossierLegislatif } of iterLoadSenatDossiersLegislatifs(
|
|
23
|
-
options["dataDir"],
|
|
24
|
-
session,
|
|
25
|
-
{ noValidation: noValidation },
|
|
26
|
-
)) {
|
|
27
|
-
console.log(dossierLegislatif["numero"])
|
|
28
|
-
}
|
|
29
|
-
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tricoteuses/senat",
|
|
3
|
-
"version": "2.20.
|
|
3
|
+
"version": "2.20.23",
|
|
4
4
|
"description": "Handle French Sénat's open data",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"France",
|
|
@@ -52,7 +52,6 @@
|
|
|
52
52
|
"data:retrieve_open_data": "tsx src/scripts/retrieve_open_data.ts --all",
|
|
53
53
|
"data:retrieve_senateurs_photos": "tsx src/scripts/retrieve_senateurs_photos.ts --fetch",
|
|
54
54
|
"data:retrieve_videos": "tsx src/scripts/retrieve_videos.ts",
|
|
55
|
-
"data:parse_textes_lois": "tsx src/scripts/parse_textes.ts",
|
|
56
55
|
"prepare": "npm run build",
|
|
57
56
|
"prepublishOnly": "npm run build",
|
|
58
57
|
"prettier": "prettier --write 'src/**/*.ts' 'tests/**/*.test.ts'",
|
|
@@ -65,17 +64,17 @@
|
|
|
65
64
|
"cheerio": "^1.1.2",
|
|
66
65
|
"command-line-args": "^6.0.1",
|
|
67
66
|
"dotenv": "^17.2.3",
|
|
68
|
-
"fast-xml-parser": "^5.3.
|
|
69
|
-
"fs-extra": "^11.3.
|
|
67
|
+
"fast-xml-parser": "^5.3.3",
|
|
68
|
+
"fs-extra": "^11.3.3",
|
|
70
69
|
"jsdom": "^27.2.0",
|
|
71
|
-
"kysely": "^0.28.
|
|
70
|
+
"kysely": "^0.28.9",
|
|
72
71
|
"luxon": "^3.7.2",
|
|
73
72
|
"node-stream-zip": "^1.8.2",
|
|
74
73
|
"p-limit": "^7.2.0",
|
|
75
74
|
"pg": "^8.13.1",
|
|
76
75
|
"pg-cursor": "^2.12.1",
|
|
77
76
|
"slug": "^11.0.0",
|
|
78
|
-
"tsx": "^4.
|
|
77
|
+
"tsx": "^4.21.0",
|
|
79
78
|
"windows-1252": "^3.0.4"
|
|
80
79
|
},
|
|
81
80
|
"devDependencies": {
|
|
@@ -93,7 +92,6 @@
|
|
|
93
92
|
"@typescript-eslint/parser": "^8.46.0",
|
|
94
93
|
"cross-env": "^10.1.0",
|
|
95
94
|
"eslint": "^8.57.1",
|
|
96
|
-
"iconv-lite": "^0.7.0",
|
|
97
95
|
"kysely-codegen": "^0.19.0",
|
|
98
96
|
"prettier": "^3.5.3",
|
|
99
97
|
"tslib": "^2.1.0",
|