| | import { httpClient } from '../../shared/utils/http-client'; |
| | import * as cheerio from 'cheerio'; |
| | import { CodeChefUserRating } from './types'; |
| | import { CODECHEF_BASE_URL, CODECHEF_SELECTORS } from './constants'; |
| |
|
| | export async function fetchUserRating(username: string): Promise<CodeChefUserRating> { |
| | const url = `${CODECHEF_BASE_URL}${username}`; |
| | try { |
| | const { data } = await httpClient.get(url); |
| | const $ = cheerio.load(data); |
| |
|
| | |
| | if ($('body').text().includes('not found') || $('title').text().includes('404')) { |
| | throw new Error(`User '${username}' not found on CodeChef`); |
| | } |
| |
|
| | const ratingElement = $(CODECHEF_SELECTORS.RATING).first(); |
| | if (ratingElement.length === 0) { |
| | throw new Error('CodeChef schema change detected: Rating selector not found'); |
| | } |
| |
|
| | const ratingText = ratingElement.text().trim(); |
| | const rating = parseInt(ratingText); |
| |
|
| | const maxRatingElement = $(CODECHEF_SELECTORS.MAX_RATING).first(); |
| | const maxRatingText = maxRatingElement.text().match(/\d+/)?.[0]; |
| | const max_rating = maxRatingText ? parseInt(maxRatingText) : undefined; |
| |
|
| | if (isNaN(rating)) { |
| | throw new Error('Could not parse CodeChef rating. Schema might have changed.'); |
| | } |
| |
|
| | return { rating, max_rating }; |
| | } catch (error: any) { |
| | if (error.response?.status === 404) { |
| | throw new Error(`User '${username}' not found on CodeChef`); |
| | } |
| | throw error; |
| | } |
| | } |
| |
|