import 'dotenv/config' import { JSDOM } from 'jsdom' import sanitizeHtml from 'sanitize-html' export function markdownLinkRegex(url) { return new RegExp( `(\\[).*?(\\]\\(https:\\/\\/${url.replaceAll('.', '\\.')}\\))`, 'i', ) } export function markdownCharEscape(text) { return text .replaceAll('`', '\\`') .replaceAll('*', '\\*') .replaceAll('_', '\\_') .replaceAll('{', '\\{') .replaceAll('}', '\\}') .replaceAll('[', '\\[') .replaceAll(']', '\\]') .replaceAll('(', '\\(') .replaceAll(')', '\\)') .replaceAll('#', '\\#') .replaceAll('+', '\\+') .replaceAll('-', '\\-') .replaceAll('.', '\\.') .replaceAll('!', '\\!') } export async function getRSSItemTitle(feedUrl) { const res = await fetch(feedUrl) const data = await res.text() const dom = new JSDOM(data) const item = dom.window.document.querySelector('item') const title = item.querySelector('title').textContent return markdownCharEscape( sanitizeHtml(title, { allowedTags: [], allowedAttributes: {}, })?.trim(), ) } export async function getJsonFeedItemTitle(feedUrl, showImage = true) { const res = await fetch(feedUrl) const data = await res.json() const post = data.items[0] const { title, image } = post const cleanTitle = markdownCharEscape(title) if (!showImage) { return cleanTitle } return image ? `${cleanTitle} ![${cleanTitle}](${image})` : cleanTitle } export async function getJsonFeedItemContent(feedUrl, showImage = true) { const res = await fetch(feedUrl) const data = await res.json() const post = data.items[0] const { content_html, image } = post const title = sanitizeHtml(content_html, { allowedTags: [], allowedAttributes: {}, })?.trim() const cleanTitle = markdownCharEscape(title) if (!showImage) { return cleanTitle } return image ? `${cleanTitle} ![${cleanTitle}](${image})` : cleanTitle } export async function getMalojaScrobble(malojaUrl) { const res = await fetch(`${malojaUrl}/apis/mlj_1/scrobbles?perpage=1`) const data = await res.json() const scrobble = data.list[0] const { title, album: { artists }, } = scrobble.track const cleanTitle = markdownCharEscape(title) const cleanArtists = markdownCharEscape(artists.join(', ')) return markdownCharEscape(`${cleanTitle}
by ${cleanArtists}`) } export async function getLetterboxdActivity(username, showImage = true) { const res = await fetch(`https://letterboxd.com/${username}/rss/`) const data = await res.text() const dom = new JSDOM(data) const item = dom.window.document.querySelector('item') const title = item.querySelector('title').textContent const cleanTitle = markdownCharEscape(title) const image = item.querySelector('description > img').src if (!showImage) { return cleanTitle } return `${cleanTitle} ![${cleanTitle}](${image})` } export async function getTraktEpisode(username, id, showImage = true) { const res = await fetch( `https://trakt.tv/users/${username}/history/episodes/added/asc.atom?slurm=${process.env.TRAKT_SLURM}`, ) const data = await res.text() const dom = new JSDOM(data) const entry = dom.window.document.querySelector('entry') const title = entry.querySelector('title').textContent const cleanTitle = markdownCharEscape(title) if (!showImage) { return cleanTitle } return `${cleanTitle} ![${cleanTitle}](https://widgets.trakt.tv/users/${id}/watched/thumb@2x.jpg?type=episode&image_only=1)` } export async function getReadingBooklogr(booklogrUrl, booklogrUser) { const res = await fetch(`${booklogrUrl}/v1/profiles/${booklogrUser}`) const data = await res.json() const books = data.books.filter( ({ reading_status }) => reading_status === 'Currently reading', ) return books.map(({ title }) => title).join(',
') }