Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/services/PlaylistService.js

    r7090fd2 r834bcc3  
    1515import { v4 as uuid } from 'uuid';
    1616
    17 /**
    18  * Een volledige datum of niets (shaer-756s).
    19  *
    20  * STRIKT, en dat is de hele functie. `year` bestaat al en blijft; dit veld
    21  * bestaat juist omdat een jaartal geen uitgavedatum is. Zou hij "2024"
    22  * doorlaten en er 2024-01-01 van maken, dan stond er straks een dag op de
    23  * federatie die niemand ooit heeft ingevoerd -- en dan hadden we het veld net
    24  * zo goed niet kunnen toevoegen.
    25  *
    26  * Ook 2024-02-31 valt af: dat is geen strengheid om de strengheid, Date rolt
    27  * hem stilletjes door naar 2 maart en dan slaan we iets anders op dan er
    28  * ingetypt is.
    29  */
    30 function normDatum(v) {
    31   const s = String(v == null ? '' : v).trim();
    32   if (!s) return null;
    33   if (!/^\d{4}-\d{2}-\d{2}$/.test(s)) return null;
    34   const d = new Date(`${s}T00:00:00Z`);
    35   return Number.isNaN(d.getTime()) || d.toISOString().slice(0, 10) !== s ? null : s;
    36 }
    37 
    38 /** Een MusicBrainz-id of niets. Zelfde vorm als sites.mb_artist_id. */
    39 function normMbid(v) {
    40   const s = String(v == null ? '' : v).trim().toLowerCase();
    41   return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(s) ? s : null;
    42 }
    43 
    4417class PlaylistService {
    4518
     
    7952    const rows = db.prepare(`
    8053      SELECT p.id, p.title, p.artist, p.year, p.cover_url, p.kind,
    81              p.release_date, p.mb_release_id,
    8254             p.created_at, p.updated_at,
    8355             (SELECT COUNT(*) FROM playlist_tracks WHERE playlist_id = p.id) AS track_count
     
    9365      cover: r.cover_url || '',
    9466      kind: r.kind || 'album',
    95       release_date: r.release_date || '',
    96       mb_release_id: r.mb_release_id || '',
    9767      track_count: r.track_count,
    9868      created_at: r.created_at,
     
    11686    if (!id) return null;
    11787    const p = db.prepare(`
    118       SELECT id, title, artist, year, cover_url, kind, release_date, mb_release_id, created_at, updated_at
     88      SELECT id, title, artist, year, cover_url, kind, created_at, updated_at
    11989      FROM playlists WHERE site_id = ? AND id = ?
    12090    `).get(siteId, id);
     
    155125      cover: p.cover_url || fallbackCover,
    156126      kind: (p.kind === 'playlist') ? 'playlist' : 'album',
    157       // created_at hoort erbij omdat de AP-kant er `published` van maakt. Zonder
    158       // dit veld viel buildAlbumObject terug op 1970, en dat stond op 16-8
    159       // gewoon op de federatie.
    160       created_at: p.created_at,
    161       // Leeg als het een afspeellijst is -- de opslag houdt ze daar al leeg,
    162       // maar dit is de plek waar de editor leest en die mag niet afhangen van
    163       // wat er toevallig in de kolom stond.
    164       release_date: p.kind === 'playlist' ? '' : (p.release_date || ''),
    165       mb_release_id: p.kind === 'playlist' ? '' : (p.mb_release_id || ''),
    166127      tracks: mappedTracks,
    167128    };
     
    180141    const kind = data.kind === 'playlist' ? 'playlist' : 'album';
    181142
    182     // Alleen een UITGAVE draagt deze twee. Een afspeellijst heeft geen
    183     // uitgavedatum en geen release-id, en dat onderscheid is precies wat de
    184     // keuze album/playlist betekent (shaer-cyg). Het afdwingen gebeurt HIER en
    185     // niet alleen in het scherm: een scherm kun je omzeilen -- de API ligt open
    186     // voor de post-editor -- en dan staat er stille rommel op een mixtape die
    187     // later als Album de deur uit gaat.
    188     const uitgave = kind === 'album';
    189     const releaseDate = uitgave ? normDatum(data.release_date) : null;
    190     const mbRelease = uitgave ? normMbid(data.mb_release_id) : null;
    191 
    192143    const tx = db.transaction(() => {
    193144      db.prepare(`
    194         INSERT INTO playlists (id, site_id, title, artist, year, cover_url, kind, release_date, mb_release_id, created_at, updated_at)
    195         VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
     145        INSERT INTO playlists (id, site_id, title, artist, year, cover_url, kind, created_at, updated_at)
     146        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
    196147      `).run(
    197148        id, siteId, title,
     
    199150        Number.isFinite(+data.year) && +data.year > 0 ? +data.year : null,
    200151        String(data.cover || '').trim() || null,
    201         kind, releaseDate, mbRelease, now, now,
     152        kind, now, now,
    202153      );
    203154      this._writeTracks(id, siteId, data.tracks);
     
    220171    if (!id) return false;
    221172    const existing = db.prepare(
    222       'SELECT id, kind FROM playlists WHERE site_id = ? AND id = ?'
     173      'SELECT id FROM playlists WHERE site_id = ? AND id = ?'
    223174    ).get(siteId, id);
    224175    if (!existing) return false;
     
    226177    const fields = [];
    227178    const values = [];
    228     // Wat wordt het NA deze wijziging? `kind` hoeft niet in data te staan, dus
    229     // val terug op wat er ligt.
    230     const nieuwKind = Object.prototype.hasOwnProperty.call(data, 'kind')
    231       ? (data.kind === 'playlist' ? 'playlist' : 'album')
    232       : (existing.kind || 'album');
    233179    if (Object.prototype.hasOwnProperty.call(data, 'title')) {
    234180      const v = String(data.title || '').trim();
     
    247193    }
    248194    if (Object.prototype.hasOwnProperty.call(data, 'kind')) {
    249       fields.push('kind = ?'); values.push(nieuwKind);
    250     }
    251     // De uitgavevelden. Wordt dit een afspeellijst, dan gaan ze ALTIJD leeg --
    252     // ook als de aanroeper er niets over zei. Anders houdt een album dat je tot
    253     // mixtape ombouwt zijn uitgavedatum en zijn release-id, en die duiken dan
    254     // weer op zodra iemand hem terugzet. Een veld dat niet meer mag bestaan
    255     // hoort weg te zijn, niet te wachten.
    256     if (nieuwKind !== 'album') {
    257       fields.push('release_date = ?'); values.push(null);
    258       fields.push('mb_release_id = ?'); values.push(null);
    259     } else {
    260       if (Object.prototype.hasOwnProperty.call(data, 'release_date')) {
    261         fields.push('release_date = ?'); values.push(normDatum(data.release_date));
    262       }
    263       if (Object.prototype.hasOwnProperty.call(data, 'mb_release_id')) {
    264         fields.push('mb_release_id = ?'); values.push(normMbid(data.mb_release_id));
    265       }
     195      fields.push('kind = ?'); values.push(data.kind === 'playlist' ? 'playlist' : 'album');
    266196    }
    267197    fields.push('updated_at = ?'); values.push(new Date().toISOString());
Note: See TracChangeset for help on using the changeset viewer.