Last active
March 14, 2021 00:19
-
-
Save taxilian/715b57f16f5985688565b549db1bcf68 to your computer and use it in GitHub Desktop.
Get ARRL ve lists for each state
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Originally written by Jason Sweeney, refactored by Richard Bateman | |
// 2021 | |
import axios from "axios"; | |
import cheerio from "cheerio"; | |
const stateListUrl = "http://www.arrl.org/ve-session-counts"; | |
const stateUrl = "http://www.arrl.org/ve-session-counts?state="; | |
type PromisedReturnType<T extends (...args: any) => any> = T extends (...args: any) => Promise<infer R> ? R : ReturnType<T>; | |
async function fetchData(url: string) { | |
let response = await axios.get(url); | |
if (response.status !== 200) { | |
console.log("Error occurred while fetching data"); | |
return; | |
} | |
return response.data as string; | |
} | |
async function getListOfStates() { | |
const rootHtml = await fetchData(stateListUrl) | |
const $ = cheerio.load(rootHtml); | |
const stateList = $("#vepcounts > form"); | |
const searchStates = stateList.find("option") | |
.toArray().map(op => $(op).val()).filter(Boolean); | |
return searchStates; | |
} | |
const nameMatch = /([a-zA-Z0-9]{4,6}) \(([^)]+)\)/; | |
async function getVeList(state: string) { | |
const stateHtml = await fetchData(`${stateUrl}${state}`); | |
const $ = cheerio.load(stateHtml); | |
const veTable = $("#vepcounts > table"); | |
const recordList = veTable.find("tr"); | |
const veList = recordList.toArray().map(op => { | |
const record: string[] = []; | |
$(op) | |
.find("td") | |
.each((i, op2) => { | |
if ($(op2).text() != "") record.push($(op2).text()); | |
}); | |
if (record.length !== 2) { | |
// console.warn("Invalid record found: ", record, $(op).find("td").html()); | |
return null; | |
} | |
const [callAndName, count] = record; | |
const found = nameMatch.exec(callAndName); | |
if (!found) { | |
console.warn("Invalid name: ", callAndName); | |
return; | |
} | |
return { | |
callsign: found[1].toUpperCase(), | |
name: found[2], | |
count, state, | |
}; | |
}).filter(Boolean); | |
return veList; | |
} | |
export async function getArrlVEList() { | |
const stateList = await getListOfStates(); | |
console.log(stateList); | |
const stateLists: {[state: string]: PromisedReturnType<typeof getVeList>} = {}; | |
for (const state of stateList) { | |
const veList = await getVeList(state); | |
console.log(`Found ${veList.length} for ${state}`); | |
stateLists[state] = veList; | |
} | |
return stateLists; | |
} | |
if (require.main === module) { | |
getArrlVEList(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment