trakt support

This commit is contained in:
Melanie Kat 2025-12-17 21:53:32 -08:00
parent 4d58fff75d
commit 911d851fb1
5 changed files with 68 additions and 47 deletions

View file

@ -1,2 +1,3 @@
OMGLOL_KEY=
OMGLOL_USERNAME=melanie
TRAKT_SLURM=

View file

@ -23,3 +23,4 @@ jobs:
env:
OMGLOL_KEY: ${{ secrets.OMGLOL_KEY }}
OMGLOL_USERNAME: ${{ vars.OMGLOL_USERNAME }}
TRAKT_SLURM: ${{ secrets.TRAKT_SLURM }}

View file

@ -21,7 +21,8 @@
},
"javascript": {
"formatter": {
"quoteStyle": "double"
"quoteStyle": "single",
"semicolons": "asNeeded"
}
},
"assist": {

View file

@ -3,36 +3,43 @@ import {
getJsonFeedItemTitle,
getLetterboxdActivity,
getMalojaScrobble,
getTraktEpisode,
markdownLinkRegex,
} from "./utils.js";
} from './utils.js'
export const items = [
{
id: "blog",
regex: markdownLinkRegex("melkat.blog"),
id: 'blog',
regex: markdownLinkRegex('melkat.blog'),
getLatest: async () =>
getJsonFeedItemTitle("https://melkat.blog/feed.json"),
getJsonFeedItemTitle('https://melkat.blog/feed.json'),
},
{
id: "pics",
regex: markdownLinkRegex("melkat.pics"),
id: 'pics',
regex: markdownLinkRegex('melkat.pics'),
getLatest: async () =>
getJsonFeedItemTitle("https://melkat.pics/feed.json"),
getJsonFeedItemTitle('https://melkat.pics/feed.json'),
},
{
id: "lol",
regex: markdownLinkRegex("melkat.lol"),
id: 'lol',
regex: markdownLinkRegex('melkat.lol'),
getLatest: async () =>
getJsonFeedItemContent("https://melkat.lol/feed.json"),
getJsonFeedItemContent('https://melkat.lol/feed.json'),
},
{
id: "maloja",
regex: markdownLinkRegex("scrobbles.melkat.dev"),
getLatest: async () => getMalojaScrobble("https://scrobbles.melkat.dev"),
id: 'maloja',
regex: markdownLinkRegex('scrobbles.melkat.dev'),
getLatest: async () => getMalojaScrobble('https://scrobbles.melkat.dev'),
},
{
id: "letterboxd",
regex: markdownLinkRegex("letterboxd.com/zicklepop"),
getLatest: async () => getLetterboxdActivity("zicklepop"),
id: 'letterboxd',
regex: markdownLinkRegex('letterboxd.com/zicklepop'),
getLatest: async () => getLetterboxdActivity('zicklepop'),
},
];
{
id: 'trakt',
regex: markdownLinkRegex('trakt.tv/users/zicklepop'),
getLatest: async () =>
getTraktEpisode('zicklepop', 'd0a982626d7793b5cf1857a2128277cc'),
},
]

View file

@ -1,51 +1,62 @@
import { JSDOM } from "jsdom";
import sanitizeHtml from "sanitize-html";
import 'dotenv/config'
import { JSDOM } from 'jsdom'
import sanitizeHtml from 'sanitize-html'
export function markdownLinkRegex(url) {
return new RegExp(
`(\\[).*?(\\]\\(https:\\/\\/${url.replaceAll(".", "\\.")}\\))`,
"i",
);
`(\\[).*?(\\]\\(https:\\/\\/${url.replaceAll('.', '\\.')}\\))`,
'i',
)
}
export async function getJsonFeedItemTitle(feedUrl) {
const res = await fetch(feedUrl);
const data = await res.json();
const post = data.items[0];
const { title, image } = post;
return image ? `${title} ![${title}](${image})` : title;
const res = await fetch(feedUrl)
const data = await res.json()
const post = data.items[0]
const { title, image } = post
return image ? `${title} ![${title}](${image})` : title
}
export async function getJsonFeedItemContent(feedUrl) {
const res = await fetch(feedUrl);
const data = await res.json();
const post = data.items[0];
const { content_html, image } = post;
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();
return image ? `${title} ![${title}](${image})` : title;
})?.trim()
return image ? `${title} ![${title}](${image})` : title
}
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 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;
return `${title}<br />by ${artists.join(", ")}`;
} = scrobble.track
return `${title}<br />by ${artists.join(', ')}`
}
export async function getLetterboxdActivity(username) {
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 image = item.querySelector("description > img").src;
return `${title} ![${title}](${image})`;
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 image = item.querySelector('description > img').src
return `${title} ![${title}](${image})`
}
export async function getTraktEpisode(username, id) {
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
return `${title} ![${title}](https://widgets.trakt.tv/users/${id}/watched/thumb@2x.jpg?type=episode&image_only=1)`
}