Skip to content

Commit c782c3d

Browse files
author
Djings
committed
manually applied the work of
https://github.com/aero31aero from the PR 405 in the original jazzband watson repo jazzband/Watson#405 to watson-next repo * added some FIXMEs in the process
1 parent a54ed45 commit c782c3d

File tree

10 files changed

+305
-50
lines changed

10 files changed

+305
-50
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
- notes can be added to frames,
11+
reapplied aero31aeros work on the original watson https://github.com/jazzband/Watson/pull/405
12+
to watson-next
13+
1014
## [2.1.0] - 2022-05-16
1115

1216
### Added

Makefile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
PYTHON ?= python
44
PIP ?= pip
55

6-
VENV = virtualenv
7-
VENV_ARGS = -p $(PYTHON)
6+
VENV = python3
7+
VENV_ARGS = -m venv
8+
#VENV = virtualenv
9+
#VENV_ARGS = -p $(PYTHON)
810
VENV_DIR = $(CURDIR)/.venv
911
VENV_WATSON_DIR = $(CURDIR)/data
1012

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,20 @@ License
6161

6262
Watson-next is released under the MIT License.
6363
See the bundled LICENSE file for details.
64+
65+
Develop
66+
-------
67+
68+
1. Make an environment
69+
```
70+
make env
71+
```
72+
2. Activate your environment
73+
```
74+
source .venv/bin/activate
75+
```
76+
3. Make it dev
77+
```
78+
make install-dev
79+
```
80+

docs/user-guide/commands.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Flag | Help
2828
`-t, --to DATETIME` | Date and time of end of tracked activity [required]
2929
`-c, --confirm-new-project` | Confirm addition of new project.
3030
`-b, --confirm-new-tag` | Confirm creation of new tag.
31+
`-n, --note TEXT` | Add log message with the added project frame.
3132
`--help` | Show this message and exit.
3233

3334
## `aggregate`
@@ -663,6 +664,7 @@ Flag | Help
663664
`-g, --gap / -G, --no-gap` | (Don't) leave gap between end time of previous project and start time of the current.
664665
`-c, --confirm-new-project` | Confirm addition of new project.
665666
`-b, --confirm-new-tag` | Confirm creation of new tag.
667+
`-n, --note TEXT` | Add log message to started frame.
666668
`--help` | Show this message and exit.
667669

668670
## `status`
@@ -710,17 +712,25 @@ If `--at` option is given, the provided stopping time is used. The
710712
specified time must be after the beginning of the to-be-ended frame and must
711713
not be in the future.
712714

715+
You can optionally pass a log message to be saved with the frame via
716+
the ``-n/--note`` option.
717+
713718
Example:
714719

715720

716721
$ watson stop --at 13:37
717722
Stopping project apollo11, started an hour ago and stopped 30 minutes ago. (id: e9ccd52) # noqa: E501
718723

724+
$ watson stop -n "Done some thinking"
725+
Stopping project apollo11, started a minute ago. (id: e7ccd52)
726+
Log message: Done some thinking
727+
719728
### Options
720729

721730
Flag | Help
722731
-----|-----
723732
`--at DATETIME` | Stop frame at this time. Must be in (YYYY-MM-DDT)?HH:MM(:SS)? format.
733+
`-n, --note TEXT` | Save given log message with the project frame.
724734
`--help` | Show this message and exit.
725735

726736
## `sync`

tests/test_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ def test_frames_to_csv(watson):
300300
result = frames_to_csv(watson.frames)
301301

302302
read_csv = list(csv.reader(StringIO(result)))
303-
header = ['id', 'start', 'stop', 'project', 'tags']
303+
header = ['id', 'start', 'stop', 'project', 'tags', 'note']
304304
assert len(read_csv) == 2
305305
assert read_csv[0] == header
306306
assert read_csv[1][3] == 'foo'
@@ -319,7 +319,7 @@ def test_frames_to_json(watson):
319319

320320
result = json.loads(frames_to_json(watson.frames))
321321

322-
keys = {'id', 'start', 'stop', 'project', 'tags'}
322+
keys = {'id', 'start', 'stop', 'project', 'tags', 'note'}
323323
assert len(result) == 1
324324
assert set(result[0].keys()) == keys
325325
assert result[0]['project'] == 'foo'

tests/test_watson.py

Lines changed: 111 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,58 @@ def test_frames_with_empty_given_state(config_dir, mocker):
197197
mocker.patch('builtins.open', mocker.mock_open(read_data=content))
198198
assert len(watson.frames) == 0
199199

200+
def test_frames_with_note(mocker, watson):
201+
"""Test loading frames with notes."""
202+
content = json.dumps([
203+
[3601, 3610, 'foo', 'abcdefg', ['A', 'B', 'C'], 3650,
204+
"My hovercraft is full of eels"]
205+
])
206+
207+
mocker.patch('builtins.open', mocker.mock_open(read_data=content))
208+
assert len(watson.frames) == 1
209+
frame = watson.frames['abcdefg']
210+
assert frame.id == 'abcdefg'
211+
assert frame.project == 'foo'
212+
assert frame.start == arrow.get(3601)
213+
assert frame.stop == arrow.get(3610)
214+
assert frame.tags == ['A', 'B', 'C']
215+
assert frame.note == "My hovercraft is full of eels"
216+
217+
218+
def test_frames_without_note(mocker, watson):
219+
"""Test loading frames without notes."""
220+
content = json.dumps([
221+
[3601, 3610, 'foo', 'abcdefg'],
222+
[3611, 3620, 'foo', 'hijklmn', ['A', 'B', 'C']],
223+
[3621, 3630, 'foo', 'opqrstu', ['A', 'B', 'C'], 3630]
224+
])
225+
226+
mocker.patch('builtins.open', mocker.mock_open(read_data=content))
227+
assert len(watson.frames) == 3
228+
frame = watson.frames['abcdefg']
229+
assert frame.id == 'abcdefg'
230+
assert frame.project == 'foo'
231+
assert frame.start == arrow.get(3601)
232+
assert frame.stop == arrow.get(3610)
233+
assert frame.tags == []
234+
assert frame.note is None
235+
236+
frame = watson.frames['hijklmn']
237+
assert frame.id == 'hijklmn'
238+
assert frame.tags == ['A', 'B', 'C']
239+
assert frame.note is None
240+
241+
frame = watson.frames['opqrstu']
242+
assert frame.id == 'opqrstu'
243+
assert frame.tags == ['A', 'B', 'C']
244+
assert frame.updated_at == arrow.get(3630)
245+
assert frame.note is None
246+
247+
248+
249+
250+
251+
200252

201253
# config
202254

@@ -355,6 +407,30 @@ def test_stop_started_project_at(watson):
355407
watson.stop(stop_at=now)
356408
assert watson.frames[-1].stop == now
357409

410+
def test_stop_started_project_without_note(watson):
411+
"""Test stopping watson without adding a note."""
412+
watson.start('foo')
413+
watson.stop()
414+
415+
assert watson.current == {}
416+
assert watson.is_started is False
417+
assert len(watson.frames) == 1
418+
frame = watson.frames[0]
419+
assert frame.project == 'foo'
420+
assert frame.note is None
421+
422+
423+
def test_stop_started_project_with_note(watson):
424+
"""Test stopping watson when adding a note."""
425+
watson.start('foo')
426+
watson.stop(None, "My hovercraft is full of eels")
427+
428+
assert watson.current == {}
429+
assert watson.is_started is False
430+
assert len(watson.frames) == 1
431+
frame = watson.frames[0]
432+
assert frame.project == 'foo'
433+
assert frame.note == "My hovercraft is full of eels"
358434

359435
# cancel
360436

@@ -419,7 +495,7 @@ def test_save_empty_current(config_dir, mocker, json_mock):
419495

420496
assert json_mock.call_count == 1
421497
result = json_mock.call_args[0][0]
422-
assert result == {'project': 'foo', 'start': 4000, 'tags': []}
498+
assert result == {'project': 'foo', 'start': 4000, 'tags': [], 'note': None}
423499

424500
watson.current = {}
425501
watson.save()
@@ -779,9 +855,12 @@ def test_report(watson):
779855
assert 'time' in report['projects'][0]['tags'][0]
780856
assert report['projects'][0]['tags'][1]['name'] == 'B'
781857
assert 'time' in report['projects'][0]['tags'][1]
858+
assert len(report['projects'][0]['notes']) == 0
859+
assert len(report['projects'][0]['tags'][0]['notes']) == 0
860+
assert len(report['projects'][0]['tags'][1]['notes']) == 0
782861

783862
watson.start('bar', tags=['C'])
784-
watson.stop()
863+
watson.stop(note='bar note')
785864

786865
report = watson.report(arrow.now(), arrow.now())
787866
assert len(report['projects']) == 2
@@ -790,6 +869,13 @@ def test_report(watson):
790869
assert len(report['projects'][0]['tags']) == 1
791870
assert report['projects'][0]['tags'][0]['name'] == 'C'
792871

872+
assert len(report['projects'][1]['notes']) == 0
873+
assert len(report['projects'][1]['tags'][0]['notes']) == 0
874+
assert len(report['projects'][1]['tags'][1]['notes']) == 0
875+
assert len(report['projects'][0]['notes']) == 0
876+
assert len(report['projects'][0]['tags'][0]['notes']) == 1
877+
assert report['projects'][0]['tags'][0]['notes'][0] == 'bar note'
878+
793879
report = watson.report(
794880
arrow.now(), arrow.now(), projects=['foo'], tags=['B']
795881
)
@@ -799,16 +885,38 @@ def test_report(watson):
799885
assert report['projects'][0]['tags'][0]['name'] == 'B'
800886

801887
watson.start('baz', tags=['D'])
802-
watson.stop()
888+
watson.stop(note='baz note')
889+
890+
watson.start('foo')
891+
watson.stop(note='foo no tags')
892+
893+
watson.start('foo', tags=['A'])
894+
watson.stop(note='foo one tag A')
803895

804896
report = watson.report(arrow.now(), arrow.now(), projects=["foo"])
897+
805898
assert len(report['projects']) == 1
899+
assert len(report['projects'][0]['notes']) == 1
900+
# A project-level note because this frame has no tags
901+
assert report['projects'][0]['notes'][0] == 'foo no tags'
902+
assert len(report['projects'][0]['tags']) == 2
903+
assert report['projects'][0]['tags'][0]['name'] == 'A'
904+
assert report['projects'][0]['tags'][1]['name'] == 'B'
905+
assert len(report['projects'][0]['tags'][0]['notes']) == 1
906+
assert len(report['projects'][0]['tags'][1]['notes']) == 0
907+
# A tag-level note because this frame has tags
908+
assert report['projects'][0]['tags'][0]['notes'][0] == 'foo one tag A'
909+
910+
806911

807912
report = watson.report(arrow.now(), arrow.now(), ignore_projects=["bar"])
808913
assert len(report['projects']) == 2
809914

810915
report = watson.report(arrow.now(), arrow.now(), tags=["A"])
811916
assert len(report['projects']) == 1
917+
assert len(report['projects'][0]['notes']) == 0
918+
assert len(report['projects'][0]['tags'][0]['notes']) == 1
919+
assert report['projects'][0]['tags'][0]['notes'][0] == 'foo one tag A'
812920

813921
report = watson.report(arrow.now(), arrow.now(), ignore_tags=["D"])
814922
assert len(report['projects']) == 2

0 commit comments

Comments
 (0)