Skip to content

Commit fe38dc3

Browse files
committed
Merge branch 'add-after-before-options'
2 parents fa3367e + 880a2fe commit fe38dc3

8 files changed

Lines changed: 133 additions & 28 deletions

File tree

.editorconfig

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
root = true
22

3-
[*]
3+
[Makefile]
4+
indent_style = tab
5+
6+
[*.js]
47
indent_style = space
58
indent_size = 2
69
end_of_line = lf
710
charset = utf-8
811
trim_trailing_whitespace = true
9-
insert_final_newline = true
12+
insert_final_newline = true

Makefile

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
help: ## Show this help
2+
@awk 'BEGIN {FS = ":.*?## "} \
3+
/^[a-zA-Z0-9_-]+:.*?## / { \
4+
sub("\\\\n", "", $$2); \
5+
printf "%-30s %s\n", $$1, $$2}' $(MAKEFILE_LIST)
6+
7+
stats: ## Run a bunch of stats commands for testing
8+
node cli.js --help && \
9+
node cli.js stats && \
10+
node cli.js stats --bucket 5 && \
11+
node cli.js stats --bucket 5 --min 20 && \
12+
node cli.js stats --bucket 5 --min 20 --max 40 && \
13+
node cli.js stats --bucket 5 --min 20 --max 40 --after "2018-01-01" && \
14+
node cli.js stats --bucket 5 --min 20 --max 40 --before "2018-01-01" && \
15+
node cli.js stats --bucket 5 --min 20 --max 40 --after "2018-11-25" && \
16+
node cli.js stats --bucket 5 --min 20 --max 40 --before "2018-11-25" && \
17+
node cli.js stats --bucket 5 --min 20 --max 40 --after "2019-11-25" && \
18+
node cli.js stats --bucket 5 --min 20 --max 40 --before "2019-11-25" && \
19+
node cli.js stats --bucket 5 --min 20 --max 40 --after "2019-11-25" --before "2019-11-27" && \
20+
node cli.js stats --bucket 5 --min 20 --max 40 --before "2019-11-27" && \
21+
node cli.js stats --bucket 5 --min 20 --max 40 --after "2019-11-25" --before "2019-11-30" && \
22+
node cli.js stats --bucket 5 --min 20 --max 40 --after "2019-11-25" --before "2019-11-29" && \
23+
node cli.js stats --bucket 5 --min 20 --max 40 --after "2019-11-25" --before "2019-11-28" && \
24+
node cli.js stats --bucket 5 --min 20 --max 40 --after "2019-11-25" --before "2019-11-27"

README.md

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ You need a GitHub account to store your solves on a Gist.
3030
3131
This will begin a solving session. All session statistics will be stored locally for this session.
3232

33-
### `solve stats [--bucket n] [--min min] [--max max]`
33+
### `solve stats [--bucket n] [--min min] [--max max] [--before timestamp] [--after timestamp]`
3434

3535
> View your lifetime statistics
3636
@@ -39,10 +39,18 @@ This will show you the mean, median, standard deviation and the distribution of
3939
The distribution is by default at a bucket size of 10 seconds. If you are an
4040
advanced solver and need more resolution, just use the bucket option and use
4141
`solve stats --bucket 2` to show your solves with a bucket size of 2 seconds
42-
each. If you would like to see just a subset of all your solves, you can use the
43-
`min` and `max` options. For eg: `solve stats --min 10 --max 20 --bucket 2` will
44-
print the distribution of your solve times between 10 and 20 seconds at a bucket
45-
sizeof 2 seconds.
42+
each.
43+
44+
If you would like to see just a subset of all your solves, you can use the `min`
45+
and `max` options. For eg: `solve stats --min 10 --max 20 --bucket 2` will print
46+
the distribution of your solve times between 10 and 20 seconds with a bucket
47+
size of 2 seconds.
48+
49+
Starting with v1.2.0, cli-cube-timer stores the time at which a solve was
50+
recorded. You can use the `--before` and `--after` options to filter out solves
51+
within a given period of time. Internally, the string is converted to a
52+
timestamp using [moment.js][1], so you can use any supported ISO 8601 string to
53+
specify the timestamps.
4654

