paradeiser 0.2.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/Guardfile +1 -0
- data/README.md +98 -6
- data/TODO.md +22 -6
- data/VISION.md +171 -26
- data/bin/par +20 -4
- data/lib/paradeiser/controllers/breaks_controller.rb +0 -1
- data/lib/paradeiser/controllers/controller.rb +15 -1
- data/lib/paradeiser/controllers/paradeiser_controller.rb +23 -1
- data/lib/paradeiser/controllers/pomodori_controller.rb +23 -1
- data/lib/paradeiser/errors.rb +6 -0
- data/lib/paradeiser/executor.rb +1 -1
- data/lib/paradeiser/initializers/inflections.rb +3 -0
- data/lib/paradeiser/models/break.rb +1 -0
- data/lib/paradeiser/models/pomodoro.rb +13 -1
- data/lib/paradeiser/models/repository.rb +11 -1
- data/lib/paradeiser/models/scheduled.rb +7 -1
- data/lib/paradeiser/refinements/pluralize.rb +10 -0
- data/lib/paradeiser/router.rb +0 -2
- data/lib/paradeiser/version.rb +1 -1
- data/lib/paradeiser/view.rb +1 -1
- data/lib/paradeiser/views/breaks/finish.erb +1 -0
- data/lib/paradeiser/views/breaks/start.erb +1 -0
- data/lib/paradeiser/views/paradeiser/init.erb +1 -1
- data/lib/paradeiser/views/paradeiser/report.erb +10 -4
- data/lib/paradeiser/views/paradeiser/status.erb +2 -1
- data/lib/paradeiser/views/pomodori/annotate.erb +1 -0
- data/lib/paradeiser/views/pomodori/cancel.erb +1 -0
- data/lib/paradeiser/views/pomodori/interrupt.erb +1 -0
- data/lib/paradeiser/views/pomodori/log.erb +1 -0
- data/lib/paradeiser/views/pomodori/start.erb +1 -1
- data/paradeiser.gemspec +2 -0
- data/test/bin/notify-send +1 -0
- data/test/helper.rb +7 -24
- data/test/integration/test_annotate.rb +19 -0
- data/test/integration/test_finish.rb +9 -0
- data/test/integration/test_interrupt.rb +9 -0
- data/test/integration/test_log.rb +12 -0
- data/test/integration/test_no_args.rb +7 -0
- data/test/integration/test_start.rb +7 -0
- data/test/integration/test_status.rb +10 -0
- data/test/integration/test_unknown.rb +7 -0
- data/test/lib/at_mock.rb +1 -1
- data/test/lib/controller_test.rb +25 -0
- data/test/lib/integration_test.rb +45 -0
- data/test/lib/paradeiser_controller_test.rb +7 -0
- data/test/lib/view_test.rb +12 -0
- data/test/unit/test_break.rb +7 -44
- data/test/unit/test_break_view.rb +22 -0
- data/test/unit/test_breaks_controller.rb +66 -0
- data/test/unit/test_paradeiser_controller_export.rb +107 -0
- data/test/unit/test_paradeiser_controller_report.rb +73 -26
- data/test/unit/test_paradeiser_controller_status.rb +42 -24
- data/test/unit/test_paradeiser_view_init.rb +7 -0
- data/test/unit/test_paradeiser_view_report.rb +132 -0
- data/test/unit/test_paradeiser_view_status.rb +17 -0
- data/test/unit/test_pomodori_controller.rb +241 -33
- data/test/unit/test_pomodori_view.rb +26 -13
- data/test/unit/test_pomodoro.rb +23 -81
- data/test/unit/test_pomodoro_hooks.rb +12 -25
- data/test/unit/test_repository.rb +5 -21
- data/test/unit/test_scheduler.rb +1 -1
- metadata +61 -8
- data/test/integration/test_par.rb +0 -17
- data/test/unit/test_break_controller.rb +0 -56
- data/test/unit/test_paradeiser_view.rb +0 -66
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd9b4f1eb7fe225041e03d1824dcfce44b17e680
|
4
|
+
data.tar.gz: 010a924c64c9ffc32d18a68324afd6a8a79b46fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0ab299f7782dd479bc50981b203a02a8e69725a3b89559ac6683dcdbcadd8197c6bacccf34b9084193d08d46cbb6b704a2013bea2234a23717d350a3378406b
|
7
|
+
data.tar.gz: 46eb79b934a8210f6ceff2f25855905f06dbcae751a445039e33d49e5ee44b4f57663bff1c9ca29c1001bc6c5dd19ee5b78201e0c71e575207920c9ea4027cfa
|
data/.travis.yml
CHANGED
data/Guardfile
CHANGED
data/README.md
CHANGED
@@ -32,20 +32,42 @@ This is scoped to a single user account (not just the `$PAR_DIR` directory, but
|
|
32
32
|
|
33
33
|
$ par pomodoro start
|
34
34
|
|
35
|
+
# Abbreviated version:
|
36
|
+
$ par start
|
37
|
+
|
35
38
|
If a break is still active, it will be stopped before the new pomodoro is started. Because of Rule #1, calling start while a pomodoro is active will print an error message.
|
36
39
|
|
37
40
|
### Finish the pomodoro
|
38
41
|
|
39
42
|
$ par pomodoro finish
|
40
43
|
|
44
|
+
# With annotation:
|
45
|
+
$ par pomodoro finish This one went very well.
|
46
|
+
|
47
|
+
# Abbreviated version:
|
48
|
+
$ par finish
|
49
|
+
|
50
|
+
# Abbreviated version with annotation:
|
51
|
+
$ par finish This one went very well.
|
52
|
+
|
41
53
|
If a pomodoro is active, it will be marked as successful after stopping it, regardless of whether the 25 minutes are over or not. Remaining arguments, if present, will be added to the pomodoro as annotation.
|
42
54
|
|
43
55
|
If there is no active pomodoro, an error message will be printed.
|
44
56
|
|
45
57
|
### Record an interruption of the current pomodoro
|
46
58
|
|
59
|
+
$ par pomodoro interrupt
|
60
|
+
$ par pomodoro interrupt --external
|
61
|
+
|
62
|
+
# Abbreviated version:
|
47
63
|
$ par interrupt
|
48
|
-
|
64
|
+
|
65
|
+
# With annotation:
|
66
|
+
$ par pomodoro interrupt Could not help checking my mail
|
67
|
+
$ par pomodoro interrupt --external VP of engineering walked into my office
|
68
|
+
|
69
|
+
# Abbreviated version with annotation:
|
70
|
+
$ par interrupt Could not help checking my mail
|
49
71
|
|
50
72
|
Remaining arguments, if present, will be added to the interrupt as annotation. If no pomodoro is active, the command will throw an error.
|
51
73
|
|
@@ -55,15 +77,48 @@ Remaining arguments, if present, will be added to the interrupt as annotation. I
|
|
55
77
|
|
56
78
|
If there is an active pomodoro, an error message will be printed. The `start` command is optional and may be omitted (it's only there for symmetry with `par break finish`, see the section about `at`).
|
57
79
|
|
58
|
-
|
80
|
+
There is a command to stop a break (see also the section about `at`):
|
81
|
+
|
82
|
+
$ par break finish
|
83
|
+
|
84
|
+
From a user's perspective it isn't really necessary to call `par break finish`, because either a new pomodoro is started, which will implicitely stop the active break, or the break ends naturally because it is over.
|
59
85
|
|
60
|
-
|
86
|
+
We do not track break time.
|
87
|
+
|
88
|
+
### Annotate a pomodoro
|
89
|
+
|
90
|
+
$ par pomodoro annotate This was intense, but I am happy about the work I finished.
|
91
|
+
|
92
|
+
# Abbreviated version:
|
93
|
+
$ par annotate This was intense, but I am happy about the work I finished.
|
94
|
+
|
95
|
+
The annotation will be added to the active or, if none is active, to the most recently finished or cancelled pomodoro. If no text is given, the annotation text is read from STDIN.
|
96
|
+
|
97
|
+
Breaks cannot have annotations.
|
61
98
|
|
62
99
|
### Cancel the pomodoro
|
63
100
|
|
101
|
+
$ par pomodoro cancel
|
64
102
|
$ par pomodoro cancel Just couldn't concentrate anymore.
|
65
103
|
|
66
|
-
|
104
|
+
# Abbreviated version:
|
105
|
+
$ par cancel
|
106
|
+
|
107
|
+
# Abbreviated version with annotation:
|
108
|
+
$ par cancel Just couldn't concentrate anymore.
|
109
|
+
|
110
|
+
The pomodoro will be marked as canceled and the timer will be cleared. If no pomodoro is active, the command will throw an error. If a break is active, the command will do nothing except printing a warning. Remaining arguments, if present, will be added to the pomodoro as annotation.
|
111
|
+
|
112
|
+
### Log a pomodoro or break
|
113
|
+
|
114
|
+
Add a successfully finished pomodoro that was never recorded as being started (maybe the user forgot to call `par pomodoro start`):
|
115
|
+
|
116
|
+
$ par pomodoro log
|
117
|
+
|
118
|
+
# Abbreviated version:
|
119
|
+
$ par log
|
120
|
+
|
121
|
+
It will appear in the reports and will count towards efficiency calculations. The current time will be used for the finish timestamp, and the start time will be calculated backwards from the finish time based on the default length of a pomodoro / break.
|
67
122
|
|
68
123
|
### Initialize Paradeiser
|
69
124
|
|
@@ -106,7 +161,7 @@ Paradeiser uses a dedicated at queue named 'p' to organize its jobs and to preve
|
|
106
161
|
|
107
162
|
## Status
|
108
163
|
|
109
|
-
Paradeiser can print the current status to STDOUT with the `par status` command. The current state is provided as process exit status (which is
|
164
|
+
Paradeiser can print the current status to STDOUT with the `par status` command. The current state is also provided as process exit status (which is useful when the output is suppressed).
|
110
165
|
|
111
166
|
* Given an active pomodoro:
|
112
167
|
|
@@ -146,7 +201,30 @@ Paradeiser can print the current status to STDOUT with the `par status` command.
|
|
146
201
|
|
147
202
|
## Reports
|
148
203
|
|
204
|
+
Without arguments, a report is shown for all pomodori and breaks.
|
205
|
+
|
149
206
|
$ par report
|
207
|
+
# Pomodoro Report
|
208
|
+
- 6 pomodori finished
|
209
|
+
- 1 pomodoro canceled
|
210
|
+
- 2 internal interrupts
|
211
|
+
- 2 external interrupts
|
212
|
+
- 4 breaks (14 minutes in total)
|
213
|
+
|
214
|
+
## Annotations
|
215
|
+
* You may pass an annotation to finish.
|
216
|
+
* Interrupts take annotations, too.
|
217
|
+
* Internal interrupts take annotations, too.
|
218
|
+
* And the last annotation is added via cancel.
|
219
|
+
|
220
|
+
Note that the annotations section is not shown if there are no annotations.
|
221
|
+
|
222
|
+
### Report Formatting
|
223
|
+
By default The output of reports is formatted as [markdown](http://TODO), so that it can easily be read at the command line, but also piped into a markdown processor, e.g. for HTML generation with [redcloth](http://TODO):
|
224
|
+
|
225
|
+
$ par report | redcloth | bcat
|
226
|
+
|
227
|
+
Here, the HTML produced by redcloth is piped into `bcat`, which opens a browser with the produced HTML.
|
150
228
|
|
151
229
|
## Output Policy
|
152
230
|
Paradeiser follows the [Rule of Silence](http://www.faqs.org/docs/artu/ch01s06.html#id2878450). If all goes well, a command will not print any output to `STDOUT` unless `--verbose` is given. `status`, `report` and `timesheet` are exempted from this rule, as their primary purpose is to print to STDOUT.
|
@@ -169,8 +247,10 @@ Instead of handling tasks itself, Paradeiser integrates with external tools via
|
|
169
247
|
* `after-start-break` is called after the processing of the break start action ended.
|
170
248
|
* `before-finish-break` is called after the timer of the current break fired (the break is over), but before the processing of the break finish action begins.
|
171
249
|
* `after-finish-break` is called after the processing of the break finish action ended.
|
250
|
+
|
172
251
|
* `before-interrupt-pomodoro` is called when the `interrupt` command was received, but before the action processing begins.
|
173
252
|
* `after-interrupt-pomodoro` is called after the processing of the `interrupt` action ended.
|
253
|
+
|
174
254
|
* `before-cancel-pomodoro` is called when the `cancel` command was received, but before the processing of the cancel action begins.
|
175
255
|
* `after-cancel-pomodoro` is called after the processing of the `cancel` action ended.
|
176
256
|
|
@@ -192,6 +272,13 @@ Variable | Used in | Description
|
|
192
272
|
`$PAR_BREAK_ID` | Hooks | Identifier of the break
|
193
273
|
`$PAR_BREAK_STARTED_AT` | Hooks | Timestamp of when the break was started
|
194
274
|
|
275
|
+
## Export
|
276
|
+
|
277
|
+
Paradeiser can export the pomodori and breaks it has stored to JSON:
|
278
|
+
|
279
|
+
$ par export
|
280
|
+
[{"type":"Pomodoro","length":1500,"status":"finished","interrupts":[],"annotati ...
|
281
|
+
|
195
282
|
## Similar Projects
|
196
283
|
|
197
284
|
These and many more exist, why another tool?
|
@@ -204,9 +291,14 @@ They have a lot of what I wanted, but pomo focuses very much on the tasks themse
|
|
204
291
|
## Implementation Notes
|
205
292
|
|
206
293
|
### State Machine
|
207
|
-
Paradeiser uses a [state machine](https://github.com/pluginaweek/state_machine) to model
|
294
|
+
Paradeiser uses a [state machine](https://github.com/pluginaweek/state_machine) to model the state of pomodori and breaks. Internal event handlers do the actual work. Calling the external hooks is one of these tasks.
|
295
|
+
|
296
|
+
Pomodoro:
|
208
297
|
|
209
298
|
![State Transition Diagram for Pomodoro](https://rawgithub.com/nerab/paradeiser/master/doc/Paradeiser::Pomodoro_status.svg)
|
299
|
+
|
300
|
+
Break:
|
301
|
+
|
210
302
|
![State Transition Diagram for Break](https://rawgithub.com/nerab/paradeiser/master/doc/Paradeiser::Break_status.svg)
|
211
303
|
|
212
304
|
The graph was created using the rake task that comes with `state_machine`:
|
data/TODO.md
CHANGED
@@ -1,16 +1,32 @@
|
|
1
1
|
# Paradeiser Backlog
|
2
2
|
|
3
|
-
*
|
3
|
+
* By default, hooks copied by `par init` should not be executable, otherwise the hooks will fail if the optional dependencies (e.g. `notify-send` on Linux) are not present
|
4
4
|
|
5
|
-
*
|
5
|
+
* Add validations to models. `finished_at` must occur at after created at, etc.
|
6
|
+
|
7
|
+
* There must be no overlap in pomodori, even if we log one.
|
8
|
+
- Logging one while another one is active must fail unless finished at is before the active one's started at.
|
9
|
+
|
10
|
+
* `par log` needs options for when the logged pomodoro was started and / or stopped
|
11
|
+
|
12
|
+
* Improve tests with more doubles
|
13
|
+
- Sandy Metz rules about testing messages:
|
14
|
+
- Incoming: Assert state
|
15
|
+
- Outgoing
|
16
|
+
* Queries: Ignore
|
17
|
+
* Commands: Expect behavior
|
18
|
+
|
19
|
+
* Implement scoped reports
|
20
|
+
|
21
|
+
* `par timesheet`
|
22
|
+
- Implement basic timesheet (global; not grouped by anything)
|
23
|
+
- Show all annotations next to each pomodoro, interrupt and break
|
6
24
|
|
7
25
|
* Improve status messages with relative times and dates (`distance_of_time_in_words_to_now`)
|
8
26
|
=> action_view/helpers/date_helper
|
9
27
|
|
10
28
|
* Simplify the status view. Separate views by class (break vs. pomodoro).
|
11
29
|
|
12
|
-
* Refactor the hooks tests: extract the common code
|
13
|
-
|
14
30
|
* Whenever par runs, it should garbage-collect pomodori or breaks (finish them and adjust their finish time) that weren't finished after they were over (e.g. because at isn't there or the hooks did not fire)
|
15
31
|
|
16
32
|
* Extend commander to allow abbreviated commands with Ruby's `Abbrev` module
|
@@ -42,7 +58,7 @@
|
|
42
58
|
- test with `if $stdin.tty?`
|
43
59
|
- If that approach works well, suggest it for TaskWarrior too (for bulk actions, e.g. in scripts)
|
44
60
|
|
45
|
-
* Implement documentation
|
61
|
+
* Implement documentation approach
|
46
62
|
- `par help` is what the user will use to get information.
|
47
63
|
- Not sure how to allow the user to look at features that are not related to a command. Either extend `par help` to accept arbitrary keywords, or look into 'gem man`.
|
48
64
|
|
@@ -55,7 +71,7 @@
|
|
55
71
|
- As part of finishing a feature, the feature file is moved from the backlog file to in individual doc file, and the README is updated to mention that feature.
|
56
72
|
|
57
73
|
* Promote Paradeiser
|
58
|
-
- Publish an [ASCII cast](http://ascii.io/)
|
74
|
+
- Publish an [ASCII cast](http://ascii.io/) or with [Showterm](http://showterm.io/)
|
59
75
|
- Tell the TaskWarrior community about Paradeiser
|
60
76
|
- Tell the Pomodoro community about Paradeiser
|
61
77
|
- Tell the Ruby community about Paradeiser (e.g. @neverbendeasy does kanban)
|
data/VISION.md
CHANGED
@@ -32,21 +32,42 @@ This is scoped to a single user account (not just the `$PAR_DIR` directory, but
|
|
32
32
|
|
33
33
|
$ par pomodoro start
|
34
34
|
|
35
|
+
# Abbreviated version:
|
36
|
+
$ par start
|
37
|
+
|
35
38
|
If a break is still active, it will be stopped before the new pomodoro is started. Because of Rule #1, calling start while a pomodoro is active will print an error message.
|
36
39
|
|
37
40
|
### Finish the pomodoro
|
38
41
|
|
39
42
|
$ par pomodoro finish
|
43
|
+
|
44
|
+
# With annotation:
|
40
45
|
$ par pomodoro finish This one went very well.
|
41
46
|
|
47
|
+
# Abbreviated version:
|
48
|
+
$ par finish
|
49
|
+
|
50
|
+
# Abbreviated version with annotation:
|
51
|
+
$ par finish This one went very well.
|
52
|
+
|
42
53
|
If a pomodoro is active, it will be marked as successful after stopping it, regardless of whether the 25 minutes are over or not. Remaining arguments, if present, will be added to the pomodoro as annotation.
|
43
54
|
|
44
55
|
If there is no active pomodoro, an error message will be printed.
|
45
56
|
|
46
57
|
### Record an interruption of the current pomodoro
|
47
58
|
|
59
|
+
$ par pomodoro interrupt
|
60
|
+
$ par pomodoro interrupt --external
|
61
|
+
|
62
|
+
# Abbreviated version:
|
48
63
|
$ par interrupt
|
49
|
-
|
64
|
+
|
65
|
+
# With annotation:
|
66
|
+
$ par pomodoro interrupt Could not help checking my mail
|
67
|
+
$ par pomodoro interrupt --external VP of engineering walked into my office
|
68
|
+
|
69
|
+
# Abbreviated version with annotation:
|
70
|
+
$ par interrupt Could not help checking my mail
|
50
71
|
|
51
72
|
Remaining arguments, if present, will be added to the interrupt as annotation. If no pomodoro is active, the command will throw an error.
|
52
73
|
|
@@ -58,29 +79,63 @@ If there is an active pomodoro, an error message will be printed. The `start` co
|
|
58
79
|
|
59
80
|
By default the break will be five minutes long. After four pomodori within a day, the break will be 30 minutes long. This can be overridden with `--short` or `--long`, with an optional argument value that determines the lenght of the break in minutes (e.g. `par break --short=10`).
|
60
81
|
|
61
|
-
|
82
|
+
There is a command to stop a break (see also the section about `at`):
|
83
|
+
|
84
|
+
$ par break finish
|
85
|
+
|
86
|
+
From a user's perspective it isn't really necessary to call `par break finish`, because either a new pomodoro is started, which will implicitely stop the active break, or the break ends naturally because it is over.
|
87
|
+
|
88
|
+
We do not track break time.
|
62
89
|
|
63
90
|
### Annotate a pomodoro
|
64
91
|
|
65
92
|
$ par pomodoro annotate This was intense, but I am happy about the work I finished.
|
66
93
|
|
94
|
+
# Abbreviated version:
|
95
|
+
$ par annotate This was intense, but I am happy about the work I finished.
|
96
|
+
|
67
97
|
The annotation will be added to the active or, if none is active, to the most recently finished or cancelled pomodoro. If no text is given, the annotation text is read from STDIN.
|
68
98
|
|
69
99
|
Breaks cannot have annotations.
|
70
100
|
|
71
101
|
### Cancel the pomodoro
|
72
102
|
|
103
|
+
$ par pomodoro cancel
|
73
104
|
$ par pomodoro cancel Just couldn't concentrate anymore.
|
74
105
|
|
75
|
-
|
106
|
+
# Abbreviated version:
|
107
|
+
$ par cancel
|
108
|
+
|
109
|
+
# Abbreviated version with annotation:
|
110
|
+
$ par cancel Just couldn't concentrate anymore.
|
76
111
|
|
77
|
-
|
112
|
+
The pomodoro will be marked as canceled and the timer will be cleared. If no pomodoro is active, the command will throw an error. If a break is active, the command will do nothing except printing a warning. Remaining arguments, if present, will be added to the pomodoro as annotation.
|
113
|
+
|
114
|
+
### Log a pomodoro or break
|
115
|
+
|
116
|
+
Add a successfully finished pomodoro that was never recorded as being started (maybe the user forgot to call `par pomodoro start`):
|
78
117
|
|
79
118
|
$ par pomodoro log
|
80
119
|
|
81
|
-
|
120
|
+
# Abbreviated version:
|
121
|
+
$ par log
|
122
|
+
|
123
|
+
# Logging a break is also possible:
|
124
|
+
$ par break log
|
82
125
|
|
83
|
-
The current time will be used for the finish timestamp, and the start time will be calculated from the finish time
|
126
|
+
It will appear in the reports and will count towards efficiency calculations. The current time will be used for the finish timestamp, and the start time will be calculated backwards from the finish time based on the default length of a pomodoro / break.
|
127
|
+
|
128
|
+
### Delete a pomodoro or break
|
129
|
+
|
130
|
+
$ par delete
|
131
|
+
|
132
|
+
Without arguments, the active pomodoro or break will be canceled and then deleted. If none is active, the most recently finished or cancelled pomodoro or break is deleted. Note that there is no long form of this command as it pertains to pomodori _and_ breaks.
|
133
|
+
|
134
|
+
A specific pomodoro or break to be deleted can be specified as argument:
|
135
|
+
|
136
|
+
$ par delete 42
|
137
|
+
|
138
|
+
This will delete the pomodoro or break identified as #42.
|
84
139
|
|
85
140
|
### Initialize Paradeiser
|
86
141
|
|
@@ -183,7 +238,7 @@ Paradeiser uses a dedicated at queue named 'p' to organize its jobs and to preve
|
|
183
238
|
|
184
239
|
## Status
|
185
240
|
|
186
|
-
Paradeiser can print the current status to STDOUT with the `par status` command. The current state is provided as process exit status (which is
|
241
|
+
Paradeiser can print the current status to STDOUT with the `par status` command. The current state is also provided as process exit status (which is useful when the output is suppressed).
|
187
242
|
|
188
243
|
* Given an active pomodoro:
|
189
244
|
|
@@ -246,37 +301,96 @@ Paradeiser can print the current status to STDOUT with the `par status` command.
|
|
246
301
|
|
247
302
|
## Reports
|
248
303
|
|
304
|
+
Without arguments, a report is shown for the most recent pomodoro or break.
|
305
|
+
|
306
|
+
* Given the most recent item was a pomodoro, finished today:
|
307
|
+
|
249
308
|
$ par report
|
250
|
-
|
309
|
+
# Report for pomodoro #12
|
310
|
+
|
311
|
+
Started 17:07, finished 17:32
|
312
|
+
|
313
|
+
## Interrupts
|
314
|
+
0 internal
|
315
|
+
0 external
|
316
|
+
|
317
|
+
## Annotations
|
318
|
+
* This one went very well.
|
319
|
+
|
320
|
+
A report can produced for a specific pomodoro or break (here, it was started earlier today and then cancelled after a few interruptions):
|
321
|
+
|
322
|
+
$ par report 11
|
323
|
+
# Report for pomodoro #11
|
324
|
+
|
325
|
+
Started 11:34, canceled 11:40
|
251
326
|
|
252
|
-
|
253
|
-
|
254
|
-
1 internal interruptions
|
255
|
-
2 external interruptions
|
256
|
-
4 breaks (3 short, 1 long; 45 minutes in total)
|
327
|
+
## Interrupts
|
328
|
+
2 internal:
|
257
329
|
|
258
|
-
|
259
|
-
|
330
|
+
* Could not help checking my mail
|
331
|
+
* Surfin' the web
|
260
332
|
|
261
|
-
|
333
|
+
1 external:
|
334
|
+
* VP of engineering walked into my office
|
335
|
+
|
336
|
+
# Annotations
|
337
|
+
* Right before lunch doesn't seem like a good time for a pomodoro.
|
338
|
+
|
339
|
+
Reports can also be grouped by `--day`, `--week`, `--month`, `--year`, or `--all`:
|
340
|
+
|
341
|
+
$ par report --day
|
342
|
+
# Daily Report for 2013-07-16
|
343
|
+
|
344
|
+
## Pomodori
|
345
|
+
- 3 finished
|
346
|
+
- 1 cancelled
|
347
|
+
|
348
|
+
## Interrupts
|
349
|
+
- 1 internal
|
350
|
+
- 2 external
|
351
|
+
|
352
|
+
## Breaks
|
353
|
+
- 3 short
|
354
|
+
- 1 long
|
355
|
+
|
356
|
+
Total: 4 breaks, 45 minutes
|
357
|
+
|
358
|
+
## Locations
|
359
|
+
Most efficient: Home Office
|
360
|
+
Least efficient: Coffeshop
|
361
|
+
|
362
|
+
Without a value, the argument assumes the current day / week / month / year. The first day of the period can be specified as argument, e.g. `par report --day=2013-07-18`. The period is parsed with [Chronic](http://chronic.rubyforge.org/), which also enables symbolic values like `par report --month="last month"`.
|
363
|
+
|
364
|
+
Note that the annotations section is not shown if there are no annotations.
|
262
365
|
|
263
366
|
The report can also be grouped by location:
|
264
367
|
|
265
|
-
$ par report location
|
266
|
-
|
368
|
+
$ par report --location
|
369
|
+
# Location Report
|
370
|
+
|
371
|
+
## Home Office
|
372
|
+
38 finished
|
373
|
+
12 cancelled
|
374
|
+
21 interrupts
|
267
375
|
|
268
|
-
|
269
|
-
|
270
|
-
|
376
|
+
## Starbucks
|
377
|
+
12 finished
|
378
|
+
2 cancelled
|
379
|
+
45 interrupts
|
380
|
+
|
381
|
+
## On the road
|
382
|
+
14 finished
|
383
|
+
0 cancelled
|
384
|
+
12 interrupts
|
271
385
|
|
272
386
|
The following locations do not have a label. Assign it with
|
273
387
|
|
274
|
-
$ par location macbook@01:23:45:67:89:0A "Your Label"
|
388
|
+
$ par --location macbook@01:23:45:67:89:0A "Your Label"
|
275
389
|
|
276
390
|
Detailed report for a single location:
|
277
391
|
|
278
|
-
$ par report location
|
279
|
-
|
392
|
+
$ par report --location="Home Office"
|
393
|
+
# Location Report for Home Office
|
280
394
|
|
281
395
|
58 pomodori finished
|
282
396
|
12 pomodoro cancelled
|
@@ -288,7 +402,7 @@ Detailed report for a single location:
|
|
288
402
|
|
289
403
|
Further grouping is also possible, e.g. by year:
|
290
404
|
|
291
|
-
$ par report location --year=2012
|
405
|
+
$ par report --location --year=2012
|
292
406
|
Pomodoro Location Report for 2012
|
293
407
|
|
294
408
|
233 pomodori finished
|
@@ -323,6 +437,13 @@ Efficiency can be reported by day, week, month, year, or location:
|
|
323
437
|
|
324
438
|
The same options as for regular reports apply. The timesheet report also details the efficiency of each location.
|
325
439
|
|
440
|
+
### Report Formatting
|
441
|
+
By default The output of reports is formatted as [markdown](http://TODO), so that it can easily be read at the command line, but also piped into a markdown processor, e.g. for HTML generation with [redcloth](http://TODO):
|
442
|
+
|
443
|
+
$ par report | redcloth | bcat
|
444
|
+
|
445
|
+
Here, the HTML produced by redcloth is piped into `bcat`, which opens a browser with the produced HTML.
|
446
|
+
|
326
447
|
### Exporting a Report
|
327
448
|
|
328
449
|
$ par report --weekly --format JSON # weekly report in JSON format
|
@@ -407,6 +528,25 @@ The configuration is stored in a config file. It is user-editable file, but edit
|
|
407
528
|
`PAR_DIR` | Directory where the data store and the hooks are stored. Defaults to `~/.paradeiser/`. Overridden by `$PAR_DIR`.
|
408
529
|
`AT_QUEUE` | Name of the `at` queue to use. Defaults to `p`.
|
409
530
|
|
531
|
+
## Export
|
532
|
+
|
533
|
+
Paradeiser can export the pomodori and breaks it has stored to JSON:
|
534
|
+
|
535
|
+
$ par export
|
536
|
+
[{"type":"Pomodoro","length":1500,"status":"finished","interrupts":[],"annotati ...
|
537
|
+
|
538
|
+
## Import
|
539
|
+
|
540
|
+
Paradeiser can import pomodori and breaks from a JSON file:
|
541
|
+
|
542
|
+
$ par import pomodori.json
|
543
|
+
|
544
|
+
If the second argument is missing, `par import` will expect the JSON that is to be imported to appear on STDIN:
|
545
|
+
|
546
|
+
$ cat pomodori.json | par import
|
547
|
+
|
548
|
+
If the import succeeds, no further message will printed and the exit status will be zero. If there is an existing pomodoro or break that overlaps with one imported from JSON, the entire import will fail and paradeiser will exit with a non-zero exit status.
|
549
|
+
|
410
550
|
## Taskwarrior Integration
|
411
551
|
|
412
552
|
This is deployed to `~/.paradeiser/hooks/after-finish` by default.
|
@@ -433,9 +573,14 @@ They have a lot of what I wanted, but pomo focuses very much on the tasks themse
|
|
433
573
|
## Implementation Notes
|
434
574
|
|
435
575
|
### State Machine
|
436
|
-
Paradeiser uses a [state machine](https://github.com/pluginaweek/state_machine) to model
|
576
|
+
Paradeiser uses a [state machine](https://github.com/pluginaweek/state_machine) to model the state of pomodori and breaks. Internal event handlers do the actual work. Calling the external hooks is one of these tasks.
|
577
|
+
|
578
|
+
Pomodoro:
|
437
579
|
|
438
580
|
![State Transition Diagram for Pomodoro](https://rawgithub.com/nerab/paradeiser/master/doc/Paradeiser::Pomodoro_status.svg)
|
581
|
+
|
582
|
+
Break:
|
583
|
+
|
439
584
|
![State Transition Diagram for Break](https://rawgithub.com/nerab/paradeiser/master/doc/Paradeiser::Break_status.svg)
|
440
585
|
|
441
586
|
The graph was created using the rake task that comes with `state_machine`:
|