Skip to content

Instantly share code, notes, and snippets.

@bradymholt
Created September 5, 2022 23:38
Show Gist options
  • Save bradymholt/8a4de035e63e8dbe842fb3ac50bc26f9 to your computer and use it in GitHub Desktop.
Save bradymholt/8a4de035e63e8dbe842fb3ac50bc26f9 to your computer and use it in GitHub Desktop.
Download usage information from Colorado Springs Utilities (csu.org)
#!/usr/bin/env npx jsh
usage(`
Usage:
${$0} service_type
Examples:
${$0} ELECTRICITY
${$0} WATER
Downloads usage information from Colorado Springs Utilities
`);
const puppeteer = require("puppeteer");
const fs = require("fs");
const path = require("path");
const [csuUserName, csuPassword] = env.assert(["CSU_USERNAME", "CSU_PASSWORD"]);
const [serviceType] = args.assertCount(1);
(async () => {
const browser = await puppeteer.launch({ defaultViewport: null, headless: true, devtools: false });
const page = await browser.newPage();
// Login
await page.goto("https://wss.csu.org/SelfService/CMSSvcLogInSlim.jsp");
await page.focus("#userId");
await page.keyboard.type(csuUserName);
await page.focus("#password");
await page.keyboard.type(csuPassword);
await page.click("a#LoginButton");
await page.waitForNavigation();
// Go to "My Usage"
await page.click(`a[href="myusage"]`);
await page.waitForSelector("div.CSUMyUsageButton");
// Select service type
const optionValue = await page.evaluate((type) => {
const option = Array.from(
document.querySelectorAll("#ContentPlaceHolder1_UI_ExternalUserControl1_dlLocationID option")
).find((i) => i.text.includes(type.toUpperCase())).value;
return option;
}, serviceType);
await page.select("#ContentPlaceHolder1_UI_ExternalUserControl1_dlLocationID", optionValue);
// Download CSV
const downloadPath = fs.mkdtempSync("csu");
const client = await page.target().createCDPSession();
await client.send("Page.setDownloadBehavior", {
behavior: "allow",
downloadPath,
});
await page.click(`input#ContentPlaceHolder1_UI_ExternalUserControl1_btnCsv`);
sleep(3000);
// Close the browser
await browser.close();
// Read downloaded file
const downloadedFilePath = path.resolve(downloadPath, fs.readdirSync(downloadPath)[0]);
const fileContentsRaw = readFile(downloadedFilePath);
rmdir(downloadPath);
// Parse CSV
const fileContentLines = fileContentsRaw.split("\n");
fileContentLines.shift(); // remove first line
const scrubRegEX = new RegExp('"|\r', "g");
const headerRowColumnNames = fileContentLines[0].split(",").map((h) => h.replace(scrubRegEX, "").toLowerCase());
fileContentLines.shift();
const results = [];
fileContentLines.forEach((dataRow) => {
if (!!dataRow[0]) {
const rowValues = dataRow.split(",").map((h) => h.replace(scrubRegEX, "").toLowerCase());
const parsedRow = {};
headerRowColumnNames.forEach((columnName, idx) => {
parsedRow[columnName] = rowValues[idx];
});
results.push(parsedRow);
}
});
echo(results);
})();
{
"name": "csu-usage-download",
"version": "1.0.0",
"description": "Downloads usage information from Colorado Springs Utilities (csu.org)",
"main": "index.js",
"author": "Brady Holt",
"license": "MIT",
"dependencies": {
"jsh": "^0.33.0",
"puppeteer": "^17.1.1"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment