Merge pull request 'add direct linking to individual items from feeds' (#1) from update/direct-links into main
Reviewed-on: https://source.tube/dylan/now-updater/pulls/1
This commit is contained in:
commit
a3ed5a4a82
4 changed files with 59 additions and 26 deletions
12
config.js
12
config.js
|
|
@ -5,7 +5,8 @@ import {
|
|||
getMalojaScrobble,
|
||||
getReadingBooklogr,
|
||||
getRSSItemTitle,
|
||||
getTraktEpisodeAndMovie,
|
||||
getTraktEpisode,
|
||||
getTraktMovie,
|
||||
htmlLinkRegex,
|
||||
} from './utils.js'
|
||||
|
||||
|
|
@ -28,9 +29,14 @@ export const items = [
|
|||
getLatest: async () => getLetterboxdActivity('stfudonny', false),
|
||||
},
|
||||
{
|
||||
id: 'trakt',
|
||||
id: 'trakt-episode',
|
||||
regex: htmlLinkRegex('trakt.tv/users/crankle'),
|
||||
getLatest: async () =>
|
||||
getTraktEpisodeAndMovie('crankle', '78e1e87b446901f7e4f0883dd4995cec', false),
|
||||
getTraktEpisode('crankle', '78e1e87b446901f7e4f0883dd4995cec', false),
|
||||
},
|
||||
{
|
||||
id: 'trakt-movie',
|
||||
regex: htmlLinkRegex('trakt.tv/users/crankle'),
|
||||
getLatest: async () => getTraktMovie('crankle', false),
|
||||
},
|
||||
]
|
||||
|
|
|
|||
14
index.js
14
index.js
|
|
@ -34,9 +34,17 @@ export default async function now() {
|
|||
items.map(async ({ id, regex, getLatest }) => {
|
||||
try {
|
||||
const latest = await getLatest()
|
||||
console.log(`${id}: ${latest}`)
|
||||
if (latest) {
|
||||
newNow = newNow.replace(regex, `$1${latest}$2`)
|
||||
console.log(`${id}: ${latest.text}`)
|
||||
console.log(`${id} URL: ${latest.url}`)
|
||||
if (latest && latest.text && latest.url) {
|
||||
newNow = newNow.replace(regex, (match, openTag, closeTag) => {
|
||||
// Replace href in opening tag
|
||||
const updatedOpenTag = openTag.replace(
|
||||
/href=["'][^"']*["']/,
|
||||
`href="${latest.url}"`,
|
||||
)
|
||||
return `${updatedOpenTag}${latest.text}${closeTag}`
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(`⚠️ Failed to fetch ${id}`, e)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,10 @@
|
|||
I rated this<br>{letterboxd} <a href="https://letterboxd.com/STFUDonny" style="color: #f38ba8 !important;">tktk</a>
|
||||
</div>
|
||||
<div style="background: rgba(250, 179, 135, 0.15); padding: 1rem; border: 4px solid #fab387; color:white;">
|
||||
I watched this<br>{trakt} <a href="https://trakt.tv/users/crankle" style="color: #fab387 !important;">tktk</a>
|
||||
I watched this episode<br>
|
||||
<i class="fa-solid fa-tv"></i> <a href="https://trakt.tv/users/crankle" style="color: #fab387 !important;">tktk</a><br>
|
||||
and this movie<br>
|
||||
<i class="fa-solid fa-film"></i> <a href="https://trakt.tv/users/crankle" style="color: #fab387 !important;">tktk</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
52
utils.js
52
utils.js
|
|
@ -38,27 +38,31 @@ export function markdownCharEscape(text) {
|
|||
export async function getRSSItemTitle(feedUrl) {
|
||||
const res = await fetch(feedUrl)
|
||||
const data = await res.text()
|
||||
const dom = new JSDOM(data)
|
||||
const dom = new JSDOM(data, { contentType: 'text/xml' })
|
||||
const item = dom.window.document.querySelector('item')
|
||||
const title = item.querySelector('title').textContent
|
||||
return markdownCharEscape(
|
||||
const link = item.querySelector('link').textContent.trim()
|
||||
const cleanTitle = markdownCharEscape(
|
||||
sanitizeHtml(title, {
|
||||
allowedTags: [],
|
||||
allowedAttributes: {},
|
||||
})?.trim(),
|
||||
)
|
||||
return { text: cleanTitle, url: link }
|
||||
}
|
||||
|
||||
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 { title, image, url } = post
|
||||
const cleanTitle = markdownCharEscape(title)
|
||||
if (!showImage) {
|
||||
return cleanTitle
|
||||
}
|
||||
return image ? `${cleanTitle} ` : cleanTitle
|
||||
const text = !showImage
|
||||
? cleanTitle
|
||||
: image
|
||||
? `${cleanTitle} `
|
||||
: cleanTitle
|
||||
return { text, url }
|
||||
}
|
||||
|
||||
export async function getJsonFeedItemContent(feedUrl, showImage = true) {
|
||||
|
|
@ -93,15 +97,22 @@ export async function getMalojaScrobble(malojaUrl) {
|
|||
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 dom = new JSDOM(data, { contentType: 'text/xml' })
|
||||
const item = dom.window.document.querySelector('item')
|
||||
const title = item.querySelector('title').textContent
|
||||
const link = item.querySelector('link').textContent.trim()
|
||||
const cleanTitle = markdownCharEscape(title)
|
||||
const image = item.querySelector('description > img').src
|
||||
if (!showImage) {
|
||||
return cleanTitle
|
||||
|
||||
let text = cleanTitle
|
||||
if (showImage) {
|
||||
// Parse CDATA content as HTML to extract image
|
||||
const description = item.querySelector('description').textContent
|
||||
const imgMatch = description.match(/<img[^>]+src="([^"]+)"/)
|
||||
const image = imgMatch ? imgMatch[1] : null
|
||||
text = image ? `${cleanTitle} ` : cleanTitle
|
||||
}
|
||||
return `${cleanTitle} `
|
||||
|
||||
return { text, url: link }
|
||||
}
|
||||
|
||||
export async function getTraktEpisode(username, id, showImage = true) {
|
||||
|
|
@ -112,11 +123,12 @@ export async function getTraktEpisode(username, id, showImage = true) {
|
|||
const dom = new JSDOM(data)
|
||||
const entry = dom.window.document.querySelector('entry')
|
||||
const title = entry.querySelector('title').textContent
|
||||
const link = entry.querySelector('link').getAttribute('href')
|
||||
const cleanTitle = markdownCharEscape(title)
|
||||
if (!showImage) {
|
||||
return cleanTitle
|
||||
}
|
||||
return `${cleanTitle} `
|
||||
const text = !showImage
|
||||
? cleanTitle
|
||||
: `${cleanTitle} `
|
||||
return { text, url: link }
|
||||
}
|
||||
|
||||
export async function getTraktMovie(username, showImage = true) {
|
||||
|
|
@ -127,13 +139,17 @@ export async function getTraktMovie(username, showImage = true) {
|
|||
const dom = new JSDOM(data)
|
||||
const entry = dom.window.document.querySelector('entry')
|
||||
const title = entry.querySelector('title').textContent
|
||||
return markdownCharEscape(title)
|
||||
const link = entry.querySelector('link').getAttribute('href')
|
||||
return { text: markdownCharEscape(title), url: link }
|
||||
}
|
||||
|
||||
export async function getTraktEpisodeAndMovie(username, id, showImage = true) {
|
||||
const episode = await getTraktEpisode(username, id, showImage)
|
||||
const movie = await getTraktMovie(username, showImage)
|
||||
return `${episode} <br>and<br> ${movie}`
|
||||
return {
|
||||
text: `${episode.text} <br>and<br> ${movie.text}`,
|
||||
url: `https://trakt.tv/users/${username}`,
|
||||
}
|
||||
}
|
||||
|
||||
export async function getReadingBooklogr(booklogrUrl, booklogrUser) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue