111 lines
3.4 KiB
TypeScript
111 lines
3.4 KiB
TypeScript
// 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<IEventInfo[]> {
|
|
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<number>(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;
|
|
} |