Skip to content

Commit

Permalink
🔨 attempt naive rendering of csv file in CF function
Browse files Browse the repository at this point in the history
  • Loading branch information
danyx23 committed May 16, 2024
1 parent 29b9e78 commit e8ec13d
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 14 deletions.
67 changes: 53 additions & 14 deletions functions/_common/grapherRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import LatoMedium from "../_common/fonts/LatoLatin-Medium.ttf.bin"
import LatoBold from "../_common/fonts/LatoLatin-Bold.ttf.bin"
import PlayfairSemiBold from "../_common/fonts/PlayfairDisplayLatin-SemiBold.ttf.bin"
import { Env } from "../grapher/thumbnail/[slug].js"
import { OwidTable } from "@ourworldindata/core-table"

Check warning on line 15 in functions/_common/grapherRenderer.ts

View workflow job for this annotation

GitHub Actions / eslint

'OwidTable' is defined but never used. Allowed unused vars must match /^_/u

Check warning on line 15 in functions/_common/grapherRenderer.ts

View workflow job for this annotation

GitHub Actions / eslint

'OwidTable' is defined but never used. Allowed unused vars must match /^_/u

declare global {
// eslint-disable-next-line no-var
Expand Down Expand Up @@ -126,19 +127,20 @@ const extractOptions = (params: URLSearchParams): ImageOptions => {
return options as ImageOptions
}

async function fetchAndRenderGrapherToSvg({
slug,
options,
searchParams,
env,
}: {
slug: string
options: ImageOptions
searchParams: URLSearchParams
env: Env
}) {
const grapherLogger = new TimeLogger("grapher")

async function initGrapher(
{
slug,
options,
searchParams,
env,
}: {
slug: string
options: ImageOptions
searchParams: URLSearchParams
env: Env
},
grapherLogger: TimeLogger
) {
// Fetch grapher config and extract it from the HTML
const grapherConfig: GrapherInterface = await env.ASSETS.fetch(
new URL(`/grapher/${slug}`, env.url)
Expand All @@ -165,9 +167,46 @@ async function fetchAndRenderGrapherToSvg({
grapher.shouldIncludeDetailsInStaticExport = options.details

grapherLogger.log("grapherInit")
return grapher
}

export async function fetchCsvForGrapher(slug: string, env: Env) {
const grapherLogger = new TimeLogger("grapher")
const grapher = await initGrapher(
{
slug,
options: TWITTER_OPTIONS,
searchParams: new URLSearchParams(""),
env,
},
grapherLogger
)
await grapher.downloadLegacyDataFromOwidVariableIds()
return new Response(grapher.inputTable.toPrettyCsv(), {
headers: {
"Content-Type": "text/csv",
},
})
}

async function fetchAndRenderGrapherToSvg({
slug,
options,
searchParams,
env,
}: {
slug: string
options: ImageOptions
searchParams: URLSearchParams
env: Env
}) {
const grapherLogger = new TimeLogger("grapher")
const grapher = await initGrapher(
{ slug, options, searchParams, env },
grapherLogger
)
const promises = []
promises.push(grapher.downloadLegacyDataFromOwidVariableIds())

if (options.details && grapher.detailsOrderedByReference.length) {
promises.push(
await fetch("https://ourworldindata.org/dods.json")
Expand Down
51 changes: 51 additions & 0 deletions functions/grapher/csv/[slug].ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { fetchCsvForGrapher } from "../../_common/grapherRenderer.js"
import { IRequestStrict, Router, error } from "itty-router"

export interface Env {
ASSETS: {
fetch: typeof fetch
}
url: URL
}

const router = Router<IRequestStrict, [URL, Env, ExecutionContext]>()
router
.get(
"/grapher/csv/:slug",
async ({ params: { slug } }, { searchParams: _ }, env) =>
fetchCsvForGrapher(slug, env)
)
.all("*", () => error(404, "Route not defined"))

export const onRequestGet: PagesFunction = async (ctx) => {
const { request, env } = ctx

const url = new URL(request.url)
const shouldCache = !url.searchParams.has("nocache")

const cache = caches.default
if (shouldCache) {
const maybeCached = await cache.match(request)
if (maybeCached) return maybeCached
}

console.log("Handling", request.url, request.headers.get("User-Agent"))

return router
.handle(request, url, { ...env, url }, ctx)
.then((resp: Response) => {
if (shouldCache) {
resp.headers.set(
"Cache-Control",
"public, s-maxage=3600, max-age=3600"
)
ctx.waitUntil(caches.default.put(request, resp.clone()))
} else
resp.headers.set(
"Cache-Control",
"public, s-maxage=0, max-age=0, must-revalidate"
)
return resp
})
.catch((e) => error(500, e))
}

0 comments on commit e8ec13d

Please sign in to comment.