Skip to content

Commit 6ab66f0

Browse files
committed
split 'sup' command so that 'sup' is read-only and 'did' modifies today's checklist. Other organizations and new 'nvm' command specs
1 parent 8a9a325 commit 6ab66f0

File tree

14 files changed

+128
-100
lines changed

14 files changed

+128
-100
lines changed

src/fob/__init__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,13 @@ def run_app():
5555
)
5656
subparsers.add_parser("reset", help="Reset fob by deleting persistent database file.")
5757
subparsers.add_parser("sup", help="Quick look at the month and today's blocks")
58-
58+
did_parser = subparsers.add_parser("did", help="Check off blocks from today's checklist")
59+
did_parser.add_argument(
60+
"block_id",
61+
type=str,
62+
help="ID of the block to check off (int)",
63+
)
64+
subparsers.add_parser("nvm", help="Revise block assignment for today and change a non-Buffer block into a Buffer block, and mark that new Buffer block as complete."
5965
args = parser.parse_args()
6066

6167
command_func = None

src/fob/commands/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
from fob.commands.sup import sup
55
from fob.commands.new_month import new_month
66
from fob.commands.reset import reset
7+
from fob.commands.did import did

src/fob/commands/did.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from rich.pretty import pprint
2+
from rich import print
3+
4+
from fob.commands.overviews import display_checklist
5+
from fob.db import checklist_complete
6+
7+
8+
def did(args, db):
9+
'''
10+
Quickly check off a block from the day's checklist.
11+
12+
The user is expected to run `fob sup` prior to running this command,
13+
which displays the month overview and the day's checklist.
14+
Then, the user can run `fob did <number>` to mark a the numbered block as completed.
15+
This command displays the updated checklist after marking the block as completed.
16+
Visually, it would exactly replace where the day's checklist was previously displayed,
17+
making it look like it was a GUI refresh.
18+
19+
args.block_id: str - contains the block number to mark as completed. The keys are str, so we just use str-ified ints.
20+
'''
21+
try:
22+
checklist = db.all()[0]['checklist']
23+
except IndexError:
24+
print("[red][bold]No day data found.[/red][/bold]")
25+
print("Run [cyan][bold]fob gm[/cyan][/bold] to start a new day.")
26+
return
27+
if args.debug:
28+
print("Checklist from DB:")
29+
pprint(checklist)
30+
31+
if checklist_complete(db):
32+
print("\n[green]All blocks have already been completed. No changes made.[/green]")
33+
print("Start a new day: [green bold]fob gm[/green bold]")
34+
return
35+
36+
# check that the block_id is within range
37+
try:
38+
checklist[args.block_id].update({"done": True})
39+
except KeyError:
40+
print("[red][bold]Invalid block number.[/red][/bold]")
41+
return
42+
43+
db.update({"checklist": checklist}, None)
44+
45+
if args.debug:
46+
print("Updated checklist:")
47+
pprint(checklist)
48+
49+
# display updated checklist
50+
display_checklist(args, db)
51+
52+
53+
if checklist_complete(db):
54+
print("[green]All blocks have been completed![/green]")
55+
print("Start a new day: [green bold]fob gm[/green bold]")
56+
return
57+
else:
58+
print("[green]Checklist updated.[/green] See overview: [cyan]fob sup[/cyan]")

src/fob/commands/gm.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
from tinydb import where, Query
1515

1616
from fob.db import MonthBlockData, TinyDBWrapper, checklist_complete
17-
from fob.commands.overviews import month_overview
18-
from fob.commands.user_flows import display_checklist
17+
from fob.commands.overviews import month_overview, display_checklist
1918

2019
class InvalidUserInput(Exception):
2120
'''
@@ -52,7 +51,8 @@ def gm(args: Namespace, db: TinyDBWrapper) -> None:
5251
print("[bold]Today's Checklist:[/bold]")
5352
display_checklist(args, db)
5453

55-
print("Run [cyan][bold]fob sup[/cyan][/bold] to track daily progress and to see the month overview again.")
54+
print("Next commands: [cyan][bold]fob sup[/cyan][/bold] to see the above overviews again.")
55+
print("[green][bold]fob did (number) [/green][/bold] to mark a block as done.")
5656

5757

5858
def new_day(args: Namespace, db: TinyDBWrapper, data) -> None:

src/fob/commands/help.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ def help(args: Namespace | None, db: TinyDBWrapper | None) -> None:
1919
[green bold]Global Options:[/green bold]
2020
[cyan bold]-d, --database[/cyan bold] [magenta not bold]<PATH_TO_DB_FILE>[/magenta not bold] Path to database file. You can use a cloud storage (eg. Dropbox) to sync the database across devices.
2121
[cyan bold]-x, --debug[/cyan bold] Enable debug mode.
22-
""")
22+
23+
First time with fob? Start by running [green][bold]fob new_month[/green][/bold] to allocate blocks for the month.""")

src/fob/commands/new_month.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ def new_month(args: Namespace, db: TinyDBWrapper) -> None:
1616
if result is not None:
1717
write_new_month(result, db)
1818
print("\n[green]New month successfully created![/green]")
19-
print("Next steps:")
20-
print("\t[green bold]fob gm[/green bold]: Start your day with the good morning command.")
19+
print("Next commands: [green bold]fob gm[/green bold] - Start your day with the good morning command.")
2120

2221
def write_new_month(data: MonthBlockData, db: TinyDBWrapper) -> None:
2322
areas = {}
@@ -81,42 +80,43 @@ def converse_with_user(args: Namespace) ->MonthBlockData:
8180
)
8281
today = today.replace(day=1)
8382
today = today.replace(month=today.month + 1)
84-
year = Prompt.ask("\n\tWhat year?", default=str(today.year))
85-
month = Prompt.ask("\tWhat month?", default=str(today.month))
83+
year = Prompt.ask("\nWhat year?", default=str(today.year))
84+
month = Prompt.ask("What month?", default=str(today.month))
8685

8786
days_in_month = monthrange(int(year), int(month))[1]
8887

8988
if args.debug:
9089
print(f"\nAllocating blocks for {year}/{month}, which has {days_in_month} days.")
9190

9291
working_days = Prompt.ask(
93-
"\n\tHow many working days?", default=str(days_in_month - 8)
92+
"How many working days?", default=str(days_in_month - 8)
9493
)
9594
if int(working_days) > days_in_month or int(working_days) <= 0:
9695
print(
9796
"[red bold]Error:[/red bold] Invalid number of working days. Please try again."
9897
)
9998

10099
if args.debug:
101-
print(f"\nYou have chosen {working_days} working days.")
100+
print(f"You have chosen {working_days} working days.")
102101

103-
blocks_per_day = Prompt.ask("\n\tHow many blocks per day?", default="5")
102+
blocks_per_day = Prompt.ask("How many blocks per day?", default="5")
104103
total_blocks = int(working_days) * int(blocks_per_day)
104+
print("---")
105105
print(
106-
f"\nYou have chosen {blocks_per_day} blocks per day, for a total of {total_blocks} blocks."
106+
f"You have chosen {blocks_per_day} blocks per day, for a total of {total_blocks} blocks.\n"
107107
)
108108

109-
print("\nWhich areas will you be working on?")
109+
print("Which areas will you be working on?")
110110
areas = []
111111

112112
while True:
113-
area = Prompt.ask("\tNew Focus Area (enter empty to finish)", default="")
113+
area = Prompt.ask("New Focus Area (enter empty to finish)", default="")
114114
if area == "":
115115
break
116116
areas.append(area)
117117

118118
if args.debug:
119-
print(f"\nYou have chosen the following areas: {', '.join(areas)}")
119+
print(f"You have chosen the following areas: {', '.join(areas)}")
120120

121121
blocks_per_area = {}
122122
for area in areas:
@@ -125,7 +125,7 @@ def converse_with_user(args: Namespace) ->MonthBlockData:
125125
areas.append("Buffer")
126126
default_buffer = min(8, total_blocks)
127127
buffer_blocks = Prompt.ask(
128-
"\n\tHow many blocks for Buffer?", default=str(default_buffer)
128+
"How many blocks for Buffer?", default=str(default_buffer)
129129
)
130130
blocks_per_area.update({"Buffer": int(buffer_blocks)})
131131

@@ -135,12 +135,12 @@ def converse_with_user(args: Namespace) ->MonthBlockData:
135135
break
136136
remaining_blocks = total_blocks - sum(blocks_per_area.values())
137137
if args.debug:
138-
print(f"\nYou have {remaining_blocks} blocks remaining.")
138+
print(f"You have {remaining_blocks} blocks remaining.")
139139
display_blocks_table(blocks_per_area, area)
140140
equal_split_from_remaining = remaining_blocks // (len(areas) - i - 1)
141141
blocks_for_area = int(
142142
Prompt.ask(
143-
f"\tHow many blocks for {area}?",
143+
f"How many blocks for {area}?",
144144
default=str(equal_split_from_remaining),
145145
)
146146
)

src/fob/commands/nvm.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from argparse import Namespace
2+
3+
from fob.db.wrapper import TinyDBWrapper
4+
5+
6+
def nvm(args: Namespace, db: TinyDBWrapper):
7+
'''
8+
'nvm' command: Abbreviation for 'Nevermind" - used to convert a non-Buffer block into a Buffer block.
9+
10+
The user would run `fob sup` to see today's checklist.
11+
If they succeed in completing a block, they would run `fob did (number)` to mark the block as done.
12+
However, if they fail to do meaningful work on a block, or somehow circumstances made it so that they couldn't do the work assigned in that block, they can run `fob nvm (number)` to convert the block into a Buffer block and mark it as a complete Buffer block. Normally this kind of assignment is done one time at the beginning of the day through `fob gm`, but this command lets us override that.
13+
'''
14+
raise NotImplementedError("This command has not been implemented yet.")
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
# This 'overviews' directory contains read-only visualizations of database content
22
from fob.commands.overviews.month_overview import *
3+
from fob.commands.overviews.day_checklist import *
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from argparse import Namespace
2+
3+
from rich.pretty import pprint
4+
from rich import print
5+
from rich.panel import Panel
6+
7+
from fob.db import TinyDBWrapper
8+
9+
def display_checklist(args: Namespace, db: TinyDBWrapper) -> None:
10+
try:
11+
checklist = db.all()[0]['checklist']
12+
except KeyError:
13+
print("[red][bold]No day data found.[/red][/bold]")
14+
print("Run [cyan][bold]fob gm[/cyan][/bold] to start a new day.")
15+
return
16+
if args.debug:
17+
print("Checklist from DB:")
18+
pprint(checklist)
19+
# print the checklist
20+
for num, info in checklist.items():
21+
print(Panel(f"{num}: {info['name']}", border_style="bold green" if info['done'] else "bold red"))

src/fob/commands/overviews/month_overview.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from calendar import monthrange
44

55
from tinydb import where
6+
from rich.pretty import pprint
67
from rich.console import Console, Group
78
from rich.panel import Panel
89
from rich.progress import Progress, BarColumn, TaskProgressColumn, TextColumn, ProgressColumn

0 commit comments

Comments
 (0)