diff --git a/app/jobs/add-missing-review-urls.ts b/app/jobs/add-missing-review-urls.ts deleted file mode 100644 index 00805ac..0000000 --- a/app/jobs/add-missing-review-urls.ts +++ /dev/null @@ -1,205 +0,0 @@ -import dotenv from 'dotenv' -import { and, eq, notLike, sql } from 'drizzle-orm' -import inquirer from 'inquirer' -import { chromium } from 'playwright' - -import { - ReviewedItem, - constructConsoleDatabase, - reviewedItems, - reviewers, -} from '~/lib/database/index.server' - -dotenv.config() - -const main = async () => { - const { database } = constructConsoleDatabase() - const publications = await database - .select() - .from(reviewers) - .where(eq(reviewers.service, 'publication')) - .orderBy(reviewers.name) - .all() - - const { publicationName, hostname } = await inquirer.prompt([ - { - type: 'rawlist', - name: 'publicationName', - message: 'Which publication?', - choices: publications.map((p) => ({ - key: p.id, - value: p.name, - })), - }, - { - type: 'input', - name: 'hostname', - message: 'What hostname should we search DuckDuckGo for?', - }, - ]) - - const reviews = await database - .select({ - id: reviewedItems.id, - createdAt: reviewedItems.createdAt, - updatedAt: reviewedItems.updatedAt, - reviewURL: reviewedItems.reviewURL, - reviewerID: reviewedItems.reviewerID, - name: reviewedItems.name, - creator: reviewedItems.creator, - service: reviewedItems.service, - resolvable: reviewedItems.resolvable, - metadata: reviewedItems.metadata, - }) - .from(reviewedItems) - .innerJoin( - reviewers, - and( - eq(reviewers.name, publicationName), - eq(reviewers.id, reviewedItems.reviewerID), - ), - ) - .where( - and( - notLike(reviewedItems.reviewURL, 'https://%'), - sql`COALESCE(json_extract(${reviewedItems.metadata}, '$.reviewUnresolvable'), 0) != 1`, - ), - ) - .orderBy(reviewedItems.id) - .all() - - if (!reviews.length) { - console.log('No reviews to update.') - return - } - - console.log(`Found ${reviews.length} reviews to update.`) - - const browser = await chromium.launch() - - const duckDuckGoUpdateAlbum = async ( - album: ReviewedItem, - hostname: string, - ): Promise => { - const context = await browser.newContext({ - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36', - }) - const page = await context.newPage() - const url = new URL('https://duckduckgo.com/') - url.searchParams.set('q', `${album.name} ${album.creator} site:${hostname}`) - await page.goto(url.toString()) - const linksLocator = page.locator( - `.react-results--main h2 a[href*="https://${hostname}"]`, - ) - - try { - await linksLocator.first().waitFor({ - timeout: 5 * 1000, - }) - } catch (e) { - console.error(e) - console.log(page.url()) - const { action } = await inquirer.prompt([ - { - type: 'input', - name: 'action', - message: `Could not search DuckDuckGo for ${album.name} by ${album.creator}. Do you want to enter URL manually?`, - }, - ]) - - let data: Partial = { - metadata: { - ...album.metadata, - reviewUnresolvable: true, - }, - } - - if (action?.startsWith('https://')) { - data.reviewURL = action as string - } - - await database - .update(reviewedItems) - .set(data) - .where(eq(reviewedItems.id, album.id)) - .run() - - return - } - - const linkElms = await linksLocator.all() - const options: { title: string; link: string }[] = [] - - for (let el of linkElms) { - const link = await el.getAttribute('href') - const title = await el.textContent() - - if (!link || !title) { - continue - } - - options.push({ title, link }) - } - - const { link } = await inquirer.prompt([ - { - type: 'rawlist', - name: 'link', - message: `Which link for ${album.name} by ${album.creator}`, - choices: [ - ...options.map((res) => ({ - name: `[${res.title}](${res.link})`, - value: res.link, - })), - { - name: 'Skip', - value: '', - }, - ], - }, - ]) - - if (!link) { - await database - .update(reviewedItems) - .set({ - metadata: { - ...album.metadata, - reviewUnresolvable: true, - }, - }) - .where(eq(reviewedItems.id, album.id)) - .run() - - return - } - - try { - return database - .update(reviewedItems) - .set({ reviewURL: link }) - .where(eq(reviewedItems.id, album.id)) - .run() - } catch (e) { - if (e instanceof Error && e.message.includes('reviewURL')) { - return database - .update(reviewedItems) - .set({ reviewURL: link + `#${album.id}` }) - .where(eq(reviewedItems.id, album.id)) - .run() - } - - console.error(e) - return duckDuckGoUpdateAlbum(album, hostname) - } finally { - await context.close() - } - } - - for (let album of reviews) { - await duckDuckGoUpdateAlbum(album, hostname) - } -} - -main() diff --git a/app/routes/twitter.$username.tsx b/app/routes/twitter.$username.tsx index cf10fa0..85d632d 100644 --- a/app/routes/twitter.$username.tsx +++ b/app/routes/twitter.$username.tsx @@ -123,7 +123,7 @@ export default function AlbumFromTwitter() { album: data.tweet.album, albumID: data.tweet.reviewMetadata.bandcamp.albumID, artist: data.tweet.artist, - imageURL: data.tweet.reviewMetadata.imageURL ?? null, + imageURL: data.tweet.reviewMetadata.bandcamp.imageURL ?? null, url: data.tweet.reviewMetadata.bandcamp.url, }} footer={tweet}