From e6a18637177954f6371fa8a8d9859a4bc36d758f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Feb 2026 18:52:01 +0000 Subject: [PATCH] Fix French translation and add localization for medal events label Co-authored-by: fabrice404 <12575390+fabrice404@users.noreply.github.com> --- scraper/ics-generator.ts | 83 +++++++++++++++++++++++++++------------- ui/lib/text.ts | 2 +- 2 files changed, 57 insertions(+), 28 deletions(-) diff --git a/scraper/ics-generator.ts b/scraper/ics-generator.ts index 1b13341f6..eafe859c1 100644 --- a/scraper/ics-generator.ts +++ b/scraper/ics-generator.ts @@ -4,6 +4,20 @@ import { mkdirSync, writeFileSync } from "fs"; import { getFlag } from "./nocs"; import { Calendar } from "./types"; +const MEDAL_EVENTS_LABEL: { [key: string]: string } = { + en: "Medal Events", + fr: "Événements avec médailles", + es: "Eventos de medallas", + de: "Medaillen-Events", + it: "Eventi con medaglie", + pt: "Eventos de medalhas", + zh: "奖牌赛事", + ja: "メダルイベント", + hi: "पदक स्पर्धाएं", + ko: "메달 이벤트", + ru: "Медальные события", +}; + export class ICSGenerator { private calendar: Calendar; @@ -13,6 +27,28 @@ export class ICSGenerator { this.calendar = calendar; } + private buildTitle( + lang: { code: string; name: string; code3: string }, + sportKey: string | null, + nocKey: string | null, + medalOnly: boolean, + ): string { + const titleComponents: string[] = []; + if (nocKey) { + titleComponents.push( + `${this.calendar.nocs.find((n) => n.key === nocKey)!.name[lang.code]}`, + ); + } + if (sportKey) { + titleComponents.push(this.calendar.sports.find((s) => s.key === sportKey)!.name[lang.code] || ""); + } + if (medalOnly) { + titleComponents.push(MEDAL_EVENTS_LABEL[lang.code] ?? MEDAL_EVENTS_LABEL["en"] ?? "Medal Events"); + } + titleComponents.push("Milano Cortina 2026"); + return titleComponents.join(" - "); + } + private cleanLine(line: string): string { if (line.length <= 75) { return line; @@ -50,21 +86,7 @@ export class ICSGenerator { const filepath = `./output/${lang.code.toLowerCase()}/${pathSportKey.toLowerCase()}/${medalPath}${pathNocKey.toLowerCase()}.ics`; mkdirSync(filepath.split("/").slice(0, -1).join("/"), { recursive: true }); - const titleComponents: string[] = []; - if (nocKey) { - titleComponents.push( - `${this.calendar.nocs.find((n) => n.key === nocKey)!.name[lang.code]}`, - ); - } - if (sportKey) { - titleComponents.push(this.calendar.sports.find((s) => s.key === sportKey)!.name[lang.code] || ""); - } - if (medalOnly) { - titleComponents.push("Medal Events"); - } - titleComponents.push("Milano Cortina 2026"); - - const title = titleComponents.join(" - "); + const title = this.buildTitle(lang, sportKey, nocKey, medalOnly); const lines: string[] = []; @@ -77,18 +99,7 @@ export class ICSGenerator { lines.push(`NAME:${title}`); this.calendar.events - .filter((event) => { - if ((sportKey && event.sport !== sportKey) || event.sport === "CER") { - return false; - } - if (nocKey && !event.nocs.includes(nocKey)) { - return false; - } - if (medalOnly && event.medal === "0") { - return false; - } - return true; - }) + .filter((event) => this.shouldIncludeEvent(event, sportKey, nocKey, medalOnly)) .forEach((event) => { lines.push("BEGIN:VEVENT"); lines.push(`UID:${event.key.replace(/--/g, "-")}`); @@ -150,6 +161,24 @@ export class ICSGenerator { }; } + private shouldIncludeEvent( + event: any, + sportKey: string | null, + nocKey: string | null, + medalOnly: boolean, + ): boolean { + if ((sportKey && event.sport !== sportKey) || event.sport === "CER") { + return false; + } + if (nocKey && !event.nocs.includes(nocKey)) { + return false; + } + if (medalOnly && event.medal === "0") { + return false; + } + return true; + } + public generate(): void { this.debug("generate"); this.generateICSFile(null, null); diff --git a/ui/lib/text.ts b/ui/lib/text.ts index 9d7a496db..605f09e77 100644 --- a/ui/lib/text.ts +++ b/ui/lib/text.ts @@ -25,7 +25,7 @@ export const FILTER_BY_SPORT = { export const MEDAL_EVENTS_ONLY = { en: "Medal events only", - fr: "Événements médaillés uniquement", + fr: "Événements avec médailles uniquement", es: "Solo eventos de medallas", de: "Nur Medaillen-Events", it: "Solo eventi con medaglie",