feat(laws,opendata): add local law storage and migrate OpenData persistence to smartdb-backed local storage

This commit is contained in:
2026-04-17 11:51:02 +00:00
parent 79e74a34ed
commit 73801f785a
40 changed files with 8514 additions and 7266 deletions
+44 -19
View File
@@ -20,15 +20,44 @@ export class HandelsRegister {
this.uniqueDowloadFolder = plugins.path.join(this.downloadDir, plugins.smartunique.uniSimple());
}
private async resetDownloadFolder() {
await plugins.smartfs.directory(this.uniqueDowloadFolder).recursive().delete().catch(() => {});
await plugins.smartfs.directory(this.uniqueDowloadFolder).create();
}
private async waitForDownloadedFile() {
for (let attempt = 0; attempt < 120; attempt++) {
const directoryEntries = await plugins.fs.readdir(this.uniqueDowloadFolder);
const fileName = directoryEntries.find(
(entry) => !entry.endsWith('.crdownload') && !entry.endsWith('.tmp')
);
if (fileName) {
const filePath = plugins.path.join(this.uniqueDowloadFolder, fileName);
const firstStat = await plugins.fs.stat(filePath);
await plugins.smartdelay.delayFor(500);
const secondStat = await plugins.fs.stat(filePath);
if (firstStat.size === secondStat.size) {
return filePath;
}
}
await plugins.smartdelay.delayFor(500);
}
throw new Error('Timed out while waiting for the download to finish.');
}
public async start() {
// Start the browser
await plugins.smartfile.fs.ensureDir(this.uniqueDowloadFolder);
await this.resetDownloadFolder();
await this.smartbrowserInstance.start();
}
public async stop() {
// Stop the browser
await plugins.smartfile.fs.remove(this.uniqueDowloadFolder);
await plugins.smartfs.directory(this.uniqueDowloadFolder).recursive().delete();
await this.smartbrowserInstance.stop();
}
@@ -184,24 +213,16 @@ export class HandelsRegister {
throw new Error('Invalid file type');
}
}, typeArg);
const downloadedFilePath = await this.waitForDownloadedFile();
const renamedFilePath = plugins.path.join(
this.uniqueDowloadFolder,
typeArg === 'AD' ? 'ad.pdf' : 'si.xml'
);
await plugins.fs.rename(downloadedFilePath, renamedFilePath);
const file = await plugins.smartfileFactory.fromFilePath(renamedFilePath);
await plugins.smartfile.fs.waitForFileToBeReady(this.uniqueDowloadFolder);
const files = await plugins.smartfile.fs.fileTreeToObject(this.uniqueDowloadFolder, '**/*');
const file = files[0];
// lets clear the folder for the next download
await plugins.smartfile.fs.ensureEmptyDir(this.uniqueDowloadFolder);
switch (typeArg) {
case 'AD':
await file.rename(`ad.pdf`);
break;
case 'SI':
await file.rename(`si.xml`);
break;
break;
}
// Keep the download folder empty between requests.
await this.resetDownloadFolder();
return file;
}
@@ -297,6 +318,10 @@ export class HandelsRegister {
*/
public async getSpecificCompany(companyArg: BusinessRecord['data']['germanParsedRegistration']) {
return this.asyncExecutionStack.getExclusiveExecutionSlot(async () => {
if (!companyArg?.type || !companyArg.number || !companyArg.court) {
throw new Error('A complete parsed German registration is required.');
}
const page = await this.getNewPage();
await this.navigateToPage(page, 'Normal search');
await page.waitForSelector('#form\\:schlagwoerter', { timeout: 5000 });