Files
Substrate/get-de-digital
svemagie 0698daea69 feat: add DE proxy datasets DS-00015–17 + metrics updates — flatten dirs to .md
- Add DE-Platform-Media (DS-00015), DE-Epistemic-Competence (DS-00016), DE-Social-Mobility (DS-00017) with source stubs
- Update DE-Democracy-Metrics, DE-Federal-Budget, DE-Lobby-Transparency, DE-Parliament-Activity, Knowledge-Worker salaries
- Add get-de-digital script for digital economy data retrieval
- Update de-plan1-sven with revised strategy sections
- Rename flat-dir index files to .md (Arguments, Claims, Problems, Values)
- Append new entries to Data/UPDATES.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 17:20:04 +02:00

113 lines
3.8 KiB
Plaintext
Executable File

#!/usr/bin/env bun
// Fetch Eurostat digital society indicators for Germany
// Endpoint: ec.europa.eu/eurostat/api/dissemination/statistics/1.0/data/isoc_ci_ac_i
// No auth required. Dataset: PC_IND (% of all individuals), IND_TOTAL, geo=DE
import { writeFileSync, mkdirSync } from "fs";
import { join } from "path";
const OUT_DIR = join(__dirname, "Data/DE-Platform-Media");
const BASE = "https://ec.europa.eu/eurostat/api/dissemination/statistics/1.0/data";
const INDICATORS: Record<string, string> = {
I_IUSNET: "Social networks participation",
I_IUNW1: "Online news reading",
I_IUPH1: "Video/voice calls",
I_IUBK: "Internet banking",
I_IUOLC: "Online courses",
I_IUUPL1: "Content upload/sharing",
I_IUWIKI: "Wiki consultation",
I_IUEM: "Email use",
I_IUIF: "Finding information online",
};
function csvEscape(value: string | number | undefined | null): string {
if (value === null || value === undefined) return "";
const s = String(value);
if (s.includes(",") || s.includes('"') || s.includes("\n"))
return `"${s.replace(/"/g, '""')}"`;
return s;
}
async function fetchEurostat(indicators: string[]): Promise<Record<string, Record<string, number>>> {
const indic_params = indicators.map((i) => `indic_is=${i}`).join("&");
const url = `${BASE}/isoc_ci_ac_i?format=JSON&lang=en&geo=DE&unit=PC_IND&ind_type=IND_TOTAL&${indic_params}`;
const res = await fetch(url);
if (!res.ok) throw new Error(`Eurostat HTTP ${res.status}`);
const data = await res.json() as any;
const dims = data.dimension ?? {};
const vals = data.value ?? {};
const idx: string[] = data.id ?? [];
const sizes: number[] = data.size ?? [];
const indicList = Object.keys(dims.indic_is?.category?.label ?? {});
const timeList = Object.keys(dims.time?.category?.label ?? {});
const nTime = sizes[idx.indexOf("time")] ?? 1;
const result: Record<string, Record<string, number>> = {};
for (const [k, v] of Object.entries(vals)) {
const ki = parseInt(k);
const iIndic = Math.floor(ki / nTime);
const iTime = ki % nTime;
const indic = indicList[iIndic];
const time = timeList[iTime];
if (!indic || !time) continue;
result[indic] ??= {};
result[indic][time] = v as number;
}
return result;
}
async function main() {
console.log("Fetching Eurostat digital society data for Germany...");
mkdirSync(OUT_DIR, { recursive: true });
const indicatorKeys = Object.keys(INDICATORS);
const data = await fetchEurostat(indicatorKeys);
// Determine recent years (last 5)
const allYears = new Set<string>();
for (const indic of Object.values(data)) {
for (const year of Object.keys(indic)) allYears.add(year);
}
const recentYears = [...allYears].sort().slice(-5);
// CSV: indicator, label, year, value_pct
const rows: string[] = ["indicator_id,indicator_label,year,value_pct"];
for (const [indicId, yearMap] of Object.entries(data)) {
const label = INDICATORS[indicId] ?? indicId;
for (const year of recentYears) {
const val = yearMap[year];
if (val !== undefined) {
rows.push(
[csvEscape(indicId), csvEscape(label), csvEscape(year), val.toFixed(2)].join(",")
);
}
}
}
const csvPath = join(OUT_DIR, "eurostat-digital-de.csv");
writeFileSync(csvPath, rows.join("\n") + "\n");
console.log(`✓ Written ${rows.length - 1} rows to ${csvPath}`);
// Print summary
console.log("\n=== Latest values (most recent year) ===");
for (const [indicId, yearMap] of Object.entries(data)) {
const years = Object.keys(yearMap).sort();
const latest = years[years.length - 1];
if (latest) {
console.log(` ${INDICATORS[indicId] ?? indicId}: ${yearMap[latest]?.toFixed(1)}% (${latest})`);
}
}
}
main().catch((err) => {
console.error("Error:", err.message);
process.exit(1);
});