Lint and format
Some checks failed
pipeline / lint-and-format (push) Failing after 56s
pipeline / build-and-push-images (push) Has been skipped

This commit is contained in:
2026-01-21 00:59:23 +01:00
parent 353baa6267
commit 3fc52205f6
53 changed files with 8505 additions and 2048 deletions

View File

@@ -1,207 +1,218 @@
const base = "https://euw1.api.riotgames.com"
const base = 'https://euw1.api.riotgames.com'
const api_key = process.env.RIOT_API_KEY
const sleep_minutes = 12
import { MongoClient } from 'mongodb'
import champion_stat from "./champion_stat"
import champion_stat from './champion_stat'
main()
async function main() {
// Check if we're in development mode with pre-loaded data
if (process.env.NODE_ENV === 'development' && process.env.USE_IMPORTED_DATA === 'true') {
console.log("MatchCollector - Development mode with pre-loaded data");
await runWithPreloadedData();
return;
// Check if we're in development mode with pre-loaded data
if (process.env.NODE_ENV === 'development' && process.env.USE_IMPORTED_DATA === 'true') {
console.log('MatchCollector - Development mode with pre-loaded data')
await runWithPreloadedData()
return
}
// Original production mode
console.log('MatchCollector - Hello !')
const client = await connectToDatabase()
const [latestPatch, latestPatchTime] = await fetchLatestPatchDate(client)
console.log(
'Connected to database, latest patch ' + latestPatch + ' was epoch: ' + latestPatchTime
)
const alreadySeenGameList = await alreadySeenGames(client, latestPatch)
console.log('We already have ' + alreadySeenGameList.length + ' matches for this patch !')
console.log('Using RIOT_API_KEY: ' + api_key)
if (api_key != null && api_key != undefined && api_key != '') {
const challengerLeague = await fetchChallengerLeague()
console.log('ChallengerLeague: got ' + challengerLeague.entries.length + ' entries')
const gameList = []
let i = 0
for (const challenger of challengerLeague.entries) {
console.log('Entry ' + i + '/' + challengerLeague.entries.length + ' ...')
const puuid = challenger.puuid
const challengerGameList = await summonerGameList(puuid, latestPatchTime)
for (const game of challengerGameList) {
if (!gameList.includes(game) && !alreadySeenGameList.includes(game)) {
gameList.push(game)
}
}
i++
}
// Original production mode
console.log("MatchCollector - Hello !");
const client = await connectToDatabase();
const [latestPatch, latestPatchTime] = await fetchLatestPatchDate(client);
console.log("Connected to database, latest patch " + latestPatch + " was epoch: " + latestPatchTime)
const alreadySeenGameList = await alreadySeenGames(client, latestPatch);
console.log("We already have " + alreadySeenGameList.length + " matches for this patch !")
console.log("Using RIOT_API_KEY: " + api_key)
if(api_key != null && api_key != undefined && api_key != "") {
const challengerLeague = await fetchChallengerLeague();
console.log("ChallengerLeague: got " + challengerLeague.entries.length + " entries");
const gameList = [];
let i = 0;
for(let challenger of challengerLeague.entries) {
console.log("Entry " + i + "/" + challengerLeague.entries.length + " ...")
const puuid = challenger.puuid;
const challengerGameList = await summonerGameList(puuid, latestPatchTime);
for(let game of challengerGameList) {
if(!gameList.includes(game) && !alreadySeenGameList.includes(game)) {
gameList.push(game)
}
}
i++;
}
console.log("Games: got " + gameList.length + " entries");
i = 0;
for(let game of gameList) {
console.log("Entry " + i + "/" + gameList.length + " ...")
const gameMatch = await match(game)
const gameTimeline = await matchTimeline(game)
gameMatch.timeline = gameTimeline
await saveMatch(client, gameMatch, latestPatch)
i++;
}
console.log('Games: got ' + gameList.length + ' entries')
i = 0
for (const game of gameList) {
console.log('Entry ' + i + '/' + gameList.length + ' ...')
const gameMatch = await match(game)
const gameTimeline = await matchTimeline(game)
gameMatch.timeline = gameTimeline
await saveMatch(client, gameMatch, latestPatch)
i++
}
}
console.log("Generating stats...");
await champion_stat.makeChampionsStats(client, latestPatch)
console.log('Generating stats...')
await champion_stat.makeChampionsStats(client, latestPatch)
console.log("All done. Closing client.");
await client.close()
console.log('All done. Closing client.')
await client.close()
}
async function handleRateLimit(url : URL) : Promise<Response> {
let response = await fetch(url)
if(response.status == 429) {
await new Promise(resolve => setTimeout(resolve, sleep_minutes * 60 * 1000))
response = await handleRateLimit(url)
}
async function handleRateLimit(url: URL): Promise<Response> {
let response = await fetch(url)
if (response.status == 429) {
await new Promise(resolve => setTimeout(resolve, sleep_minutes * 60 * 1000))
response = await handleRateLimit(url)
}
return response
return response
}
function handleError(response : Response) {
if(!response.ok) {
console.log("Error during fetch(" + response.url + "): STATUS " + response.status + " (" + response.statusText + ")");
process.exit(1);
}
function handleError(response: Response) {
if (!response.ok) {
console.log(
'Error during fetch(' +
response.url +
'): STATUS ' +
response.status +
' (' +
response.statusText +
')'
)
process.exit(1)
}
}
async function connectToDatabase() {
// Create a MongoClient with a MongoClientOptions object to set the Stable API version
let uri = `mongodb://${process.env.MONGO_USER}:${process.env.MONGO_PASS}@${process.env.MONGO_HOST}`
if(process.env.MONGO_URI != undefined && process.env.MONGO_URI != null && process.env.MONGO_URI != "") {
uri = process.env.MONGO_URI
}
const client = new MongoClient(uri)
await client.connect()
return client
// Create a MongoClient with a MongoClientOptions object to set the Stable API version
let uri = `mongodb://${process.env.MONGO_USER}:${process.env.MONGO_PASS}@${process.env.MONGO_HOST}`
if (
process.env.MONGO_URI != undefined &&
process.env.MONGO_URI != null &&
process.env.MONGO_URI != ''
) {
uri = process.env.MONGO_URI
}
const client = new MongoClient(uri)
await client.connect()
return client
}
async function fetchLatestPatchDate(client) {
const database = client.db("patches");
const patches = database.collection("patches");
const latestPatch = await patches.find().limit(1).sort({date:-1}).next()
return [latestPatch.patch, Math.floor(latestPatch.date.valueOf() / 1000)]
const database = client.db('patches')
const patches = database.collection('patches')
const latestPatch = await patches.find().limit(1).sort({ date: -1 }).next()
return [latestPatch.patch, Math.floor(latestPatch.date.valueOf() / 1000)]
}
async function fetchChallengerLeague() {
const queue = "RANKED_SOLO_5x5"
const endpoint = `/lol/league/v4/challengerleagues/by-queue/${queue}`
const url = `${base}${endpoint}?api_key=${api_key}`
const queue = 'RANKED_SOLO_5x5'
const endpoint = `/lol/league/v4/challengerleagues/by-queue/${queue}`
const url = `${base}${endpoint}?api_key=${api_key}`
const challengerLeagueResponse = await handleRateLimit(new URL(url));
handleError(challengerLeagueResponse)
const challengerLeagueResponse = await handleRateLimit(new URL(url))
const challengerLeague = await challengerLeagueResponse.json();
return challengerLeague;
handleError(challengerLeagueResponse)
const challengerLeague = await challengerLeagueResponse.json()
return challengerLeague
}
async function summonerGameList(puuid, startTime) {
const base = "https://europe.api.riotgames.com"
const endpoint = `/lol/match/v5/matches/by-puuid/${puuid}/ids`;
const url = `${base}${endpoint}?queue=420&type=ranked&startTime=${startTime}&api_key=${api_key}`
const base = 'https://europe.api.riotgames.com'
const endpoint = `/lol/match/v5/matches/by-puuid/${puuid}/ids`
const url = `${base}${endpoint}?queue=420&type=ranked&startTime=${startTime}&api_key=${api_key}`
const gameListResponse = await handleRateLimit(new URL(url));
handleError(gameListResponse)
const gameList = await gameListResponse.json();
const gameListResponse = await handleRateLimit(new URL(url))
handleError(gameListResponse)
const gameList = await gameListResponse.json()
return gameList;
return gameList
}
async function match(matchId) {
const base = "https://europe.api.riotgames.com"
const endpoint = `/lol/match/v5/matches/${matchId}`
const url = `${base}${endpoint}?api_key=${api_key}`
const base = 'https://europe.api.riotgames.com'
const endpoint = `/lol/match/v5/matches/${matchId}`
const url = `${base}${endpoint}?api_key=${api_key}`
const matchResponse = await handleRateLimit(new URL(url))
handleError(matchResponse)
const match = await matchResponse.json();
const matchResponse = await handleRateLimit(new URL(url))
handleError(matchResponse)
const match = await matchResponse.json()
return match;
return match
}
async function matchTimeline(matchId) {
const base = "https://europe.api.riotgames.com"
const endpoint = `/lol/match/v5/matches/${matchId}/timeline`
const url = `${base}${endpoint}?api_key=${api_key}`
const base = 'https://europe.api.riotgames.com'
const endpoint = `/lol/match/v5/matches/${matchId}/timeline`
const url = `${base}${endpoint}?api_key=${api_key}`
const timelineResponse = await handleRateLimit(new URL(url))
handleError(timelineResponse)
const timeline = await timelineResponse.json();
const timelineResponse = await handleRateLimit(new URL(url))
handleError(timelineResponse)
const timeline = await timelineResponse.json()
return timeline
return timeline
}
async function alreadySeenGames(client, latestPatch) {
const database = client.db("matches")
const matches = database.collection(latestPatch)
const database = client.db('matches')
const matches = database.collection(latestPatch)
const alreadySeen = await matches.distinct("metadata.matchId")
return alreadySeen
const alreadySeen = await matches.distinct('metadata.matchId')
return alreadySeen
}
async function saveMatch(client, match, latestPatch) {
const database = client.db("matches")
const matches = database.collection(latestPatch)
await matches.insertOne(match)
const database = client.db('matches')
const matches = database.collection(latestPatch)
await matches.insertOne(match)
}
/**
* Development mode function that generates stats from pre-loaded data
*/
async function runWithPreloadedData() {
console.log("Using pre-loaded match data for development");
console.log('Using pre-loaded match data for development')
const client = await connectToDatabase();
try {
const [latestPatch] = await fetchLatestPatchDate(client);
console.log(`Latest patch: ${latestPatch}`);
const client = await connectToDatabase()
try {
const [latestPatch] = await fetchLatestPatchDate(client)
console.log(`Latest patch: ${latestPatch}`)
// Check if we have matches for this patch
const matchesDb = client.db("matches");
const collections = await matchesDb.listCollections().toArray();
const patchCollections = collections
.map(c => c.name)
.filter(name => name === latestPatch);
// Check if we have matches for this patch
const matchesDb = client.db('matches')
const collections = await matchesDb.listCollections().toArray()
const patchCollections = collections.map(c => c.name).filter(name => name === latestPatch)
if (patchCollections.length === 0) {
console.error(`❌ No match data found for patch ${latestPatch}`);
console.log("💡 Please run the data import script first:");
console.log(" node dev/scripts/setup-db.js");
return;
}
console.log(`Found ${patchCollections.length} match collection(s)`);
// Generate stats for each patch with data
for (const patch of patchCollections) {
console.log(`Generating stats for patch ${patch}...`);
await champion_stat.makeChampionsStats(client, patch);
console.log(`Stats generated for patch ${patch}`);
}
console.log("🎉 All stats generated successfully!");
console.log("🚀 Your development database is ready for frontend testing!");
} catch (error) {
console.error("❌ Error in development mode:", error);
throw error;
} finally {
await client.close();
if (patchCollections.length === 0) {
console.error(`❌ No match data found for patch ${latestPatch}`)
console.log('💡 Please run the data import script first:')
console.log(' node dev/scripts/setup-db.js')
return
}
console.log(`Found ${patchCollections.length} match collection(s)`)
// Generate stats for each patch with data
for (const patch of patchCollections) {
console.log(`Generating stats for patch ${patch}...`)
await champion_stat.makeChampionsStats(client, patch)
console.log(`Stats generated for patch ${patch}`)
}
console.log('🎉 All stats generated successfully!')
console.log('🚀 Your development database is ready for frontend testing!')
} catch (error) {
console.error('❌ Error in development mode:', error)
throw error
} finally {
await client.close()
}
}