forked from cnumr/GreenIT-Analysis-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1eac31b
commit d001ba5
Showing
42 changed files
with
4,240 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
.git | ||
.gitignore | ||
dist/ | ||
script/ | ||
node_modules/ | ||
results/ | ||
results.xlsx |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
.scannerwork | ||
.vscode | ||
node_modules/ | ||
dist/ | ||
results/ | ||
results_test/ | ||
*.xlsx | ||
*.yaml |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
FROM node | ||
RUN apt-get update \ | ||
&& apt-get install -y wget gnupg \ | ||
&& wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \ | ||
&& sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \ | ||
&& apt-get update \ | ||
&& apt-get install -y google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 \ | ||
--no-install-recommends \ | ||
&& rm -rf /var/lib/apt/lists/* | ||
WORKDIR /app | ||
COPY . . | ||
RUN npm i \ | ||
&& npm link \ | ||
&& groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \ | ||
&& mkdir -p /home/pptruser/Downloads \ | ||
&& chown -R pptruser:pptruser /home/pptruser \ | ||
&& chown -R pptruser:pptruser /app/ | ||
USER pptruser | ||
|
||
CMD ["greenit","analyse", "url.yaml", "results/results.xlsx"] |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
const concat = require('concat-files'); | ||
const glob = require('glob'); | ||
const fs = require('fs') | ||
|
||
const DIR = './dist'; | ||
|
||
if (!fs.existsSync(DIR)){ | ||
fs.mkdirSync(DIR); | ||
} | ||
|
||
const rules = glob.sync('./greenit-core/rules/*.js') | ||
|
||
//One script to analyse them all | ||
concat([ | ||
'./greenit-core/analyseFrameCore.js', | ||
'./greenit-core/utils.js', | ||
'./greenit-core/rulesManager.js', | ||
'./greenit-core/ecoIndex.js', | ||
...rules, | ||
'./greenit-core/greenpanel.js' | ||
], './dist/bundle.js', function(err) { | ||
if (err) throw err | ||
console.log('build complete'); | ||
}); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
const PuppeteerHar = require('puppeteer-har'); | ||
const fs = require('fs') | ||
const path = require('path'); | ||
const ProgressBar = require('progress'); | ||
const sizes = require('../sizes.js'); | ||
|
||
|
||
//Path to the url file | ||
const SUBRESULTS_DIRECTORY = path.join(__dirname,'../results'); | ||
|
||
|
||
//Analyse a webpage | ||
async function analyseURL(browser, url, options) { | ||
let result = {}; | ||
|
||
const TIMEOUT = options.timeout | ||
const TAB_ID = options.tabId | ||
const TRY_NB = options.tryNb || 1 | ||
const DEVICE = options.device || "desktop" | ||
|
||
try { | ||
const page = await browser.newPage(); | ||
await page.setViewport(sizes[DEVICE]); | ||
//get har file | ||
const pptrHar = new PuppeteerHar(page); | ||
await pptrHar.start(); | ||
//go to ulr | ||
await page.goto(url, {timeout : TIMEOUT}); | ||
let harObj = await pptrHar.stop(); | ||
//get ressources | ||
const client = await page.target().createCDPSession(); | ||
let ressourceTree = await client.send('Page.getResourceTree'); | ||
await client.detach() | ||
|
||
//get rid of chrome.i18n.getMessage not declared | ||
await page.evaluate(x=>(chrome = { "i18n" : {"getMessage" : function () {return undefined}}})); | ||
//add script, get run, then remove it to not interfere with the analysis | ||
let script = await page.addScriptTag({ path: path.join(__dirname,'../dist/bundle.js')}); | ||
await script.evaluate(x=>(x.remove())); | ||
//pass node object to browser | ||
await page.evaluate(x=>(har = x), harObj.log); | ||
await page.evaluate(x=>(resources = x), ressourceTree.frameTree.resources); | ||
|
||
//launch analyse | ||
result = await page.evaluate(()=>(launchAnalyse())); | ||
page.close(); | ||
result.success = true; | ||
} catch (error) { | ||
result.url = url; | ||
result.success = false; | ||
} | ||
result.tryNb = TRY_NB; | ||
result.tabId = TAB_ID; | ||
return result; | ||
} | ||
|
||
//handle login | ||
async function login(browser,loginInformations) { | ||
//use the tab that opens with the browser | ||
const page = (await browser.pages())[0]; | ||
//go to login page | ||
await page.goto(loginInformations.url) | ||
//ensure page is loaded | ||
await page.waitForSelector(loginInformations.loginButtonSelector); | ||
//complete fields | ||
for (let index = 0; index < loginInformations.fields.length; index++) { | ||
let field = loginInformations.fields[index] | ||
await page.type(field.selector, field.value) | ||
} | ||
//click login button | ||
await page.click(loginInformations.loginButtonSelector); | ||
//make sure to not wait for the full authentification procedure | ||
await page.waitForNavigation(); | ||
} | ||
|
||
//Core | ||
async function createJsonReports(browser, urlTable, options) { | ||
//Timeout for an analysis | ||
const TIMEOUT = options.timeout; | ||
//Concurent tab | ||
const MAX_TAB = options.max_tab; | ||
//Nb of retry before dropping analysis | ||
const RETRY = options.retry; | ||
//Device to emulate | ||
const DEVICE = options.device; | ||
|
||
//initialise progress bar | ||
let progressBar; | ||
if (!options.ci){ | ||
progressBar = new ProgressBar(' Analysing [:bar] :percent Remaining: :etas Time: :elapseds', { | ||
complete: '=', | ||
incomplete: ' ', | ||
width: 40, | ||
total: urlTable.length+2 | ||
}); | ||
progressBar.tick(); | ||
} else { | ||
console.log("Analysing ..."); | ||
} | ||
|
||
let asyncFunctions = []; | ||
let results; | ||
let resultId = 1; | ||
let index = 0 | ||
let reports = []; | ||
let writeList = []; | ||
|
||
let convert = []; | ||
|
||
for (let i = 0; i < MAX_TAB; i++) { | ||
convert[i] = i; | ||
} | ||
|
||
//create directory for subresults | ||
if (fs.existsSync(SUBRESULTS_DIRECTORY)){ | ||
fs.rmdirSync(SUBRESULTS_DIRECTORY, { recursive: true }); | ||
} | ||
fs.mkdirSync(SUBRESULTS_DIRECTORY); | ||
//Asynchronous analysis with MAX_TAB open simultaneously to json | ||
for (let i = 0; i < MAX_TAB && index < urlTable.length; i++) { | ||
asyncFunctions.push(analyseURL(browser,urlTable[index],{ | ||
device: DEVICE, | ||
timeout:TIMEOUT, | ||
tabId: i | ||
})); | ||
index++; | ||
//console.log(`Start of analysis #${index}/${urlTable.length}`) | ||
} | ||
|
||
while (asyncFunctions.length != 0) { | ||
results = await Promise.race(asyncFunctions); | ||
if (!results.success && results.tryNb <= RETRY) { | ||
asyncFunctions.splice(convert[results.tabId],1,analyseURL(browser,results.url,{ | ||
device: DEVICE, | ||
timeout:TIMEOUT, | ||
tabId: results.tabId, | ||
tryNb: results.tryNb + 1 | ||
})); // convert is NEEDED, varialbe size array | ||
}else{ | ||
let filePath = path.resolve(SUBRESULTS_DIRECTORY,`${resultId}.json`) | ||
writeList.push(fs.promises.writeFile(filePath, JSON.stringify(results))); | ||
reports.push({name:`${resultId}`, path: filePath}); | ||
//console.log(`End of an analysis (${resultId}/${urlTable.length}). Results will be saved in ${filePath}`); | ||
if (progressBar){ | ||
progressBar.tick() | ||
} else { | ||
console.log(`${resultId}/${urlTable.length}`); | ||
} | ||
resultId++; | ||
if (index == (urlTable.length)){ | ||
asyncFunctions.splice(convert[results.tabId],1); // convert is NEEDED, varialbe size array | ||
for (let i = results.tabId+1; i < convert.length; i++) { | ||
convert[i] = convert[i]-1; | ||
} | ||
} else { | ||
asyncFunctions.splice(results.tabId,1,analyseURL(browser,urlTable[index],{ | ||
device: DEVICE, | ||
timeout:TIMEOUT, | ||
tabId: results.tabId | ||
})); // No need for convert, fixed size array | ||
index++; | ||
//console.log(`Start of analysis #${index}/${urlTable.length}`) | ||
} | ||
} | ||
} | ||
|
||
//wait for all file to be written | ||
await Promise.all(writeList); | ||
//results to xlsx file | ||
if (progressBar){ | ||
progressBar.tick() | ||
} else { | ||
console.log("Analyse done"); | ||
} | ||
return reports | ||
} | ||
|
||
module.exports = { | ||
createJsonReports, | ||
login | ||
} |
Oops, something went wrong.