ver dump metadata

This commit is contained in:
Cat /dev/Nulo 2023-12-08 16:21:16 -03:00
parent e0bb1b0ee6
commit 264a7f2adf
6 changed files with 98 additions and 14 deletions

View file

@ -1,8 +1,8 @@
<script lang="ts"> <script lang="ts">
import type { Params } from "navaid";
import { currentRoute, type ComponentType } from "./lib/router"; import { currentRoute, type ComponentType } from "./lib/router";
import NotFound from "./lib/routes/NotFound.svelte"; import NotFound from "./lib/routes/NotFound.svelte";
import Dump from "./lib/routes/Dump.svelte";
import Portal from "./lib/routes/Portal.svelte"; import Portal from "./lib/routes/Portal.svelte";
import Dataset from "./lib/routes/Dataset.svelte"; import Dataset from "./lib/routes/Dataset.svelte";
@ -10,9 +10,10 @@
if (route === "NotFound") return NotFound; if (route === "NotFound") return NotFound;
else if (route === "Dataset") return Dataset; else if (route === "Dataset") return Dataset;
else if (route === "Portal") return Portal; else if (route === "Portal") return Portal;
else if (route === "Dump") return Dump;
} }
$: component = chooseComponent($currentRoute.component); $: component = chooseComponent($currentRoute.component) as any;
$: params = $currentRoute.params as any; $: params = $currentRoute.params as any;
</script> </script>

View file

