refactor: don't fetch steam / lastfm / bsky posts on user request, instead peridocially do it in the background every minute
This commit is contained in:
parent
4b81de80d5
commit
a90bf50558
@ -43,8 +43,10 @@
|
||||
"@neodrag/svelte": "^2.3.0",
|
||||
"@skyware/bot": "^0.3.8",
|
||||
"@std/toml": "npm:@jsr/std__toml",
|
||||
"@types/node-schedule": "^2.1.7",
|
||||
"base64url": "^3.0.1",
|
||||
"nanoid": "^5.0.9",
|
||||
"node-schedule": "^2.1.1",
|
||||
"rehype-autolink-headings": "^7.1.0",
|
||||
"rehype-slug": "^6.0.0",
|
||||
"robots-parser": "^3.0.1",
|
||||
|
17
src/hooks.server.ts
Normal file
17
src/hooks.server.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { updateLastPosts } from '$lib/bluesky';
|
||||
import { lastFmUpdateNowPlaying } from '$lib/lastfm';
|
||||
import { steamUpdateNowPlaying } from '$lib/steam'
|
||||
import { cancelJob, scheduleJob, scheduledJobs } from 'node-schedule'
|
||||
|
||||
const UPDATE_LAST_JOB_NAME = "update steam game, lastfm track, bsky posts"
|
||||
|
||||
if (UPDATE_LAST_JOB_NAME in scheduledJobs) {
|
||||
console.log(`${UPDATE_LAST_JOB_NAME} is already running, cancelling so we can start a new one`)
|
||||
cancelJob(UPDATE_LAST_JOB_NAME)
|
||||
}
|
||||
|
||||
console.log(`starting ${UPDATE_LAST_JOB_NAME} job...`);
|
||||
scheduleJob(UPDATE_LAST_JOB_NAME, "*/1 * * * *", async () => {
|
||||
console.log(`running ${UPDATE_LAST_JOB_NAME} job...`)
|
||||
await Promise.all([steamUpdateNowPlaying(), lastFmUpdateNowPlaying(), updateLastPosts()])
|
||||
}).invoke() // invoke once immediately
|
@ -32,4 +32,13 @@ export const getUserPosts = async (did: string, includeReposts: boolean = false,
|
||||
feedCursor = feedData.cursor
|
||||
}
|
||||
return posts
|
||||
}
|
||||
}
|
||||
|
||||
const lastPosts = writable<Post[]>([])
|
||||
|
||||
export const updateLastPosts = async () => {
|
||||
const posts = await getUserPosts("did:plc:dfl62fgb7wtjj3fcbb72naae", false, 13)
|
||||
lastPosts.set(posts)
|
||||
}
|
||||
|
||||
export const getLastPosts = () => { return get(lastPosts) }
|
@ -1,17 +1,11 @@
|
||||
import { get, writable } from "svelte/store"
|
||||
|
||||
const GET_RECENT_TRACKS_ENDPOINT = "https://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=yusdacra&api_key=da1911d405b5b37383e200b8f36ee9ec&format=json&limit=1"
|
||||
const CACHE_EXPIRY_SECONDS = 10
|
||||
|
||||
type LastTrack = {name: string, artist: string, image: string | null, link: string}
|
||||
type CachedLastTrack = {track: LastTrack | null, since: number}
|
||||
const cachedLastTrack = writable<CachedLastTrack>({track: null, since: 0})
|
||||
const lastTrack = writable<LastTrack | null>(null)
|
||||
|
||||
export const lastFmGetNowPlaying: () => Promise<LastTrack | null> = async () => {
|
||||
var cached = get(cachedLastTrack)
|
||||
if (Date.now() - cached.since < CACHE_EXPIRY_SECONDS * 1000) {
|
||||
return cached.track
|
||||
}
|
||||
export const lastFmUpdateNowPlaying = async () => {
|
||||
try {
|
||||
var resp = await (await fetch(GET_RECENT_TRACKS_ENDPOINT)).json()
|
||||
var track = resp.recenttracks.track[0] ?? null
|
||||
@ -24,11 +18,11 @@ export const lastFmGetNowPlaying: () => Promise<LastTrack | null> = async () =>
|
||||
image: track.image[2]['#text'] ?? null,
|
||||
link: track.url,
|
||||
}
|
||||
cachedLastTrack.set({track: data, since: Date.now()})
|
||||
return data
|
||||
lastTrack.set(data)
|
||||
} catch(why) {
|
||||
console.log("could not fetch last fm: ", why)
|
||||
cachedLastTrack.set({track: null, since: Date.now()})
|
||||
return null
|
||||
lastTrack.set(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const getNowPlaying = () => { return get(lastTrack) }
|
@ -4,42 +4,36 @@ import { get, writable } from "svelte/store";
|
||||
|
||||
const STEAM_ID = "76561198106829949"
|
||||
const GET_PLAYER_SUMMARY_ENDPOINT = `http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=${env.STEAM_API_KEY}&steamids=${STEAM_ID}&format=json`
|
||||
const CACHE_EXPIRY_SECONDS = 10
|
||||
|
||||
type LastGame = {name: string, link: string, icon: string, pfp: string}
|
||||
type CachedLastGame = {game: LastGame | null, since: number}
|
||||
|
||||
const steamgriddbClient = writable<SGDB | null>(null);
|
||||
const cachedLastGame = writable<CachedLastGame>({game: null, since: 0})
|
||||
const steamgriddbClient = writable<SGDB | null>(null)
|
||||
const lastGame = writable<LastGame | null>(null)
|
||||
|
||||
export const steamGetNowPlaying: () => Promise<LastGame | null> = async () => {
|
||||
export const steamUpdateNowPlaying = async () => {
|
||||
var griddbClient = get(steamgriddbClient)
|
||||
if (griddbClient === null) {
|
||||
griddbClient = new SGDB(env.STEAMGRIDDB_API_KEY)
|
||||
steamgriddbClient.set(griddbClient)
|
||||
}
|
||||
var cached = get(cachedLastGame)
|
||||
if (Date.now() - cached.since < CACHE_EXPIRY_SECONDS * 1000) {
|
||||
return cached.game
|
||||
}
|
||||
try {
|
||||
var profile = (await (await fetch(GET_PLAYER_SUMMARY_ENDPOINT)).json()).response.players[0]
|
||||
if (!profile.gameid) {
|
||||
throw "no game is being played"
|
||||
}
|
||||
var icons = await griddbClient.getIconsBySteamAppId(profile.gameid, ['official'])
|
||||
console.log(icons)
|
||||
var game = {
|
||||
//console.log(icons)
|
||||
var game: LastGame = {
|
||||
name: profile.gameextrainfo,
|
||||
link: `https://store.steampowered.com/app/${profile.gameid}`,
|
||||
icon: icons[0].thumb.toString(),
|
||||
pfp: profile.avatarmedium,
|
||||
}
|
||||
cachedLastGame.set({game, since: Date.now()})
|
||||
return game
|
||||
lastGame.set(game)
|
||||
} catch(why) {
|
||||
console.log("could not fetch steam: ", why)
|
||||
cachedLastGame.set({game: null, since: Date.now()})
|
||||
return null
|
||||
lastGame.set(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const getLastGame = () => { return get(lastGame) }
|
@ -1,12 +1,13 @@
|
||||
import { getUserPosts } from "$lib/bluesky.js"
|
||||
import { lastFmGetNowPlaying } from "$lib/lastfm"
|
||||
import { steamGetNowPlaying } from "$lib/steam"
|
||||
import { getLastPosts } from "$lib/bluesky.js"
|
||||
import { getNowPlaying } from "$lib/lastfm"
|
||||
import { getLastGame } from "$lib/steam"
|
||||
import { noteFromBskyPost } from "../components/note.svelte"
|
||||
|
||||
export const load = async ({}) => {
|
||||
const lastTrack = await lastFmGetNowPlaying()
|
||||
const lastGame = await steamGetNowPlaying()
|
||||
const lastNote = noteFromBskyPost((await getUserPosts("did:plc:dfl62fgb7wtjj3fcbb72naae", false, 1))[0])
|
||||
const lastTrack = getNowPlaying()
|
||||
const lastGame = getLastGame()
|
||||
const lastPosts = getLastPosts()
|
||||
const lastNote = lastPosts.length > 0 ? noteFromBskyPost(lastPosts[0]) : null
|
||||
let banners: number[] = []
|
||||
while (banners.length < 3) {
|
||||
const no = getBannerNo(banners)
|
||||
|
@ -146,6 +146,7 @@
|
||||
</div>
|
||||
</Window>
|
||||
<Window title="status" style="mt-auto" removePadding>
|
||||
{#if data.lastNote}
|
||||
<div class="m-1.5 flex flex-col font-monospace">
|
||||
<div
|
||||
class="prose prose-ralsei items-center p-1 border-4 text-sm font-bold bg-ralsei-black"
|
||||
@ -158,6 +159,7 @@
|
||||
<Note note={data.lastNote} onlyContent/>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if data.lastTrack}
|
||||
<div class="flex flex-row m-1.5 border-4 border-double bg-ralsei-black">
|
||||
<!-- svelte-ignore a11y-missing-attribute -->
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { getUserPosts } from '$lib/bluesky.js';
|
||||
import { getLastPosts, getUserPosts } from '$lib/bluesky.js';
|
||||
import { noteFromBskyPost } from '../../components/note.svelte';
|
||||
|
||||
export const load = async ({ }) => {
|
||||
@ -7,6 +7,6 @@ export const load = async ({ }) => {
|
||||
|
||||
export const _load = async () => {
|
||||
return {
|
||||
feedPosts: (await getUserPosts("did:plc:dfl62fgb7wtjj3fcbb72naae", false, 13)).map(noteFromBskyPost),
|
||||
feedPosts: getLastPosts().map(noteFromBskyPost),
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user