Changeset cf5073b in Klonkt
- Timestamp:
- 08/08/2026 05:47:57 AM (5 weeks ago)
- Branches:
- main
- Children:
- f3a2556
- Parents:
- 4d81de5
- git-author:
- Robin <roboburr@…> (08/08/2026 05:46:48 AM)
- git-committer:
- Robin <roboburr@…> (08/08/2026 05:47:57 AM)
- Files:
-
- 1 added
- 2 edited
-
src/services/ActivityPubService.js (modified) (4 diffs)
-
test/ap-track-fields.test.js (added)
-
test/ap-tracks.test.js (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/services/ActivityPubService.js
r4d81de5 rcf5073b 52 52 value: 'schema:value', 53 53 embedUrl: { '@id': 'schema:embedUrl', '@type': '@id' }, 54 // Wat een track beschrijft en AS2 niet kent (shaer-0nh). Funkwhale zet deze 55 // vier op zijn Audio; het bleken geen eigen verzinsels maar termen die 56 // schema.org gewoon heeft -- en schema.org stond hier al. De SLEUTELS zijn 57 // die van Funkwhale, want daar leest hij op; de BETEKENIS komt van 58 // schema.org, dus we hoeven geen vreemd vocabulaire binnen te halen. 59 license: { '@id': 'schema:license', '@type': '@id' }, 60 position: 'schema:position', 61 bitrate: 'schema:bitrate', 62 size: 'schema:contentSize', 54 63 // Poll (Question) extension: Question/oneOf/anyOf/endTime/closed are AS2 core, but the 55 64 // per-poll unique-voter count is a Mastodon (toot) term — declare it so the emitted … … 1067 1076 // m.size hoort erbij voor de RSS-enclosure: die eist een lengte in bytes. 1068 1077 const TRACK_KOLOMMEN = `t.id, t.title, t.artist, t.duration, t.cover_url, t.created_at, 1078 t.position, t.license, 1069 1079 m.filename, m.storage_path, m.mime_type, m.size`; 1070 1080 … … 1123 1133 const abs = (u) => !u ? null : (/^https?:/i.test(u) ? u : `${base}${u.startsWith('/') ? '' : '/'}${u}`); 1124 1134 const fn = r.filename || (r.storage_path || '').split('/').pop(); 1135 // De bestandsgegevens horen bij de LINK, niet bij het object: het is die ene 1136 // representatie die zoveel bytes is en die bitrate heeft, niet het nummer. 1137 // Zo doet Funkwhale het ook. 1138 const bestand = { type: 'Link', href: `${base}/audio/stream/${encodeURIComponent(fn)}`, mediaType: r.mime_type || 'audio/mpeg' }; 1139 if (Number(r.size)) bestand.size = Number(r.size); 1140 // Bitrate leiden we af uit bytes en seconden. Geen gok: voor een bestand IS 1141 // dat de gemiddelde bitrate, en bij CBR ook de echte. Alleen als we allebei 1142 // de getallen hebben -- liever geen veld dan een verzonnen getal. 1143 if (Number(r.size) && Number(r.duration)) bestand.bitrate = Math.round((Number(r.size) * 8) / Number(r.duration)); 1144 1125 1145 const a = { 1126 1146 ...(opts.standalone ? { '@context': AP_CONTEXT } : {}), … … 1129 1149 name: r.title || 'Audio', 1130 1150 attributedTo: actorId(base, site.slug), 1131 url: [{ type: 'Link', href: `${base}/audio/stream/${encodeURIComponent(fn)}`, mediaType: r.mime_type || 'audio/mpeg' }], 1151 // Op het OBJECT, niet alleen op de omhullende Create: een los opgehaalde 1152 // track moet zelf kunnen zeggen dat hij openbaar is. 1153 to: [PUBLIC], 1154 url: [bestand], 1132 1155 }; 1133 1156 if (r.artist) a.summary = r.artist; // artiest als summary: kaal AS2, geen eigen vocab 1134 1157 if (r.duration) a.duration = `PT${Math.round(r.duration)}S`; 1135 1158 if (r.created_at) a.published = new Date(r.created_at).toISOString(); 1159 if (Number(r.position)) a.position = Number(r.position); 1160 const lic = licentieUri(r.license); 1161 if (lic) a.license = lic; 1136 1162 const art = abs(r.cover_url || opts.coverFallback || null); 1137 if (art) a.icon = { type: 'Image', mediaType: guessMediaType(art), url: art }; 1163 // icon EN image: allebei AS2-kern. Wij gebruikten alleen icon; Funkwhale 1164 // leest image. Dezelfde hoes, twee namen, niemand die iets misloopt. 1165 if (art) { 1166 const plaat = { type: 'Image', mediaType: guessMediaType(art), url: art }; 1167 a.icon = plaat; 1168 a.image = plaat; 1169 } 1138 1170 return a; 1171 } 1172 1173 /** 1174 * Onze licentie is VRIJE TEKST uit een keuzelijst ("CC BY 4.0", "Alle rechten 1175 * voorbehouden"); schema.org en Funkwhale willen een URI. Alleen de waarden die 1176 * onze eigen keuzelijst aanbiedt worden vertaald -- die kennen we exact. Al het 1177 * andere levert niets op: een zelfbedachte licentie-URI is erger dan geen, want 1178 * een lezer gelooft hem. 1179 */ 1180 const LICENTIES = { 1181 'cc0 1.0 (publiek domein)': 'http://creativecommons.org/publicdomain/zero/1.0/', 1182 'cc by 4.0': 'http://creativecommons.org/licenses/by/4.0/', 1183 'cc by-sa 4.0': 'http://creativecommons.org/licenses/by-sa/4.0/', 1184 'cc by-nc 4.0': 'http://creativecommons.org/licenses/by-nc/4.0/', 1185 'cc by-nc-sa 4.0': 'http://creativecommons.org/licenses/by-nc-sa/4.0/', 1186 'cc by-nd 4.0': 'http://creativecommons.org/licenses/by-nd/4.0/', 1187 }; 1188 export function licentieUri(waarde) { 1189 const s = String(waarde || '').trim(); 1190 if (!s) return null; 1191 if (/^https?:\/\//i.test(s)) return safeUrl(s); // iemand vulde al een URI in 1192 return LICENTIES[s.toLowerCase()] || null; // "Alle rechten voorbehouden" heeft er geen 1139 1193 } 1140 1194 -
test/ap-tracks.test.js
r4d81de5 rcf5073b 75 75 assert.equal(a.duration, 'PT203S'); 76 76 assert.equal(a.summary, 'De Band'); 77 assert.deepEqual(a.url, [{ 78 type: 'Link', href: 'https://test.example/audio/stream/open.mp3', mediaType: 'audio/mpeg', 79 }], 'de mediaType hoort bij de link, niet bij het object'); 77 // De Link draagt sinds de veldvergelijking met Funkwhale ook de 78 // bestandsgegevens: die horen bij DEZE representatie, niet bij het nummer. 79 assert.equal(a.url.length, 1); 80 assert.equal(a.url[0].type, 'Link'); 81 assert.equal(a.url[0].href, 'https://test.example/audio/stream/open.mp3'); 82 assert.equal(a.url[0].mediaType, 'audio/mpeg', 'de mediaType hoort bij de link, niet bij het object'); 83 assert.equal(a.mediaType, undefined, 'en dus NIET op het object'); 80 84 assert.equal(a.icon.url, 'https://test.example/media/hoes.jpg'); 81 85 });
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)