A decentralized music tracking and discovery platform built on AT Protocol 馃幍
listenbrainz spotify atproto lastfm musicbrainz scrobbling
at setup-tracing 126 lines 3.6 kB view raw
1import { equals } from "@xata.io/client"; 2import chalk from "chalk"; 3import { ctx } from "context"; 4import { createHash } from "crypto"; 5import { publishScrobble } from "nowplaying/nowplaying.service"; 6 7const args = process.argv.slice(2); 8 9async function updateUris(did: string) { 10 const { records } = await ctx.client.db.scrobbles 11 .select(["track_id.*", "user_id.*"]) 12 .filter({ 13 $any: [{ "user_id.did": did }, { "user_id.handle": did }], 14 }) 15 .getPaginated({ 16 pagination: { 17 size: process.env.SYNC_SIZE ? parseInt(process.env.SYNC_SIZE) : 20, 18 }, 19 sort: [{ xata_createdat: "desc" }], 20 }); 21 for (const { track_id: track } of records) { 22 const existingTrack = await ctx.client.db.tracks 23 .filter( 24 "sha256", 25 equals( 26 createHash("sha256") 27 .update( 28 `${track.title} - ${track.artist} - ${track.album}`.toLowerCase(), 29 ) 30 .digest("hex"), 31 ), 32 ) 33 .getFirst(); 34 35 if (existingTrack && !existingTrack.album_uri) { 36 console.log(`Updating album uri for ${chalk.cyan(track.xata_id)} ...`); 37 const album = await ctx.client.db.albums 38 .filter( 39 "sha256", 40 equals( 41 createHash("sha256") 42 .update(`${track.album} - ${track.album_artist}`.toLowerCase()) 43 .digest("hex"), 44 ), 45 ) 46 .getFirst(); 47 if (album) { 48 await ctx.client.db.tracks.update(existingTrack.xata_id, { 49 album_uri: album.uri, 50 }); 51 } 52 } 53 54 if (existingTrack && !existingTrack.artist_uri) { 55 console.log(`Updating artist uri for ${chalk.cyan(track.xata_id)} ...`); 56 const artist = await ctx.client.db.artists 57 .filter( 58 "sha256", 59 equals( 60 createHash("sha256") 61 .update(track.album_artist.toLowerCase()) 62 .digest("hex"), 63 ), 64 ) 65 .getFirst(); 66 if (artist) { 67 await ctx.client.db.tracks.update(existingTrack.xata_id, { 68 artist_uri: artist.uri, 69 }); 70 } 71 } 72 73 const album = await ctx.client.db.albums 74 .filter( 75 "sha256", 76 equals( 77 createHash("sha256") 78 .update(`${track.album} - ${track.album_artist}`.toLowerCase()) 79 .digest("hex"), 80 ), 81 ) 82 .getFirst(); 83 84 if (existingTrack && !album.artist_uri) { 85 console.log(`Updating artist uri for ${chalk.cyan(album.xata_id)} ...`); 86 const artist = await ctx.client.db.artists 87 .filter( 88 "sha256", 89 equals( 90 createHash("sha256") 91 .update(track.album_artist.toLowerCase()) 92 .digest("hex"), 93 ), 94 ) 95 .getFirst(); 96 if (artist) { 97 await ctx.client.db.albums.update(album.xata_id, { 98 artist_uri: artist.uri, 99 }); 100 } 101 } 102 } 103} 104 105for (const arg of args) { 106 console.log(`Syncing scrobbles ${chalk.magenta(arg)} ...`); 107 await updateUris(arg); 108 109 const { records } = await ctx.client.db.scrobbles 110 .filter({ 111 $any: [{ "user_id.did": arg }, { "user_id.handle": arg }], 112 }) 113 .getPaginated({ 114 pagination: { 115 size: process.env.SYNC_SIZE ? parseInt(process.env.SYNC_SIZE) : 20, 116 }, 117 sort: [{ xata_createdat: "desc" }], 118 }); 119 for (const scrobble of records) { 120 console.log(`Syncing scrobble ${chalk.cyan(scrobble.xata_id)} ...`); 121 await publishScrobble(ctx, scrobble.xata_id); 122 } 123 console.log(`Synced ${chalk.greenBright(records.length)} scrobbles`); 124} 125 126process.exit(0);