Changeset eb071a7 in Klonkt
- Timestamp:
- 08/14/2026 12:12:58 AM (4 weeks ago)
- Branches:
- main
- Children:
- 919b82d
- Parents:
- 98acb97
- Files:
-
- 4 edited
-
src/services/MigrationService.js (modified) (4 diffs)
-
src/services/i18n.js (modified) (3 diffs)
-
src/views/pages/admin-migrate.ejs (modified) (1 diff)
-
test/fep1580-migration.test.js (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/services/MigrationService.js
r98acb97 reb071a7 84 84 export function alGemigreerd(slug, origin) { 85 85 try { return !!db.prepare('SELECT 1 FROM ap_migration WHERE slug = ? AND origin = ?').get(slug, String(origin)); } catch { return false; } 86 } 87 88 /** 89 * Waar kwam deze bron-URI hier terecht? Null als hij nog niet gemigreerd is. 90 * 91 * Bestaat omdat "al gehad" en "overslaan" niet hetzelfde horen te zijn. Een 92 * tweede ronde na een uitgebreide ingest (hoezen, duur, playlists erbij) moet 93 * de bestaande nummers KUNNEN AANVULLEN in plaats van ze te passeren. Deed hij 94 * dat niet, dan zat je vast: opnieuw ophalen sloeg alles over, en opruimen hielp 95 * niet omdat deze tabel de blokkade in stand hield. 96 */ 97 export function migrationTarget(slug, origin) { 98 try { 99 const r = db.prepare('SELECT target FROM ap_migration WHERE slug = ? AND origin = ?').get(slug, String(origin)); 100 return r ? r.target : null; 101 } catch { return null; } 86 102 } 87 103 … … 346 362 const rapport = { 347 363 bron: bronActor.id, posts: 0, overgeslagen: 0, media: 0, mediaMislukt: 0, 348 blocks: 0, tracksBinnen: 0, tracksMislukt: 0, overgeslagenTracks: 0,364 blocks: 0, tracksBinnen: 0, tracksMislukt: 0, tracksBijgewerkt: 0, overgeslagenTracks: 0, 349 365 playlistsBinnen: 0, playlistsMislukt: 0, waarschuwingen: [], 350 366 }; … … 480 496 if (!a || !a.id) continue; 481 497 if (a.type && a.type !== 'Audio') continue; 482 if (alGemigreerd(site.slug, a.id)) { rapport.overgeslagenTracks++; continue; } 498 // AL BINNEN? Dan AANVULLEN, niet overslaan. Een tweede ronde bestaat 499 // juist omdat er iets bij is gekomen (hoezen, duur, playlists), en een 500 // pull die dan alles passeert laat je met een half resultaat zitten 501 // zonder uitweg: opruimen hielp niet, want deze tabel hield de blokkade 502 // in stand. 503 // 504 // Alleen LEGE velden worden gevuld. Wat jij zelf hebt aangepast blijft 505 // staan; een migratie hoort je correcties niet terug te draaien. 506 const eerder = migrationTarget(site.slug, a.id); 507 if (eerder) { 508 const lokaalId = String(eerder).split('/').pop(); 509 const rij = db.prepare('SELECT id, cover_url, duration, artist FROM audio_tracks WHERE id = ? AND site_id = ?') 510 .get(lokaalId, site.id); 511 if (rij) { 512 trackKaart.set(String(a.id), rij.id); // MOET, anders vinden de playlists hem niet 513 const duur = rij.duration ? null : duurSeconden(a.duration); 514 const artiest = rij.artist ? null : (a.summary || a.artist || null); 515 let hoes = null; 516 const hUrl = (a.icon && (a.icon.url || a.icon)) || (a.image && (a.image.url || a.image)) || null; 517 if (!rij.cover_url && hUrl && /^https?:\/\//i.test(String(hUrl)) && safeFetch && fs && path && mediaRoot) { 518 const h = await haalBijlage(String(hUrl), { 519 safeFetch, mediaRoot, fs, path, maxBytes, 520 headers: signHeaders ? signHeaders(site.slug, String(hUrl), '*/*') : null, 521 }).catch(() => null); 522 if (h) { hoes = h.url; rapport.media++; } 523 } 524 if (duur || artiest || hoes) { 525 db.prepare(`UPDATE audio_tracks SET 526 duration = COALESCE(?, duration), 527 artist = COALESCE(?, artist), 528 cover_url = COALESCE(?, cover_url) 529 WHERE id = ?`).run(duur, artiest, hoes, rij.id); 530 rapport.tracksBijgewerkt++; 531 } else { 532 rapport.overgeslagenTracks++; 533 } 534 continue; 535 } 536 // De rij is weg maar de mapping staat er nog. Dan is opnieuw ophalen 537 // precies wat je wilt, dus we vallen door naar de gewone tak. 538 } 483 539 const bron = a.url && (typeof a.url === 'string' ? a.url : (Array.isArray(a.url) ? (a.url[0] && (a.url[0].href || a.url[0])) : a.url.href)); 484 540 if (!bron || !/^https?:\/\//i.test(String(bron))) { rapport.tracksMislukt++; continue; } … … 549 605 continue; 550 606 } 551 const plId = crypto.randomUUID(); 607 // Bestond hij al? Dan dezelfde rij bijwerken. Zonder deze stap levert 608 // elke tweede ronde een dubbele plaat op. 609 const eerderPl = migrationTarget(site.slug, uri); 610 const plId = (() => { 611 if (!eerderPl) return crypto.randomUUID(); 612 const bestaand = String(eerderPl).split('/').pop(); 613 return db.prepare('SELECT 1 FROM playlists WHERE id = ? AND site_id = ?').get(bestaand, site.id) 614 ? bestaand : crypto.randomUUID(); 615 })(); 552 616 try { 553 db.prepare('INSERT INTO playlists (id, site_id, title, artist, year, kind) VALUES (?,?,?,?,?,?)') 554 .run(plId, site.id, plc.name || 'zonder titel', plc.attributedTo && plc.artist || plc.artist || null, 617 db.prepare(`INSERT INTO playlists (id, site_id, title, artist, year, kind) VALUES (?,?,?,?,?,?) 618 ON CONFLICT(id) DO UPDATE SET title = excluded.title, artist = COALESCE(playlists.artist, excluded.artist)`) 619 .run(plId, site.id, plc.name || 'zonder titel', plc.artist || null, 555 620 plc.year || null, plc['shaer:kind'] || null); 621 // De volgorde opnieuw zetten: die IS de plaat, en een halve 622 // bijgewerkte volgorde is erger dan een verse. 623 db.prepare('DELETE FROM playlist_tracks WHERE playlist_id = ?').run(plId); 556 624 const ins = db.prepare('INSERT OR IGNORE INTO playlist_tracks (playlist_id, track_id, position) VALUES (?,?,?)'); 557 625 nummers.forEach((tid, i) => ins.run(plId, tid, i)); 626 recordMigrated(site.slug, { origin: uri, target: `${me}/ap/playlists/${plId}`, sourceActor: bronActor.id, isPublic: false }); 558 627 rapport.playlistsBinnen++; 559 628 const kwijt = (plc.orderedItems || plc.items || []).length - nummers.length; -
src/services/i18n.js
r98acb97 reb071a7 76 76 'admin.b_media': 'π¬ Media', 'admin.t_media': 'Media', 'admin.media_images': 'Afbeeldingen', 'admin.media_videos': "Video's", 'admin.videos_count': "video's", 'admin.videos_empty': "Nog geen video's geupload.", 'admin.videos_del_confirm': 'Deze video verwijderen?', 'admin.media_count': 'afbeeldingen', 'admin.media_unused': 'ongebruikt', 'admin.media_cleanup': 'Ongebruikt opruimen', 'admin.media_cleanup_confirm': 'Alle ongebruikte afbeeldingen verwijderen?', 'admin.media_empty': 'Nog geen afbeeldingen geΓΌpload.', 'admin.media_copy': 'Kopieer URL', 'admin.media_del_confirm': 'Deze afbeelding verwijderen?', 77 77 'admin.b_playlists': 'π Playlists', 'admin.b_comments': 'π¬ Reacties', 'admin.b_seo': 'π SEO', 78 'admin.b_settings': 'βοΈ Instellingen', "mig.title": "Migreren", "mig.r_tracks_ missing": "{n} nummer(s) zijn NIET aangekomen, want het geluidsbestand ontbrak. Ze zijn met opzet niet aangemaakt: een nummer dat in de lijst staat en niet afspeelt is erger dan een nummer dat er niet is.", "mig.c_tracks": "nummers", "mig.c_playlists": "playlists", "mig.audio_missing": "Let op: van {n} nummer(s) is het geluidsbestand niet te vinden. Die gaan niet mee.", "mig.audio_none": "Let op: deze site heeft muziek, maar er gaat geen enkel nummer mee. Waarschijnlijk staan de bestanden ergens anders dan de database denkt.", "mig.pull_title": "Ophalen bij je oude Klonkt", "mig.pull_hint": "Als je al verhuisd bent, kan deze Klonkt je berichten rechtstreeks bij de oude ophalen. Je hoeft geen code over te typen: de verhuizing zelf is de sleutel, want beide kanten hebben elkaar toen al erkend.", "mig.pull_source": "Adres van je oude account", "mig.pull_source_hint": "Ingevuld vanuit je aliassen. Klopt dit niet, pas het dan aan.", "mig.pull_btn": "Berichten ophalen", "mig.pull_done": "Opgehaald", "mig.pull_failed": "Ophalen lukte niet", "mig.r_blocks": "blokkades overgenomen", "mig.state": "{n} berichten hebben een verwijzing van hun oude adres.", "mig.state_done": "De lijst is compleet.", "mig.state_busy": "De lijst is nog niet compleet.", "mig.e_no_source": "Er is geen oud account bekend. Vul het adres hierboven in.", "mig.e_unreachable": "De oude Klonkt is niet bereikbaar.", "mig.e_not_moved_here": "Dat account is niet naar deze Klonkt verhuisd, dus het geeft ons niets.", "mig.e_no_backreference": "Dit account noemt dat oude adres niet als eigen alias. Zet het eerst bij je aliassen, anders kan niemand zien dat jij het bent.", "mig.e_no_outbox": "De oude Klonkt heeft geen berichtenlijst.", "mig.e_partial": "Halverwege gestopt. Wat binnen is blijft staan; probeer het nog eens.", "mig.e_config": "Deze Klonkt weet zijn eigen adres niet.", "mig.e_crash": "Er ging iets onverwachts mis.", "mig.e_points_at": "Dat account wijst naar:", "mig.lead": "Neem je berichten en media mee naar een andere Klonkt, of haal ze hiernaartoe. Hetzelfde archief dat het serverscript maakt, maar dan hier.", "mig.export_title": "Meenemen", "mig.export_hint": "Dit maakt een zip met je berichten, de reacties erop, en de media die erbij hoort.", "mig.c_posts": "berichten", "mig.c_replies": "reacties", "mig.c_media": "mediabestanden", "mig.c_following": "volgingen", "mig.c_size": "groot", "mig.missing": "Let op: van {n} mediaverwijzing(en) staat het bestand niet meer op schijf. Die gaan dus niet mee.", "mig.too_big": "Dit archief is te groot voor de webinterface. Gebruik scripts/export-archive.mjs op de server.", "mig.export_btn": "Archief downloaden (.zip)", "mig.export_none": "Er valt nog niets te exporteren.", "mig.import_title": "Hierheen halen", "mig.import_hint": "Kies een archief. Hij kijkt eerst wat er zou gebeuren en verandert nog niets.", "mig.file_label": "Archiefbestand (.zip)", "mig.overwrite_label": "Bestaande berichten overschrijven", "mig.overwrite_hint": "Standaard wordt een bericht dat er al staat overgeslagen. Overschrijven verwijdert ook een bericht met dezelfde webadres-naam maar een ander id, en dat komt niet terug.", "mig.check_btn": "Controleren", "mig.check_hint": "Dit verandert nog niets. Je krijgt eerst te zien wat er zou gebeuren.", "mig.r_dry": "Wat er zou gebeuren", "mig.r_done": "Ge\u00efmporteerd", "mig.r_would": "zouden erbij komen", "mig.r_imported": "erbij gekomen", "mig.r_skipped": "overgeslagen (staan er al)", "mig.r_overwritten": "overschreven", "mig.r_media": "mediabestanden", "mig.r_media_missing": "media ontbrak in het archief", "mig.r_new_ids": "Dit archief komt van een ander adres. De berichten krijgen daarom nieuwe adressen en gelden voor de fediverse als nieuwe berichten; reacties die elders naar de oude adressen wijzen komen niet mee.", "mig.r_confirm_hint": "Ziet het er goed uit? Kies hetzelfde bestand nog een keer om het echt te doen.", "mig.r_confirm_btn": "Nu echt importeren", "mig.follows_title": "Wie je volgt", "mig.follows_hint": "Je volglijst zit ook in het archief, en je kunt hem los downloaden en terugzetten bij Connect.", "mig.follows_btn": "Naar Connect", "admin.b_migrate": "\ud83d\udce6 Migreren", 'admin.b_newpost': 'βοΈ Nieuwe post', 'admin.b_look': 'π¨ Uiterlijk',78 'admin.b_settings': 'βοΈ Instellingen', "mig.title": "Migreren", "mig.r_tracks_updated": "nummers aangevuld", "mig.r_tracks_missing": "{n} nummer(s) zijn NIET aangekomen, want het geluidsbestand ontbrak. Ze zijn met opzet niet aangemaakt: een nummer dat in de lijst staat en niet afspeelt is erger dan een nummer dat er niet is.", "mig.c_tracks": "nummers", "mig.c_playlists": "playlists", "mig.audio_missing": "Let op: van {n} nummer(s) is het geluidsbestand niet te vinden. Die gaan niet mee.", "mig.audio_none": "Let op: deze site heeft muziek, maar er gaat geen enkel nummer mee. Waarschijnlijk staan de bestanden ergens anders dan de database denkt.", "mig.pull_title": "Ophalen bij je oude Klonkt", "mig.pull_hint": "Als je al verhuisd bent, kan deze Klonkt je berichten rechtstreeks bij de oude ophalen. Je hoeft geen code over te typen: de verhuizing zelf is de sleutel, want beide kanten hebben elkaar toen al erkend.", "mig.pull_source": "Adres van je oude account", "mig.pull_source_hint": "Ingevuld vanuit je aliassen. Klopt dit niet, pas het dan aan.", "mig.pull_btn": "Berichten ophalen", "mig.pull_done": "Opgehaald", "mig.pull_failed": "Ophalen lukte niet", "mig.r_blocks": "blokkades overgenomen", "mig.state": "{n} berichten hebben een verwijzing van hun oude adres.", "mig.state_done": "De lijst is compleet.", "mig.state_busy": "De lijst is nog niet compleet.", "mig.e_no_source": "Er is geen oud account bekend. Vul het adres hierboven in.", "mig.e_unreachable": "De oude Klonkt is niet bereikbaar.", "mig.e_not_moved_here": "Dat account is niet naar deze Klonkt verhuisd, dus het geeft ons niets.", "mig.e_no_backreference": "Dit account noemt dat oude adres niet als eigen alias. Zet het eerst bij je aliassen, anders kan niemand zien dat jij het bent.", "mig.e_no_outbox": "De oude Klonkt heeft geen berichtenlijst.", "mig.e_partial": "Halverwege gestopt. Wat binnen is blijft staan; probeer het nog eens.", "mig.e_config": "Deze Klonkt weet zijn eigen adres niet.", "mig.e_crash": "Er ging iets onverwachts mis.", "mig.e_points_at": "Dat account wijst naar:", "mig.lead": "Neem je berichten en media mee naar een andere Klonkt, of haal ze hiernaartoe. Hetzelfde archief dat het serverscript maakt, maar dan hier.", "mig.export_title": "Meenemen", "mig.export_hint": "Dit maakt een zip met je berichten, de reacties erop, en de media die erbij hoort.", "mig.c_posts": "berichten", "mig.c_replies": "reacties", "mig.c_media": "mediabestanden", "mig.c_following": "volgingen", "mig.c_size": "groot", "mig.missing": "Let op: van {n} mediaverwijzing(en) staat het bestand niet meer op schijf. Die gaan dus niet mee.", "mig.too_big": "Dit archief is te groot voor de webinterface. Gebruik scripts/export-archive.mjs op de server.", "mig.export_btn": "Archief downloaden (.zip)", "mig.export_none": "Er valt nog niets te exporteren.", "mig.import_title": "Hierheen halen", "mig.import_hint": "Kies een archief. Hij kijkt eerst wat er zou gebeuren en verandert nog niets.", "mig.file_label": "Archiefbestand (.zip)", "mig.overwrite_label": "Bestaande berichten overschrijven", "mig.overwrite_hint": "Standaard wordt een bericht dat er al staat overgeslagen. Overschrijven verwijdert ook een bericht met dezelfde webadres-naam maar een ander id, en dat komt niet terug.", "mig.check_btn": "Controleren", "mig.check_hint": "Dit verandert nog niets. Je krijgt eerst te zien wat er zou gebeuren.", "mig.r_dry": "Wat er zou gebeuren", "mig.r_done": "Ge\u00efmporteerd", "mig.r_would": "zouden erbij komen", "mig.r_imported": "erbij gekomen", "mig.r_skipped": "overgeslagen (staan er al)", "mig.r_overwritten": "overschreven", "mig.r_media": "mediabestanden", "mig.r_media_missing": "media ontbrak in het archief", "mig.r_new_ids": "Dit archief komt van een ander adres. De berichten krijgen daarom nieuwe adressen en gelden voor de fediverse als nieuwe berichten; reacties die elders naar de oude adressen wijzen komen niet mee.", "mig.r_confirm_hint": "Ziet het er goed uit? Kies hetzelfde bestand nog een keer om het echt te doen.", "mig.r_confirm_btn": "Nu echt importeren", "mig.follows_title": "Wie je volgt", "mig.follows_hint": "Je volglijst zit ook in het archief, en je kunt hem los downloaden en terugzetten bij Connect.", "mig.follows_btn": "Naar Connect", "admin.b_migrate": "\ud83d\udce6 Migreren", 'admin.b_newpost': 'βοΈ Nieuwe post', 'admin.b_look': 'π¨ Uiterlijk', 79 79 'admin.t_admin': 'Beheer', 'admin.t_settings': 'Instellingen', 'admin.t_audio': 'Audiotracks', 'admin.t_epk': 'Perskit bewerken', 'admin.t_newsletter': 'Nieuwsbrief', 'admin.t_playlists': 'Afspeellijsten', 'admin.t_seo': 'SEO', 'admin.t_shows': 'Agenda', 'admin.t_sites': 'Sites', 'admin.t_newsite': 'Nieuwe site', 'admin.t_editsite': 'Bewerken: {title}', 'admin.t_stats': 'Statistieken', 'admin.t_updates': 'Updates', 'admin.t_users': 'Gebruikers', 'admin.t_hub': 'Mijn Klonkt Hub', 'admin.t_manual': 'Handleiding', 'aset.premium_gate': '{feature} is premium β koppel Patreon in Beheer β Instellingen.', 80 80 'admin.b_makesite': 'π¨ Maak je site aan', 'admin.b_circle': 'π Cirkel', 'admin.b_stats': 'π Statistieken', … … 1044 1044 'admin.b_media': 'π¬ Media', 'admin.t_media': 'Media', 'admin.media_images': 'Images', 'admin.media_videos': 'Videos', 'admin.videos_count': 'videos', 'admin.videos_empty': 'No videos uploaded yet.', 'admin.videos_del_confirm': 'Delete this video?', 'admin.media_count': 'images', 'admin.media_unused': 'unused', 'admin.media_cleanup': 'Delete unused', 'admin.media_cleanup_confirm': 'Delete all unused images?', 'admin.media_empty': 'No images uploaded yet.', 'admin.media_copy': 'Copy URL', 'admin.media_del_confirm': 'Delete this image?', 1045 1045 'admin.b_playlists': 'π Playlists', 'admin.b_comments': 'π¬ Comments', 'admin.b_seo': 'π SEO', 1046 'admin.b_settings': 'βοΈ Settings', "mig.title": "Migrate", "mig.r_tracks_ missing": "{n} track(s) did NOT arrive, because the audio file was absent. They were deliberately not created: a track that sits in the list and will not play is worse than one that is missing.", "mig.c_tracks": "tracks", "mig.c_playlists": "playlists", "mig.audio_missing": "Note: for {n} track(s) the audio file cannot be found. Those will not travel.", "mig.audio_none": "Note: this site has music, but not a single track is travelling. The files are probably somewhere other than the database thinks.", "mig.pull_title": "Fetch from your old Klonkt", "mig.pull_hint": "If you already moved, this Klonkt can fetch your posts straight from the old one. No code to type over: the move itself is the key, because both sides already recognised each other back then.", "mig.pull_source": "Address of your old account", "mig.pull_source_hint": "Filled in from your aliases. Change it if this is not right.", "mig.pull_btn": "Fetch posts", "mig.pull_done": "Fetched", "mig.pull_failed": "Fetching did not work", "mig.r_blocks": "blocks carried over", "mig.state": "{n} posts have a pointer from their old address.", "mig.state_done": "The list is complete.", "mig.state_busy": "The list is not complete yet.", "mig.e_no_source": "No old account is known. Fill in the address above.", "mig.e_unreachable": "The old Klonkt cannot be reached.", "mig.e_not_moved_here": "That account did not move to this Klonkt, so it gives us nothing.", "mig.e_no_backreference": "This account does not list that old address as its own alias. Add it to your aliases first, otherwise nobody can see it is you.", "mig.e_no_outbox": "The old Klonkt has no post list.", "mig.e_partial": "Stopped halfway. What arrived stays; try again.", "mig.e_config": "This Klonkt does not know its own address.", "mig.e_crash": "Something unexpected went wrong.", "mig.e_points_at": "That account points at:", "mig.lead": "Take your posts and media to another Klonkt, or bring them here. The same archive the server script makes, but from here.", "mig.export_title": "Take with you", "mig.export_hint": "This builds a zip with your posts, their replies, and the media that belongs to them.", "mig.c_posts": "posts", "mig.c_replies": "replies", "mig.c_media": "media files", "mig.c_following": "follows", "mig.c_size": "in size", "mig.missing": "Note: for {n} media reference(s) the file is no longer on disk. Those will not travel.", "mig.too_big": "This archive is too large for the web interface. Use scripts/export-archive.mjs on the server.", "mig.export_btn": "Download archive (.zip)", "mig.export_none": "Nothing to export yet.", "mig.import_title": "Bring here", "mig.import_hint": "Pick an archive. It first shows what would happen and changes nothing yet.", "mig.file_label": "Archive file (.zip)", "mig.overwrite_label": "Overwrite existing posts", "mig.overwrite_hint": "By default a post that already exists is skipped. Overwriting also deletes a post with the same web address but a different id, and that does not come back.", "mig.check_btn": "Check", "mig.check_hint": "This changes nothing yet. You will see what would happen first.", "mig.r_dry": "What would happen", "mig.r_done": "Imported", "mig.r_would": "would be added", "mig.r_imported": "added", "mig.r_skipped": "skipped (already here)", "mig.r_overwritten": "overwritten", "mig.r_media": "media files", "mig.r_media_missing": "media missing from the archive", "mig.r_new_ids": "This archive comes from another address. The posts get new addresses and count as new posts on the fediverse; replies elsewhere pointing at the old addresses will not follow.", "mig.r_confirm_hint": "Looks right? Pick the same file once more to actually do it.", "mig.r_confirm_btn": "Import for real", "mig.follows_title": "Who you follow", "mig.follows_hint": "Your following list is in the archive too, and you can download and restore it separately under Connect.", "mig.follows_btn": "Go to Connect", "admin.b_migrate": "\ud83d\udce6 Migrate", 'admin.b_newpost': 'βοΈ New post', 'admin.b_look': 'π¨ Appearance',1046 'admin.b_settings': 'βοΈ Settings', "mig.title": "Migrate", "mig.r_tracks_updated": "tracks completed", "mig.r_tracks_missing": "{n} track(s) did NOT arrive, because the audio file was absent. They were deliberately not created: a track that sits in the list and will not play is worse than one that is missing.", "mig.c_tracks": "tracks", "mig.c_playlists": "playlists", "mig.audio_missing": "Note: for {n} track(s) the audio file cannot be found. Those will not travel.", "mig.audio_none": "Note: this site has music, but not a single track is travelling. The files are probably somewhere other than the database thinks.", "mig.pull_title": "Fetch from your old Klonkt", "mig.pull_hint": "If you already moved, this Klonkt can fetch your posts straight from the old one. No code to type over: the move itself is the key, because both sides already recognised each other back then.", "mig.pull_source": "Address of your old account", "mig.pull_source_hint": "Filled in from your aliases. Change it if this is not right.", "mig.pull_btn": "Fetch posts", "mig.pull_done": "Fetched", "mig.pull_failed": "Fetching did not work", "mig.r_blocks": "blocks carried over", "mig.state": "{n} posts have a pointer from their old address.", "mig.state_done": "The list is complete.", "mig.state_busy": "The list is not complete yet.", "mig.e_no_source": "No old account is known. Fill in the address above.", "mig.e_unreachable": "The old Klonkt cannot be reached.", "mig.e_not_moved_here": "That account did not move to this Klonkt, so it gives us nothing.", "mig.e_no_backreference": "This account does not list that old address as its own alias. Add it to your aliases first, otherwise nobody can see it is you.", "mig.e_no_outbox": "The old Klonkt has no post list.", "mig.e_partial": "Stopped halfway. What arrived stays; try again.", "mig.e_config": "This Klonkt does not know its own address.", "mig.e_crash": "Something unexpected went wrong.", "mig.e_points_at": "That account points at:", "mig.lead": "Take your posts and media to another Klonkt, or bring them here. The same archive the server script makes, but from here.", "mig.export_title": "Take with you", "mig.export_hint": "This builds a zip with your posts, their replies, and the media that belongs to them.", "mig.c_posts": "posts", "mig.c_replies": "replies", "mig.c_media": "media files", "mig.c_following": "follows", "mig.c_size": "in size", "mig.missing": "Note: for {n} media reference(s) the file is no longer on disk. Those will not travel.", "mig.too_big": "This archive is too large for the web interface. Use scripts/export-archive.mjs on the server.", "mig.export_btn": "Download archive (.zip)", "mig.export_none": "Nothing to export yet.", "mig.import_title": "Bring here", "mig.import_hint": "Pick an archive. It first shows what would happen and changes nothing yet.", "mig.file_label": "Archive file (.zip)", "mig.overwrite_label": "Overwrite existing posts", "mig.overwrite_hint": "By default a post that already exists is skipped. Overwriting also deletes a post with the same web address but a different id, and that does not come back.", "mig.check_btn": "Check", "mig.check_hint": "This changes nothing yet. You will see what would happen first.", "mig.r_dry": "What would happen", "mig.r_done": "Imported", "mig.r_would": "would be added", "mig.r_imported": "added", "mig.r_skipped": "skipped (already here)", "mig.r_overwritten": "overwritten", "mig.r_media": "media files", "mig.r_media_missing": "media missing from the archive", "mig.r_new_ids": "This archive comes from another address. The posts get new addresses and count as new posts on the fediverse; replies elsewhere pointing at the old addresses will not follow.", "mig.r_confirm_hint": "Looks right? Pick the same file once more to actually do it.", "mig.r_confirm_btn": "Import for real", "mig.follows_title": "Who you follow", "mig.follows_hint": "Your following list is in the archive too, and you can download and restore it separately under Connect.", "mig.follows_btn": "Go to Connect", "admin.b_migrate": "\ud83d\udce6 Migrate", 'admin.b_newpost': 'βοΈ New post', 'admin.b_look': 'π¨ Appearance', 1047 1047 'admin.t_admin': 'Admin', 'admin.t_settings': 'Settings', 'admin.t_audio': 'Audio tracks', 'admin.t_epk': 'Edit press kit', 'admin.t_newsletter': 'Newsletter', 'admin.t_playlists': 'Playlists', 'admin.t_seo': 'SEO', 'admin.t_shows': 'Agenda', 'admin.t_sites': 'Sites', 'admin.t_newsite': 'New site', 'admin.t_editsite': 'Edit: {title}', 'admin.t_stats': 'Statistics', 'admin.t_updates': 'Updates', 'admin.t_users': 'Users', 'admin.t_hub': 'My Klonkt Hub', 'admin.t_manual': 'Manual', 'aset.premium_gate': '{feature} is a premium feature β connect Patreon in Admin β Settings.', 1048 1048 'admin.b_makesite': 'π¨ Create your site', 'admin.b_circle': 'π Circle', 'admin.b_stats': 'π Statistics', … … 2006 2006 'admin.b_media': 'π¬ Medien', 'admin.t_media': 'Medien', 'admin.media_images': 'Bilder', 'admin.media_videos': 'Videos', 'admin.videos_count': 'Videos', 'admin.videos_empty': 'Noch keine Videos hochgeladen.', 'admin.videos_del_confirm': 'Dieses Video lΓΆschen?', 'admin.media_count': 'Bilder', 'admin.media_unused': 'ungenutzt', 'admin.media_cleanup': 'Ungenutzte lΓΆschen', 'admin.media_cleanup_confirm': 'Alle ungenutzten Bilder lΓΆschen?', 'admin.media_empty': 'Noch keine Bilder hochgeladen.', 'admin.media_copy': 'URL kopieren', 'admin.media_del_confirm': 'Dieses Bild lΓΆschen?', 2007 2007 'admin.b_playlists': 'π Playlists', 'admin.b_comments': 'π¬ Kommentare', 'admin.b_seo': 'π SEO', 2008 'admin.b_settings': 'βοΈ Einstellungen', "mig.title": "Migrieren", "mig.r_tracks_ missing": "{n} Titel sind NICHT angekommen, weil die Audiodatei fehlte. Sie wurden bewusst nicht angelegt: ein Titel, der in der Liste steht und nicht spielt, ist schlimmer als ein fehlender.", "mig.c_tracks": "Titel", "mig.c_playlists": "Playlists", "mig.audio_missing": "Achtung: Bei {n} Titel(n) ist die Audiodatei nicht auffindbar. Die kommen nicht mit.", "mig.audio_none": "Achtung: Diese Seite hat Musik, aber es kommt kein einziger Titel mit. Die Dateien liegen vermutlich woanders als die Datenbank denkt.", "mig.pull_title": "Von deinem alten Klonkt holen", "mig.pull_hint": "Wenn du schon umgezogen bist, kann dieses Klonkt deine Beitr\u00e4ge direkt beim alten holen. Kein Code zum Abtippen: der Umzug selbst ist der Schl\u00fcssel, denn beide Seiten haben sich damals schon anerkannt.", "mig.pull_source": "Adresse deines alten Kontos", "mig.pull_source_hint": "Aus deinen Aliassen eingetragen. Stimmt das nicht, \u00e4ndere es.", "mig.pull_btn": "Beitr\u00e4ge holen", "mig.pull_done": "Geholt", "mig.pull_failed": "Holen hat nicht geklappt", "mig.r_blocks": "Blockierungen \u00fcbernommen", "mig.state": "{n} Beitr\u00e4ge haben einen Verweis von ihrer alten Adresse.", "mig.state_done": "Die Liste ist vollst\u00e4ndig.", "mig.state_busy": "Die Liste ist noch nicht vollst\u00e4ndig.", "mig.e_no_source": "Es ist kein altes Konto bekannt. Trage die Adresse oben ein.", "mig.e_unreachable": "Das alte Klonkt ist nicht erreichbar.", "mig.e_not_moved_here": "Dieses Konto ist nicht zu diesem Klonkt umgezogen, also gibt es uns nichts.", "mig.e_no_backreference": "Dieses Konto f\u00fchrt die alte Adresse nicht als eigenen Alias. Trage sie erst bei deinen Aliassen ein, sonst kann niemand sehen, dass du es bist.", "mig.e_no_outbox": "Das alte Klonkt hat keine Beitragsliste.", "mig.e_partial": "Auf halbem Weg gestoppt. Was da ist, bleibt; versuche es noch einmal.", "mig.e_config": "Dieses Klonkt kennt seine eigene Adresse nicht.", "mig.e_crash": "Etwas Unerwartetes ist schiefgegangen.", "mig.e_points_at": "Dieses Konto verweist auf:", "mig.lead": "Nimm deine Beitr\u00e4ge und Medien zu einem anderen Klonkt mit, oder hole sie hierher. Dasselbe Archiv wie das Server-Skript, nur von hier aus.", "mig.export_title": "Mitnehmen", "mig.export_hint": "Das erstellt ein Zip mit deinen Beitr\u00e4gen, den Antworten darauf und den zugeh\u00f6rigen Medien.", "mig.c_posts": "Beitr\u00e4ge", "mig.c_replies": "Antworten", "mig.c_media": "Mediendateien", "mig.c_following": "Folge ich", "mig.c_size": "gro\u00df", "mig.missing": "Achtung: Bei {n} Medienverweis(en) liegt die Datei nicht mehr auf der Platte. Die kommen nicht mit.", "mig.too_big": "Dieses Archiv ist zu gro\u00df f\u00fcr die Weboberfl\u00e4che. Nutze scripts/export-archive.mjs auf dem Server.", "mig.export_btn": "Archiv herunterladen (.zip)", "mig.export_none": "Noch nichts zu exportieren.", "mig.import_title": "Hierher holen", "mig.import_hint": "W\u00e4hle ein Archiv. Es zeigt zuerst, was passieren w\u00fcrde, und \u00e4ndert noch nichts.", "mig.file_label": "Archivdatei (.zip)", "mig.overwrite_label": "Vorhandene Beitr\u00e4ge \u00fcberschreiben", "mig.overwrite_hint": "Standardm\u00e4\u00dfig wird ein bereits vorhandener Beitrag \u00fcbersprungen. \u00dcberschreiben l\u00f6scht auch einen Beitrag mit derselben Webadresse aber anderer id, und der kommt nicht zur\u00fcck.", "mig.check_btn": "Pr\u00fcfen", "mig.check_hint": "Das \u00e4ndert noch nichts. Du siehst zuerst, was passieren w\u00fcrde.", "mig.r_dry": "Was passieren w\u00fcrde", "mig.r_done": "Importiert", "mig.r_would": "k\u00e4men dazu", "mig.r_imported": "dazugekommen", "mig.r_skipped": "\u00fcbersprungen (schon vorhanden)", "mig.r_overwritten": "\u00fcberschrieben", "mig.r_media": "Mediendateien", "mig.r_media_missing": "Medien fehlten im Archiv", "mig.r_new_ids": "Dieses Archiv kommt von einer anderen Adresse. Die Beitr\u00e4ge bekommen neue Adressen und gelten im Fediverse als neue Beitr\u00e4ge; Antworten anderswo auf die alten Adressen kommen nicht mit.", "mig.r_confirm_hint": "Sieht gut aus? W\u00e4hle dieselbe Datei noch einmal, um es wirklich zu tun.", "mig.r_confirm_btn": "Jetzt wirklich importieren", "mig.follows_title": "Wem du folgst", "mig.follows_hint": "Deine Folgeliste ist auch im Archiv, und du kannst sie unter Connect separat herunterladen und zur\u00fcckspielen.", "mig.follows_btn": "Zu Connect", "admin.b_migrate": "\ud83d\udce6 Migrieren", 'admin.b_newpost': 'βοΈ Neuer Beitrag', 'admin.b_look': 'π¨ Aussehen',2008 'admin.b_settings': 'βοΈ Einstellungen', "mig.title": "Migrieren", "mig.r_tracks_updated": "Titel erg\u00e4nzt", "mig.r_tracks_missing": "{n} Titel sind NICHT angekommen, weil die Audiodatei fehlte. Sie wurden bewusst nicht angelegt: ein Titel, der in der Liste steht und nicht spielt, ist schlimmer als ein fehlender.", "mig.c_tracks": "Titel", "mig.c_playlists": "Playlists", "mig.audio_missing": "Achtung: Bei {n} Titel(n) ist die Audiodatei nicht auffindbar. Die kommen nicht mit.", "mig.audio_none": "Achtung: Diese Seite hat Musik, aber es kommt kein einziger Titel mit. Die Dateien liegen vermutlich woanders als die Datenbank denkt.", "mig.pull_title": "Von deinem alten Klonkt holen", "mig.pull_hint": "Wenn du schon umgezogen bist, kann dieses Klonkt deine Beitr\u00e4ge direkt beim alten holen. Kein Code zum Abtippen: der Umzug selbst ist der Schl\u00fcssel, denn beide Seiten haben sich damals schon anerkannt.", "mig.pull_source": "Adresse deines alten Kontos", "mig.pull_source_hint": "Aus deinen Aliassen eingetragen. Stimmt das nicht, \u00e4ndere es.", "mig.pull_btn": "Beitr\u00e4ge holen", "mig.pull_done": "Geholt", "mig.pull_failed": "Holen hat nicht geklappt", "mig.r_blocks": "Blockierungen \u00fcbernommen", "mig.state": "{n} Beitr\u00e4ge haben einen Verweis von ihrer alten Adresse.", "mig.state_done": "Die Liste ist vollst\u00e4ndig.", "mig.state_busy": "Die Liste ist noch nicht vollst\u00e4ndig.", "mig.e_no_source": "Es ist kein altes Konto bekannt. Trage die Adresse oben ein.", "mig.e_unreachable": "Das alte Klonkt ist nicht erreichbar.", "mig.e_not_moved_here": "Dieses Konto ist nicht zu diesem Klonkt umgezogen, also gibt es uns nichts.", "mig.e_no_backreference": "Dieses Konto f\u00fchrt die alte Adresse nicht als eigenen Alias. Trage sie erst bei deinen Aliassen ein, sonst kann niemand sehen, dass du es bist.", "mig.e_no_outbox": "Das alte Klonkt hat keine Beitragsliste.", "mig.e_partial": "Auf halbem Weg gestoppt. Was da ist, bleibt; versuche es noch einmal.", "mig.e_config": "Dieses Klonkt kennt seine eigene Adresse nicht.", "mig.e_crash": "Etwas Unerwartetes ist schiefgegangen.", "mig.e_points_at": "Dieses Konto verweist auf:", "mig.lead": "Nimm deine Beitr\u00e4ge und Medien zu einem anderen Klonkt mit, oder hole sie hierher. Dasselbe Archiv wie das Server-Skript, nur von hier aus.", "mig.export_title": "Mitnehmen", "mig.export_hint": "Das erstellt ein Zip mit deinen Beitr\u00e4gen, den Antworten darauf und den zugeh\u00f6rigen Medien.", "mig.c_posts": "Beitr\u00e4ge", "mig.c_replies": "Antworten", "mig.c_media": "Mediendateien", "mig.c_following": "Folge ich", "mig.c_size": "gro\u00df", "mig.missing": "Achtung: Bei {n} Medienverweis(en) liegt die Datei nicht mehr auf der Platte. Die kommen nicht mit.", "mig.too_big": "Dieses Archiv ist zu gro\u00df f\u00fcr die Weboberfl\u00e4che. Nutze scripts/export-archive.mjs auf dem Server.", "mig.export_btn": "Archiv herunterladen (.zip)", "mig.export_none": "Noch nichts zu exportieren.", "mig.import_title": "Hierher holen", "mig.import_hint": "W\u00e4hle ein Archiv. Es zeigt zuerst, was passieren w\u00fcrde, und \u00e4ndert noch nichts.", "mig.file_label": "Archivdatei (.zip)", "mig.overwrite_label": "Vorhandene Beitr\u00e4ge \u00fcberschreiben", "mig.overwrite_hint": "Standardm\u00e4\u00dfig wird ein bereits vorhandener Beitrag \u00fcbersprungen. \u00dcberschreiben l\u00f6scht auch einen Beitrag mit derselben Webadresse aber anderer id, und der kommt nicht zur\u00fcck.", "mig.check_btn": "Pr\u00fcfen", "mig.check_hint": "Das \u00e4ndert noch nichts. Du siehst zuerst, was passieren w\u00fcrde.", "mig.r_dry": "Was passieren w\u00fcrde", "mig.r_done": "Importiert", "mig.r_would": "k\u00e4men dazu", "mig.r_imported": "dazugekommen", "mig.r_skipped": "\u00fcbersprungen (schon vorhanden)", "mig.r_overwritten": "\u00fcberschrieben", "mig.r_media": "Mediendateien", "mig.r_media_missing": "Medien fehlten im Archiv", "mig.r_new_ids": "Dieses Archiv kommt von einer anderen Adresse. Die Beitr\u00e4ge bekommen neue Adressen und gelten im Fediverse als neue Beitr\u00e4ge; Antworten anderswo auf die alten Adressen kommen nicht mit.", "mig.r_confirm_hint": "Sieht gut aus? W\u00e4hle dieselbe Datei noch einmal, um es wirklich zu tun.", "mig.r_confirm_btn": "Jetzt wirklich importieren", "mig.follows_title": "Wem du folgst", "mig.follows_hint": "Deine Folgeliste ist auch im Archiv, und du kannst sie unter Connect separat herunterladen und zur\u00fcckspielen.", "mig.follows_btn": "Zu Connect", "admin.b_migrate": "\ud83d\udce6 Migrieren", 'admin.b_newpost': 'βοΈ Neuer Beitrag', 'admin.b_look': 'π¨ Aussehen', 2009 2009 'admin.t_admin': 'Verwaltung', 'admin.t_settings': 'Einstellungen', 'admin.t_audio': 'Audiotracks', 'admin.t_epk': 'Pressemappe bearbeiten', 'admin.t_newsletter': 'Newsletter', 'admin.t_playlists': 'Playlists', 'admin.t_seo': 'SEO', 'admin.t_shows': 'Termine', 'admin.t_sites': 'Sites', 'admin.t_newsite': 'Neue Site', 'admin.t_editsite': 'Bearbeiten: {title}', 'admin.t_stats': 'Statistiken', 'admin.t_updates': 'Updates', 'admin.t_users': 'Benutzer', 'admin.t_hub': 'Mein Klonkt Hub', 'admin.t_manual': 'Handbuch', 'aset.premium_gate': '{feature} ist eine Premium-Funktion β verbinde Patreon in Verwaltung β Einstellungen.', 2010 2010 'admin.b_makesite': 'π¨ Seite erstellen', 'admin.b_circle': 'π Kreis', 'admin.b_stats': 'π Statistik', -
src/views/pages/admin-migrate.ejs
r98acb97 reb071a7 82 82 <% if (haalVerslag.blocks) { %><li><strong><%= haalVerslag.blocks %></strong> <%= t('mig.r_blocks') %></li><% } %> 83 83 <% if (haalVerslag.tracksBinnen) { %><li><strong><%= haalVerslag.tracksBinnen %></strong> <%= t('mig.c_tracks') %></li><% } %> 84 <%# Aangevuld telt apart van nieuw. Een tweede ronde die "0 erbij" 85 meldt terwijl hij drie nummers compleet maakte, leest als niets 86 gedaan. %> 87 <% if (haalVerslag.tracksBijgewerkt) { %><li><strong><%= haalVerslag.tracksBijgewerkt %></strong> <%= t('mig.r_tracks_updated') %></li><% } %> 88 <% if (haalVerslag.playlistsBinnen) { %><li><strong><%= haalVerslag.playlistsBinnen %></strong> <%= t('mig.c_playlists') %></li><% } %> 84 89 </ul> 85 90 <% if (haalVerslag.tracksMislukt) { %> -
test/fep1580-migration.test.js
r98acb97 reb071a7 398 398 }); 399 399 400 test('een tweede ronde VULT AAN en slaat niet over', async () => { 401 // De val die Robin bijna in liep: de eerste versie van de ingest onthield per 402 // bron-URI "al gehad" en passeerde die daarna altijd. Kwam er later iets bij 403 // (hoezen, duur, playlists), dan kon je opnieuw drukken zoveel je wilde en 404 // gebeurde er niets. Opruimen hielp ook niet, want ap_migration hield de 405 // blokkade in stand. Dus: aanvullen, niet overslaan. 406 const s = site({ aliases: [BRON] }); 407 const AUDIO = `${BRON}/audio/x.mp3`; 408 const HOES = `${BRON}/media/hoes.png`; 409 const maakKaart = (metHoes) => new Map([ 410 [BRON, { id: BRON, type: 'Person', movedTo: IK, outbox: `${BRON}/outbox`, streams: [`${BRON}/tracks`] }], 411 [`${BRON}/outbox`, { type: 'OrderedCollection', orderedItems: [] }], 412 [`${BRON}/tracks`, { 413 type: 'OrderedCollection', 414 orderedItems: [{ 415 id: `${BRON}/tracks/t1`, type: 'Audio', name: 'Nummer', summary: 'Robo', duration: 'PT212S', 416 url: [{ type: 'Link', href: AUDIO, mediaType: 'audio/mpeg' }], 417 ...(metHoes ? { icon: { type: 'Image', url: HOES } } : {}), 418 }], 419 }], 420 ]); 421 const gehaald = []; 422 const deps = (metHoes) => ({ 423 getJson: async (_slug, url) => maakKaart(metHoes).get(url) || null, 424 noteId: (b, id) => `${b}/ap/notes/${id}`, 425 noteVisibility: AP.noteVisibility, 426 audioRoot: '/nep/audio', mediaRoot: '/nep/media', 427 signHeaders: () => ({ Signature: 'nep' }), 428 safeFetch: async (url) => { 429 gehaald.push(url); 430 return { ok: true, arrayBuffer: async () => Buffer.from('x'), headers: { get: () => 'audio/mpeg' } }; 431 }, 432 fs: { mkdirSync() {}, writeFileSync() {} }, 433 path, 434 }); 435 436 // Ronde 1: zonder hoes, zoals de eerste uitrol. 437 const r1 = await stil(() => Mig.ingestFromSource(s, { deps: deps(false) })); 438 assert.equal(r1.tracksBinnen, 1); 439 const na1 = db.prepare('SELECT id, cover_url, duration FROM audio_tracks').get(); 440 assert.equal(na1.cover_url, null); 441 assert.equal(na1.duration, 212, 'PT212S hoort 212 seconden te worden'); 442 443 // Ronde 2: nu MET hoes. Hij moet aanvullen, niet passeren en niet verdubbelen. 444 const voor = gehaald.length; 445 const r2 = await stil(() => Mig.ingestFromSource(s, { deps: deps(true) })); 446 assert.equal(r2.tracksBinnen, 0, 'er komt niets nieuws bij'); 447 assert.equal(r2.tracksBijgewerkt, 1, 'maar het bestaande nummer wordt wel aangevuld'); 448 assert.equal(db.prepare('SELECT COUNT(*) n FROM audio_tracks').get().n, 1, 'geen dubbele'); 449 const na2 = db.prepare('SELECT id, cover_url FROM audio_tracks').get(); 450 assert.equal(na2.id, na1.id, 'dezelfde rij, niet een nieuwe'); 451 assert.ok(na2.cover_url, 'en de hoes is er nu wel'); 452 assert.ok(!gehaald.slice(voor).includes(AUDIO), 'het geluidsbestand wordt NIET opnieuw gedownload'); 453 454 // Ronde 3: alles compleet, dus er valt niets meer aan te vullen. 455 const r3 = await stil(() => Mig.ingestFromSource(s, { deps: deps(true) })); 456 assert.equal(r3.tracksBijgewerkt, 0); 457 assert.equal(r3.overgeslagenTracks, 1); 458 }); 459 400 460 test('een niet-publiek bericht komt wel mee maar niet in de publieke tabel', async () => { 401 461 const s = site({ aliases: [BRON] });
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)