add eslint

This commit is contained in:
Fabrice Lamant
2024-07-10 11:11:40 +01:00
parent 371982f547
commit c82cdbcbe1
5 changed files with 1108 additions and 119 deletions

26
eslint.config.mjs Normal file
View File

@ -0,0 +1,26 @@
import globals from "globals";
import pluginJs from "@eslint/js";
export default [
{
files: ["**/*.js"],
languageOptions: {
sourceType: "commonjs",
},
},
{
languageOptions: {
globals: globals.node,
},
},
pluginJs.configs.recommended,
{
rules: {
"comma-dangle": ["error", "always-multiline"],
complexity: ["error", 8],
quotes: ["error", "double"],
semi: ["error", "always"],
},
},
];

239
index.js
View File

@ -1,8 +1,8 @@
const cheerio = require('cheerio');
const fs = require('fs');
const autoprefixer = require('autoprefixer');
const postcss = require('postcss');
const tailwindcss = require('tailwindcss');
const cheerio = require("cheerio");
const fs = require("fs");
const autoprefixer = require("autoprefixer");
const postcss = require("postcss");
const tailwindcss = require("tailwindcss");
const downloadSchedule = async (sportKey) => {
const cacheFile = `${__dirname}/cache/${sportKey}.html`;
@ -13,87 +13,96 @@ const downloadSchedule = async (sportKey) => {
fs.writeFileSync(cacheFile, content);
}
const html = fs.readFileSync(cacheFile, 'utf-8');
const html = fs.readFileSync(cacheFile, "utf-8");
const $ = cheerio.load(html);
return JSON.parse($('#__NEXT_DATA__').text());
return JSON.parse($("#__NEXT_DATA__").text());
};
const getSportIcon = (sport) => {
switch (sport.toLowerCase()) {
case "3x3-basketball": return "🏀③"
case "basketball": return "🏀";
case "football": return "⚽";
case "handball": return "🤾";
case "hockey": return "🏑";
case "rugby-sevens": return "🏉";
case "volleyball": return "🏐";
case "water-polo": return "🤽";
default: throw new Error(`No icon set for ${sport}`);
const sports = {
"3x3-basketball": "🏀③",
"basketball": "🏀",
"football": "⚽",
"handball": "🤾",
"hockey": "🏑",
"rugby-sevens": "🏉",
"volleyball": "🏐",
"water-polo": "🤽",
};
if (sports[sport]) {
return sports[sport];
}
throw new Error(`No icon set for ${sport}`);
};
const getFlagIcon = (country) => {
if (country.toLowerCase().startsWith("winner oqt")) {
return "🏳️";
}
switch (country.toLowerCase()) {
case "angola": return "🇦🇴";
case "argentina": return "🇦🇷";
case "australia": return "🇦🇺";
case "azerbaijan": return "🇦🇿";
case "belgium": return "🇧🇪";
case "brazil": return "🇧🇷";
case "canada": return "🇨🇦";
case "china": return "🇨🇳";
case "colombia": return "🇨🇴";
case "croatia": return "🇭🇷";
case "denmark": return "🇩🇰";
case "dominican republic": return "🇩🇴";
case "fiji": return "🇫🇯";
case "france": return "🇫🇷";
case "egypt": return "🇪🇬";
case "germany": return "🇩🇪";
case "great britain": return "🇬🇧";
case "greece": return "🇬🇷";
case "guinea": return "🇬🇳";
case "hungary": return "🇭🇺";
case "india": return "🇮🇳";
case "iraq": return "🇮🇶";
case "ireland": return "🇮🇪";
case "israel": return "🇮🇱";
case "italy": return "🇮🇱";
case "japan": return "🇯🇵";
case "kenya": return "🇰🇪";
case "latvia": return "🇱🇻";
case "lithuania": return "🇱🇹";
case "korea": return "🇰🇷";
case "mali": return "🇲🇱";
case "montenegro": return "🇲🇪";
case "morocco": return "🇲🇦";
case "nigeria": return "🇳🇬";
case "netherlands": return "🇳🇱";
case "new zealand": return "🇳🇿";
case "norway": return "🇳🇴";
case "paraguay": return "🇵🇾";
case "poland": return "🇵🇱";
case "puerto rico": return "🇵🇷";
case "romania": return "🇷🇴";
case "serbia": return "🇷🇸";
case "south africa": return "🇿🇦";
case "south sudan": return "🇸🇸";
case "slovenia": return "🇸🇮";
case "samoa": return "🇼🇸";
case "spain": return "🇪🇸";
case "sweden": return "🇸🇪";
case "türkiye": return "🇹🇷";
case "ukraine": return "🇺🇦";
case "united states": return "🇺🇸";
case "uruguay": return "🇺🇾";
case "uzbekistan": return "🇺🇿";
case "zambia": return "🇿🇲";
default: throw new Error(`No flag set for ${country}`);
}
const teams = {
"angola": "🇦🇴",
"argentina": "🇦🇷",
"australia": "🇦🇺",
"azerbaijan": "🇦🇿",
"belgium": "🇧🇪",
"brazil": "🇧🇷",
"canada": "🇨🇦",
"china": "🇨🇳",
"colombia": "🇨🇴",
"croatia": "🇭🇷",
"denmark": "🇩🇰",
"dominican republic": "🇩🇴",
"fiji": "🇫🇯",
"france": "🇫🇷",
"egypt": "🇪🇬",
"germany": "🇩🇪",
"great britain": "🇬🇧",
"greece": "🇬🇷",
"guinea": "🇬🇳",
"hungary": "🇭🇺",
"india": "🇮🇳",
"iraq": "🇮🇶",
"ireland": "🇮🇪",
"israel": "🇮🇱",
"italy": "🇮🇱",
"japan": "🇯🇵",
"kenya": "🇰🇪",
"latvia": "🇱🇻",
"lithuania": "🇱🇹",
"korea": "🇰🇷",
"mali": "🇲🇱",
"montenegro": "🇲🇪",
"morocco": "🇲🇦",
"nigeria": "🇳🇬",
"netherlands": "🇳🇱",
"new zealand": "🇳🇿",
"norway": "🇳🇴",
"paraguay": "🇵🇾",
"poland": "🇵🇱",
"puerto rico": "🇵🇷",
"romania": "🇷🇴",
"serbia": "🇷🇸",
"south africa": "🇿🇦",
"south sudan": "🇸🇸",
"slovenia": "🇸🇮",
"samoa": "🇼🇸",
"spain": "🇪🇸",
"sweden": "🇸🇪",
"türkiye": "🇹🇷",
"ukraine": "🇺🇦",
"united states": "🇺🇸",
"uruguay": "🇺🇾",
"uzbekistan": "🇺🇿",
"zambia": "🇿🇲",
};
if (teams[country.toLowerCase()]) {
return teams[country.toLowerCase()];
}
throw new Error(`No flag set for ${country}`);
};
const SPORTS = [];
const TEAMS = [];
@ -103,28 +112,28 @@ const OUTPUT = [];
const generateCalendar = (title, key, events) => {
const lines = [];
lines.push(`BEGIN:VCALENDAR`);
lines.push(`VERSION:2.0`);
lines.push("BEGIN:VCALENDAR");
lines.push("VERSION:2.0");
lines.push(`PRODID:-//fabrice404//olympics-calendar//${key}//EN`);
lines.push(`X-WR-CALNAME:${title}`);
lines.push(`NAME:${title}`);
events.forEach((event) => {
lines.push(`BEGIN:VEVENT`);
lines.push("BEGIN:VEVENT");
lines.push(
...Object.entries(event)
.filter(([key, value]) => !key.startsWith('_'))
.map(([key, value]) => `${key}:${value}`)
.filter(([key]) => !key.startsWith("_"))
.map(([key, value]) => `${key}:${value}`),
);
lines.push(`END:VEVENT`);
lines.push("END:VEVENT");
});
lines.push(`END:VCALENDAR`);
lines.push("END:VCALENDAR");
const folder = `${__dirname}/docs/${key}.ics`.split('/').slice(0, -1).join('/');
fs.mkdirSync(folder, { recursive: true })
fs.writeFileSync(`${__dirname}/docs/${key}.ics`, lines.join('\r\n'));
}
const folder = `${__dirname}/docs/${key}.ics`.split("/").slice(0, -1).join("/");
fs.mkdirSync(folder, { recursive: true });
fs.writeFileSync(`${__dirname}/docs/${key}.ics`, lines.join("\r\n"));
};
const generateSportCalendar = (sportKey) => {
const sport = SPORTS.find((sport) => sport.key === sportKey);
@ -143,7 +152,7 @@ const generateSportCalendar = (sportKey) => {
</div>
</div>
`);
}
};
const generateSportTeamCalendar = (sportKey, teamKey) => {
const sport = SPORTS.find((sport) => sport.key === sportKey);
@ -182,7 +191,7 @@ const addSport = (name, key, icon) => {
if (!SPORTS.find((sport) => sport.key === key)) {
SPORTS.push({ name, key, icon, teams: [] });
}
}
};
const addTeam = (name, key, icon) => {
if (!TEAMS.find((team) => team.key === key)) {
@ -195,7 +204,7 @@ const addSportTeam = (sportKey, teamKey) => {
if (sport && !sport.teams.includes(teamKey)) {
sport.teams.push(teamKey);
}
}
};
const isValidTeam = (team) => !team.toLowerCase().startsWith("winner oqt");
@ -211,15 +220,15 @@ const teamSport = async (sportKey) => {
schedule.units.forEach(unit => {
const event = {
UID: `${sportKey}-${unit.startDateTimeUtc.replace(/[:-]/g, '')}`,
DTSTAMP: unit.startDateTimeUtc.replace(/[:-]/g, ''),
DTSTART: unit.startDateTimeUtc.replace(/[:-]/g, ''),
DTEND: unit.endDateTimeUtc.replace(/[:-]/g, ''),
UID: `${sportKey}-${unit.startDateTimeUtc.replace(/[:-]/g, "")}`,
DTSTAMP: unit.startDateTimeUtc.replace(/[:-]/g, ""),
DTSTART: unit.startDateTimeUtc.replace(/[:-]/g, ""),
DTEND: unit.endDateTimeUtc.replace(/[:-]/g, ""),
DESCRIPTION: `${sportName} - ${unit.description}`,
SUMMARY: `${sportIcon} ${unit.description}`,
LOCATION: schedule.venue ? schedule.venue.description : unit.venue.description,
_SPORT: sportKey,
}
};
if (unit.match &&
unit.match.team1 && isValidTeam(unit.match.team1.description) &&
@ -230,14 +239,14 @@ const teamSport = async (sportKey) => {
key: unit.match.team1.teamCode,
icon: getFlagIcon(unit.match.team1.description),
};
addTeam(team1.name, team1.key, team1.icon)
addTeam(team1.name, team1.key, team1.icon);
const team2 = {
name: unit.match.team2.description,
key: unit.match.team2.teamCode,
icon: getFlagIcon(unit.match.team2.description),
};
addTeam(team2.name, team2.key, team2.icon)
addTeam(team2.name, team2.key, team2.icon);
event.UID += `-${team1.key}-${team2.key}`;
event.SUMMARY = `${sportIcon} ${team1.key} ${team1.icon} - ${team2.icon} ${team2.key}`;
@ -251,55 +260,55 @@ const teamSport = async (sportKey) => {
});
});
}
};
const teamSports = async () => {
await Promise.all(
[
'3x3-basketball',
'basketball',
'football',
'handball',
'hockey',
'rugby-sevens',
'volleyball',
'water-polo',
"3x3-basketball",
"basketball",
"football",
"handball",
"hockey",
"rugby-sevens",
"volleyball",
"water-polo",
]
.map((key) => teamSport(key))
.map((key) => teamSport(key)),
);
SPORTS.sort((a, b) => a.name > b.name ? 1 : -1).forEach((sport) => {
const sportKey = sport.key;
generateSportCalendar(sportKey);
OUTPUT.push("<ul>")
OUTPUT.push("<ul>");
sport.teams
.sort((a, b) => a > b ? 1 : -1)
.forEach((teamKey) => {
generateSportTeamCalendar(sportKey, teamKey);
});
OUTPUT.push("</ul>")
OUTPUT.push("</ul>");
});
OUTPUT.push(`<div class="text-3xl pb-4 pt-8">🌍 Teams</div>`);
OUTPUT.push("<div class=\"text-3xl pb-4 pt-8\">🌍 Teams</div>");
TEAMS
.sort((a, b) => a.name > b.name ? 1 : -1)
.forEach((team) => {
generateTeamCalendar(team.key);
});
}
};
const main = async () => {
await teamSports();
const template = fs.readFileSync(`${__dirname}/template.html`, 'utf-8');
const output = template.replace('{{calendars}}', OUTPUT.join('\n'));
fs.writeFileSync('docs/index.html', output);
const template = fs.readFileSync(`${__dirname}/template.html`, "utf-8");
const output = template.replace("{{calendars}}", OUTPUT.join("\n"));
fs.writeFileSync("docs/index.html", output);
postcss([autoprefixer, tailwindcss])
.process(fs.readFileSync(`${__dirname}/template.css`, 'utf-8'), { from: 'template.css', to: 'docs/style.css' })
.process(fs.readFileSync(`${__dirname}/template.css`, "utf-8"), { from: "template.css", to: "docs/style.css" })
.then((result) => {
fs.writeFileSync('docs/style.css', result.css);
})
fs.writeFileSync("docs/style.css", result.css);
});
};

955
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,14 +3,19 @@
"version": "1.0.0",
"main": "handball.js",
"scripts": {
"start": "node index.js",
"lint": "eslint .",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"description": "",
"devDependencies": {
"@eslint/js": "^9.6.0",
"autoprefixer": "^10.4.19",
"cheerio": "^1.0.0-rc.12",
"eslint": "^9.6.0",
"globals": "^15.8.0",
"postcss": "^8.4.39",
"tailwindcss": "^3.4.4"
}

View File

@ -5,5 +5,5 @@ module.exports = {
extend: {},
},
plugins: [],
}
};