diff --git a/src/routes/api.ts b/src/routes/api.ts new file mode 100644 index 0000000..5022182 --- /dev/null +++ b/src/routes/api.ts @@ -0,0 +1,88 @@ +import { + WALLABAG_CLIENT_ID, + WALLABAG_CLIENT_SECRET, + WALLABAG_USERNAME, + WALLABAG_PASSWORD, + WALLABAG_URL +} from '$env/static/private'; +import { URLSearchParams } from 'url'; + +const base: string = WALLABAG_URL; + +export async function fetchArticlesApi( + method: string, + resource: string, + queryParams: Record, + data?: Record +) { + let lastFetched = null; + + const authBody = { + grant_type: 'password', + client_id: WALLABAG_CLIENT_ID, + client_secret: WALLABAG_CLIENT_SECRET, + username: WALLABAG_USERNAME, + password: WALLABAG_PASSWORD + }; + + const authResponse = await fetch(`${base}/oauth/v2/token`, { + method: 'POST', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + body: new URLSearchParams(authBody) + }); + + const auth = await authResponse.json(); + + const pageQuery = { + sort: 'updated', + perPage: 500 + }; + + if (lastFetched) { + pageQuery.since = Math.round(lastFetched / 1000); + } + + lastFetched = new Date(); + + let nbEntries = 0; + const pageResponse = await fetch( + `${WALLABAG_URL}/api/entries.json?${new URLSearchParams(pageQuery)}`, + { + method: 'GET', + headers: { + Authorization: `Bearer ${auth.access_token}` + } + } + ); + + if (!pageResponse.ok) { + throw new Error(pageResponse.statusText); + } + + let entries = await pageResponse.json(); + const articles = []; + + do { + nbEntries += entries._embedded.items.length; + console.log(`number of articles fetched: ${nbEntries}`); + entries._embedded.items.forEach((article) => { + article.created_at = new Date(article.created_at); + article.updated_at = new Date(article.updated_at); + article.archived_at = article.archived_at ? new Date(article.archived_at) : null; + articles.push(article); + }); + + if (!entries._links.next) { + return; + } + const response = await fetch(entries._links.next.href, { + method: 'GET', + headers: { + Authorization: `Bearer ${auth.access_token}` + } + }); + entries = await response.json(); + } while (entries._links.next); + + return { articles }; +} diff --git a/src/routes/articles/+page.server.ts b/src/routes/articles/+page.server.ts new file mode 100644 index 0000000..1e928ad --- /dev/null +++ b/src/routes/articles/+page.server.ts @@ -0,0 +1,32 @@ +import { error } from '@sveltejs/kit'; +import { fetchArticlesApi } from '../api'; +import type { PageServerLoad } from './$types'; + +export const load: PageServerLoad = async ({ params, setHeaders }) => { + const queryParams = { + // ids: `${params?.id}`, + // fields: + // 'id,name,price,min_age,min_players,max_players,thumb_url,playtime,min_playtime,max_playtime,min_age,description,year_published,url,image_url' + }; + + try { + const response = await fetchArticlesApi('get', `search`, queryParams); + + if (response?.articles) { + // const gameResponse = await response.json(); + + setHeaders({ + 'Cache-Control': 'max-age=3600' + }); + + const articles = response.articles; + console.log(`Found articles ${articles.length}`); + + return {}; + } + } catch (error) { + console.error(error); + } + + throw error(500, 'error'); +}; diff --git a/svelte.config.js b/svelte.config.js index e77c85b..6f0f99b 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -1,4 +1,4 @@ -import adapter from '@sveltejs/adapter-auto'; +import adapter from '@sveltejs/adapter-vercel'; import { vitePreprocess } from '@sveltejs/kit/vite'; /** @type {import('@sveltejs/kit').Config} */