// import { fetch } from 'bun'; import type { IEventInfo, Player } from "./types"; import * as cheerio from "cheerio"; import fs from 'fs'; import path from 'path'; import { chunk } from 'lodash'; const BASE_URL = `https://kaiqiuwang.cc`; /** * @param tagid 俱乐部 ID */ export async function listEvent(tagid: string): Promise { return parseEventList(await fetchEventListHTML(tagid)); return parseEventList( fs.readFileSync( path.resolve(__dirname, '..', '__test__', 'data', 'view-event.html') ).toString() ); } /** * @param tagid 俱乐部 ID * @return HTML */ export async function fetchEventListHTML(tagid: string) { const url = `${BASE_URL}/home/space.php?do=mtag&tagid=${tagid}&view=event`; const resp = await fetch(url); return resp.text() ?? ''; } export function parseEventList(html: string) { const $ = cheerio.load(html); const blockList = $('div.event_list > ol > li'); const list: IEventInfo[] = []; for (const block of blockList) { const titleEl = $(block).find('.event_title'); const title = titleEl.text(); const url = $(titleEl).find('a').attr('href') ?? ''; const startDate = $(block).find('ul li:nth-of-type(1)').text().replace('比赛开始: \\t', '').trim(); const place = $(block).find('ul li:nth-of-type(2)').text().replace('比赛地点: \\t', '').trim(); const event: IEventInfo = { title, info: [startDate, place], url: `${BASE_URL}/home/${url}`, matchId: /\S+-(\d+).html$/.exec(url)?.[1] ?? '', } list.push(event); } return list; } /** * * @param matchId 比赛 ID * @returns HTML */ export async function fetchEventContentHTML(matchId: string) { const url = `${BASE_URL}/home/space.php?do=event&id=${matchId}&view=member&status=2`; const resp = await fetch(url); return resp.text() ?? '' } export function parseEventInfo(html: string) { const $ = cheerio.load(html); const itemHref = $('.sub_menu a.active').attr('href') ?? ''; const itemId = /\S+item_id=(\d+)$/.exec(itemHref)?.[1] ?? ''; const players: Player[] = []; const playersEl = $('.thumb'); for (const player of playersEl) { const img = $(player).find('.image img').attr('src') ?? ''; const name = $(player).find('h6').text().trim(); const info = $(player).find('p:nth-of-type(2)').text().replace(/\s/g, ''); const score = Number(/^.*?\b(\d+)\b/.exec(info)?.[1]); players.push({ name, avatar: img, score, info }); } return { itemId, players, } } export async function getMatchInfo(matchId: string) { return parseEventInfo(await fetchEventContentHTML(matchId)); return parseEventInfo( fs .readFileSync( path.resolve(__dirname, '..', '__test__', 'data', 'view-event-content.html') ) .toString() ); } export function sneckGroup(size: number, groupLen: number) { const indexArray = new Array(size).fill(0).map((_, i) => i); const chunckSize = Math.round((size / groupLen)); const chunckedGroup = chunk(indexArray, groupLen); const reversedGroup = chunckedGroup.map((e, i) => { if (i % 2 === 0) return e; return e.toReversed(); }); const newGroups: number[][] = []; for (let groupIndex = 0; groupIndex < groupLen; groupIndex++) { const group: number[] = []; for (let colIndex = 0; colIndex < chunckSize; colIndex++) { const data = reversedGroup[colIndex]?.[groupIndex]; group.push(data === undefined ? NaN : data); } newGroups.push(group); } return newGroups; }