'use strict'; const unprint = require('unprint'); const fs = require('fs'); const { Readable } = require('stream'); const { pipeline } = require('stream/promises'); const knex = require('../knex'); const argv = require('../argv'); const slugify = require('../utils/slugify'); const apiUrl = 'https://vjoc5ygk89-dsn.algolia.net/1/indexes/*/queries?x-algolia-agent=Algolia%20for%20JavaScript%20(3.33.0)%3B%20Browser%20(lite)%3B%20react%20(16.8.6)%3B%20react-instantsearch%20(5.7.0)%3B%20JS%20Helper%20(2.28.1)&x-algolia-application-id=VJOC5YGK89&x-algolia-api-key=c5546bdfb4d3f31daf49ed3bb1463561'; async function fetchBanners() { const res = await unprint.post( apiUrl, { requests: [ { indexName: 'creatives', params: new URLSearchParams({ hitsPerPage: 1000, maxValuesPerFacet: 100, page: 0, filters: '(ProgramType:Legacy OR ProgramType:Internal) AND NOT OverlayActive:false', facets: '["SceneActors","SceneCategories","ProgramName","Size","Niche","MediaExt","SiteTag","OverlayName"]', facetFilters: `[["SiteTag:${argv.site}"],["MediaExt:jpg", "MediaExt:png", "MediaExt:gif"]]`, }).toString(), }, ], }, { headers: { 'content-type': 'application/x-www-form-urlencoded', referer: 'https://creatives.gammae.com/', }, }, ); if (res.ok && res.data.results[0]) { return res.data.results[0].hits; } console.error(`Failed API request (${res.status}): ${res.body}`); return null; } async function matchTags(rawTags) { if (!rawTags) { return []; } const tags = rawTags .map((tag) => tag?.trim().match(/[a-z0-9()]+/ig)?.join(' ').toLowerCase()) .filter(Boolean); const tagEntries = await knex('tags') .select('tags.slug', 'aliases.slug as alias_slug') .whereIn(knex.raw('lower(tags.name)'), tags) .leftJoin('tags as aliases', 'aliases.id', 'tags.alias_for') .orderByRaw('CASE WHEN tags.alias_for IS NOT NULL THEN aliases.priority ELSE tags.priority END DESC'); return tagEntries.map((tagEntry) => tagEntry.alias_slug || tagEntry.slug); } async function init() { const banners = await fetchBanners(); if (!banners) { return; } await banners.reduce(async (chain, banner) => { await chain; const channel = slugify(banner.SiteTag, ''); const url = unprint.prefixUrl(banner.MediaLocation || banner.CreativeURL, 'https://cdn.banhq.com'); if (!url) { console.log('No URL found'); console.log(banner); return; } const tags = await matchTags([ ...banner.Tags?.map((tag) => tag.Value) || [], ...banner.SceneCategories || [], banner.Niche, ].filter(Boolean)); const fileTags = tags.slice(0, 4).join('_'); const fileActors = banner.SceneActors?.slice(0, 2).map((actor) => slugify(actor, '_')).join('_'); const filename = `${channel}_${banner.Width}_${banner.Height}_${fileActors || banner.MediaID}${fileTags ? `-${fileTags}` : ''}.${banner.MediaExt}`; const filepath = `/tmp/gamma/${channel}/${filename}`; if (argv.inspect) { console.log(banner); } if (argv.preview) { console.log(`Preview ${url}: ${filepath}`); return; } await fs.promises.mkdir(`/tmp/gamma/${channel}`, { recursive: true }); try { const res = await fetch(url); if (res.ok && res.body) { const writer = fs.createWriteStream(filepath); await pipeline(Readable.fromWeb(res.body), writer); console.log(`Saved ${url} to ${filepath}`); } else { console.log(`Failed to fetch ${url} (${res.status})`); } } catch (error) { console.log(`Failed to fetch ${url}: ${error.message}`); } }, Promise.resolve()); await knex.destroy(); } init();