Created
September 5, 2022 23:38
-
-
Save bradymholt/8a4de035e63e8dbe842fb3ac50bc26f9 to your computer and use it in GitHub Desktop.
Download usage information from Colorado Springs Utilities (csu.org)
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
#!/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); | |
})(); |
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
{ | |
"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