/**
* @fileOverview Scraper
* @author Paul Orlob
* @module scraper
*/
const puppeteer = require('puppeteer');
const sunny_helper = require('./helpers');
class Scraper {
/**
* @constructor
* @param {string} username Username for sunnyportal
* @param {string} password Password
* @param {number }refreshLoginTimer time until login is refreshed in seconds
* @param {number} dataRefreshTimer data update interval in seconds
*/
constructor(username, password, refreshLoginTimer = 5 * 60, dataRefreshTimer = 5) {
this.user = username;
this.pass = password;
this.timeRefreshMillis = refreshLoginTimer * 1000;
this.dataRefreshMillis = dataRefreshTimer * 1000;
this.data = null;
this.isRelogging = false;
}
/**
* Setups the scraper. Needs to be called once.
* @param {boolean} headless True for headless operation.
* @param {Array} args args for chromium
* @returns {Promise<void>}
*/
async setup(headless = true, args = []) {
this.browser = await puppeteer.launch({headless: headless, args: args});
this.page = await this.browser.newPage();
}
/**
* get data
* @returns {?SunnyData}
*/
getData(){
return this.data;
}
/**
* Starts retrieving data
*/
async start(){
this.loginInterval = setInterval(async () => {
try {
this.isRelogging = true;
await this.login();
this.isRelogging = false
} catch (e) {
throw new Error(e)
}
}, this.timeRefreshMillis);
this.dataInterval = setInterval(async () => {
try {
if(!this.isRelogging){
this.data = await sunny_helper.getStatusData(this.page);
}
} catch (e) {
throw new Error(e)
}
}, this.dataRefreshMillis);
await this.login();
}
/**
* Stops retrieving data
*/
stop(){
clearInterval(this.loginInterval);
clearInterval(this.dataInterval);
}
/**
* Call to destroy the browser instance.
* @returns {Promise<void>} resolves when destroyed
*/
async destroy(){
await this.browser.close();
}
/**
* Performs login or relog on page.
* @returns {Promise<void>}
*/
async login(){
await this.page.goto("https://www.sunnyportal.com", {waitUntil: "domcontentloaded"});
if (this.page.$("ctl00_ContentPlaceHolder1_Logincontrol1_DivLogin") != null && !this.page.url().includes("UserProfile")) {
/* Not logged in, login field exists. */
await sunny_helper.authenticate(this.page, this.pass, this.user)
}
await sunny_helper.navigateToStatusPage(this.page)
}
}
module.exports = Scraper;