mirror of
https://github.com/fabrice404/olympics-calendar.git
synced 2025-12-13 22:59:44 +00:00
add eslint
This commit is contained in:
26
eslint.config.mjs
Normal file
26
eslint.config.mjs
Normal 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
239
index.js
@ -1,8 +1,8 @@
|
|||||||
const cheerio = require('cheerio');
|
const cheerio = require("cheerio");
|
||||||
const fs = require('fs');
|
const fs = require("fs");
|
||||||
const autoprefixer = require('autoprefixer');
|
const autoprefixer = require("autoprefixer");
|
||||||
const postcss = require('postcss');
|
const postcss = require("postcss");
|
||||||
const tailwindcss = require('tailwindcss');
|
const tailwindcss = require("tailwindcss");
|
||||||
|
|
||||||
const downloadSchedule = async (sportKey) => {
|
const downloadSchedule = async (sportKey) => {
|
||||||
const cacheFile = `${__dirname}/cache/${sportKey}.html`;
|
const cacheFile = `${__dirname}/cache/${sportKey}.html`;
|
||||||
@ -13,87 +13,96 @@ const downloadSchedule = async (sportKey) => {
|
|||||||
fs.writeFileSync(cacheFile, content);
|
fs.writeFileSync(cacheFile, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
const html = fs.readFileSync(cacheFile, 'utf-8');
|
const html = fs.readFileSync(cacheFile, "utf-8");
|
||||||
const $ = cheerio.load(html);
|
const $ = cheerio.load(html);
|
||||||
return JSON.parse($('#__NEXT_DATA__').text());
|
return JSON.parse($("#__NEXT_DATA__").text());
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSportIcon = (sport) => {
|
const getSportIcon = (sport) => {
|
||||||
switch (sport.toLowerCase()) {
|
const sports = {
|
||||||
case "3x3-basketball": return "🏀③"
|
"3x3-basketball": "🏀③",
|
||||||
case "basketball": return "🏀";
|
"basketball": "🏀",
|
||||||
case "football": return "⚽";
|
"football": "⚽",
|
||||||
case "handball": return "🤾";
|
"handball": "🤾",
|
||||||
case "hockey": return "🏑";
|
"hockey": "🏑",
|
||||||
case "rugby-sevens": return "🏉";
|
"rugby-sevens": "🏉",
|
||||||
case "volleyball": return "🏐";
|
"volleyball": "🏐",
|
||||||
case "water-polo": return "🤽";
|
"water-polo": "🤽",
|
||||||
default: throw new Error(`No icon set for ${sport}`);
|
};
|
||||||
|
|
||||||
|
if (sports[sport]) {
|
||||||
|
return sports[sport];
|
||||||
}
|
}
|
||||||
|
throw new Error(`No icon set for ${sport}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getFlagIcon = (country) => {
|
const getFlagIcon = (country) => {
|
||||||
if (country.toLowerCase().startsWith("winner oqt")) {
|
if (country.toLowerCase().startsWith("winner oqt")) {
|
||||||
return "🏳️";
|
return "🏳️";
|
||||||
}
|
}
|
||||||
switch (country.toLowerCase()) {
|
|
||||||
case "angola": return "🇦🇴";
|
const teams = {
|
||||||
case "argentina": return "🇦🇷";
|
"angola": "🇦🇴",
|
||||||
case "australia": return "🇦🇺";
|
"argentina": "🇦🇷",
|
||||||
case "azerbaijan": return "🇦🇿";
|
"australia": "🇦🇺",
|
||||||
case "belgium": return "🇧🇪";
|
"azerbaijan": "🇦🇿",
|
||||||
case "brazil": return "🇧🇷";
|
"belgium": "🇧🇪",
|
||||||
case "canada": return "🇨🇦";
|
"brazil": "🇧🇷",
|
||||||
case "china": return "🇨🇳";
|
"canada": "🇨🇦",
|
||||||
case "colombia": return "🇨🇴";
|
"china": "🇨🇳",
|
||||||
case "croatia": return "🇭🇷";
|
"colombia": "🇨🇴",
|
||||||
case "denmark": return "🇩🇰";
|
"croatia": "🇭🇷",
|
||||||
case "dominican republic": return "🇩🇴";
|
"denmark": "🇩🇰",
|
||||||
case "fiji": return "🇫🇯";
|
"dominican republic": "🇩🇴",
|
||||||
case "france": return "🇫🇷";
|
"fiji": "🇫🇯",
|
||||||
case "egypt": return "🇪🇬";
|
"france": "🇫🇷",
|
||||||
case "germany": return "🇩🇪";
|
"egypt": "🇪🇬",
|
||||||
case "great britain": return "🇬🇧";
|
"germany": "🇩🇪",
|
||||||
case "greece": return "🇬🇷";
|
"great britain": "🇬🇧",
|
||||||
case "guinea": return "🇬🇳";
|
"greece": "🇬🇷",
|
||||||
case "hungary": return "🇭🇺";
|
"guinea": "🇬🇳",
|
||||||
case "india": return "🇮🇳";
|
"hungary": "🇭🇺",
|
||||||
case "iraq": return "🇮🇶";
|
"india": "🇮🇳",
|
||||||
case "ireland": return "🇮🇪";
|
"iraq": "🇮🇶",
|
||||||
case "israel": return "🇮🇱";
|
"ireland": "🇮🇪",
|
||||||
case "italy": return "🇮🇱";
|
"israel": "🇮🇱",
|
||||||
case "japan": return "🇯🇵";
|
"italy": "🇮🇱",
|
||||||
case "kenya": return "🇰🇪";
|
"japan": "🇯🇵",
|
||||||
case "latvia": return "🇱🇻";
|
"kenya": "🇰🇪",
|
||||||
case "lithuania": return "🇱🇹";
|
"latvia": "🇱🇻",
|
||||||
case "korea": return "🇰🇷";
|
"lithuania": "🇱🇹",
|
||||||
case "mali": return "🇲🇱";
|
"korea": "🇰🇷",
|
||||||
case "montenegro": return "🇲🇪";
|
"mali": "🇲🇱",
|
||||||
case "morocco": return "🇲🇦";
|
"montenegro": "🇲🇪",
|
||||||
case "nigeria": return "🇳🇬";
|
"morocco": "🇲🇦",
|
||||||
case "netherlands": return "🇳🇱";
|
"nigeria": "🇳🇬",
|
||||||
case "new zealand": return "🇳🇿";
|
"netherlands": "🇳🇱",
|
||||||
case "norway": return "🇳🇴";
|
"new zealand": "🇳🇿",
|
||||||
case "paraguay": return "🇵🇾";
|
"norway": "🇳🇴",
|
||||||
case "poland": return "🇵🇱";
|
"paraguay": "🇵🇾",
|
||||||
case "puerto rico": return "🇵🇷";
|
"poland": "🇵🇱",
|
||||||
case "romania": return "🇷🇴";
|
"puerto rico": "🇵🇷",
|
||||||
case "serbia": return "🇷🇸";
|
"romania": "🇷🇴",
|
||||||
case "south africa": return "🇿🇦";
|
"serbia": "🇷🇸",
|
||||||
case "south sudan": return "🇸🇸";
|
"south africa": "🇿🇦",
|
||||||
case "slovenia": return "🇸🇮";
|
"south sudan": "🇸🇸",
|
||||||
case "samoa": return "🇼🇸";
|
"slovenia": "🇸🇮",
|
||||||
case "spain": return "🇪🇸";
|
"samoa": "🇼🇸",
|
||||||
case "sweden": return "🇸🇪";
|
"spain": "🇪🇸",
|
||||||
case "türkiye": return "🇹🇷";
|
"sweden": "🇸🇪",
|
||||||
case "ukraine": return "🇺🇦";
|
"türkiye": "🇹🇷",
|
||||||
case "united states": return "🇺🇸";
|
"ukraine": "🇺🇦",
|
||||||
case "uruguay": return "🇺🇾";
|
"united states": "🇺🇸",
|
||||||
case "uzbekistan": return "🇺🇿";
|
"uruguay": "🇺🇾",
|
||||||
case "zambia": return "🇿🇲";
|
"uzbekistan": "🇺🇿",
|
||||||
default: throw new Error(`No flag set for ${country}`);
|
"zambia": "🇿🇲",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (teams[country.toLowerCase()]) {
|
||||||
|
return teams[country.toLowerCase()];
|
||||||
}
|
}
|
||||||
}
|
throw new Error(`No flag set for ${country}`);
|
||||||
|
};
|
||||||
|
|
||||||
const SPORTS = [];
|
const SPORTS = [];
|
||||||
const TEAMS = [];
|
const TEAMS = [];
|
||||||
@ -103,28 +112,28 @@ const OUTPUT = [];
|
|||||||
|
|
||||||
const generateCalendar = (title, key, events) => {
|
const generateCalendar = (title, key, events) => {
|
||||||
const lines = [];
|
const lines = [];
|
||||||
lines.push(`BEGIN:VCALENDAR`);
|
lines.push("BEGIN:VCALENDAR");
|
||||||
lines.push(`VERSION:2.0`);
|
lines.push("VERSION:2.0");
|
||||||
lines.push(`PRODID:-//fabrice404//olympics-calendar//${key}//EN`);
|
lines.push(`PRODID:-//fabrice404//olympics-calendar//${key}//EN`);
|
||||||
lines.push(`X-WR-CALNAME:${title}`);
|
lines.push(`X-WR-CALNAME:${title}`);
|
||||||
lines.push(`NAME:${title}`);
|
lines.push(`NAME:${title}`);
|
||||||
|
|
||||||
events.forEach((event) => {
|
events.forEach((event) => {
|
||||||
lines.push(`BEGIN:VEVENT`);
|
lines.push("BEGIN:VEVENT");
|
||||||
lines.push(
|
lines.push(
|
||||||
...Object.entries(event)
|
...Object.entries(event)
|
||||||
.filter(([key, value]) => !key.startsWith('_'))
|
.filter(([key]) => !key.startsWith("_"))
|
||||||
.map(([key, value]) => `${key}:${value}`)
|
.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('/');
|
const folder = `${__dirname}/docs/${key}.ics`.split("/").slice(0, -1).join("/");
|
||||||
fs.mkdirSync(folder, { recursive: true })
|
fs.mkdirSync(folder, { recursive: true });
|
||||||
fs.writeFileSync(`${__dirname}/docs/${key}.ics`, lines.join('\r\n'));
|
fs.writeFileSync(`${__dirname}/docs/${key}.ics`, lines.join("\r\n"));
|
||||||
}
|
};
|
||||||
|
|
||||||
const generateSportCalendar = (sportKey) => {
|
const generateSportCalendar = (sportKey) => {
|
||||||
const sport = SPORTS.find((sport) => sport.key === sportKey);
|
const sport = SPORTS.find((sport) => sport.key === sportKey);
|
||||||
@ -143,7 +152,7 @@ const generateSportCalendar = (sportKey) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
}
|
};
|
||||||
|
|
||||||
const generateSportTeamCalendar = (sportKey, teamKey) => {
|
const generateSportTeamCalendar = (sportKey, teamKey) => {
|
||||||
const sport = SPORTS.find((sport) => sport.key === sportKey);
|
const sport = SPORTS.find((sport) => sport.key === sportKey);
|
||||||
@ -182,7 +191,7 @@ const addSport = (name, key, icon) => {
|
|||||||
if (!SPORTS.find((sport) => sport.key === key)) {
|
if (!SPORTS.find((sport) => sport.key === key)) {
|
||||||
SPORTS.push({ name, key, icon, teams: [] });
|
SPORTS.push({ name, key, icon, teams: [] });
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const addTeam = (name, key, icon) => {
|
const addTeam = (name, key, icon) => {
|
||||||
if (!TEAMS.find((team) => team.key === key)) {
|
if (!TEAMS.find((team) => team.key === key)) {
|
||||||
@ -195,7 +204,7 @@ const addSportTeam = (sportKey, teamKey) => {
|
|||||||
if (sport && !sport.teams.includes(teamKey)) {
|
if (sport && !sport.teams.includes(teamKey)) {
|
||||||
sport.teams.push(teamKey);
|
sport.teams.push(teamKey);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const isValidTeam = (team) => !team.toLowerCase().startsWith("winner oqt");
|
const isValidTeam = (team) => !team.toLowerCase().startsWith("winner oqt");
|
||||||
|
|
||||||
@ -211,15 +220,15 @@ const teamSport = async (sportKey) => {
|
|||||||
schedule.units.forEach(unit => {
|
schedule.units.forEach(unit => {
|
||||||
|
|
||||||
const event = {
|
const event = {
|
||||||
UID: `${sportKey}-${unit.startDateTimeUtc.replace(/[:-]/g, '')}`,
|
UID: `${sportKey}-${unit.startDateTimeUtc.replace(/[:-]/g, "")}`,
|
||||||
DTSTAMP: unit.startDateTimeUtc.replace(/[:-]/g, ''),
|
DTSTAMP: unit.startDateTimeUtc.replace(/[:-]/g, ""),
|
||||||
DTSTART: unit.startDateTimeUtc.replace(/[:-]/g, ''),
|
DTSTART: unit.startDateTimeUtc.replace(/[:-]/g, ""),
|
||||||
DTEND: unit.endDateTimeUtc.replace(/[:-]/g, ''),
|
DTEND: unit.endDateTimeUtc.replace(/[:-]/g, ""),
|
||||||
DESCRIPTION: `${sportName} - ${unit.description}`,
|
DESCRIPTION: `${sportName} - ${unit.description}`,
|
||||||
SUMMARY: `${sportIcon} ${unit.description}`,
|
SUMMARY: `${sportIcon} ${unit.description}`,
|
||||||
LOCATION: schedule.venue ? schedule.venue.description : unit.venue.description,
|
LOCATION: schedule.venue ? schedule.venue.description : unit.venue.description,
|
||||||
_SPORT: sportKey,
|
_SPORT: sportKey,
|
||||||
}
|
};
|
||||||
|
|
||||||
if (unit.match &&
|
if (unit.match &&
|
||||||
unit.match.team1 && isValidTeam(unit.match.team1.description) &&
|
unit.match.team1 && isValidTeam(unit.match.team1.description) &&
|
||||||
@ -230,14 +239,14 @@ const teamSport = async (sportKey) => {
|
|||||||
key: unit.match.team1.teamCode,
|
key: unit.match.team1.teamCode,
|
||||||
icon: getFlagIcon(unit.match.team1.description),
|
icon: getFlagIcon(unit.match.team1.description),
|
||||||
};
|
};
|
||||||
addTeam(team1.name, team1.key, team1.icon)
|
addTeam(team1.name, team1.key, team1.icon);
|
||||||
|
|
||||||
const team2 = {
|
const team2 = {
|
||||||
name: unit.match.team2.description,
|
name: unit.match.team2.description,
|
||||||
key: unit.match.team2.teamCode,
|
key: unit.match.team2.teamCode,
|
||||||
icon: getFlagIcon(unit.match.team2.description),
|
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.UID += `-${team1.key}-${team2.key}`;
|
||||||
event.SUMMARY = `${sportIcon} ${team1.key} ${team1.icon} - ${team2.icon} ${team2.key}`;
|
event.SUMMARY = `${sportIcon} ${team1.key} ${team1.icon} - ${team2.icon} ${team2.key}`;
|
||||||
@ -251,55 +260,55 @@ const teamSport = async (sportKey) => {
|
|||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
const teamSports = async () => {
|
const teamSports = async () => {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
[
|
[
|
||||||
'3x3-basketball',
|
"3x3-basketball",
|
||||||
'basketball',
|
"basketball",
|
||||||
'football',
|
"football",
|
||||||
'handball',
|
"handball",
|
||||||
'hockey',
|
"hockey",
|
||||||
'rugby-sevens',
|
"rugby-sevens",
|
||||||
'volleyball',
|
"volleyball",
|
||||||
'water-polo',
|
"water-polo",
|
||||||
]
|
]
|
||||||
.map((key) => teamSport(key))
|
.map((key) => teamSport(key)),
|
||||||
);
|
);
|
||||||
|
|
||||||
SPORTS.sort((a, b) => a.name > b.name ? 1 : -1).forEach((sport) => {
|
SPORTS.sort((a, b) => a.name > b.name ? 1 : -1).forEach((sport) => {
|
||||||
const sportKey = sport.key;
|
const sportKey = sport.key;
|
||||||
generateSportCalendar(sportKey);
|
generateSportCalendar(sportKey);
|
||||||
OUTPUT.push("<ul>")
|
OUTPUT.push("<ul>");
|
||||||
sport.teams
|
sport.teams
|
||||||
.sort((a, b) => a > b ? 1 : -1)
|
.sort((a, b) => a > b ? 1 : -1)
|
||||||
.forEach((teamKey) => {
|
.forEach((teamKey) => {
|
||||||
generateSportTeamCalendar(sportKey, 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
|
TEAMS
|
||||||
.sort((a, b) => a.name > b.name ? 1 : -1)
|
.sort((a, b) => a.name > b.name ? 1 : -1)
|
||||||
.forEach((team) => {
|
.forEach((team) => {
|
||||||
generateTeamCalendar(team.key);
|
generateTeamCalendar(team.key);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
const main = async () => {
|
const main = async () => {
|
||||||
await teamSports();
|
await teamSports();
|
||||||
|
|
||||||
const template = fs.readFileSync(`${__dirname}/template.html`, 'utf-8');
|
const template = fs.readFileSync(`${__dirname}/template.html`, "utf-8");
|
||||||
const output = template.replace('{{calendars}}', OUTPUT.join('\n'));
|
const output = template.replace("{{calendars}}", OUTPUT.join("\n"));
|
||||||
fs.writeFileSync('docs/index.html', output);
|
fs.writeFileSync("docs/index.html", output);
|
||||||
|
|
||||||
postcss([autoprefixer, tailwindcss])
|
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) => {
|
.then((result) => {
|
||||||
fs.writeFileSync('docs/style.css', result.css);
|
fs.writeFileSync("docs/style.css", result.css);
|
||||||
})
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
955
package-lock.json
generated
955
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -3,14 +3,19 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"main": "handball.js",
|
"main": "handball.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"start": "node index.js",
|
||||||
|
"lint": "eslint .",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"description": "",
|
"description": "",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@eslint/js": "^9.6.0",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.19",
|
||||||
"cheerio": "^1.0.0-rc.12",
|
"cheerio": "^1.0.0-rc.12",
|
||||||
|
"eslint": "^9.6.0",
|
||||||
|
"globals": "^15.8.0",
|
||||||
"postcss": "^8.4.39",
|
"postcss": "^8.4.39",
|
||||||
"tailwindcss": "^3.4.4"
|
"tailwindcss": "^3.4.4"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,5 +5,5 @@ module.exports = {
|
|||||||
extend: {},
|
extend: {},
|
||||||
},
|
},
|
||||||
plugins: [],
|
plugins: [],
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user