| 1 | /**
|
|---|
| 2 | * Hoe ver zijn we van Funkwhale's bibliotheek-ingest?
|
|---|
| 3 | *
|
|---|
| 4 | * node scripts/funkwhale-gat.mjs https://dev.klonkt.com/ap/users/dev/library
|
|---|
| 5 | *
|
|---|
| 6 | * Loopt de eisen na die in api/funkwhale_api/federation/serializers.py staan
|
|---|
| 7 | * (develop, gelezen 16-8) en zegt per veld of het er is. Geen oordeel, geen
|
|---|
| 8 | * schatting: de lijst komt uit hun bron en de waarden uit onze eigen uitvoer.
|
|---|
| 9 | *
|
|---|
| 10 | * WAAROM DIT ER IS. "Zijn we er al?" is drie keer beantwoord met een gevoel en
|
|---|
| 11 | * drie keer bijgesteld. Deze vraag hoort een commando te zijn.
|
|---|
| 12 | *
|
|---|
| 13 | * LET OP wat dit NIET meet: de kanaal-weg. open.audio heeft onze tracks al
|
|---|
| 14 | * langs de outbox binnengehaald, met naam en artiest. Wat daar ontbreekt is
|
|---|
| 15 | * `uploads` -- en dat is precies wat deze ingest zou vullen.
|
|---|
| 16 | */
|
|---|
| 17 | const BRON = process.argv[2] || 'https://dev.klonkt.com/ap/users/dev/library';
|
|---|
| 18 |
|
|---|
| 19 | const haal = async (u) => {
|
|---|
| 20 | const r = await fetch(u, { headers: { Accept: 'application/activity+json' } });
|
|---|
| 21 | if (!r.ok) throw new Error(`${u} gaf ${r.status}`);
|
|---|
| 22 | return r.json();
|
|---|
| 23 | };
|
|---|
| 24 |
|
|---|
| 25 | // serializers.py regel 1741 -- UploadSerializer, per item in een bibliotheekpagina
|
|---|
| 26 | const UPLOAD = [
|
|---|
| 27 | ['type', (a) => a.type === 'Audio'],
|
|---|
| 28 | ['id', (a) => !!a.id],
|
|---|
| 29 | ['library', (a) => !!a.library],
|
|---|
| 30 | ['url.href', (a) => !!(Array.isArray(a.url) ? a.url[0] : a.url)?.href],
|
|---|
| 31 | ['url.mediaType', (a) => !!(Array.isArray(a.url) ? a.url[0] : a.url)?.mediaType],
|
|---|
| 32 | ['published', (a) => !!a.published],
|
|---|
| 33 | ['duration', (a) => typeof a.duration === 'string'],
|
|---|
| 34 | // fw:bitrate en fw:size, en TOP-LEVEL. Wij zetten ze op de Link (waar hun
|
|---|
| 35 | // eigen outbox ze ook zet) en binden ze aan schema: -- zie shaer-f1y4.
|
|---|
| 36 | ['bitrate (top-level)', (a) => a.bitrate !== undefined],
|
|---|
| 37 | ['size (top-level)', (a) => a.size !== undefined],
|
|---|
| 38 | ['track', (a) => !!a.track],
|
|---|
| 39 | ];
|
|---|
| 40 |
|
|---|
| 41 | // regel 1569 -- TrackSerializer, plus MusicEntitySerializer (1278) eronder
|
|---|
| 42 | const TRACK = [
|
|---|
| 43 | ['track.id', (t) => !!t?.id],
|
|---|
| 44 | ['track.name', (t) => !!t?.name],
|
|---|
| 45 | ['track.published', (t) => !!t?.published],
|
|---|
| 46 | ['track.artist_credit[>=1]', (t) => Array.isArray(t?.artist_credit) && t.artist_credit.length >= 1],
|
|---|
| 47 | ['track.album', (t) => !!t?.album],
|
|---|
| 48 | ];
|
|---|
| 49 |
|
|---|
| 50 | const lib = await haal(BRON);
|
|---|
| 51 | const pagina = lib.first ? await haal(lib.first) : lib;
|
|---|
| 52 | const items = pagina.items || pagina.orderedItems || [];
|
|---|
| 53 | if (!items.length) { console.log('geen items in de bibliotheek'); process.exit(1); }
|
|---|
| 54 |
|
|---|
| 55 | // ALLE items, niet het eerste. De eerste versie keek naar items[0] en gaf
|
|---|
| 56 | // daarover een oordeel alsof het over de bibliotheek ging -- op 16-8 meldde hij
|
|---|
| 57 | // zo `track.album` als GAT terwijl drie van de vier tracks hem wel hadden: het
|
|---|
| 58 | // ene nummer dat hij toevallig pakte stond niet op een plaat. Een steekproef
|
|---|
| 59 | // van een is geen meting, en een meting die je vertrouwt moet zeggen hoeveel.
|
|---|
| 60 | console.log(`bron: ${BRON}\nitems: ${items.length}\n`);
|
|---|
| 61 |
|
|---|
| 62 | let gaten = 0;
|
|---|
| 63 | const toon = (kop, lijst, kies) => {
|
|---|
| 64 | console.log(kop);
|
|---|
| 65 | for (const [naam, test] of lijst) {
|
|---|
| 66 | let ok = 0;
|
|---|
| 67 | for (const a of items) { try { if (test(kies(a))) ok++; } catch { /* telt als niet ok */ } }
|
|---|
| 68 | const staat = ok === items.length ? 'OK ' : (ok === 0 ? 'GAT' : 'DEELS');
|
|---|
| 69 | if (ok !== items.length) gaten++;
|
|---|
| 70 | console.log(` ${staat.padEnd(5)} ${naam}${ok !== items.length ? ` (${ok}/${items.length})` : ''}`);
|
|---|
| 71 | }
|
|---|
| 72 | };
|
|---|
| 73 | toon('UploadSerializer (regel 1741):', UPLOAD, (a) => a);
|
|---|
| 74 | console.log();
|
|---|
| 75 | toon('TrackSerializer (regel 1569 + MusicEntity 1278):', TRACK, (a) => a.track);
|
|---|
| 76 |
|
|---|
| 77 | console.log(`\n${gaten === 0 ? 'niets meer nodig voor hun ingest' : gaten + ' veld(en) nog niet op ELK item'}`);
|
|---|