Changeset 98acb97 in Klonkt for src/services/MigrationService.js
- Timestamp:
- 08/14/2026 12:03:55 AM (4 weeks ago)
- Branches:
- main
- Children:
- eb071a7
- Parents:
- 9529d7b
- File:
-
- 1 edited
-
src/services/MigrationService.js (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/services/MigrationService.js
r9529d7b r98acb97 219 219 const AFBEELDING = /^image\//i; 220 220 221 /** AS2 geeft de duur als ISO-8601 ("PT212S"), de database wil seconden. */ 222 function duurSeconden(v) { 223 if (v == null) return null; 224 if (typeof v === 'number') return Math.round(v) || null; 225 const m = /^P(?:.*?T)?(?:(\d+)H)?(?:(\d+)M)?(?:([\d.]+)S)?$/.exec(String(v)); 226 if (!m) { const n = Number(v); return Number.isFinite(n) && n > 0 ? Math.round(n) : null; } 227 const sec = (Number(m[1]) || 0) * 3600 + (Number(m[2]) || 0) * 60 + (Number(m[3]) || 0); 228 return sec > 0 ? Math.round(sec) : null; 229 } 230 221 231 /** 222 232 * De titel terugwinnen uit de content. … … 336 346 const rapport = { 337 347 bron: bronActor.id, posts: 0, overgeslagen: 0, media: 0, mediaMislukt: 0, 338 blocks: 0, tracksBinnen: 0, tracksMislukt: 0, overgeslagenTracks: 0, waarschuwingen: [], 348 blocks: 0, tracksBinnen: 0, tracksMislukt: 0, overgeslagenTracks: 0, 349 playlistsBinnen: 0, playlistsMislukt: 0, waarschuwingen: [], 339 350 }; 340 351 … … 459 470 // geldt voor de bestanden zelf, die anders achter de gated audio-route 460 471 // blijven. 472 const trackKaart = new Map(); // bron-URI van een nummer -> ons nieuwe id 461 473 const streams = [].concat(bronActor.streams || []).filter((u) => typeof u === 'string'); 462 474 const tracksUrl = streams.find((u) => /\/tracks\/?$/.test(u)); … … 480 492 continue; // dezelfde regel als bij de zip: geen bestand, geen track 481 493 } 494 // De hoes. Die reisde als URL wel mee en als bestand niet, dus kwam een 495 // nummer aan met een verwijzing naar een plaatje dat er niet is. 496 let hoes = null; 497 const hoesUrl = (a.icon && (a.icon.url || a.icon)) || (a.image && (a.image.url || a.image)) || null; 498 if (hoesUrl && /^https?:\/\//i.test(String(hoesUrl))) { 499 const h = await haalBijlage(String(hoesUrl), { 500 safeFetch, mediaRoot, fs, path, maxBytes, 501 headers: signHeaders ? signHeaders(site.slug, String(hoesUrl), '*/*') : null, 502 }).catch(() => null); 503 if (h) { hoes = h.url; rapport.media++; } 504 else rapport.waarschuwingen.push(`hoes niet opgehaald: ${a.name || hoesUrl}`); 505 } 482 506 const trackId = crypto.randomUUID(); 483 507 const mediaId = crypto.randomUUID(); … … 485 509 db.prepare('INSERT INTO media (id, site_id, filename, mime_type, size, storage_path) VALUES (?,?,?,?,?,?)') 486 510 .run(mediaId, site.id, g.filename, g.mediaType, g.size, g.storage_path); 487 db.prepare(`INSERT INTO audio_tracks (id, site_id, title, artist, album, duration, media_id, fedi_open)488 VALUES (?,?,?,?,?,?,?, 0)`)489 .run(trackId, site.id, a.name || 'zonder titel', a. artist || null, a.album || null,490 Number(a.duration) || null, mediaId);511 db.prepare(`INSERT INTO audio_tracks (id, site_id, title, artist, album, duration, media_id, cover_url, fedi_open) 512 VALUES (?,?,?,?,?,?,?,?,0)`) 513 .run(trackId, site.id, a.name || 'zonder titel', a.summary || a.artist || null, a.album || null, 514 duurSeconden(a.duration), mediaId, hoes); 491 515 recordMigrated(site.slug, { origin: a.id, target: `${me}/ap/tracks/${trackId}`, sourceActor: bronActor.id, isPublic: false }); 516 trackKaart.set(String(a.id), trackId); 492 517 rapport.tracksBinnen++; 493 518 } catch (e) { … … 499 524 rapport.waarschuwingen.push('muziekbibliotheek overgeslagen: geen audiomap meegegeven'); 500 525 } 526 527 // ── De playlists ────────────────────────────────────────────── 528 // 529 // Los van de nummers, want de VOLGORDE is de playlist. Die staat nergens 530 // anders: haal je alleen de tracks op, dan heb je wel alle muziek en geen 531 // enkele plaat. De bron geeft ons de volledige lijst omdat we de doel-actor 532 // zijn; anders zaten er alleen de opengezette nummers in en kreeg je een 533 // plaat met gaten. 534 const plUrl = streams.find((u) => /\/playlists\/?$/.test(u)); 535 if (plUrl && trackKaart.size) { 536 const coll = await getJson(site.slug, plUrl); 537 const lijst = (coll && (coll.orderedItems || coll.items)) || []; 538 for (const p of (Array.isArray(lijst) ? lijst : []).slice(0, 200)) { 539 const uri = typeof p === 'string' ? p : (p && p.id); 540 if (!uri) continue; 541 const plc = typeof p === 'object' && (p.orderedItems || p.items) ? p : await getJson(site.slug, uri); 542 if (!plc) { rapport.playlistsMislukt++; continue; } 543 const nummers = (plc.orderedItems || plc.items || []) 544 .map((x) => (x && typeof x === 'object' ? x.id : x)) 545 .map((id) => trackKaart.get(String(id))) 546 .filter(Boolean); 547 if (!nummers.length) { 548 rapport.waarschuwingen.push(`playlist ${plc.name || uri}: geen van de nummers is aangekomen, overgeslagen`); 549 continue; 550 } 551 const plId = crypto.randomUUID(); 552 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, 555 plc.year || null, plc['shaer:kind'] || null); 556 const ins = db.prepare('INSERT OR IGNORE INTO playlist_tracks (playlist_id, track_id, position) VALUES (?,?,?)'); 557 nummers.forEach((tid, i) => ins.run(plId, tid, i)); 558 rapport.playlistsBinnen++; 559 const kwijt = (plc.orderedItems || plc.items || []).length - nummers.length; 560 if (kwijt > 0) rapport.waarschuwingen.push(`playlist ${plc.name || uri}: ${kwijt} nummer(s) ontbraken en zijn eruit gelaten`); 561 } catch (e) { 562 rapport.playlistsMislukt++; 563 rapport.waarschuwingen.push(`playlist niet opgeslagen: ${plc.name || uri} (${e && e.message})`); 564 } 565 } 566 } 501 567 } catch (e) { 502 568 // 9-bij-mislukking: de vlag blijft OPEN staan. Derden blijven dan kijken,
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)