source: Klonkt/scripts/import-archive.mjs@ 6248497

main
Last change on this file since 6248497 was 6248497, checked in by roboburr <roboburr@…>, 5 weeks ago

Export en import kiezen de juiste instance, en tijdstempels zijn echt UTC

Twee fouten, allebei op productie gevonden en allebei van het soort dat SUCCES
meldt.

## 1. Het script opende de verkeerde database

Op een split install deelt elke Klonkt de code in /opt/klonkt maar staat zijn data
onder /var/lib/klonkt/<slug>/ met een eigen .env. De scripts lazen die .env niet,
dus database.js viel terug op storage/database.sqlite IN DE CODE-MAP. Op een
server die ooit de enkelvoudige opzet draaide ligt daar een achtergebleven oude
database.

Waargenomen: export-archive.mjs boiert schreef een archief van 444 bytes met
"posts: 0" en meldde dat het gelukt was, terwijl het in een oude lege database
keek. liz en sood gaven "onbekende site". Het script raakte die oude database
ook nog aan (boot-migraties), terwijl het alleen hoort te lezen.

Nu leest scripts/instance-env.mjs de .env van de instance (standaard
/var/lib/klonkt/<slug>/.env, of --data-root / --env) VOORDAT de service geladen
wordt -- database.js opent de database namelijk bij import. De uitvoer noemt
voortaan welke .env en welke database gebruikt zijn.

En zonder PUBLIC_BASE_URL stopt hij nu HARD in plaats van het als bijzin te
melden: zonder origin krijgt het archief een lege origin, en dan maakt een import
nieuwe AP-ids. Dan is het een kopie van de tekst en geen herstel -- precies de
belofte waar het formaat om draait.

Voor de importer weegt dit zwaarder dan voor de exporter: in de verkeerde
database schrijven draai je niet terug.

## 2. Tijdstempels schoven met de tijdzone van de machine

Vraag van Bart: normaliseert de export wel naar UTC? Nee.

SQLite schrijft CURRENT_TIMESTAMP als "2026-07-01 12:56:10" -- in UTC, maar zonder
zone. Date.parse leest die vorm als LOKALE tijd. Op een machine in Amsterdam komt
daar 10:56:10Z uit: twee uur verschoven, in elk archief.

Geen enkele test kon dat zien, want de testmachine draait op UTC. En mijn eigen
rondgang-vergelijking plakte er zelf een Z achter, waarmee ik er precies overheen
keek.

toISO leest een zoneloze vorm nu expliciet als UTC. Nieuwe test die alleen onder
een niet-UTC zone iets bewijst; gecontroleerd dat hij onder Europe/Amsterdam
omvalt zonder de fix. Hele suite 577/577 onder zowel UTC als Europe/Amsterdam.

  • Property mode set to 100644
File size: 3.1 KB
RevLine 
[58cfe5f]1#!/usr/bin/env node
2//
3// Importeer een inhoudsarchief in een site (shaer-pmr).
4//
5// node scripts/import-archive.mjs <slug> <archief.zip|map> --dry-run
6// node scripts/import-archive.mjs <slug> <archief.zip|map>
7// node scripts/import-archive.mjs <slug> <archief.zip|map> --overwrite
8//
9// Het formaat staat in docs/EXPORT-FORMAT.md.
10//
11// Standaard wordt een bestaande post met hetzelfde id of dezelfde slug
12// OVERGESLAGEN. Dat maakt de import idempotent en zorgt dat je nooit per ongeluk
13// inhoud vernietigt die er al staat. --overwrite doet het wel, expliciet.
14//
15// Er gaat GEEN Update de fediverse in. Als andere servers een oudere kopie
16// hebben, blijft die daar staan; dat rechttrekken is een uitzending naar iedereen
17// en hoort een aparte, bewuste actie te zijn.
18
[6248497]19import { kiesInstance, eisOrigin } from './instance-env.mjs';
[58cfe5f]20
21const args = process.argv.slice(2);
22const vrij = args.filter((a) => !a.startsWith('-'));
23const [slug, bron] = vrij;
24
25if (!slug || !bron) {
[6248497]26 console.error('gebruik: node scripts/import-archive.mjs <slug> <archief.zip|map> [--data-root <map>] [--env <pad>] [--dry-run] [--overwrite]');
[58cfe5f]27 process.exit(1);
28}
29
[6248497]30// EERST de instance kiezen, DAN pas de service laden -- database.js opent de
31// database bij import. Bij een IMPORT weegt dit zwaarder dan bij een export: in
32// de verkeerde database schrijven is niet terug te draaien.
33const vlag = (naam) => { const i = args.indexOf(naam); return i >= 0 ? (args[i + 1] || null) : null; };
34let gekozen;
35try {
36 gekozen = kiesInstance(slug, { dataRoot: vlag('--data-root'), envPad: vlag('--env') });
37} catch (e) { console.error(e.message); process.exit(1); }
38eisOrigin(gekozen.bron);
39console.log(`instellingen uit: ${gekozen.bron || 'de omgeving'}`);
40console.log(`database : ${process.env.DATABASE_PATH || '(standaard in de code-map)'}`);
41
42const { readArchive, importArchive } = await import('../src/services/ArchiveImportService.js');
43
[58cfe5f]44let files;
45try { files = readArchive(bron); }
46catch (e) { console.error(`kan het archief niet lezen: ${e.message}`); process.exit(1); }
47
48let r;
49try { r = importArchive(files, { slug, dryRun: args.includes('--dry-run'), overwrite: args.includes('--overwrite') }); }
50catch (e) { console.error(`geweigerd: ${e.message}`); process.exit(1); }
51
52console.log(`formaatversie : ${r.formatVersion}`);
53console.log(`herkomst : ${r.origin || '(geen)'}`);
54console.log(`AP-ids : ${r.idsBehouden ? 'BEHOUDEN (zelfde origin)' : 'nieuw (andere origin)'}`);
55console.log(`posts : ${r.posts}${r.overschreven ? `, waarvan ${r.overschreven} overschreven` : ''}`);
56console.log(`overgeslagen : ${r.overgeslagen} (bestonden al)`);
57console.log(`antwoorden : ${r.replies} (alleen-lezen archief)`);
58console.log(`media : ${r.media} teruggezet, ${r.mediaMissing} ontbrekend`);
59
60if (r.gemist.length) {
61 console.log('\nontbrekende media:');
62 for (const m of r.gemist.slice(0, 20)) console.log(` ${m.post} ${m.url}`);
63 if (r.gemist.length > 20) console.log(` ... en nog ${r.gemist.length - 20}`);
64}
65for (const w of r.waarschuwingen) console.log(`\nLET OP: ${w}`);
66
67if (args.includes('--dry-run')) console.log('\n--dry-run: niets geschreven.');
Note: See TracBrowser for help on using the repository browser.