UNPKG

@rr0/cms

Version:

RR0 Content Management System (CMS)

88 lines (87 loc) 3.74 kB
import { HttpSource } from "../HttpSource.js"; import { UrlUtil } from "../../../util/index.js"; import { ObjectUtil } from "../../../util/ObjectUtil.js"; import { NuforcState } from "./NuforcState.js"; import assert from "assert"; import { Level2Date as EdtfDate } from "@rr0/time"; import { NuforcCountry } from "./NuforcCountry.js"; import { NuforcShape } from "./NuforcShape.js"; import { NuforcDatasource } from "./NuforcDatasource.js"; export class NuforcHttpDatasource extends NuforcDatasource { constructor(baseUrl = new URL("https://nuforc.org"), searchPath = "subndx") { super(); this.baseUrl = baseUrl; this.searchPath = searchPath; this.http = new HttpSource(); } queryUrl(context) { const day = context.time.getDayOfMonth(); const month = context.time.getMonth(); const year = context.time.getYear(); const queryParams = { id: "e" + year + String(month).padStart(2, "0") }; const queryParamsStr = UrlUtil.objToQueryParams(queryParams); const searchUrl = new URL(this.searchPath, this.baseUrl); searchUrl.search = queryParamsStr; return searchUrl; } async readCases(context) { const searchUrl = this.queryUrl(context); const doc = await this.http.get(searchUrl, { headers: { accept: "text/html;charset=utf-8" } }); const rowEls = doc.querySelectorAll("#table_1 tbody tr"); return Array.from(rowEls).map(row => this.getNativeCase(context, row)); } getShape(shapeField) { return NuforcShape[shapeField.textContent]; } getCountry(countryField) { const countryStr = countryField.textContent; const country = ObjectUtil.enumFromValue(NuforcCountry, countryStr); assert.ok(country, `Unknown NUFORC country "${countryStr}"`); return country; } getState(caseField) { const stateStr = caseField.textContent; return ObjectUtil.enumFromValue(NuforcState, stateStr); } getTime(dateField, context) { const dateFields = NuforcHttpDatasource.dateFormat.exec(dateField.textContent); const dayOfMonth = dateFields[2]; const hour = parseInt(dateFields[4], 10); const minutes = parseInt(dateFields[5], 10); return new EdtfDate({ year: parseInt(dateFields[3], 10), month: parseInt(dateFields[1], 10), day: dayOfMonth !== "00" ? parseInt(dayOfMonth, 10) : undefined, hour, minute: minutes }); } getLink(caseField) { const caseLink = caseField.firstElementChild; return new URL(caseLink.href, this.baseUrl); } dateFromField(reportField) { return new Date(reportField.textContent); } getImage(imageField) { return imageField.textContent === "Y"; } getNativeCase(context, row) { const columns = row.querySelectorAll("td"); const url = this.getLink(columns[0]); const caseNumber = new URLSearchParams(url.search).get("id"); const time = this.getTime(columns[1], context); const city = columns[2].textContent; const state = this.getState(columns[3]); const country = this.getCountry(columns[4]); const shape = this.getShape(columns[5]); const summary = columns[6].textContent; const reportDate = this.dateFromField(columns[7]); const postDate = this.dateFromField(columns[8]); const image = this.getImage(columns[9]); return { id: caseNumber, url: url.href, city, state, country, time, shape, summary, reportDate, postDate, image }; } } NuforcHttpDatasource.dateFormat = /(\d\d)\/(\d\d)\/(\d\d\d\d) (\d\d):(\d\d)/;