UNPKG

@rr0/cms

Version:

RR0 Content Management System (CMS)

83 lines (82 loc) 3.12 kB
import { HttpSource } from "../HttpSource.js"; import { UrlUtil } from "../../../util/index.js"; import { JSDOM } from "jsdom"; import { FuforaDatasource } from "./FuforaDatasource.js"; import { Level2Date as EdtfDate } from "@rr0/time"; export class FuforaHttpDatasource extends FuforaDatasource { constructor(baseUrl, searchPath) { super(); this.baseUrl = baseUrl; this.searchPath = searchPath; this.http = new HttpSource(); } async fetch(context) { const { formData, searchUrl } = this.queryUrl(context); const page = await this.http.submitForm(searchUrl, formData); const doc = new JSDOM(page).window.document.documentElement; const rowEls = doc.querySelectorAll(".udb_u_taulukko .rivi"); const rows = Array.from(rowEls); rows.shift(); // Skip header row return this.getFromRows(context, rows); } getFromRows(context, rows) { const cases = []; for (const row of rows) { if (row.hasChildNodes()) { cases.push(this.getFromRow(context, row)); } } return cases; } queryUrl(context) { const day = context.time.getDayOfMonth(); const month = context.time.getMonth(); const year = context.time.getYear(); const queryParams = { sid: "" }; const queryParamsStr = UrlUtil.objToQueryParams(queryParams); const formData = { alkupv: 1, alkukk: month, alkuvv: year, loppupv: 31, loppukk: month, loppuvv: year, h_paikka: "", l1_valinta1: 0, l3_valinta1: 0, tark: 1 }; const searchUrl = new URL(this.searchPath, this.baseUrl); searchUrl.search = queryParamsStr; return { formData, searchUrl }; } getFromRow(context, row) { const fields = row.querySelectorAll("div"); const caseLink = fields[0].firstElementChild; const dateFormat = /(?:(\d\d).(\d\d).(\d\d\d\d))?\n?(.+)?/; const dateFields = dateFormat.exec(fields[1].textContent); const dayOfMonth = dateFields[1]; const dateTime = new EdtfDate({ year: parseInt(dateFields[3], 10), month: parseInt(dateFields[2], 10), day: dayOfMonth !== "00" ? parseInt(dayOfMonth, 10) : undefined }); const dateTimeRefinement = dateFields[4] ? dateFields[4].trim() : undefined; const placeStr = fields[2].innerHTML; const placeRows = placeStr.split("<br>"); const sightingPlace = placeRows[0]; const city = placeRows.length > 1 ? context.messages.country.fi.cityName(placeRows[1]) : undefined; const url = new URL(caseLink.href, this.baseUrl); const id = new URLSearchParams(url.search).get("u"); const classification = fields[3].textContent; return { id, url: url.href, sightingPlace, city, dateTime, dateTimeRefinement, classification }; } }