-
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.
Fix #46 make me umami 2.9.0 compatible
- Loading branch information
Showing
673 changed files
with
126,575 additions
and
2,178 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
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
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
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
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 |
---|---|---|
@@ -1,142 +1,174 @@ | ||
import path from 'path'; | ||
import fs from 'fs'; | ||
import core from '@actions/core'; | ||
import github from '@actions/github'; | ||
|
||
import axios from 'axios' | ||
import UmamiApiClient from 'umami-api' | ||
import UmamiClient from 'umami-api-client' | ||
|
||
import ReportGenerator from './reportGenerator.js'; | ||
import axios from "axios"; | ||
|
||
const DEBUG_ACTION = process.env.UMAMI_DEBUG_ACTION === 'true'; | ||
const UMAMI_OUTPUT_DIRECTORY = process.env.UMAMI_OUTPUT_DIRECTORY || './umami'; | ||
const rethrow = (err) => {throw err;} | ||
const rethrow = (err) => { | ||
throw new Error(err); | ||
} | ||
|
||
class Action { | ||
|
||
static async fetchUmamiServerApi(server, timeoutMs = 50000) { | ||
const username = 'abc'; | ||
const password = 'abc'; | ||
console.log(`fetchUmamiServerApi`); | ||
for (var i = 1 ; i < 10 ; i++) { | ||
var expectedResult = []; | ||
const action = "post " + i; | ||
console.time(action); | ||
const client = axios.create({ baseURL: `${server}/api`, timeout: timeoutMs }); | ||
const loginResult = await client.post("/auth/login", { username, password }).catch(error => { | ||
console.timeEnd(action); | ||
const message = typeof error.response !== "undefined" ? error.response.data : error.message; | ||
const status = typeof error.response !== "undefined" ? `${error.response.status} ${error.response.statusText}`:''; | ||
const logMessage = status !== message ? `[${status}] ${message}` : message; | ||
if (logMessage !== '401 Unauthorized') { | ||
console.log(`Login failed: ${logMessage}`); | ||
} else { | ||
expectedResult.push(error); | ||
/** | ||
* fetch umami api to understand flaky results | ||
* cf. https://github.com/boly38/action-umami-report/issues/37 | ||
* @param server | ||
* @param timeoutMs | ||
* @returns {Promise<unknown>} | ||
*/ | ||
static async fetchUmamiServerApi(server, timeoutMs = 50000) { | ||
return new Promise(async (resolve, reject) => { | ||
const username = 'admin'; | ||
const password = '075827845F'; | ||
console.log(`fetchUmamiServerApi`); | ||
let fetchResults = []; | ||
for (let i = 1; i < 10; i++) { | ||
const action = "post " + i; | ||
console.time(action); | ||
const client = axios.create({baseURL: `${server}/api`, timeout: timeoutMs}); | ||
const loginResult = await client.post("/auth/login", {username, password}).catch(error => { | ||
console.timeEnd(action); | ||
const message = typeof error.response !== "undefined" ? error.response.data : error.message; | ||
const status = typeof error.response !== "undefined" ? `${error.response.status} ${error.response.statusText}` : ''; | ||
const logMessage = status !== message ? `[${status}] ${message}` : message; | ||
if (logMessage !== '401 Unauthorized') { | ||
console.log(`Login failed: ${logMessage}`); | ||
} | ||
fetchResults.push(status); | ||
}); | ||
if (loginResult !== undefined) { | ||
fetchResults.push(`OK ${JSON.stringify(loginResult.status)}`); | ||
} | ||
} | ||
resolve(fetchResults); | ||
}); | ||
if (loginResult !== undefined || expectedResult.length > 0) { | ||
return; | ||
} | ||
} | ||
} | ||
|
||
static async produceActionResult(resultName, resultValue, outputFile = null) { | ||
const outFileAddition = outputFile !== null ? `file:${outputFile}` : ''; | ||
console.info(`produce action result (output): ${resultName} ${outFileAddition}`); | ||
core.setOutput(resultName, resultValue);// core action output: to be declared as outputs by current job and used by another job | ||
// disabled by #12 // core.exportVariable(resultName, resultValue);// core action env: to be used by current job by another step | ||
|
||
var targetFile = null; | ||
if (isSet(UMAMI_OUTPUT_DIRECTORY) && isSet(outputFile)) { | ||
targetFile = `${UMAMI_OUTPUT_DIRECTORY}/${outputFile}`; | ||
try { | ||
ensureDirectoryExistence(targetFile); | ||
fs.writeFileSync(targetFile, resultValue); | ||
} catch (error) { | ||
console.error(`ERROR: unable to write to ${targetFile} : ${error}`); | ||
targetFile = null; | ||
} | ||
} | ||
return { targetFile }; | ||
} | ||
|
||
|
||
static async produceReport(umamiSite, umamiSiteStats, sitePageViews = null, siteEvents = null, siteMetricsUrl = null, | ||
outputFile = null, reportContent = 'pageviews|events|urls', period = '24h', unit = 'hour') { | ||
//~~ generate umami report content | ||
const generator = new ReportGenerator(umamiSite, reportContent, period, unit, umamiSiteStats, sitePageViews, siteEvents, siteMetricsUrl); | ||
const umamiOneLineReport = generator.oneLineReport(); | ||
const umamiReport = generator.detailedReport(); | ||
|
||
//~~ produce github actions results (output) | ||
Action.produceActionResult("pageViews", umamiSiteStats.pageviews.value, null); | ||
Action.produceActionResult("umamiOneLineReport", umamiOneLineReport); | ||
const { targetFile } = await Action.produceActionResult("umamiReport", umamiReport, outputFile); | ||
Action.produceActionResult("umamiReportLength", umamiReport.length, null);// #14 | ||
if ( isSet(targetFile) ) { | ||
Action.produceActionResult("umamiReportFile", targetFile, null); | ||
return targetFile; | ||
} | ||
return null; | ||
} | ||
|
||
/** | ||
* @deprecated : please use umamiReport(...) | ||
*/ | ||
static async umamiDailyReportV0(server, user, password, domain = '', outputFile = null, reportContent = 'pageviews|events|urls') { | ||
var options = { server, user, password, domain, outputFile, reportContent }; | ||
return await Action.umamiReport(options); | ||
} | ||
|
||
static async umamiReport(options) { | ||
// options | ||
var { server, user, password, domain, outputFile, reportContent, period, unit, tz } = options; | ||
// default options | ||
if (!isSet(user)) { | ||
user = 'admin'; | ||
} | ||
if (!isSet(outputFile)) { | ||
outputFile = null; | ||
} | ||
if (!isSet(reportContent)) { | ||
reportContent = 'pageviews|events|urls'; | ||
} | ||
if (!isSet(period)) { | ||
period = '24h'; | ||
} | ||
if (!isSet(unit)) { | ||
unit = 'hour'; | ||
|
||
static async produceActionResult(resultName, resultValue, outputFile = null) { | ||
const outFileAddition = outputFile !== null ? `file:${outputFile}` : ''; | ||
console.info(`produce action result (output): ${resultName} ${outFileAddition}`); | ||
core.setOutput(resultName, resultValue);// core action output: to be declared as outputs by current job and used by another job | ||
// disabled by #12 // core.exportVariable(resultName, resultValue);// core action env: to be used by current job by another step | ||
|
||
let targetFile = null; | ||
if (isSet(UMAMI_OUTPUT_DIRECTORY) && isSet(outputFile)) { | ||
targetFile = `${UMAMI_OUTPUT_DIRECTORY}/${outputFile}`; | ||
try { | ||
ensureDirectoryExistence(targetFile); | ||
fs.writeFileSync(targetFile, resultValue); | ||
} catch (error) { | ||
console.info(`ERROR: unable to write to ${targetFile} : ${error}`); | ||
targetFile = null; | ||
} | ||
} | ||
if (isSet(targetFile)) { | ||
console.info(`produce action result (targetFile): ${targetFile}`); | ||
return {targetFile}; | ||
} | ||
return {}; | ||
} | ||
if (!isSet(tz)) { | ||
tz = 'Europe/Paris'; | ||
|
||
|
||
static async produceReport(umamiSite, umamiSiteStats, sitePageViews = null, siteEvents = null, siteMetricsUrl = null, | ||
outputFile = null, reportContent = 'pageviews|events|urls', period = '24h', unit = 'hour') { | ||
//~~ generate umami report content | ||
const generator = new ReportGenerator(umamiSite, reportContent, period, unit, umamiSiteStats, sitePageViews, siteEvents, siteMetricsUrl); | ||
const umamiOneLineReport = generator.oneLineReport(); | ||
const umamiReport = generator.detailedReport(); | ||
|
||
//~~ produce github actions results (output) | ||
await Action.produceActionResult("pageViews", umamiSiteStats.pageviews.value, null); | ||
await Action.produceActionResult("umamiOneLineReport", umamiOneLineReport); | ||
const {targetFile} = await Action.produceActionResult("umamiReport", umamiReport, outputFile); | ||
await Action.produceActionResult("umamiReportLength", umamiReport.length, null);// #14 | ||
if (isSet(targetFile)) { | ||
await Action.produceActionResult("umamiReportFile", targetFile, null); | ||
return targetFile; | ||
} | ||
return null; | ||
} | ||
|
||
const umami = new UmamiApiClient(server, user, password); | ||
const site = isSet(domain) ? await umami.getWebsiteBy("domain", domain).catch(rethrow) : await umami.getWebsite().catch(rethrow); | ||
const siteStats = await site.getStats({ period }).catch(rethrow); | ||
const sitePageViews = await site.getPageviews({ period, unit, tz }).catch(rethrow); | ||
const siteEvents = await site.getEvents({ period, unit, tz }).catch(rethrow); | ||
const siteMetricsUrl = await site.getMetrics({ period }).catch(rethrow); | ||
|
||
DEBUG_ACTION && console.log(site); | ||
DEBUG_ACTION && console.log(siteStats); | ||
const targetFile = await Action.produceReport(site, siteStats, sitePageViews, siteEvents, siteMetricsUrl, | ||
outputFile, reportContent, period); | ||
if (targetFile != null) { | ||
return { site, siteStats, targetFile } | ||
static async umamiReport(options) { | ||
return new Promise(async (resolve, reject) => { | ||
try { | ||
// options | ||
let {server, user, password, domain, outputFile, reportContent, period, unit, tz} = options; | ||
// default options | ||
if (!isSet(user)) { | ||
user = 'admin'; | ||
} | ||
if (!isSet(outputFile)) { | ||
outputFile = null; | ||
} | ||
if (!isSet(reportContent)) { | ||
reportContent = 'pageviews|events|urls'; | ||
} | ||
if (!isSet(period)) { | ||
period = '24h'; | ||
} | ||
if (!isSet(unit)) { | ||
unit = 'hour'; | ||
} | ||
if (!isSet(tz)) { | ||
tz = 'Europe/Paris'; | ||
} | ||
|
||
DEBUG_ACTION && console.log("options : " + JSON.stringify({ | ||
server, | ||
user, | ||
password, | ||
domain, | ||
outputFile, | ||
reportContent, | ||
period, | ||
unit, | ||
tz | ||
})); | ||
|
||
const umamiClient = new UmamiClient({server}); | ||
const authData = await umamiClient.login(user, password).catch(rethrow); | ||
|
||
const sites = await umamiClient.getSites(authData).catch(err => { | ||
console.error("errBX" + err); | ||
throw new Error(err); | ||
}) | ||
const site = umamiClient.selectSiteByDomain(sites, domain); | ||
DEBUG_ACTION && console.log(site); | ||
const siteStats = await umamiClient.getStats(authData, site, period).catch(rethrow); | ||
const sitePageViews = await umamiClient.getPageViews(authData, site, {unit, tz}, period).catch(rethrow); | ||
const siteEvents = await umamiClient.getEvents(authData, site, {unit, tz}, period).catch(rethrow); | ||
const siteMetricsUrl = await umamiClient.getMetrics(authData, site, {type: 'url'}, period).catch(rethrow); | ||
|
||
DEBUG_ACTION && console.log(siteStats); | ||
const targetFile = await Action.produceReport(site, siteStats, sitePageViews, siteEvents, siteMetricsUrl, | ||
outputFile, reportContent, period); | ||
if (isSet(targetFile)) { | ||
resolve({site, siteStats, targetFile}); | ||
} else { | ||
resolve({site, siteStats}); | ||
} | ||
} catch (err) { | ||
console.error("err" + err); | ||
reject(err); | ||
} | ||
}); | ||
} | ||
return { site, siteStats }; | ||
} | ||
} | ||
|
||
export default Action; | ||
|
||
const isSet = (value) => value !== null && value !== undefined && value !== ''; | ||
const ensureDirectoryExistence = (filePath) => { | ||
var dirname = path.dirname(filePath); | ||
if (fs.existsSync(dirname)) { | ||
return true; | ||
} | ||
ensureDirectoryExistence(dirname); | ||
fs.mkdirSync(dirname); | ||
const dirname = path.dirname(filePath); | ||
if (fs.existsSync(dirname)) { | ||
return true; | ||
} | ||
ensureDirectoryExistence(dirname); | ||
fs.mkdirSync(dirname); | ||
}; |
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
Oops, something went wrong.