You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@couchdb.apache.org by ja...@apache.org on 2015/02/18 11:17:01 UTC
[1/4] admin commit: updated refs/heads/master to db84dab
Repository: couchdb-admin
Updated Branches:
refs/heads/master 59aab1212 -> db84dab07
Automate mailinglist message count collection
It seems that there is a lot of manual work needed to generate
the board reports. This is an attempt to start automating the
recurring tasks.
Happy reporting! :)
Project: http://git-wip-us.apache.org/repos/asf/couchdb-admin/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-admin/commit/e5a2458e
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-admin/tree/e5a2458e
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-admin/diff/e5a2458e
Branch: refs/heads/master
Commit: e5a2458e9619d46d495a4a4ff02f29a08691a50e
Parents: 59aab12
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Sat Nov 15 21:12:15 2014 +0100
Committer: Robert Kowalski <ro...@kowalski.gd>
Committed: Sat Nov 15 21:12:15 2014 +0100
----------------------------------------------------------------------
.gitignore | 1 +
board-report/README.md | 10 ++++
board-report/generate-report | 112 ++++++++++++++++++++++++++++++++++++++
board-report/lib/index.js | 60 ++++++++++++++++++++
board-report/package.json | 17 ++++++
5 files changed, 200 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/e5a2458e/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3c3629e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+node_modules
http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/e5a2458e/board-report/README.md
----------------------------------------------------------------------
diff --git a/board-report/README.md b/board-report/README.md
new file mode 100644
index 0000000..821294a
--- /dev/null
+++ b/board-report/README.md
@@ -0,0 +1,10 @@
+# generate-report
+
+## Usage
+
+```shell
+generate-report <daterange> | --help
+```
+
+If you are reporting for February 2014, for instance,
+set the date range to: `201311-201402`.
http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/e5a2458e/board-report/generate-report
----------------------------------------------------------------------
diff --git a/board-report/generate-report b/board-report/generate-report
new file mode 100755
index 0000000..230a859
--- /dev/null
+++ b/board-report/generate-report
@@ -0,0 +1,112 @@
+#!/usr/bin/env node
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const crawler = require('./lib/index.js');
+
+const arg = process.argv[2];
+
+if (arg === '-h' || arg === '--help') {
+ return printUsage();
+}
+
+if (!validArg(arg)) {
+ console.log('Error: format is YYYYMM-YYYYMM - see ' +
+ "'generate-report --help'");
+ return;
+}
+
+const template = '{{count}} {{messages}} since {{month}} ' +
+ '(DIFF change)';
+
+crawler(arg, function (err, data) {
+ if (err) {
+ logLine('Error:');
+ console.log(err);
+ return;
+ }
+
+ logLine('Your message counts:');
+ data.forEach(function (el) {
+ const month = getStartMonthAsWord(arg),
+ messageCount = +el[1].replace(',', ''),
+ message = messageCount > 1 ? 'messages' : 'message',
+ wikitext = template
+ .replace('{{count}}', el[1])
+ .replace('{{month}}', month)
+ .replace('{{messages}}', message);
+
+ console.log(el[0] + ':');
+ logLine(wikitext);
+ });
+ console.log('Happy reporting! :)');
+});
+
+function logLine (line) {
+ console.log(line + '\n');
+}
+
+function getStartMonthAsWord (date) {
+ const i = parseInt(date.substr(4, 2), 10);
+ return getMonthAsWord(i);
+}
+
+function getMonthAsWord (i) {
+ return [
+ 'January',
+ 'February',
+ 'March',
+ 'April',
+ 'May',
+ 'June',
+ 'July',
+ 'August',
+ 'September',
+ 'October',
+ 'November',
+ 'December'
+ ][i - 1];
+}
+
+function validArg (arg) {
+ if (!arg) {
+ return false;
+ }
+
+ const dates = arg.split('-');
+
+ if (dates.length !== 2) {
+ return false;
+ }
+
+ if (dates[0].length !== 6 || dates[1].length !== 6) {
+ return false;
+ }
+
+ if (Number.isNaN(+dates[0]) || Number.isNaN(+dates[1])) {
+ return false;
+ }
+
+ return true;
+}
+
+function printUsage () {
+ logLine('usage: generate-report <daterange> | --help');
+ console.log('If you are reporting for February 2014, for instance,');
+ logLine('set the date range to: 201311-201402');
+ console.log('guide:');
+ console.log('https://cwiki.apache.org/confluence/display' +
+ '/COUCHDB/Guide');
+ console.log('template:');
+ console.log('https://cwiki.apache.org/confluence/display' +
+ '/COUCHDB/Template');
+}
http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/e5a2458e/board-report/lib/index.js
----------------------------------------------------------------------
diff --git a/board-report/lib/index.js b/board-report/lib/index.js
new file mode 100644
index 0000000..db2a324
--- /dev/null
+++ b/board-report/lib/index.js
@@ -0,0 +1,60 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const async = require('async'),
+ request = require('request'),
+ cheerio = require('cheerio');
+
+const urlTemplate = 'http://markmail.org/search/?q=list%3A' +
+ 'org.apache.{{listname}}%20date%3A{{date}}';
+
+const lists = [
+ 'couchdb-announce',
+ 'couchdb-user',
+ 'couchdb-erlang',
+ 'couchdb-dev',
+ 'couchdb-commits',
+ 'couchdb-l10n',
+ 'couchdb-replication',
+ 'couchdb-marketing'
+];
+
+function getMessageCounts (date, cb) {
+ const listUrls = lists.map(function (list) {
+ return urlTemplate
+ .replace('{{date}}', date)
+ .replace('{{listname}}', list);
+ });
+
+ async.map(listUrls, request, function (err, results) {
+ if (err) {
+ return cb(err);
+ }
+
+ const bodies = results.reduce(function (acc, cur) {
+ acc.push(cur.request.req.res.body);
+ return acc;
+ }, []);
+
+ const res = bodies.map(function (markup) {
+ const $ = cheerio.load(markup),
+ count = $('#lists .count').text(),
+ list = $('#lists a').text().replace('org.apache.couchdb.', '');
+
+ return [list, count];
+ });
+
+ return cb(null, res);
+ });
+}
+
+module.exports = getMessageCounts;
http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/e5a2458e/board-report/package.json
----------------------------------------------------------------------
diff --git a/board-report/package.json b/board-report/package.json
new file mode 100644
index 0000000..6fb1742
--- /dev/null
+++ b/board-report/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "board-report",
+ "version": "1.0.0",
+ "private": true,
+ "description": "I'm helping to prepare board reports",
+ "main": "lib/index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "Robert Kowalski <ro...@kowalski.gd>",
+ "license": "Apache License, Version 2.0",
+ "dependencies": {
+ "async": "0.9.0",
+ "cheerio": "0.18.0",
+ "request": "2.48.0"
+ }
+}
[3/4] admin commit: updated refs/heads/master to db84dab
Posted by ja...@apache.org.
bin mode
Project: http://git-wip-us.apache.org/repos/asf/couchdb-admin/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-admin/commit/b456c034
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-admin/tree/b456c034
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-admin/diff/b456c034
Branch: refs/heads/master
Commit: b456c0343c6a032edc0d3b6a94dbd9047512cbeb
Parents: 0ec747a
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Mon Feb 16 18:16:23 2015 +0100
Committer: Robert Kowalski <ro...@kowalski.gd>
Committed: Mon Feb 16 18:18:20 2015 +0100
----------------------------------------------------------------------
board-report/README.md | 1 +
board-report/package.json | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/b456c034/board-report/README.md
----------------------------------------------------------------------
diff --git a/board-report/README.md b/board-report/README.md
index 821294a..9709935 100644
--- a/board-report/README.md
+++ b/board-report/README.md
@@ -3,6 +3,7 @@
## Usage
```shell
+npm i -g
generate-report <daterange> | --help
```
http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/b456c034/board-report/package.json
----------------------------------------------------------------------
diff --git a/board-report/package.json b/board-report/package.json
index 2a1abbd..41c680d 100644
--- a/board-report/package.json
+++ b/board-report/package.json
@@ -1,9 +1,10 @@
{
- "name": "board-report",
+ "name": "generate-report",
"version": "1.0.0",
"private": true,
"description": "I'm helping to prepare board reports",
"main": "lib/index.js",
+ "bin": "./generate-report",
"scripts": {
"test": "mocha -R spec"
},
[4/4] admin commit: updated refs/heads/master to db84dab
Posted by ja...@apache.org.
fix bugs
Project: http://git-wip-us.apache.org/repos/asf/couchdb-admin/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-admin/commit/db84dab0
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-admin/tree/db84dab0
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-admin/diff/db84dab0
Branch: refs/heads/master
Commit: db84dab079108366dcdbe70cbe12e1c1cc97abb7
Parents: b456c03
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Mon Feb 16 19:12:45 2015 +0100
Committer: Robert Kowalski <ro...@kowalski.gd>
Committed: Mon Feb 16 19:14:21 2015 +0100
----------------------------------------------------------------------
board-report/generate-report | 4 ++--
board-report/lib/argument.js | 5 +++--
board-report/lib/index.js | 27 +++++++++++++++------------
board-report/test/argument.js | 8 ++++----
4 files changed, 24 insertions(+), 20 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/db84dab0/board-report/generate-report
----------------------------------------------------------------------
diff --git a/board-report/generate-report b/board-report/generate-report
index 2ec0335..79c9fa8 100755
--- a/board-report/generate-report
+++ b/board-report/generate-report
@@ -15,7 +15,7 @@ const crawler = require('./lib/index.js'),
argument = require('./lib/argument.js');
const arg = process.argv[2];
-const template = '{{count}} {{messages}} since {{month}} ' +
+const template = '{{count}} {{messages}} since end of {{month}} ' +
'({{diff}} change)';
if (arg === '-h' || arg === '--help') {
@@ -41,7 +41,7 @@ crawler(queryParams, monthsForDiff, function (err, data) {
logLine('Your message counts:');
Object.keys(data).forEach(function (el) {
- const month = argument.getMonthAsWordFromNow(arg, monthsForDiff),
+ const month = argument.getMonthAsWordFromNow(arg, monthsForDiff + 1),
messageCount = data[el].curr,
message = messageCount > 1 ? 'messages' : 'message',
wikitext = template
http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/db84dab0/board-report/lib/argument.js
----------------------------------------------------------------------
diff --git a/board-report/lib/argument.js b/board-report/lib/argument.js
index 5fda129..a75e460 100644
--- a/board-report/lib/argument.js
+++ b/board-report/lib/argument.js
@@ -14,6 +14,7 @@ const moment = require('moment');
exports.prepareQueryParams = prepareQueryParams;
function prepareQueryParams (arg) {
+ console.log(arg)
const startEnd = getStartEndDates(arg, 3);
startAsString = startEnd[0].format('YYYYMM'),
diffStartEnd = getStartEndDates(startAsString, 3);
@@ -50,6 +51,7 @@ function getMonthAsWordFromNow (reportEnd, time) {
return moment(inter, 'YYYYMM').format('MMMM');
}
+exports.getMonthAsWord = getMonthAsWord;
function getMonthAsWord (reportEnd) {
return moment(reportEnd, 'YYYYMM').format('MMMM');
}
@@ -60,8 +62,7 @@ function formatQuery (startEnd) {
}
function getStartEndDates (arg, time) {
- const end = moment(arg, 'YYYYMM'),
+ const end = moment(arg, 'YYYYMM').subtract(1, 'month'),
start = moment(arg, 'YYYYMM').subtract(time, 'months');
-
return [start, end];
}
http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/db84dab0/board-report/lib/index.js
----------------------------------------------------------------------
diff --git a/board-report/lib/index.js b/board-report/lib/index.js
index 63ec26c..d1e783c 100644
--- a/board-report/lib/index.js
+++ b/board-report/lib/index.js
@@ -16,8 +16,9 @@ const async = require('async'),
assert = require('assert'),
argument = require('./argument.js');
-const urlTemplate = 'http://markmail.org/search/?q=list%3A' +
- 'org.apache.{{listname}}%20date%3A{{date}}';
+const urlPrefix = 'http://markmail.org/search/?q=list%3Aorg.apache.';
+const urlTemplate = urlPrefix + '{{listname}}%20date%3A{{date}}';
+
const lists = [
'couchdb-announce',
@@ -40,9 +41,6 @@ function api (queryParams, timeframe, cb) {
const listUrlsCurr = getUrls(queryParams.queryCurr),
listUrlsDiff = getUrls(queryParams.queryDiff);
- console.log(listUrlsCurr);
- console.log(listUrlsDiff);
-
async.parallel({
current: function (cb) {
getMessageCounts(listUrlsCurr, cb);
@@ -86,7 +84,7 @@ function pick (element, structure) {
}
function getDiffString (count, countOld) {
- const result = normalize(countOld) - normalize(count);
+ const result = normalize(count) - normalize(countOld);
if (result >= 0) {
return '+' + result;
@@ -95,6 +93,9 @@ function getDiffString (count, countOld) {
}
function normalize (string) {
+ if (!string) {
+ string = '0';
+ }
return parseInt(string.replace(',', ''), 10);
}
@@ -113,21 +114,23 @@ function requestWithOptions (url, cb) {
maxSockets: Infinity
}
}, function (err, res, body) {
- cb(err, body);
+ cb(err, [url, body]);
})
}
+function normalizeListName (list) {
+ return list.replace(urlPrefix, '').split('%20date')[0];
+}
+
function getMessageCounts (urlList, cb) {
async.map(urlList, requestWithOptions, function (err, results) {
if (err) {
return cb(err);
}
-
- const res = results.map(function (markup) {
- const $ = cheerio.load(markup),
+ const res = results.map(function (element) {
+ const $ = cheerio.load(element[1]),
count = $('#lists .count').text(),
- list = $('#lists a').text().replace('org.apache.couchdb.', '');
-
+ list = normalizeListName(element[0]);
return [list, count];
});
http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/db84dab0/board-report/test/argument.js
----------------------------------------------------------------------
diff --git a/board-report/test/argument.js b/board-report/test/argument.js
index 0074425..b3dad7e 100644
--- a/board-report/test/argument.js
+++ b/board-report/test/argument.js
@@ -29,14 +29,14 @@ describe('arguments', function () {
it('prepares query parameters', function () {
const queryParams = argument.prepareQueryParams('201411');
- assert.equal(queryParams.queryCurr, '201408-201411');
- assert.equal(queryParams.queryDiff, '201405-201408');
+ assert.equal(queryParams.queryCurr, '201408-201410');
+ assert.equal(queryParams.queryDiff, '201405-201407');
});
it('prepares urls for the current and the diff', function () {
const queryParams = argument.prepareQueryParams('201411');
- assert.equal(queryParams.queryCurr, '201408-201411');
- assert.equal(queryParams.queryDiff, '201405-201408');
+ assert.equal(queryParams.queryCurr, '201408-201410');
+ assert.equal(queryParams.queryDiff, '201405-201407');
});
});
[2/4] admin commit: updated refs/heads/master to db84dab
Posted by ja...@apache.org.
wip
Project: http://git-wip-us.apache.org/repos/asf/couchdb-admin/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-admin/commit/0ec747a1
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-admin/tree/0ec747a1
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-admin/diff/0ec747a1
Branch: refs/heads/master
Commit: 0ec747a14ef0b4b23992379819b20ebd92bb6c3e
Parents: e5a2458
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Fri Nov 21 02:45:32 2014 +0100
Committer: Robert Kowalski <ro...@kowalski.gd>
Committed: Fri Nov 21 02:48:50 2014 +0100
----------------------------------------------------------------------
.gitignore | 1 +
board-report/generate-report | 81 ++++++++----------------------
board-report/lib/argument.js | 67 +++++++++++++++++++++++++
board-report/lib/index.js | 100 +++++++++++++++++++++++++++++++++----
board-report/package.json | 6 ++-
board-report/test/argument.js | 42 ++++++++++++++++
6 files changed, 225 insertions(+), 72 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/0ec747a1/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 3c3629e..93f1361 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
node_modules
+npm-debug.log
http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/0ec747a1/board-report/generate-report
----------------------------------------------------------------------
diff --git a/board-report/generate-report b/board-report/generate-report
index 230a859..2ec0335 100755
--- a/board-report/generate-report
+++ b/board-report/generate-report
@@ -11,41 +11,46 @@
// License for the specific language governing permissions and limitations under
// the License.
-const crawler = require('./lib/index.js');
+const crawler = require('./lib/index.js'),
+ argument = require('./lib/argument.js');
const arg = process.argv[2];
+const template = '{{count}} {{messages}} since {{month}} ' +
+ '({{diff}} change)';
if (arg === '-h' || arg === '--help') {
return printUsage();
}
-if (!validArg(arg)) {
- console.log('Error: format is YYYYMM-YYYYMM - see ' +
+if (!argument.validArg(arg)) {
+ console.error('Error: format is YYYYMM - see ' +
"'generate-report --help'");
+ process.exit(1);
return;
}
-const template = '{{count}} {{messages}} since {{month}} ' +
- '(DIFF change)';
-
-crawler(arg, function (err, data) {
+var monthsForDiff = 3
+const queryParams = argument.prepareQueryParams(arg);
+crawler(queryParams, monthsForDiff, function (err, data) {
if (err) {
logLine('Error:');
- console.log(err);
+ console.error(err);
+ process.exit(1);
return;
}
logLine('Your message counts:');
- data.forEach(function (el) {
- const month = getStartMonthAsWord(arg),
- messageCount = +el[1].replace(',', ''),
+ Object.keys(data).forEach(function (el) {
+ const month = argument.getMonthAsWordFromNow(arg, monthsForDiff),
+ messageCount = data[el].curr,
message = messageCount > 1 ? 'messages' : 'message',
wikitext = template
- .replace('{{count}}', el[1])
+ .replace('{{count}}', messageCount)
.replace('{{month}}', month)
- .replace('{{messages}}', message);
+ .replace('{{messages}}', message)
+ .replace('{{diff}}', data[el].diff);
- console.log(el[0] + ':');
+ console.log(el + ':');
logLine(wikitext);
});
console.log('Happy reporting! :)');
@@ -55,54 +60,10 @@ function logLine (line) {
console.log(line + '\n');
}
-function getStartMonthAsWord (date) {
- const i = parseInt(date.substr(4, 2), 10);
- return getMonthAsWord(i);
-}
-
-function getMonthAsWord (i) {
- return [
- 'January',
- 'February',
- 'March',
- 'April',
- 'May',
- 'June',
- 'July',
- 'August',
- 'September',
- 'October',
- 'November',
- 'December'
- ][i - 1];
-}
-
-function validArg (arg) {
- if (!arg) {
- return false;
- }
-
- const dates = arg.split('-');
-
- if (dates.length !== 2) {
- return false;
- }
-
- if (dates[0].length !== 6 || dates[1].length !== 6) {
- return false;
- }
-
- if (Number.isNaN(+dates[0]) || Number.isNaN(+dates[1])) {
- return false;
- }
-
- return true;
-}
-
function printUsage () {
- logLine('usage: generate-report <daterange> | --help');
+ logLine('usage: generate-report <date> | --help');
console.log('If you are reporting for February 2014, for instance,');
- logLine('set the date range to: 201311-201402');
+ logLine('set the date to: 201402');
console.log('guide:');
console.log('https://cwiki.apache.org/confluence/display' +
'/COUCHDB/Guide');
http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/0ec747a1/board-report/lib/argument.js
----------------------------------------------------------------------
diff --git a/board-report/lib/argument.js b/board-report/lib/argument.js
new file mode 100644
index 0000000..5fda129
--- /dev/null
+++ b/board-report/lib/argument.js
@@ -0,0 +1,67 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const moment = require('moment');
+
+exports.prepareQueryParams = prepareQueryParams;
+function prepareQueryParams (arg) {
+ const startEnd = getStartEndDates(arg, 3);
+ startAsString = startEnd[0].format('YYYYMM'),
+ diffStartEnd = getStartEndDates(startAsString, 3);
+
+ return {
+ queryCurr: formatQuery(startEnd),
+ queryDiff: formatQuery(diffStartEnd)
+ };
+}
+
+exports.validArg = validArg;
+function validArg (arg) {
+ if (!arg) {
+ return false;
+ }
+
+ if (arg.length !== 6) {
+ return false;
+ }
+
+ if (Number.isNaN(+arg)) {
+ return false;
+ }
+
+ return moment(arg, 'YYYYMM').isValid();
+}
+
+exports.getMonthAsWordFromNow = getMonthAsWordFromNow;
+function getMonthAsWordFromNow (reportEnd, time) {
+ const inter = moment(reportEnd, 'YYYYMM')
+ .subtract(time, 'months')
+ .format('YYYYMM');
+
+ return moment(inter, 'YYYYMM').format('MMMM');
+}
+
+function getMonthAsWord (reportEnd) {
+ return moment(reportEnd, 'YYYYMM').format('MMMM');
+}
+
+function formatQuery (startEnd) {
+ return startEnd[0].format('YYYYMM') + '-' +
+ startEnd[1].format('YYYYMM');
+}
+
+function getStartEndDates (arg, time) {
+ const end = moment(arg, 'YYYYMM'),
+ start = moment(arg, 'YYYYMM').subtract(time, 'months');
+
+ return [start, end];
+}
http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/0ec747a1/board-report/lib/index.js
----------------------------------------------------------------------
diff --git a/board-report/lib/index.js b/board-report/lib/index.js
index db2a324..63ec26c 100644
--- a/board-report/lib/index.js
+++ b/board-report/lib/index.js
@@ -12,7 +12,9 @@
const async = require('async'),
request = require('request'),
- cheerio = require('cheerio');
+ cheerio = require('cheerio'),
+ assert = require('assert'),
+ argument = require('./argument.js');
const urlTemplate = 'http://markmail.org/search/?q=list%3A' +
'org.apache.{{listname}}%20date%3A{{date}}';
@@ -28,24 +30,100 @@ const lists = [
'couchdb-marketing'
];
-function getMessageCounts (date, cb) {
- const listUrls = lists.map(function (list) {
+function api (queryParams, timeframe, cb) {
+ assert.ok(queryParams.queryCurr, 'queryParams must be defined');
+ assert.ok(queryParams.queryDiff, 'queryParams must be defined');
+ assert.equal(typeof timeframe, 'number',
+ 'timeframe must be a number');
+ assert.equal(typeof cb, 'function', 'callback must a a function');
+
+ const listUrlsCurr = getUrls(queryParams.queryCurr),
+ listUrlsDiff = getUrls(queryParams.queryDiff);
+
+ console.log(listUrlsCurr);
+ console.log(listUrlsDiff);
+
+ async.parallel({
+ current: function (cb) {
+ getMessageCounts(listUrlsCurr, cb);
+ },
+ diff: function (cb) {
+ getMessageCounts(listUrlsDiff, cb);
+ }
+ },
+ function (err, res) {
+ const data = joinDiffWithCurrent(res);
+ cb(null, data);
+ });
+}
+
+function joinDiffWithCurrent (structure) {
+ const curr = structure.current,
+ diff = structure.diff;
+
+ return curr.reduce(function (acc, el) {
+ const name = el[0],
+ count = el[1],
+ countOld = pick(name, diff);
+
+ acc[name] = {
+ curr: normalize(count),
+ old: normalize(countOld),
+ diff: getDiffString(count, countOld)
+ };
+
+ return acc;
+ }, {});
+}
+
+function pick (element, structure) {
+ return structure.reduce(function (acc, row) {
+ if (row[0] === element) {
+ acc = acc + row[1];
+ }
+ return acc;
+ }, 0);
+}
+
+function getDiffString (count, countOld) {
+ const result = normalize(countOld) - normalize(count);
+
+ if (result >= 0) {
+ return '+' + result;
+ }
+ return '' + result;
+}
+
+function normalize (string) {
+ return parseInt(string.replace(',', ''), 10);
+}
+
+function getUrls (date) {
+ return lists.map(function (list) {
return urlTemplate
.replace('{{date}}', date)
.replace('{{listname}}', list);
});
+}
+
+function requestWithOptions (url, cb) {
+ request({
+ uri: url,
+ pool: {
+ maxSockets: Infinity
+ }
+ }, function (err, res, body) {
+ cb(err, body);
+ })
+}
- async.map(listUrls, request, function (err, results) {
+function getMessageCounts (urlList, cb) {
+ async.map(urlList, requestWithOptions, function (err, results) {
if (err) {
return cb(err);
}
- const bodies = results.reduce(function (acc, cur) {
- acc.push(cur.request.req.res.body);
- return acc;
- }, []);
-
- const res = bodies.map(function (markup) {
+ const res = results.map(function (markup) {
const $ = cheerio.load(markup),
count = $('#lists .count').text(),
list = $('#lists a').text().replace('org.apache.couchdb.', '');
@@ -57,4 +135,4 @@ function getMessageCounts (date, cb) {
});
}
-module.exports = getMessageCounts;
+module.exports = api;
http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/0ec747a1/board-report/package.json
----------------------------------------------------------------------
diff --git a/board-report/package.json b/board-report/package.json
index 6fb1742..2a1abbd 100644
--- a/board-report/package.json
+++ b/board-report/package.json
@@ -5,13 +5,17 @@
"description": "I'm helping to prepare board reports",
"main": "lib/index.js",
"scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
+ "test": "mocha -R spec"
},
"author": "Robert Kowalski <ro...@kowalski.gd>",
"license": "Apache License, Version 2.0",
"dependencies": {
"async": "0.9.0",
"cheerio": "0.18.0",
+ "moment": "2.8.3",
"request": "2.48.0"
+ },
+ "devDependencies": {
+ "mocha": "~2.0.1"
}
}
http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/0ec747a1/board-report/test/argument.js
----------------------------------------------------------------------
diff --git a/board-report/test/argument.js b/board-report/test/argument.js
new file mode 100644
index 0000000..0074425
--- /dev/null
+++ b/board-report/test/argument.js
@@ -0,0 +1,42 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const assert = require('assert'),
+ argument = require('../lib/argument.js');
+
+describe('arguments', function () {
+
+ it('validates arguments', function () {
+ assert.ok(argument.validArg('201401'));
+ assert.equal(argument.validArg('2ente'), false);
+ assert.equal(argument.validArg('2014123'), false);
+ });
+
+ it('has a method for getting names of months', function () {
+ assert.equal(argument.getMonthAsWord('201401'), 'January');
+ assert.equal(argument.getMonthAsWord('201412'), 'December');
+ });
+
+ it('prepares query parameters', function () {
+ const queryParams = argument.prepareQueryParams('201411');
+
+ assert.equal(queryParams.queryCurr, '201408-201411');
+ assert.equal(queryParams.queryDiff, '201405-201408');
+ });
+
+ it('prepares urls for the current and the diff', function () {
+ const queryParams = argument.prepareQueryParams('201411');
+
+ assert.equal(queryParams.queryCurr, '201408-201411');
+ assert.equal(queryParams.queryDiff, '201405-201408');
+ });
+});