A decentralized music tracking and discovery platform built on AT Protocol 馃幍
at fff48ea3213bb11efcfcb7db85be1dfcd2bebc5e 60 lines 1.7 kB view raw
1import chalk from "chalk"; 2import { consola } from "consola"; 3import { ctx } from "context"; 4import { eq } from "drizzle-orm"; 5import { createAgent } from "lib/agent"; 6import tables from "schema"; 7 8const args = process.argv.slice(2); 9 10if (args.length === 0) { 11 consola.error("Please provide user author identifier (handle or DID)."); 12 consola.info(`Usage: ${chalk.cyan("npm run feed -- <handle|did>")}`); 13 process.exit(1); 14} 15 16let did = args[0]; 17 18if (!did.startsWith("did:plc:")) { 19 did = await ctx.baseIdResolver.handle.resolve(did); 20} 21 22const agent = await createAgent(ctx.oauthClient, did); 23let cursor: string | undefined; 24const BATCH_SIZE = 100; 25let i = 1; 26do { 27 const records = await agent.com.atproto.repo.listRecords({ 28 repo: agent.assertDid, 29 collection: "app.rocksky.scrobble", 30 limit: BATCH_SIZE, 31 }); 32 33 for (const record of records.data.records) { 34 const result = await ctx.db 35 .select() 36 .from(tables.scrobbles) 37 .where(eq(tables.scrobbles.uri, record.uri)) 38 .limit(1); 39 if (result.length === 0) { 40 consola.info(`${i} Deleting record:`); 41 consola.info(record); 42 const rkey = record.uri.split("/").pop(); 43 await agent.com.atproto.repo.deleteRecord({ 44 repo: agent.assertDid, 45 collection: "app.rocksky.scrobble", 46 rkey, 47 }); 48 await new Promise((resolve) => setTimeout(resolve, 1000)); // rate limit 49 } else { 50 consola.info(chalk.greenBright(`${i} Keeping record:`)); 51 consola.info(record); 52 } 53 i += 1; 54 } 55 cursor = records.data.cursor; 56} while (cursor); 57 58consola.info(chalk.greenBright("Deduplication complete.")); 59 60process.exit(0);