A decentralized music tracking and discovery platform built on AT Protocol 馃幍
rocksky.app
spotify
atproto
lastfm
musicbrainz
scrobbling
listenbrainz
1import chalk from "chalk";
2import { ctx } from "context";
3import { and, count, eq } from "drizzle-orm";
4import tables from "schema";
5import type { InsertArtistAlbum } from "schema/artist-albums";
6
7const size = 100;
8const total = await ctx.db
9 .select({ value: count() })
10 .from(tables.tracks)
11 .execute()
12 .then(([row]) => row.value);
13
14console.log(`Total tracks to process: ${chalk.magentaBright(total)}`);
15
16for (let i = 0; i < total; i += size) {
17 const skip = i;
18 console.log(
19 `Processing ${chalk.magentaBright("tracks")}: ${chalk.magentaBright(skip)} to ${chalk.magentaBright(skip + size)}`,
20 );
21 const results = await ctx.db
22 .select()
23 .from(tables.tracks)
24 .limit(size)
25 .offset(skip)
26 .execute();
27
28 for (const track of results) {
29 if (!track.artistUri || !track.albumUri) {
30 console.log(
31 `Skipping track ${chalk.cyan(track.title)} due to missing artist or album URI`,
32 );
33 console.log("artistUri", track.artistUri);
34 console.log("albumUri", track.albumUri);
35 continue;
36 }
37
38 const found = await ctx.db
39 .select()
40 .from(tables.artistAlbums)
41 .leftJoin(
42 tables.artists,
43 eq(tables.artistAlbums.artistId, tables.artists.id),
44 )
45 .leftJoin(
46 tables.albums,
47 eq(tables.artistAlbums.albumId, tables.albums.id),
48 )
49 .where(
50 and(
51 eq(tables.artists.uri, track.artistUri),
52 eq(tables.albums.uri, track.albumUri),
53 ),
54 )
55 .limit(1)
56 .execute()
57 .then((rows) => rows.length > 0);
58
59 if (!found) {
60 console.log(`Creating artist-album relationship for track: ${track.uri}`);
61 const [artist, album] = await Promise.all([
62 ctx.db
63 .select()
64 .from(tables.artists)
65 .where(eq(tables.artists.uri, track.artistUri))
66 .limit(1)
67 .execute()
68 .then((rows) => rows[0]),
69 ctx.db
70 .select()
71 .from(tables.albums)
72 .where(eq(tables.albums.uri, track.albumUri))
73 .limit(1)
74 .execute()
75 .then((rows) => rows[0]),
76 ]);
77
78 if (!artist || !album) {
79 console.error(
80 `Artist or album not found for track: ${track.uri}. Skipping...`,
81 );
82 console.log("artist", artist);
83 console.log("album", album);
84 continue;
85 }
86
87 await ctx.db
88 .insert(tables.artistAlbums)
89 .values({
90 artistId: artist.id,
91 albumId: album.id,
92 } as InsertArtistAlbum)
93 .execute();
94 }
95 }
96}
97
98process.exit(0);