@ -1,5 +1,5 @@
import streamSaver from "streamsaver"; import streamSaver from "streamsaver";
import { zData, type Distribution, zError } from "common/schema"; import { zData, type Distribution, zError, zDumpMetadata } from "common/schema";
export async function downloadFile( export async function downloadFile(
dataPath: string, dataPath: string,
@ -48,11 +48,16 @@ async function loadGzippedJson(url: string): Promise<unknown> {
return json; return json;
} }
export async function fetchData(url: string) { export async function fetchData(portalUrl: string) {
const json = await loadGzippedJson(`${url}/data.json.gz`); const json = await loadGzippedJson(`${portalUrl}/data.json.gz`);
if (import.meta.env.DEV) console.debug(json); if (import.meta.env.DEV) console.debug(json);
return zData.parse(json); return zData.parse(json);
} }
export async function fetchDumpMetadata(dumpUrl: string) {
const json = await loadGzippedJson(`${dumpUrl}/dump-metadata.json.gz`);
if (import.meta.env.DEV) console.debug(json);
return zDumpMetadata.parse(json);
}
export async function fetchErrors(url: string) { export async function fetchErrors(url: string) {
const res = await fetchGzipped(`${url}/errors.jsonl.gz`); const res = await fetchGzipped(`${url}/errors.jsonl.gz`);
const text = await res.text(); const text = await res.text();

View file

@ -2,11 +2,12 @@ import navaid, { type Params } from "navaid";
import { writable } from "svelte/store"; import { writable } from "svelte/store";
export const routes = { export const routes = {
Dump: "/dump/:dumpUrl",
Portal: "/portal/:portalUrl", Portal: "/portal/:portalUrl",
Dataset: "/portal/:portalUrl/dataset/:id", Dataset: "/portal/:portalUrl/dataset/:id",
}; };
export type ComponentType = "NotFound" | "Portal" | "Dataset"; export type ComponentType = "NotFound" | keyof typeof routes;
type Route = { type Route = {
component: ComponentType; component: ComponentType;
@ -17,10 +18,9 @@ export const currentRoute = writable<Route>();
export const router = navaid(undefined, () => export const router = navaid(undefined, () =>
currentRoute.set({ component: "NotFound" }), currentRoute.set({ component: "NotFound" }),
); );
router.on(routes.Portal, (params) => for (const [component, path] of Object.entries(routes)) {
currentRoute.set({ component: "Portal", params }), router.on(path, (params) =>
); currentRoute.set({ component: component as keyof typeof routes, params }),
router.on(routes.Dataset, (params) =>
currentRoute.set({ component: "Dataset", params }),
); );
}
router.listen(); router.listen();

View file

@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import ArrowBack from "eva-icons/outline/svg/arrow-back-outline.svg?component"; import ArrowBack from "eva-icons/outline/svg/arrow-back-outline.svg?component";
import ExternalLink from "eva-icons/outline/svg/external-link-outline.svg?component"; import ExternalLink from "eva-icons/outline/svg/external-link-outline.svg?component";
import { downloadFile, fetchData, fetchErrors } from "../portal"; import { downloadFile, fetchData, fetchErrors } from "../fetch";
import NotFound from "./NotFound.svelte"; import NotFound from "./NotFound.svelte";
import { inject } from "regexparam"; import { inject } from "regexparam";
import { routes } from "../router"; import { routes } from "../router";

View file

@ -0,0 +1,78 @@
<script lang="ts">
import { inject } from "regexparam";
import ExternalLink from "eva-icons/outline/svg/external-link-outline.svg?component";
import { fetchDumpMetadata } from "../fetch";
import { routes } from "../router";
export let params: { dumpUrl: string };
const url = decodeURIComponent(params.dumpUrl);
const metadataPromise = fetchDumpMetadata(url);
</script>
<main class="mx-auto max-w-3xl">
<div class="rounded-lg border bg-white m-2">
{#await metadataPromise}
<p class="p-6">Cargando..</p>
{:then metadata}
<header class="py-5 px-6 border-b border-b-gray-200">
<small>
Viendo archivo en
<a
class="underline text-blue-500"
target="_blank"
rel="noopener"
href={url}>{url}</a
>
</small>
<!-- <h1 class="font-bold text-3xl">{data.title}</h1>
<p class="text-xl">{data.description}</p>
{#if data.homepage}
<a
class="flex items-center leading-none text-gray-600 gap-1 pt-2"
href={arreglarHomepageUrl(data.homepage)}
target="_blank"
rel="noopener"
>
<ExternalLink fill="currentColor" class="h-4" />
Fuente
</a>
{/if} -->
</header>
<ul class="divide-y divide-gray-100">
{#each metadata.sites as site}
{@const portalLink = inject(routes.Portal, {
portalUrl: encodeURIComponent(`${url}/${site.path}`),
})}
<li>
<div class="flex px-6 py-5 justify-between gap-3">
<div class="flex flex-col">
<h3 class="text-lg">{site.title}</h3>
<p class="text-sm">{site.description}</p>
</div>
<div class="flex flex-col items-center justify-center shrink-0">
<a
href={portalLink}
class="inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-white transition-colors duration-200 bg-blue-600 rounded-md hover:bg-blue-700 focus:ring-2 focus:ring-offset-2 focus:ring-blue-700 focus:shadow-outline focus:outline-none"
>Ver portal</a
>
<a
class="flex items-center leading-none text-gray-600 gap-1 pt-2"
href={site.url}
target="_blank"
rel="noopener"
>
<ExternalLink fill="currentColor" class="h-4" />
Fuente
</a>
</div>
</div>
</li>
{/each}
</ul>
{:catch error}
Hubo un error intenando cargar este archivo. <pre>{error}</pre>
{/await}
</div>
</main>

View file

@ -2,7 +2,7 @@
import { inject } from "regexparam"; import { inject } from "regexparam";
import ArrowForward from "eva-icons/outline/svg/arrow-forward-outline.svg?component"; import ArrowForward from "eva-icons/outline/svg/arrow-forward-outline.svg?component";
import ExternalLink from "eva-icons/outline/svg/external-link-outline.svg?component"; import ExternalLink from "eva-icons/outline/svg/external-link-outline.svg?component";
import { fetchData, fetchErrors } from "../portal"; import { fetchData, fetchErrors } from "../fetch";
import { routes } from "../router"; import { routes } from "../router";
import type { Dataset } from "common/schema"; import type { Dataset } from "common/schema";