4755
### `solve push`
4856

@@ -92,3 +100,5 @@ on the dashboard, please do feel free to create new ones!
92100
Code licensed under MIT.
93101

94102
Copyright Siddharth Kannan 2015.
103+
104+
[1]: https://momentjs.com/docs/#/parsing/string/

cli.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ var cli = meow({
1616
' - View statistics for all solves above 20 seconds',
1717
' solve stats --max 30',
1818
' - View statistics for all solves below 30 seconds',
19+
' solve stats --min 20 --after "2019-01-01"',
20+
' - View statistics for all solves above 20s, created (with v1.2.0+) after 1st January, 2019',
21+
' solve stats --before "2019-11-01"',
22+
' - View statistics for all solves created (with v1.2.0+) before 1st November, 2019',
1923
' solve login',
2024
' - Run the one time authentication module (GitHub)',
2125
' solve push',
@@ -39,6 +43,8 @@ if (cli.flags.show) {
3943
bucket: cli.flags.bucket,
4044
min: cli.flags.min,
4145
max: cli.flags.max,
46+
before: cli.flags.before,
47+
after: cli.flags.after,
4248
});
4349
break;
4450
case 'login': require('./login-module.js')();

index.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,15 @@ module.exports = function () {
77
var threebythree = new Scrambo();
88
var prettyMs = require('pretty-ms');
99
var this_scramble, last_scramble, this_solve, stats = { };
10+
// Helper functions
11+
var prettifyVerbose = require('./utils.js').prettifyVerbose;
1012

1113
const STATS_LINES = 11;
1214

1315
function prettify (ms) {
1416
return prettyMs(ms, {secDecimalDigits: 2});
1517
}
1618

17-
function prettifyVerbose (ms) {
18-
return prettyMs(ms, {verbose: true, secDecimalDigits: 2});
19-
}
20-
2119
function botSay (phrase) {
2220
console.log(clc.red('Bot: ') + phrase);
2321
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"math-avg": "1.0.0",
4343
"meow": "3.7.0",
4444
"mkdirp": "0.5.1",
45+
"moment": "^2.24.0",
4546
"pretty-ms": "1.4.0",
4647
"read": "1.0.7",
4748
"remove-min-max": "1.0.0",

stats-module.js

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
1-
module.exports = function ({ bucket, min, max }) {
2-
var bucket_size = typeof bucket === 'number' ? bucket : 10;
3-
var min_solve = typeof min === 'number' ? min : 0;
4-
var max_solve = typeof max === 'number' ? max : Number.MAX_SAFE_INTEGER;
5-
1+
module.exports = function ({ bucket, min, max, before, after }) {
62
var async = require('async');
7-
var fileModule = require('./file-module.js');
8-
var pushed_file_name = require('./constants.js').PUSHED_FILE_PATH;
9-
var local_file_name = require('./constants.js').LOCAL_FILE_PATH;
10-
113
var fs = require('fs');
124
var csv = require('fast-csv');
135
var Stats = require('fast-stats').Stats;
146
var clc = require('cli-color');
157
var barHorizontal = require('bar-horizontal');
8+
// Local modules
9+
var fileModule = require('./file-module.js');
10+
// Constants
11+
var pushed_file_name = require('./constants.js').PUSHED_FILE_PATH;
12+
var local_file_name = require('./constants.js').LOCAL_FILE_PATH;
13+
// Helper functions
14+
var parseStrToMomentOrUndefined = require('./utils.js').parseStrToMomentOrUndefined;
15+
var solveValidator = require('./utils.js').solveValidator;
16+
var prettifyVerbose = require('./utils.js').prettifyVerbose;
1617

17-
var prettyMs = require('pretty-ms');
18-
19-
function prettifyVerbose (ms) {
20-
return prettyMs(ms, {verbose: true, secDecimalDigits: 2});
21-
}
18+
var bucket_size = typeof bucket === 'number' ? bucket : 10;
19+
var min_solve = typeof min === 'number' ? min : 0;
20+
var max_solve = typeof max === 'number' ? max : Number.MAX_SAFE_INTEGER;
21+
var before_timestamp = parseStrToMomentOrUndefined(before);
22+
var after_timestamp = parseStrToMomentOrUndefined(after);
23+
var validatorFunc = solveValidator(min_solve, max_solve, before_timestamp, after_timestamp);
2224

2325
var all_times = new Stats({bucket_precision: bucket_size});
2426

2527
var avail_files = [ ];
26-
2728
if (fileModule.pushedFileExists()) {
2829
avail_files.push(pushed_file_name);
2930
}
30-
3131
if (fileModule.localFileExists()) {
3232
avail_files.push(local_file_name);
3333
}
@@ -36,8 +36,16 @@ module.exports = function ({ bucket, min, max }) {
3636
function (file_name, callback) {
3737
var csvStream = csv()
3838
.on('data', function (data) {
39+
// Step 1: Get the solve time, this should always be present
3940
var solve_time = parseFloat(data[0]);
40-
if (!isNaN(solve_time) && solve_time >= min_solve && solve_time <= max_solve) {
41+
42+
// Step 2: Try to parse solve timestamp
43+
// This was introduced in v1.2.0. Files written by versions of cli-cube-timer before v1.2.0
44+
// will not have this column.
45+
var solve_timestamp = data.length >= 3 ? data[2] : undefined;
46+
var solve_unix_ts = parseFloat(solve_timestamp, 10) / 1000;
47+
48+
if (validatorFunc(solve_time, solve_unix_ts)) {
4149
all_times.push(solve_time);
4250
}
4351
})
@@ -71,6 +79,17 @@ module.exports = function ({ bucket, min, max }) {
7179
});
7280

7381
barHorizontal(input_obj, { labels: true });
82+
83+
if (before_timestamp !== undefined || after_timestamp !== undefined) {
84+
console.log('\nTime constraints:');
85+
}
86+
87+
if (after_timestamp !== undefined) {
88+
console.log(`After: ${clc.green(after_timestamp)}`);
89+
}
90+
if (before_timestamp !== undefined) {
91+
console.log(`Before: ${clc.green(before_timestamp)}`);
92+
}
7493
}
7594
});
7695
};

utils.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
var prettyMs = require('pretty-ms');
2+
var moment = require('moment');
3+
4+
exports.parseStrToMomentOrUndefined = function (input) {
5+
return input !== undefined && moment(input).isValid() ? moment(input) : undefined;
6+
}
7+
8+
exports.solveValidator = function (min_solve, max_solve, before_timestamp, after_timestamp) {
9+
return function (solve_time, solve_unix_ts) {
10+
var solveTimeValid = (!isNaN(solve_time) && solve_time >= min_solve && solve_time <= max_solve);
11+
12+
var solveTsExists = !isNaN(solve_unix_ts) && typeof solve_unix_ts === 'number' && solve_unix_ts > 0;
13+
var inputOptionsValid = before_timestamp !== undefined || after_timestamp !== undefined;
14+
15+
// Solve time itself is invalid
16+
if (!solveTimeValid) {
17+
return solveTimeValid;
18+
}
19+
20+
// --after or --before not provided, so timestamp validity needn't be checked
21+
if (!inputOptionsValid) {
22+
return solveTimeValid;
23+
}
24+
25+
// User has provided --after or --before, solves without timestamps will not be included in
26+
// the statistics
27+
if (inputOptionsValid && !solveTsExists) {
28+
return false;
29+
}
30+
31+
var solve_moment = moment.unix(solve_unix_ts);
32+
if (before_timestamp === undefined) {
33+
return solve_moment.isAfter(after_timestamp);
34+
}
35+
if (after_timestamp === undefined) {
36+
return solve_moment.isBefore(before_timestamp);
37+
}
38+
return solve_moment.isBetween(after_timestamp, before_timestamp);
39+
};
40+
}
41+
42+
exports.prettifyVerbose = function (ms) {
43+
return prettyMs(ms, {verbose: true, secDecimalDigits: 2});
44+
}

0 commit comments

Comments
 (0)