commit 29a0f490a65094a593c0badbd184947a7c9a7d84 Author: Fabrice Lamant Date: Mon Jul 8 15:06:59 2024 +0100 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..7aa77bcb5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +cache/ +node_modules/ diff --git a/docs/handball.ics b/docs/handball.ics new file mode 100644 index 000000000..b734ae4da --- /dev/null +++ b/docs/handball.ics @@ -0,0 +1,688 @@ +BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//fabrice404//olympics-calendar//EN +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPA-000100-- +DTSTAMP:20240725T070000Z +DTSTART:20240725T070000Z +DTEND:20240725T083000Z +DESCRIPTION:Women's Preliminary Round Group A +SUMMARY:Slovenia 🇸🇮 - 🇩🇰 Denmark +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPB-000300-- +DTSTAMP:20240725T090000Z +DTSTART:20240725T090000Z +DTEND:20240725T103000Z +DESCRIPTION:Women's Preliminary Round Group B +SUMMARY:Netherlands 🇳🇱 - 🇦🇴 Angola +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPB-000400-- +DTSTAMP:20240725T120000Z +DTSTART:20240725T120000Z +DTEND:20240725T133000Z +DESCRIPTION:Women's Preliminary Round Group B +SUMMARY:Spain 🇪🇸 - 🇧🇷 Brazil +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPA-000200-- +DTSTAMP:20240725T140000Z +DTSTART:20240725T140000Z +DTEND:20240725T153000Z +DESCRIPTION:Women's Preliminary Round Group A +SUMMARY:Germany 🇩🇪 - 🇰🇷 Korea +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPB-000700-- +DTSTAMP:20240725T170000Z +DTSTART:20240725T170000Z +DTEND:20240725T183000Z +DESCRIPTION:Women's Preliminary Round Group B +SUMMARY:Hungary 🇭🇺 - 🇫🇷 France +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPA-000300-- +DTSTAMP:20240725T190000Z +DTSTART:20240725T190000Z +DTEND:20240725T203000Z +DESCRIPTION:Women's Preliminary Round Group A +SUMMARY:Norway 🇳🇴 - 🇸🇪 Sweden +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPA-001000-- +DTSTAMP:20240727T070000Z +DTSTART:20240727T070000Z +DTEND:20240727T083000Z +DESCRIPTION:Men's Preliminary Round Group A +SUMMARY:Spain 🇪🇸 - 🇸🇮 Slovenia +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPB-000200-- +DTSTAMP:20240727T090000Z +DTSTART:20240727T090000Z +DTEND:20240727T103000Z +DESCRIPTION:Men's Preliminary Round Group B +SUMMARY:Hungary 🇭🇺 - 🇪🇬 Egypt +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPA-000500-- +DTSTAMP:20240727T120000Z +DTSTART:20240727T120000Z +DTEND:20240727T133000Z +DESCRIPTION:Men's Preliminary Round Group A +SUMMARY:Croatia 🇭🇷 - 🇯🇵 Japan +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPB-000300-- +DTSTAMP:20240727T140000Z +DTSTART:20240727T140000Z +DTEND:20240727T153000Z +DESCRIPTION:Men's Preliminary Round Group B +SUMMARY:Norway 🇳🇴 - 🇦🇷 Argentina +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPA-000100-- +DTSTAMP:20240727T170000Z +DTSTART:20240727T170000Z +DTEND:20240727T183000Z +DESCRIPTION:Men's Preliminary Round Group A +SUMMARY:Germany 🇩🇪 - 🇸🇪 Sweden +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPB-000500-- +DTSTAMP:20240727T190000Z +DTSTART:20240727T190000Z +DTEND:20240727T203000Z +DESCRIPTION:Men's Preliminary Round Group B +SUMMARY:Denmark 🇩🇰 - 🇫🇷 France +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPB-000100-- +DTSTAMP:20240728T070000Z +DTSTART:20240728T070000Z +DTEND:20240728T083000Z +DESCRIPTION:Women's Preliminary Round Group B +SUMMARY:Brazil 🇧🇷 - 🇭🇺 Hungary +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPA-000400-- +DTSTAMP:20240728T090000Z +DTSTART:20240728T090000Z +DTEND:20240728T103000Z +DESCRIPTION:Women's Preliminary Round Group A +SUMMARY:Korea 🇰🇷 - 🇸🇮 Slovenia +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPA-000500-- +DTSTAMP:20240728T120000Z +DTSTART:20240728T120000Z +DTEND:20240728T133000Z +DESCRIPTION:Women's Preliminary Round Group A +SUMMARY:Sweden 🇸🇪 - 🇩🇪 Germany +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPA-000600-- +DTSTAMP:20240728T140000Z +DTSTART:20240728T140000Z +DTEND:20240728T153000Z +DESCRIPTION:Women's Preliminary Round Group A +SUMMARY:Denmark 🇩🇰 - 🇳🇴 Norway +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPB-001000-- +DTSTAMP:20240728T170000Z +DTSTART:20240728T170000Z +DTEND:20240728T183000Z +DESCRIPTION:Women's Preliminary Round Group B +SUMMARY:Angola 🇦🇴 - 🇪🇸 Spain +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPB-000800-- +DTSTAMP:20240728T190000Z +DTSTART:20240728T190000Z +DTEND:20240728T203000Z +DESCRIPTION:Women's Preliminary Round Group B +SUMMARY:France 🇫🇷 - 🇳🇱 Netherlands +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPA-000300-- +DTSTAMP:20240729T070000Z +DTSTART:20240729T070000Z +DTEND:20240729T083000Z +DESCRIPTION:Men's Preliminary Round Group A +SUMMARY:Japan 🇯🇵 - 🇩🇪 Germany +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPA-000200-- +DTSTAMP:20240729T090000Z +DTSTART:20240729T090000Z +DTEND:20240729T103000Z +DESCRIPTION:Men's Preliminary Round Group A +SUMMARY:Slovenia 🇸🇮 - 🇭🇷 Croatia +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPB-000400-- +DTSTAMP:20240729T120000Z +DTSTART:20240729T120000Z +DTEND:20240729T133000Z +DESCRIPTION:Men's Preliminary Round Group B +SUMMARY:Egypt 🇪🇬 - 🇩🇰 Denmark +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPA-000800-- +DTSTAMP:20240729T140000Z +DTSTART:20240729T140000Z +DTEND:20240729T153000Z +DESCRIPTION:Men's Preliminary Round Group A +SUMMARY:Sweden 🇸🇪 - 🇪🇸 Spain +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPB-000100-- +DTSTAMP:20240729T170000Z +DTSTART:20240729T170000Z +DTEND:20240729T183000Z +DESCRIPTION:Men's Preliminary Round Group B +SUMMARY:France 🇫🇷 - 🇳🇴 Norway +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPB-001200-- +DTSTAMP:20240729T190000Z +DTSTART:20240729T190000Z +DTEND:20240729T203000Z +DESCRIPTION:Men's Preliminary Round Group B +SUMMARY:Argentina 🇦🇷 - 🇭🇺 Hungary +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPA-000700-- +DTSTAMP:20240730T070000Z +DTSTART:20240730T070000Z +DTEND:20240730T083000Z +DESCRIPTION:Women's Preliminary Round Group A +SUMMARY:Germany 🇩🇪 - 🇸🇮 Slovenia +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPA-000800-- +DTSTAMP:20240730T090000Z +DTSTART:20240730T090000Z +DTEND:20240730T103000Z +DESCRIPTION:Women's Preliminary Round Group A +SUMMARY:Norway 🇳🇴 - 🇰🇷 Korea +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPB-001100-- +DTSTAMP:20240730T120000Z +DTSTART:20240730T120000Z +DTEND:20240730T133000Z +DESCRIPTION:Women's Preliminary Round Group B +SUMMARY:Netherlands 🇳🇱 - 🇪🇸 Spain +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPB-000900-- +DTSTAMP:20240730T140000Z +DTSTART:20240730T140000Z +DTEND:20240730T153000Z +DESCRIPTION:Women's Preliminary Round Group B +SUMMARY:Hungary 🇭🇺 - 🇦🇴 Angola +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPB-001200-- +DTSTAMP:20240730T170000Z +DTSTART:20240730T170000Z +DTEND:20240730T183000Z +DESCRIPTION:Women's Preliminary Round Group B +SUMMARY:France 🇫🇷 - 🇧🇷 Brazil +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPA-000900-- +DTSTAMP:20240730T190000Z +DTSTART:20240730T190000Z +DTEND:20240730T203000Z +DESCRIPTION:Women's Preliminary Round Group A +SUMMARY:Sweden 🇸🇪 - 🇩🇰 Denmark +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPB-001000-- +DTSTAMP:20240731T070000Z +DTSTART:20240731T070000Z +DTEND:20240731T083000Z +DESCRIPTION:Men's Preliminary Round Group B +SUMMARY:Norway 🇳🇴 - 🇭🇺 Hungary +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPA-000400-- +DTSTAMP:20240731T090000Z +DTSTART:20240731T090000Z +DTEND:20240731T103000Z +DESCRIPTION:Men's Preliminary Round Group A +SUMMARY:Croatia 🇭🇷 - 🇩🇪 Germany +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPA-000700-- +DTSTAMP:20240731T120000Z +DTSTART:20240731T120000Z +DTEND:20240731T133000Z +DESCRIPTION:Men's Preliminary Round Group A +SUMMARY:Spain 🇪🇸 - 🇯🇵 Japan +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPA-000600-- +DTSTAMP:20240731T140000Z +DTSTART:20240731T140000Z +DTEND:20240731T153000Z +DESCRIPTION:Men's Preliminary Round Group A +SUMMARY:Slovenia 🇸🇮 - 🇸🇪 Sweden +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPB-000900-- +DTSTAMP:20240731T170000Z +DTSTART:20240731T170000Z +DTEND:20240731T183000Z +DESCRIPTION:Men's Preliminary Round Group B +SUMMARY:France 🇫🇷 - 🇪🇬 Egypt +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPB-000700-- +DTSTAMP:20240731T190000Z +DTSTART:20240731T190000Z +DTEND:20240731T203000Z +DESCRIPTION:Men's Preliminary Round Group B +SUMMARY:Denmark 🇩🇰 - 🇦🇷 Argentina +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPB-000500-- +DTSTAMP:20240801T070000Z +DTSTART:20240801T070000Z +DTEND:20240801T083000Z +DESCRIPTION:Women's Preliminary Round Group B +SUMMARY:Netherlands 🇳🇱 - 🇧🇷 Brazil +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPA-001000-- +DTSTAMP:20240801T090000Z +DTSTART:20240801T090000Z +DTEND:20240801T103000Z +DESCRIPTION:Women's Preliminary Round Group A +SUMMARY:Korea 🇰🇷 - 🇸🇪 Sweden +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPB-000600-- +DTSTAMP:20240801T120000Z +DTSTART:20240801T120000Z +DTEND:20240801T133000Z +DESCRIPTION:Women's Preliminary Round Group B +SUMMARY:Spain 🇪🇸 - 🇭🇺 Hungary +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPB-000200-- +DTSTAMP:20240801T140000Z +DTSTART:20240801T140000Z +DTEND:20240801T153000Z +DESCRIPTION:Women's Preliminary Round Group B +SUMMARY:Angola 🇦🇴 - 🇫🇷 France +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPA-001100-- +DTSTAMP:20240801T170000Z +DTSTART:20240801T170000Z +DTEND:20240801T183000Z +DESCRIPTION:Women's Preliminary Round Group A +SUMMARY:Germany 🇩🇪 - 🇩🇰 Denmark +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPA-001200-- +DTSTAMP:20240801T190000Z +DTSTART:20240801T190000Z +DTEND:20240801T203000Z +DESCRIPTION:Women's Preliminary Round Group A +SUMMARY:Slovenia 🇸🇮 - 🇳🇴 Norway +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPB-001300-- +DTSTAMP:20240802T070000Z +DTSTART:20240802T070000Z +DTEND:20240802T083000Z +DESCRIPTION:Men's Preliminary Round Group B +SUMMARY:Hungary 🇭🇺 - 🇩🇰 Denmark +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPB-001100-- +DTSTAMP:20240802T090000Z +DTSTART:20240802T090000Z +DTEND:20240802T103000Z +DESCRIPTION:Men's Preliminary Round Group B +SUMMARY:Argentina 🇦🇷 - 🇫🇷 France +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPA-001100-- +DTSTAMP:20240802T120000Z +DTSTART:20240802T120000Z +DTEND:20240802T133000Z +DESCRIPTION:Men's Preliminary Round Group A +SUMMARY:Croatia 🇭🇷 - 🇸🇪 Sweden +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPA-000900-- +DTSTAMP:20240802T140000Z +DTSTART:20240802T140000Z +DTEND:20240802T153000Z +DESCRIPTION:Men's Preliminary Round Group A +SUMMARY:Germany 🇩🇪 - 🇪🇸 Spain +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPA-001200-- +DTSTAMP:20240802T170000Z +DTSTART:20240802T170000Z +DTEND:20240802T183000Z +DESCRIPTION:Men's Preliminary Round Group A +SUMMARY:Japan 🇯🇵 - 🇸🇮 Slovenia +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPB-001500-- +DTSTAMP:20240802T190000Z +DTSTART:20240802T190000Z +DTEND:20240802T203000Z +DESCRIPTION:Men's Preliminary Round Group B +SUMMARY:Norway 🇳🇴 - 🇪🇬 Egypt +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPB-001400-- +DTSTAMP:20240803T070000Z +DTSTART:20240803T070000Z +DTEND:20240803T083000Z +DESCRIPTION:Women's Preliminary Round Group B +SUMMARY:Hungary 🇭🇺 - 🇳🇱 Netherlands +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPB-001300-- +DTSTAMP:20240803T090000Z +DTSTART:20240803T090000Z +DTEND:20240803T103000Z +DESCRIPTION:Women's Preliminary Round Group B +SUMMARY:Spain 🇪🇸 - 🇫🇷 France +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPB-001500-- +DTSTAMP:20240803T120000Z +DTSTART:20240803T120000Z +DTEND:20240803T133000Z +DESCRIPTION:Women's Preliminary Round Group B +SUMMARY:Brazil 🇧🇷 - 🇦🇴 Angola +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPA-001300-- +DTSTAMP:20240803T140000Z +DTSTART:20240803T140000Z +DTEND:20240803T153000Z +DESCRIPTION:Women's Preliminary Round Group A +SUMMARY:Slovenia 🇸🇮 - 🇸🇪 Sweden +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPA-001500-- +DTSTAMP:20240803T170000Z +DTSTART:20240803T170000Z +DTEND:20240803T183000Z +DESCRIPTION:Women's Preliminary Round Group A +SUMMARY:Norway 🇳🇴 - 🇩🇪 Germany +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------GPA-001400-- +DTSTAMP:20240803T190000Z +DTSTART:20240803T190000Z +DTEND:20240803T203000Z +DESCRIPTION:Women's Preliminary Round Group A +SUMMARY:Denmark 🇩🇰 - 🇰🇷 Korea +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPA-001300-- +DTSTAMP:20240804T070000Z +DTSTART:20240804T070000Z +DTEND:20240804T083000Z +DESCRIPTION:Men's Preliminary Round Group A +SUMMARY:Sweden 🇸🇪 - 🇯🇵 Japan +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPB-000800-- +DTSTAMP:20240804T090000Z +DTSTART:20240804T090000Z +DTEND:20240804T103000Z +DESCRIPTION:Men's Preliminary Round Group B +SUMMARY:Egypt 🇪🇬 - 🇦🇷 Argentina +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPA-001400-- +DTSTAMP:20240804T120000Z +DTSTART:20240804T120000Z +DTEND:20240804T133000Z +DESCRIPTION:Men's Preliminary Round Group A +SUMMARY:Germany 🇩🇪 - 🇸🇮 Slovenia +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPB-000600-- +DTSTAMP:20240804T140000Z +DTSTART:20240804T140000Z +DTEND:20240804T153000Z +DESCRIPTION:Men's Preliminary Round Group B +SUMMARY:Hungary 🇭🇺 - 🇫🇷 France +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPB-001400-- +DTSTAMP:20240804T170000Z +DTSTART:20240804T170000Z +DTEND:20240804T183000Z +DESCRIPTION:Men's Preliminary Round Group B +SUMMARY:Denmark 🇩🇰 - 🇳🇴 Norway +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------GPA-001500-- +DTSTAMP:20240804T190000Z +DTSTART:20240804T190000Z +DTEND:20240804T203000Z +DESCRIPTION:Men's Preliminary Round Group A +SUMMARY:Spain 🇪🇸 - 🇭🇷 Croatia +LOCATION:South Paris Arena 6 +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------QFNL000100-- +DTSTAMP:20240806T073000Z +DTSTART:20240806T073000Z +DTEND:20240806T093000Z +DESCRIPTION:Women's Quarterfinal +SUMMARY:Women's Quarterfinal +LOCATION:Pierre Mauroy Stadium +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------QFNL000200-- +DTSTAMP:20240806T113000Z +DTSTART:20240806T113000Z +DTEND:20240806T133000Z +DESCRIPTION:Women's Quarterfinal +SUMMARY:Women's Quarterfinal +LOCATION:Pierre Mauroy Stadium +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------QFNL000300-- +DTSTAMP:20240806T153000Z +DTSTART:20240806T153000Z +DTEND:20240806T173000Z +DESCRIPTION:Women's Quarterfinal +SUMMARY:Women's Quarterfinal +LOCATION:Pierre Mauroy Stadium +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------QFNL000400-- +DTSTAMP:20240806T193000Z +DTSTART:20240806T193000Z +DTEND:20240806T213000Z +DESCRIPTION:Women's Quarterfinal +SUMMARY:Women's Quarterfinal +LOCATION:Pierre Mauroy Stadium +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------QFNL000400-- +DTSTAMP:20240807T073000Z +DTSTART:20240807T073000Z +DTEND:20240807T093000Z +DESCRIPTION:Men's Quarterfinal +SUMMARY:Men's Quarterfinal +LOCATION:Pierre Mauroy Stadium +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------QFNL000300-- +DTSTAMP:20240807T113000Z +DTSTART:20240807T113000Z +DTEND:20240807T133000Z +DESCRIPTION:Men's Quarterfinal +SUMMARY:Men's Quarterfinal +LOCATION:Pierre Mauroy Stadium +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------QFNL000200-- +DTSTAMP:20240807T153000Z +DTSTART:20240807T153000Z +DTEND:20240807T173000Z +DESCRIPTION:Men's Quarterfinal +SUMMARY:Men's Quarterfinal +LOCATION:Pierre Mauroy Stadium +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------QFNL000100-- +DTSTAMP:20240807T193000Z +DTSTART:20240807T193000Z +DTEND:20240807T213000Z +DESCRIPTION:Men's Quarterfinal +SUMMARY:Men's Quarterfinal +LOCATION:Pierre Mauroy Stadium +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------SFNL000100-- +DTSTAMP:20240808T143000Z +DTSTART:20240808T143000Z +DTEND:20240808T163000Z +DESCRIPTION:Women's Semifinal +SUMMARY:Women's Semifinal +LOCATION:Pierre Mauroy Stadium +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------SFNL000200-- +DTSTAMP:20240808T193000Z +DTSTART:20240808T193000Z +DTEND:20240808T213000Z +DESCRIPTION:Women's Semifinal +SUMMARY:Women's Semifinal +LOCATION:Pierre Mauroy Stadium +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------SFNL000100-- +DTSTAMP:20240809T143000Z +DTSTART:20240809T143000Z +DTEND:20240809T163000Z +DESCRIPTION:Men's Semifinal +SUMMARY:Men's Semifinal +LOCATION:Pierre Mauroy Stadium +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------SFNL000200-- +DTSTAMP:20240809T193000Z +DTSTART:20240809T193000Z +DTEND:20240809T213000Z +DESCRIPTION:Men's Semifinal +SUMMARY:Men's Semifinal +LOCATION:Pierre Mauroy Stadium +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------FNL-000200-- +DTSTAMP:20240810T080000Z +DTSTART:20240810T080000Z +DTEND:20240810T100000Z +DESCRIPTION:Women's Bronze Medal Match +SUMMARY:Women's Bronze Medal Match +LOCATION:Pierre Mauroy Stadium +END:VEVENT +BEGIN:VEVENT +UID:HBLWTEAM7-------------FNL-000100-- +DTSTAMP:20240810T130000Z +DTSTART:20240810T130000Z +DTEND:20240810T150000Z +DESCRIPTION:Women's Gold Medal Match +SUMMARY:Women's Gold Medal Match +LOCATION:Pierre Mauroy Stadium +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------FNL-000200-- +DTSTAMP:20240811T070000Z +DTSTART:20240811T070000Z +DTEND:20240811T090000Z +DESCRIPTION:Men's Bronze Medal Match +SUMMARY:Men's Bronze Medal Match +LOCATION:Pierre Mauroy Stadium +END:VEVENT +BEGIN:VEVENT +UID:HBLMTEAM7-------------FNL-000100-- +DTSTAMP:20240811T113000Z +DTSTART:20240811T113000Z +DTEND:20240811T133000Z +DESCRIPTION:Men's Gold Medal Match +SUMMARY:Men's Gold Medal Match +LOCATION:Pierre Mauroy Stadium +END:VEVENT +END:VCALENDAR \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 000000000..83df07605 --- /dev/null +++ b/index.js @@ -0,0 +1,80 @@ +const cheerio = require('cheerio'); +const fs = require('fs'); + +const URL = 'https://olympics.com/en/paris-2024/schedule/handball'; + +const downloadSchedule = async () => { + const response = await fetch(URL); + const content = await response.text(); + fs.writeFileSync('cache/handball.html', content); + return content; +}; + +const getFlag = (country) => { + switch (country.toLowerCase()) { + case "angola": return "🇦🇴"; + case "argentina": return "🇦🇷"; + case "brazil": return "🇧🇷"; + case "croatia": return "🇭🇷"; + case "denmark": return "🇩🇰"; + case "france": return "🇫🇷"; + case "egypt": return "🇪🇬"; + case "germany": return "🇩🇪"; + case "hungary": return "🇭🇺"; + case "japan": return "🇯🇵"; + case "korea": return "🇰🇷"; + case "netherlands": return "🇳🇱"; + case "norway": return "🇳🇴"; + case "slovenia": return "🇸🇮"; + case "spain": return "🇪🇸"; + case "sweden": return "🇸🇪"; + default: throw new Error(`No flag set for ${country}`); + } +} + +const countryNameAndFlag = (name, flagFirst = false) => { + const flag = getFlag(name); + if (!flag) { + console.log(name) + } + if (flagFirst) return `${flag} ${name}`; + return `${name} ${flag}`; +} + +const main = async () => { + // const html = await downloadSchedule(); + // const $ = cheerio.load(html); + // const data = JSON.parse($('#__NEXT_DATA__').text()); + // fs.writeFileSync('cache/handball.json', JSON.stringify(data, null, 2)); + const events = []; + const data = JSON.parse(fs.readFileSync('cache/handball.json', 'utf-8')); + data.props.pageProps.page.items.find(item => item.name === "scheduleWrapper").data.schedules.forEach(schedule => { + const location = schedule.venue.description; + schedule.units.forEach(unit => { + let title = unit.description; + + if (unit.match && unit.match.team1) { + title = `${countryNameAndFlag(unit.match.team1.description)} - ${countryNameAndFlag(unit.match.team2.description, true)}`; + } + + const event = { + UID: unit.unitCode, + DTSTAMP: unit.startDateTimeUtc.replace(/[:-]/g, ''), + DTSTART: unit.startDateTimeUtc.replace(/[:-]/g, ''), + DTEND: unit.endDateTimeUtc.replace(/[:-]/g, ''), + DESCRIPTION: unit.description, + SUMMARY: title, + LOCATION: location, + } + events.push(event); + }) + }); + + const icalEvents = events.map(event => { + return `BEGIN:VEVENT\n${Object.entries(event).map(([key, value]) => `${key}:${value}`).join('\n')}\nEND:VEVENT`; + }); + + fs.writeFileSync('docs/handball.ics', `BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//fabrice404//olympics-calendar//EN\n${icalEvents.join('\n')}\nEND:VCALENDAR`); +}; + +main(); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..4d51877e7 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,211 @@ +{ + "name": "olympics-calendar", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "olympics-calendar", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "cheerio": "^1.0.0-rc.12" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "license": "MIT", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.2", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 000000000..84e10c2eb --- /dev/null +++ b/package.json @@ -0,0 +1,14 @@ +{ + "name": "olympics-calendar", + "version": "1.0.0", + "main": "handball.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "description": "", + "dependencies": { + "cheerio": "^1.0.0-rc.12" + } +}