diff options
| author | wabilin <[email protected]> | 2020-07-31 22:41:55 +0900 |
|---|---|---|
| committer | wabilin <[email protected]> | 2020-07-31 22:44:00 +0900 |
| commit | 3df2b359a94fc0e0017f3c6d299e85d815ee0ed2 (patch) | |
| tree | 554ba8d6cb996bad9f8d9ad8b805d8225aacb5c8 /src/parseScheduleHtml.ts | |
| parent | get datas without date (diff) | |
| download | holo-schedule-3df2b359a94fc0e0017f3c6d299e85d815ee0ed2.tar.xz holo-schedule-3df2b359a94fc0e0017f3c6d299e85d815ee0ed2.zip | |
basic infos done
Diffstat (limited to 'src/parseScheduleHtml.ts')
| -rw-r--r-- | src/parseScheduleHtml.ts | 96 |
1 files changed, 91 insertions, 5 deletions
diff --git a/src/parseScheduleHtml.ts b/src/parseScheduleHtml.ts index 8177eee..51254dc 100644 --- a/src/parseScheduleHtml.ts +++ b/src/parseScheduleHtml.ts @@ -22,16 +22,102 @@ function dataFromAThumbnail(thumb: Element) { }; } -function parseScheduleHtml(html: string | Buffer) { +interface LiveBlock { + time: Date, + streamer: string, + images: string[], +} + +function parseToLiveBlocks(html: string | Buffer): LiveBlock[] { const { window } = new JSDOM(html); const { document } = window; + const year = (new Date()).getFullYear().toString() + + const rows = document.querySelectorAll('#all > .container > .row') + + let date = '' + + const lives: LiveBlock[] = [] + + rows.forEach(row => { + const dateDiv = row.querySelector('.holodule') + if (dateDiv) { + date = dateDiv.textContent?.replace(/\s+/g, "") || ""; + date = date.match(/\d+\/\d+/)![0].replace('/', '-') + } else { + const allThumbnail = row.querySelectorAll("a.thumbnail"); + allThumbnail.forEach(thumbnail => { + const { time, name, images } = dataFromAThumbnail(thumbnail) + lives.push({ + images, + time: new Date(`${year}-${date}T${time}:00+09:00`), + streamer: name, + }); + }) + } + }) + + return lives; +} + +type StreamerImageDict = Record<string, string> +type ImageStreamerDict = Record<string, string> + +function nextStreamerImageDict(liveBlocks: LiveBlock[], oldDict: StreamerImageDict) { + const dict = {...oldDict} + liveBlocks.forEach(({ images, streamer }) => { + dict[streamer] = images[0]; + }); + + return dict +} + +function reverseDict(dict: StreamerImageDict): ImageStreamerDict { + const reversed: ImageStreamerDict = {} + Object.entries(dict).forEach(([streamer, img]) => { + reversed[img] = streamer + }) + + return reversed +} + +interface LiveInfo { + time: Date + streamer: string + guests: string[] +} + +interface ParseResult { + lives: LiveInfo[] + dict: StreamerImageDict +} + +/** + * @param html - Html of https://schedule.hololive.tv. Get with Japan timezone (GTM+9) + * @param storedDict - An object stored { vtuberName: iconImageSrc } + * @returns - Lives schedule and updated dict + */ +function parseScheduleHtml( + html: string | Buffer, + storedDict: StreamerImageDict = {} +): ParseResult { + const liveBlocks = parseToLiveBlocks(html) + const streamerImageDict = nextStreamerImageDict(liveBlocks, storedDict) + const dict = reverseDict(streamerImageDict) + + const lives = liveBlocks.map(liveBlocks => { + const { streamer, images, time } = liveBlocks - const allThumbnail = document.querySelectorAll("a.thumbnail"); - const data = mapNodeList(allThumbnail, dataFromAThumbnail); + const guests = images.splice(1).map(x => dict[x]).filter(Boolean) - console.log(data); + return { + time, + streamer, + guests, + } + }) - return ""; + return { lives, dict }; } export default parseScheduleHtml; |