Changeset 9a585bf in Klonkt
- Timestamp:
- 08/16/2026 01:29:11 PM (3 weeks ago)
- Branches:
- main
- Children:
- 21257e4
- Parents:
- 38d5e40
- Files:
-
- 3 edited
-
src/services/ap-core.js (modified) (1 diff)
-
src/services/music/index.js (modified) (2 diffs)
-
test/ap-fw-track.test.js (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/services/ap-core.js
r38d5e40 r9a585bf 88 88 Track: 'fw:Track', 89 89 track: { '@id': 'fw:track', '@type': '@id' }, 90 // ARTIEST-CREDIT. Hun TrackSerializer eist minstens een artist_credit, en 91 // dat leek lang onmogelijk: het vraagt een Artist met een eigen id, en bij 92 // ons was een artiest tekst. Sinds de MusicBrainz-koppeling (shaer-mbz) is 93 // dat niet meer waar -- de site-ACTOR is de artiest. Een echte, opvraagbare 94 // URI, met de sitetitel als naam en een musicbrainzId als hij gekoppeld is. 95 // Er valt hier niets te verzinnen; open.audio leidde dit zelfs al zelf af 96 // uit onze attributedTo (gemeten 13-8). 97 // 98 // `@container: @list` is GEEN opsmuk. Ze lezen dit veld met 99 // first_attr(FW.artist_credit, "@list"), en zonder die declaratie expandeert 100 // onze array niet naar een @list -- dan staat er iets dat er goed uitziet en 101 // door hun lezer niet gevonden wordt. Letterlijk hun contexts.py regel 311. 102 Artist: 'fw:Artist', 103 ArtistCredit: 'fw:ArtistCredit', 104 artist: { '@id': 'fw:artist', '@type': '@id' }, 105 artist_credit: { '@id': 'fw:artist_credit', '@type': '@id', '@container': '@list' }, 106 credit: 'fw:credit', 107 musicbrainzId: 'fw:musicbrainzId', 90 108 position: 'schema:position', 91 109 bitrate: 'schema:bitrate', -
src/services/music/index.js
r38d5e40 r9a585bf 14 14 15 15 import db from '../../config/database.js'; 16 import { AP_CONTEXT, PUBLIC, actorId, noteId, safeUrl, guessMediaType, buildHashtagList, pagedCollection } from '../ap-core.js';16 import { AP_CONTEXT, PUBLIC, actorId, noteId, safeUrl, guessMediaType, buildHashtagList, pagedCollection, isMbid } from '../ap-core.js'; 17 17 import { afleidenUitInsluitingen, ingeslotenPlaylists } from '../../assets/js/shared/post-music-type.js'; 18 18 // De luisteraars horen bij de muziekkant; hier doorgegeven zodat … … 195 195 // een tekstkolom; er hier een adres van maken zou een ding beloven dat niet 196 196 // bestaat. Zie shaer-k37k -- dat is de keuze die daarvoor eerst moet vallen. 197 // 198 // WIE IS DE ARTIEST. Hun Artist is een ENTITEIT met een id, en bij ons is een 199 // artiest een tekstkolom op de track. Die twee verzoenen we zo: de entiteit 200 // is de site-ACTOR -- een echt, opvraagbaar adres, het account dat dit 201 // uitbrengt -- en de tekst uit de kolom gaat naar `credit`, want dat is 202 // precies waar hun model de credittekst verwacht. 203 // 204 // Dat is eerlijk en het is niet nieuw: open.audio leidde op 13-8 al zelf een 205 // artist_credit af uit onze attributedTo. We maken alleen expliciet wat daar 206 // toch al gebeurde. 207 // 208 // DE GRENS ERVAN: brengt een site werk van iemand anders uit, dan zegt dit 209 // dat de site de artiest is. Dat stond al in attributedTo, dus we maken het 210 // niet erger -- maar het is wel de reden dat we hier geen id per artiestnaam 211 // verzinnen. Identiteit uit een string is dezelfde fout als bij het album 212 // (shaer-756s). 213 const wanneer = r.created_at ? new Date(r.created_at).toISOString() 214 : (site.created_at ? new Date(site.created_at).toISOString() : new Date(0).toISOString()); 215 const artiest = { 216 type: 'Artist', 217 id: actorId(base, site.slug), 218 name: site.title || site.slug, 219 published: site.created_at ? new Date(site.created_at).toISOString() : wanneer, 220 }; 221 if (isMbid(site.mb_artist_id)) artiest.musicbrainzId = String(site.mb_artist_id).trim().toLowerCase(); 222 197 223 a.track = { 198 224 type: 'Track', 199 225 id: `${a.id}#track`, 200 226 name: a.name, 227 published: wanneer, 201 228 ...(Number(r.position) ? { position: Number(r.position) } : {}), 229 artist_credit: [{ 230 type: 'ArtistCredit', 231 id: `${a.id}#artist-credit`, 232 published: wanneer, 233 artist: artiest, 234 ...(r.artist ? { credit: r.artist } : {}), 235 }], 202 236 }; 203 237 if (r.duration) a.duration = `PT${Math.round(r.duration)}S`; -
test/ap-fw-track.test.js
r38d5e40 r9a585bf 84 84 for (const a of col.orderedItems) assert.equal(a.track.type, 'Track', `${a.name} zonder track`); 85 85 }); 86 87 // ── artist_credit (shaer-3f8a, het gat naar hun ingest) ────────────── 88 // 89 // TrackSerializer (regel 1569) eist `artist_credit` met min_length=1, en elke 90 // ArtistCredit eist een Artist die zelf id, name en published nodig heeft 91 // (MusicEntitySerializer, regel 1278). Dat leek onmogelijk zolang een artiest 92 // bij ons tekst was -- tot de MusicBrainz-koppeling liet zien dat de ACTOR de 93 // artiest is. 94 95 test('de track draagt een artist_credit met een echte Artist', () => { 96 const a = audio('t1'); 97 assert.ok(Array.isArray(a.track.artist_credit), 'geen lijst'); 98 assert.equal(a.track.artist_credit.length, 1); 99 const ac = a.track.artist_credit[0]; 100 assert.equal(ac.type, 'ArtistCredit'); 101 assert.ok(ac.id && ac.published, 'ArtistCredit mist id of published'); 102 assert.equal(ac.artist.type, 'Artist'); 103 assert.equal(ac.artist.id, `${BASE}/ap/users/band`, 'de actor IS de artiest'); 104 assert.equal(ac.artist.name, 'De Band'); 105 assert.ok(ac.artist.published, 'Artist mist published'); 106 }); 107 108 test('de artiestnaam van de track gaat naar credit, niet naar de entiteit', () => { 109 // De kolom is een credittekst, geen identiteit. Er een id van maken zou 110 // dezelfde fout zijn als bij het album (shaer-756s). 111 assert.equal(audio('t1').track.artist_credit[0].credit, 'De Band'); 112 assert.equal(audio('t2').track.artist_credit[0].credit, undefined, 'geen artiest, geen credit'); 113 }); 114 115 test('de track heeft published -- MusicEntitySerializer eist het', () => { 116 assert.ok(audio('t1').track.published); 117 }); 118 119 test('artist_credit is een @list in de context, anders vindt hun lezer niets', async () => { 120 // Ze lezen dit met first_attr(FW.artist_credit, "@list"). Zonder de 121 // container-declaratie expandeert onze array niet naar een @list en staat er 122 // iets dat er goed uitziet en niet gevonden wordt. 123 const core = await import('../src/services/ap-core.js'); 124 const term = core.AP_CONTEXT.find((x) => x && typeof x === 'object' && x.artist_credit); 125 assert.deepEqual(term.artist_credit, { '@id': 'fw:artist_credit', '@type': '@id', '@container': '@list' }); 126 assert.equal(term.ArtistCredit, 'fw:ArtistCredit'); 127 assert.equal(term.Artist, 'fw:Artist'); 128 }); 129 130 test('musicbrainzId komt mee zodra de site gekoppeld is', () => { 131 assert.equal(audio('t1').track.artist_credit[0].artist.musicbrainzId, undefined); 132 db.prepare("UPDATE sites SET mb_artist_id = '5441c29d-3602-4898-b1a1-b77fa23b8e50' WHERE id = 's1'").run(); 133 const s2 = db.prepare("SELECT * FROM sites WHERE id = 's1'").get(); 134 const a = AP.buildTrackAudio(BASE, s2, AP.openTrack('s1', 't1'), { hostPosts: null }); 135 assert.equal(a.track.artist_credit[0].artist.musicbrainzId, '5441c29d-3602-4898-b1a1-b77fa23b8e50'); 136 db.prepare("UPDATE sites SET mb_artist_id = NULL WHERE id = 's1'").run(); 137 });
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)