Ignore:
Timestamp:
08/14/2026 02:35:06 AM (4 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
47f1183
Parents:
fc664ce
Message:

Een track zonder bestand is niet hetzelfde als een kapotte track

Robin, over het ene nummer dat niet meekwam: "ah, dat was een no audio 'audio'
voor alleen spotify en youtube links". Dat is een bestaand Klonkt-type, geen
ongelukje: geen gehost bestand, wel externe links, en buildNote maakt er een
embed-kaart van (trackEmbedLinks). Mijn regel "geen bestand, geen track" was te
grof en gooide hem weg.

"Geen bestand" en "niets om te tonen" zijn niet hetzelfde. De regel blijft
staan waar hij hoort: een track zonder bestand EN zonder links wordt nog steeds
geweigerd, want die kan niets.

Het archiefformaat heeft nu drie staten in plaats van twee: included, missing,
en linkOnly. Een link-only track telt dus ook niet meer als "ontbrekend", want
er ontbreekt niets.

EN EEN TWEEDE FOUT DIE HIERONDER LAG. De pull viste de audio-URL uit de
url-lijst met element NUL. buildTrackAudio zet daar een text/html-link naar de
post voor het bestand: wie blind de eerste pakt downloadt een HTML-pagina en
schrijft die weg als mp3. Nu wordt de link met mediaType audio/* gezocht, met
/audio/stream/ als terugval. Dat het bij Robin niet misging is geluk: zijn
tracks hadden geen host-post in die lijst.

Changed files:
src/services/ArchiveExportService.js

  • shaer:availability kent linkOnly; die telt niet als audioMissing

src/services/ArchiveImportService.js

  • link-only tracks komen mee, met media_id NULL zoals op de bron
  • de schrijftak kan een track zonder bestand aan

src/services/MigrationService.js

  • de pull vist de audio-link uit de lijst in plaats van element nul
  • een track met alleen externe links wordt gewoon aangemaakt

test/archive-audio.test.js

  • link-only reist mee; zonder bestand en zonder links blijft geweigerd

test/fep1580-migration.test.js

  • hetzelfde voor de ophaalknop, plus: de audio-link wordt gevist

remarks: Robins Youngstown-nummer komt hiermee alsnog over. Suite 1009 groen;
tegenproef op beide, en de eerste poging daarvan kwam niet aan (te slordige
sabotage), dus opnieuw gedaan met twee rode tests als bewijs.

-robo
Co-Authored-By: Claude Opus 4.8 <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/services/ArchiveImportService.js

    rfc664ce rf704237  
    166166    const bestand = t['shaer:file'];
    167167    const bytes = bestand ? files.get(bestand) : null;
    168     if (!bytes || !bytes.length) {
     168    // "Geen bestand" en "niets om te tonen" zijn niet hetzelfde. Een LINK-ONLY
     169    // track heeft nooit een bestand gehad: hij bestaat uit een Spotify- of
     170    // YouTube-link en Klonkt maakt daar een embed-kaart van. Die hoort gewoon
     171    // mee. Mijn eerste regel gooide hem weg, en dat kostte Robin een nummer
     172    // (Youngstown) dat op de oude site prima werkte.
     173    const links = Array.isArray(t.url) ? t.url.filter(Boolean) : [];
     174    const alleenLinks = t['shaer:availability'] === 'linkOnly' || (!bestand && links.length > 0);
     175    if ((!bytes || !bytes.length) && !alleenLinks) {
    169176      rapport.tracksMissing += 1;
    170177      rapport.waarschuwingen.push(`${t.name || id}: geluidsbestand zit niet in het archief, track niet aangemaakt`);
    171       continue;                       // de hele regel van deze functie
     178      continue;
     179    }
     180    if (alleenLinks) {
     181      // Geen bestand om weg te schrijven, geen mediarij: alleen de track zelf.
     182      werk.push({ soort: 'track', id, t, naam: null, bytes: null, doel: null, hoes: hoesTerug(files, t['shaer:coverFile'], werk) });
     183      rapport.tracks += 1;
     184      rapport.tracksLinks = (rapport.tracksLinks || 0) + 1;
     185      continue;
    172186    }
    173187    // Naam op de schijf: de hash uit het archief, met zijn extensie. De speler
     
    256270    posts: 0, overgeslagen: 0, overschreven: 0,
    257271    replies: 0, media: 0, mediaMissing: 0, gemist: [], waarschuwingen: [],
    258     tracks: 0, tracksMissing: 0, playlists: 0, linksBijgetrokken: 0,
     272    tracks: 0, tracksMissing: 0, tracksLinks: 0, playlists: 0, linksBijgetrokken: 0,
    259273  };
    260274
     
    417431        // rolt de hele transactie terug: liever geen import dan een track zonder
    418432        // geluid, want dat is precies de val waar dit uit voortkomt.
    419         fs.mkdirSync(path.dirname(s.doel), { recursive: true });
    420         fs.writeFileSync(s.doel, s.bytes);
    421         const mediaId = randomUUID();
    422         db.prepare('INSERT INTO media (id, site_id, filename, mime_type, size, storage_path) VALUES (?,?,?,?,?,?)')
    423           .run(mediaId, site.id, s.naam, s.t['shaer:mediaType'] || 'audio/mpeg', s.bytes.length, s.doel);
     433        //
     434        // Een link-only track heeft geen bestand en dus ook geen mediarij; die
     435        // krijgt media_id NULL, precies zoals op de bron.
     436        let mediaId = null;
     437        if (s.doel && s.bytes) {
     438          fs.mkdirSync(path.dirname(s.doel), { recursive: true });
     439          fs.writeFileSync(s.doel, s.bytes);
     440          mediaId = randomUUID();
     441          db.prepare('INSERT INTO media (id, site_id, filename, mime_type, size, storage_path) VALUES (?,?,?,?,?,?)')
     442            .run(mediaId, site.id, s.naam, s.t['shaer:mediaType'] || 'audio/mpeg', s.bytes.length, s.doel);
     443        }
    424444        const link = (k) => (s.t.url || []).find((u) => String(u).includes(k)) || null;
    425445        db.prepare(`INSERT OR REPLACE INTO audio_tracks
Note: See TracChangeset for help on using the changeset viewer.