Changeset dc802b4 in Klonkt


Ignore:
Timestamp:
08/14/2026 01:55:45 AM (4 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
e9128bc
Parents:
861c228
Message:

Een verhuizing krijgt de rauwe inhoud, niet de gebakken

Robin: het is gelukt, maar posts laden de playlists, albums of audio niet. Het
bericht toonde "šŸŽµ TikTik — listen on soundfabrics" als tekstlink, waar een
speler hoort te staan.

buildNote bakt de shorthand om voor de fediverse: [[track:]], [[album:]] en
[[playlist:]] worden GESTRIPT en er komt achteraan een blok met de titels. Dat
is precies goed voor Mastodon, en precies fout voor een verhuizing: de
doelinstantie is zelf een Klonkt en maakt van [[track:]] gewoon een speler.

Ik heb eerst overwogen om die link terug te vertalen naar de shorthand. Dat kan
niet zonder verlies:

  • de shorthand wordt gestript, dus zijn PLAATS in de post is weg; het blok komt altijd achteraan;
  • er gaan hooguit VIER titels in, dus een album van tien nummers is onherstelbaar;
  • [[album:]] en [[playlist:]] worden opgelost naar losse tracks, dus je krijgt tien spelers in plaats van een plaat.

Dus niet terugvertalen maar niet bakken. buildNote kreeg een optie
rauweInhoud, de outbox-route zet hem aan voor precies de actor waar dit
account naartoe verhuisd is. Dezelfde regel als bij de outbox-audience, de
tracks en de playlists: wie ondertekend vraagt namens de doel-actor krijgt onze
eigen kijk.

Gemeten op twee instanties, dezelfde post twee keer opgehaald:

anoniem <p>šŸŽµ <strong><a href=".../tiktik#track-t-a">Nummer A</a>...
verhuizing <p>hoor dit</p>[[track:t-a]]

En [[playlist:pl]] komt heel aan, wat met terugvertalen nooit was gelukt.

Changed files:
src/services/ActivityPubService.js

  • buildNote kent rauweInhoud: niet strippen, geen listen-blok aanplakken
  • buildCreate en buildOutbox geven de optie door

src/routes/activitypub.js

  • de outbox zet hem aan voor de doel-actor van een Move

test/fep1580-migration.test.js

  • dezelfde post gebakken en rauw, naast elkaar

remarks: dit raakt alleen wie ondertekend vraagt namens moved_to. Voor de rest
van de fediverse verandert er niets aan de outbox. Suite 1001 groen, tegenproef
gedaan.

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

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/routes/activitypub.js

    r861c228 rdc802b4  
    212212    limit: AP.PAGINA_GROOTTE,
    213213  });
    214   const ob = AP.buildOutbox(baseUrl(req), site, posts, tracks, { page: nr, totalItems: totaal, alGesneden: true });
     214  // FEP-1580: de instantie waar dit account naartoe verhuisd is krijgt de
     215  // RAUWE inhoud, met [[track:]] en [[playlist:]] er nog in. Zij is een
     216  // Klonkt en rendert die zelf tot een speler. De gebakken variant komt
     217  // daar aan als tekstlink, en is bovendien onherstelbaar afgeknot: het
     218  // bakken plakt hooguit vier titels aan.
     219  const rauweInhoud = verifiedActor ? AP.isMoveTarget(site.slug, verifiedActor) : false;
     220  const ob = AP.buildOutbox(baseUrl(req), site, posts, tracks, { page: nr, totalItems: totaal, alGesneden: true, rauweInhoud });
    215221  if (audience === 'friend') {
    216222    // The owner's app builds its feed from this leg, and every note here is
  • src/services/ActivityPubService.js

    r861c228 rdc802b4  
    706706    } catch { /* non-fatal */ }
    707707  }
    708   body = body.replace(/\[\[(track|album|playlist):[^\]]+\]\]/gi, '');
     708  // ONVERTAALD voor een verhuizing (FEP-1580). De doelinstantie IS een Klonkt:
     709  // die rendert [[track:]], [[album:]] en [[playlist:]] zelf en maakt er een
     710  // speler van. Bakken we ze eerst om, dan komt er een tekstlink aan en is de
     711  // speler weg. Onherstelbaar bovendien: het bakken STRIPT de shorthand en
     712  // plakt achteraan hooguit VIER titels, dus een album van tien nummers
     713  // overleeft het niet.
     714  //
     715  // Dezelfde regel als bij de outbox en de tracks: wie ondertekend vraagt
     716  // namens de actor waar wij naartoe verhuisd zijn, krijgt onze eigen kijk.
     717  if (!opts.rauweInhoud) body = body.replace(/\[\[(track|album|playlist):[^\]]+\]\]/gi, '');
    709718  // External embeds ([[embed:url]]) → emit the bare URL as a link so Mastodon
    710719  // renders its OWN preview/player card (YouTube/Spotify/SoundCloud/etc) instead
     
    714723    return `<p><a href="${u}">${u}</a></p>`;
    715724  });
    716   if (hadAudio) {
     725  if (hadAudio && !opts.rauweInhoud) {
    717726    // Elke titel als eigen link naar zijn anker; een titel zonder id (een
    718727    // albumnaam zonder tracks) blijft gewone tekst.
     
    10391048}
    10401049
    1041 export function buildCreate(base, site, post) {
    1042   const note = buildNote(base, site, post);
     1050export function buildCreate(base, site, post, opts = {}) {
     1051  const note = buildNote(base, site, post, opts);
    10431052  return {
    10441053    '@context': AP_CONTEXT,
     
    11231132}
    11241133
    1125 export function buildOutbox(base, site, posts, tracks = [], { page = false, totalItems, alGesneden = false } = {}) {
     1134export function buildOutbox(base, site, posts, tracks = [], { page = false, totalItems, alGesneden = false, rauweInhoud = false } = {}) {
    11261135  const id = `${actorId(base, site.slug)}/outbox`;
    11271136  const wanneer = (x) => Date.parse(x && x.published ? x.published : 0) || 0;
    11281137  const items = [
    1129     ...(posts || []).map((p) => buildCreate(base, site, p)),
     1138    ...(posts || []).map((p) => buildCreate(base, site, p, { rauweInhoud })),
    11301139    // EĆ©n zoekopdracht voor alle tracks samen, niet per stuk.
    11311140    ...(() => {
  • test/fep1580-migration.test.js

    r861c228 rdc802b4  
    612612});
    613613
     614test('de doelinstantie krijgt de RAUWE inhoud, met de shorthand er nog in', () => {
     615  // Robins laatste klacht: de post kwam aan met "šŸŽµ TikTik — listen on
     616  // soundfabrics" en zonder speler. De bron BAKT de shorthand namelijk om voor
     617  // de fediverse: [[track:]] wordt gestript en er komt achteraan een blok met
     618  // hooguit VIER titels. Onherstelbaar dus: een album van tien nummers is weg.
     619  //
     620  // Voor een verhuizing hoort dat bakken niet te gebeuren. De doelinstantie is
     621  // zelf een Klonkt en maakt van [[track:]] gewoon weer een speler.
     622  const s = site();
     623  db.prepare("INSERT INTO media (id, site_id, filename, mime_type, size, storage_path) VALUES ('m1','s1','a.mp3','audio/mpeg',1,'/x/a.mp3')").run();
     624  db.prepare("INSERT INTO audio_tracks (id, site_id, title, media_id) VALUES ('t1','s1','Nummer A','m1')").run();
     625  db.prepare(`INSERT INTO posts (id, site_id, author_id, slug, title, content, status, published_at)
     626              VALUES ('pa','s1','u1','plaat','Plaat','<p>hoor dit</p>[[track:t1]]','published','2026-01-01T10:00:00Z')`).run();
     627  const post = db.prepare("SELECT * FROM posts WHERE id = 'pa'").get();
     628
     629  const gebakken = AP.buildNote('https://oud.example', s, post);
     630  assert.ok(!gebakken.content.includes('[[track:t1]]'), 'de gewone federatie bakt hem om');
     631  assert.match(gebakken.content, /listen on/, 'en plakt er een tekstlink aan');
     632
     633  const rauw = AP.buildNote('https://oud.example', s, post, { rauweInhoud: true });
     634  assert.ok(rauw.content.includes('[[track:t1]]'), 'voor een verhuizing blijft de shorthand staan');
     635  assert.ok(!/listen on/.test(rauw.content), 'en er wordt geen tekstlink aangeplakt');
     636});
     637
    614638test('een bericht dat je zelf hebt verwijderd komt bij een tweede ronde terug', async () => {
    615639  // Robin: "ik kan handmatig deze keer de posts verwijderen en opnieuw ophalen."
Note: See TracChangeset for help on using the changeset viewer.