import 'dotenv/config' import { items, linkFormat } from './config.js' import { getAtomFeed, getHardcoverActivity, getJsonFeedItemTitle, getLetterboxdActivity, getListenBrainzScrobble, getMalojaScrobble, getMastodonPost, getRSSItemTitle, getSomePicsPost, getSourceTubeActivity, getSteamRecentlyPlayed, getTraktEpisode, getTraktMovie, htmlServiceLinkRegex, markdownCharEscape, markdownServiceLinkRegex, } from './utils.js' const feedHandlers = { rss: getRSSItemTitle, atom: getAtomFeed, json: getJsonFeedItemTitle, 'some.pics': getSomePicsPost, 'source.tube': getSourceTubeActivity, mastodon: getMastodonPost, letterboxd: getLetterboxdActivity, 'trakt-episode': getTraktEpisode, 'trakt-movie': getTraktMovie, steam: getSteamRecentlyPlayed, listenbrainz: getListenBrainzScrobble, maloja: getMalojaScrobble, hardcover: getHardcoverActivity, } const OMGLOL_API = `https://api.omg.lol/address/${process.env.OMGLOL_USERNAME}/now` export async function getNow() { const res = await fetch(OMGLOL_API) const data = await res.json() return data.response.now.content } export async function setNow(newNow) { const res = await fetch(OMGLOL_API, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${process.env.OMGLOL_KEY}`, }, body: JSON.stringify({ content: newNow, listed: 1, }), }) const data = await res.json() console.log(`\n${data.response.message}`) } export default async function now() { const now = await getNow() let newNow = now await Promise.all( items.map(async (item) => { try { const handler = feedHandlers[item.feedType] if (!handler) { throw new Error(`Unknown feedType: ${item.feedType}`) } // build feedUrl from template if provided let feedUrl = item.feedUrl if (item.feedUrlTemplate) { feedUrl = item.feedUrlTemplate .replace('{userId}', item.userId || '') .replace('{instance}', item.instance || '') } // generic handlers expect just feedUrl string, special handlers expect config object const handlerParam = [ 'rss', 'atom', 'json', 'maloja', 'some.pics', ].includes(item.feedType) ? feedUrl : { ...item, feedUrl } const latest = await handler(handlerParam) console.log(`${item.id}: ${latest.text}`) console.log(`${item.id} URL: ${latest.url}`) if (latest.image) console.log(`${item.id} Image: ${latest.image}`) if (latest.video) console.log(`${item.id} Video: ${latest.video}`) // apply markdown escaping only for markdown links const displayText = linkFormat === 'html' ? latest.text : markdownCharEscape(latest.text) if (latest && latest.text && latest.url) { // generate regex based on id and linkFormat const regex = linkFormat === 'html' ? htmlServiceLinkRegex(item.id) : markdownServiceLinkRegex(item.id) console.log(`\nDEBUG: Testing regex for ${item.id}`) console.log(`Regex: ${regex}`) const matched = regex.test(newNow) console.log(`Regex match found: ${matched}`) newNow = newNow.replace(regex, (match, openTag, oldText, closeTag) => { console.log(`DEBUG: Replacing match for ${item.id}`) console.log(`Old match: ${match}`) console.log(`Old text: ${oldText}`) // replace href in opening tag const updatedOpenTag = openTag.replace( /href=["'][^"']*["']/, `href="${latest.url}"`, ) const result = `${updatedOpenTag}${displayText}${closeTag}` console.log(`New replacement: ${result}`) return result }) // replace image/video placeholders if available, otherwise remove tags const imageId = `${item.id}-image` const videoId = `${item.id}-video` if (latest.image) { // html image replacement newNow = newNow.replace( new RegExp(`(]+src=["'])${imageId}(["'][^>]*>)`, 'gi'), `$1${latest.image}$2`, ) // markdown image replacement newNow = newNow.replace( new RegExp(`(!\\[[^\\]]*\\]\\()${imageId}(\\))`, 'gi'), `$1${latest.image}$2`, ) } else { // remove img tags if no image available (handle multi-line tags and any attribute order) newNow = newNow.replace( new RegExp(`\\s*]*\\bsrc=["']${imageId}["'][^>]*>\\s*`, 'gis'), '', ) // remove markdown image newNow = newNow.replace( new RegExp(`!\\[[^\\]]*\\]\\(${imageId}\\)`, 'gi'), '', ) } if (latest.video) { // html video replacement newNow = newNow.replace( new RegExp(`(]+src=["'])${videoId}(["'][^>]*>)`, 'gi'), `$1${latest.video}$2`, ) } else { // remove video tags if no video available newNow = newNow.replace( new RegExp(`\\s*]*\\bsrc=["']${videoId}["'][^>]*>[\\s\\S]*?\\s*`, 'gis'), '', ) } } } catch (e) { console.warn(`⚠️ Failed to fetch ${item.id}`, e) } }), ) console.log('\n=== FINAL COMPARISON ===') console.log(`Original length: ${now.length}`) console.log(`New length: ${newNow.length}`) console.log(`Strings are equal: ${now === newNow}`) if (now === newNow) { console.log('\nNow page has no changes') } else { console.log('\nChanges detected! Updating Now page...') await setNow(newNow) } } await now()