From 7fb77a718dab832a64316b855a386fbe442e01e9 Mon Sep 17 00:00:00 2001 From: Andris Reinman Date: Sat, 12 Nov 2016 15:33:09 +0200 Subject: [PATCH] initial --- .eslintrc.js | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++ .gitignore | 6 +++++ README.md | 29 ++++++++++++++++++++++ index.js | 44 +++++++++++++++++++++++++++++++++ package.json | 11 +++++++++ 5 files changed, 160 insertions(+) create mode 100644 .eslintrc.js create mode 100644 .gitignore create mode 100644 README.md create mode 100644 index.js create mode 100644 package.json diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..04f79c0 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,70 @@ +'use strict'; + +module.exports = { + rules: { + indent: [2, 4, { + SwitchCase: 1 + }], + quotes: [2, 'single'], + 'linebreak-style': [2, 'unix'], + semi: [2, 'always'], + strict: [2, 'global'], + eqeqeq: 2, + 'dot-notation': 2, + curly: 2, + 'no-fallthrough': 2, + 'quote-props': [2, 'as-needed'], + 'no-unused-expressions': [2, { + allowShortCircuit: true + }], + 'no-unused-vars': 2, + 'no-undefined': 2, + 'handle-callback-err': 2, + 'no-new': 2, + 'new-cap': 2, + 'no-eval': 2, + 'no-invalid-this': 2, + radix: [2, 'always'], + 'no-use-before-define': [2, 'nofunc'], + 'callback-return': [2, ['callback', 'cb', 'done']], + 'comma-dangle': [2, 'never'], + 'comma-style': [2, 'last'], + 'no-regex-spaces': 2, + 'no-empty': 2, + 'no-duplicate-case': 2, + 'no-empty-character-class': 2, + 'no-redeclare': [2, { + builtinGlobals: true + }], + 'block-scoped-var': 2, + 'no-sequences': 2, + 'no-throw-literal': 2, + 'no-useless-call': 2, + 'no-useless-concat': 2, + 'no-void': 2, + yoda: 2, + 'no-undef': 2, + 'global-require': 2, + 'no-var': 2, + 'no-bitwise': 2, + 'no-lonely-if': 2, + 'no-mixed-spaces-and-tabs': 2, + 'arrow-body-style': [2, 'as-needed'], + 'arrow-parens': [2, 'as-needed'], + 'prefer-arrow-callback': 2, + 'object-shorthand': 2, + 'prefer-spread': 2 + }, + env: { + es6: true, + node: true + }, + extends: 'eslint:recommended', + globals: { + it: true, + describe: true, + beforeEach: true, + afterEach: true + }, + fix: true +}; diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6f330af --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +node_modules +.DS_Store +npm-debug.log +config/production.* +config/development.* +*v8.log diff --git a/README.md b/README.md new file mode 100644 index 0000000..81d099e --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# zonemta-delivery-counters + +Delivery counters plugin for [ZoneMTA](https://github.com/zone-eu/zone-mta). Install this to see delivery counts and sending speed in [ZoneMTA WebAdmin](https://github.com/zone-eu/zmta-webadmin). + +## Setup + +Add this as a dependency for your ZoneMTA app + +``` +npm install zonemta-delivery-counters --save +``` + +Add a configuration entry in the "plugins" section of your ZoneMTA app + +```json +... + "plugins": { + "modules/zonemta-delivery-counters": { + "enabled": "main", + "redis": "redis://localhost:6379/2", + "prefix": "zmta" + } + } +... +``` + +## License + +European Union Public License 1.1 ([details](http://ec.europa.eu/idabc/eupl.html)) diff --git a/index.js b/index.js new file mode 100644 index 0000000..7c5262c --- /dev/null +++ b/index.js @@ -0,0 +1,44 @@ +'use strict'; + +const redis = require('redis'); + +module.exports.title = 'Stats Counter'; +module.exports.init = function (app, done) { + + const client = redis.createClient(app.config.redis); + const prefix = app.config.prefix ? app.config.prefix + '_' : ''; + + client.on('error', err => app.logger.error('Redis', err.message)); + + app.addHook('queue:release', (zone, data, next) => { + if (!data || !data.status) { + return next(); + } + + let date = new Date(); + let year = date.getUTCFullYear() + ''; + let month = date.getUTCMonth() + 1; + let day = date.getUTCDate(); + + month = (month < 10 ? '0' : '') + month; + day = (day < 10 ? '0' : '') + day; + + let key = data.status.delivered ? prefix + 'delivered' : prefix + 'bounced'; + let domainKey = prefix + 'domains'; + + client.multi(). + incr(key). + incr(key + '^' + year + '/' + month + '/' + day). + incr(key + '_' + zone.name). + incr(key + '_' + zone.name + '^' + year + '/' + month + '/' + day). + zincrby(domainKey, 1, data.domain). + zincrby(domainKey + '^' + year + '/' + month + '/' + day, 1, data.domain). + // Do not wait until counters are updated before returning. This prevents from issues + // with Redis connection. Redis is not needed for ZoneMTA to function + exec(() => false); + + setImmediate(next); + }); + + done(); +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..b61b6ee --- /dev/null +++ b/package.json @@ -0,0 +1,11 @@ +{ + "name": "zonemta-delivery-counters", + "version": "1.0.0", + "description": "Delivery counters plugin for ZoneMTA", + "main": "index.js", + "author": "Andris Reinman", + "license": "EUPL-1.1", + "dependencies": { + "redis": "^2.6.3" + } +}