Skip to content

Instantly share code, notes, and snippets.

@taxilian
Last active March 14, 2021 00:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save taxilian/715b57f16f5985688565b549db1bcf68 to your computer and use it in GitHub Desktop.
Save taxilian/715b57f16f5985688565b549db1bcf68 to your computer and use it in GitHub Desktop.
Get ARRL ve lists for each state
// 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