New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

ackee-report

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ackee-report - npm Package Compare versions

Comparing version 0.2.2 to 0.3.0

src/templates/ackee.ejs

11

CHANGELOG.md

@@ -7,7 +7,14 @@ # Changelog

## [v.2.2] - 2020-10-26
## [v0.3.0] - 2020-10-26
### Added
- include all data available through API in report
### Changed
- use ejs to render email html
- structure of data returned in report
## [v0.2.2] - 2020-10-26
### Fixed
- correctly calculate average duration of all domains
## [v.2.1] - 2020-10-26
## [v0.2.1] - 2020-10-26
### Added

@@ -14,0 +21,0 @@ - use `-d all` to generate a report for all domains

3

package.json
{
"name": "ackee-report",
"version": "0.2.2",
"version": "0.3.0",
"description": "CLI tool to generate performance reports of websites using the self-hosted analytics tool Ackee.",

@@ -26,2 +26,3 @@ "bin": "./src/index.js",

"configstore": "^5.0.1",
"ejs": "^3.1.5",
"nodemailer": "^6.4.14",

@@ -28,0 +29,0 @@ "ora": "^5.1.0",

@@ -98,2 +98,3 @@ <div align="center">

<details><summary>Gmail</summary>
If you use gmail to send emails, use these values:

@@ -109,2 +110,3 @@

<details><summary>SendGrid</summary>
If you use SendGrid to send emails, use these values:

@@ -119,2 +121,3 @@

<details><summary>MailGun</summary>
If you use SendGrid to send emails, use these values:

@@ -129,2 +132,12 @@

## 📝 To do
Here is what's currently planned for [ackee-report](https://github.com/BetaHuhn/ackee-report):
- include more data in report
- better design/structure of email report
- more customization of data included in report
- change config file via cli
- add more services (e.g. Telegram)
## 💻 Development

@@ -131,0 +144,0 @@

@@ -70,3 +70,3 @@ const axios = require('axios')

async domains() {
async getDomains() {
try {

@@ -98,3 +98,3 @@ const query = `

async domain(id) {
async _getDomainData(id) {
try {

@@ -107,18 +107,36 @@ const query = `

facts {
averageViews
averageDuration
viewsMonth
averageViews
averageDuration
viewsMonth
}
statistics {
pages(sorting: TOP, limit:5) {
id
count
created
pages(sorting: TOP, limit:5) {
id
count
}
referrers(sorting: TOP, limit:5) {
id
count
}
languages(sorting: TOP, limit:3) {
id
count
}
browsers(sorting: TOP, type: WITH_VERSION, limit:3) {
id
count
}
devices(sorting: TOP, type: WITH_MODEL, limit:3) {
id
count
}
sizes(sorting: TOP, type: SCREEN_RESOLUTION, limit:3) {
id
count
}
systems(sorting: TOP, type: NO_VERSION, limit:3) {
id
count
}
}
referrers(sorting: TOP, limit:5) {
id
count
created
}
}
}

@@ -149,2 +167,45 @@ }

async get(ids) {
const getData = async () => Promise.all(ids.map((id) => this._getDomainData(id)))
const data = await getData()
const durationAvg = () => {
const durations = data.filter((domain) => domain.facts.averageDuration > 0)
const avg = data.reduce((n, { facts }) => n + facts.averageDuration, 0) / durations.length
return Math.round(avg / 1000)
}
const names = data.map((domain) => domain.title).join(', ')
const namesShort = (data.length > 2 ? data.slice(0, 2) : data).map((domain) => domain.title).join(', ') + ` and ${ data.length - 2 } more`
const total = data.reduce((n, { facts }) => n + facts.viewsMonth, 0)
const domains = data.map((domain) => {
return {
id: domain.id,
title: domain.title,
viewsAvgDay: domain.facts.averageViews,
viewsMonth: domain.facts.viewsMonth,
durationAvg: Math.round(domain.facts.averageDuration / 1000),
pages: domain.statistics.pages,
referrers: domain.statistics.referrers,
languages: domain.statistics.languages,
browsers: domain.statistics.browsers,
devices: domain.statistics.devices,
sizes: domain.statistics.sizes,
systems: domain.statistics.systems
}
})
const result = {
views: total,
durationAvg: durationAvg(),
names,
namesShort,
domains
}
return result
}
}

@@ -151,0 +212,0 @@

@@ -31,3 +31,3 @@ const Ackee = require('./Interface')

domains = await ackee.domains()
domains = await ackee.getDomains()

@@ -45,7 +45,5 @@ if (domain[0] !== 'all') {

const getData = async () => Promise.all(domains.map((id) => ackee.domain(id)))
spinner.text = 'Getting data...'
const data = await ackee.get(domains)
spinner.text = 'Getting domain data...'
const data = await getData()
if (service === 'email') {

@@ -88,3 +86,3 @@ if (!to) return spinner.fail(' error: no recipient specified with --to')

let domains = await ackee.domains()
let domains = await ackee.getDomains()

@@ -91,0 +89,0 @@ if (args.length > 0) {

const nodemailer = require('nodemailer')
const ejs = require('ejs')
const path = require('path')
const loadConfig = require('../Config')

@@ -19,38 +21,8 @@

build(domains, endpoint, to) {
const total = domains.reduce((n, { facts }) => n + facts.viewsMonth, 0)
const durations = domains.filter((domain) => domain.facts.averageDuration > 0)
const average = Math.round((durations.reduce((n, { facts }) => n + facts.averageDuration, 0) / durations.length) / 1000)
const head = `
<h2>Ackee report</h2>
<p>You've had ${ total } visitors in total 🎉! Each visitor stayed on you website for an average of ${ average } seconds. See below for a more detailed report of each domain:</p>
async html(data, endpoint, to) {
const generatedAt = new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '')
`
const html = await ejs.renderFile(path.join(__dirname, '../templates/ackee.ejs'), { domains: data.domains, total: data.views, durationAvg: data.durationAvg, names: data.names, namesShort: data.namesShort, endpoint, to, generatedAt })
const domainData = (domain) => `
<h2>${ domain.title }</h2>
<p>Average views per day: ${ domain.facts.averageViews }</p>
<p>Average duration: ${ domain.facts.averageDuration / 1000 } seconds</p>
<p>Views this month: ${ domain.facts.viewsMonth }</p>
<p>Top pages:</p>
<ul>${ domain.statistics.pages.map((page) => `<li>${ page.id } - ${ page.count } visits</li>`) }</ul>
<p>Top referrers:</p>
<ul>${ domain.statistics.referrers.map((referrer) => `<li>${ referrer.id } - ${ referrer.count } visits</li>`).join('') }</ul>
`
const names = domains.map((domain) => domain.title).join(', ')
const footer = `
<br>
<p>View all current statistics on <a href="${ endpoint }">${ endpoint }</a></p>
<p>This report was generated at ${ new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '') } for ${ names } and sent to ${ to }</p>
`
const html = `
${ head }
${ domains.map(domainData).join('') }
${ footer }
`
return html
}

@@ -78,4 +50,5 @@

const report = async function(domains, to) {
return new Promise((resolve) => {
const report = async function(data, to) {
// eslint-disable-next-line no-async-promise-executor
return new Promise(async (resolve) => {
const config = loadConfig()

@@ -86,5 +59,5 @@

const email = new Email(host, port, username, password)
const html = email.build(domains, config.get('ackee').server, to)
const html = await email.html(data, config.get('ackee').server, to)
const subject = `Ackee report for ${ domains.map((domain) => domain.title).join(', ') }`
const subject = `Ackee report for ${ data.namesShort }`

@@ -91,0 +64,0 @@ email.send(from, to, subject, html).then((info) => {

const fs = require('fs')
const report = async function(domains, output) {
const report = async function(data, output) {
return new Promise((resolve, reject) => {
const data = JSON.stringify(domains, null, 2)
const result = JSON.stringify(data, null, 2)
fs.writeFile(output, data, (err) => {
fs.writeFile(output, result, (err) => {
if (err) reject(err)

@@ -9,0 +9,0 @@ resolve()

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc