88import click
99from rich .prompt import Confirm , Prompt
1010from rich .table import Table
11+ from rich .tree import Tree
12+ from rich .panel import Panel
13+ from rich .layout import Layout
1114
1215from PyTM import __version__ , settings
13- from PyTM .commands .project import project
16+ from PyTM .commands .project import project , get_duration_str
1417from PyTM .commands .task import task
1518from PyTM .console import console
1619from PyTM .core import data_handler , invoice_handler
@@ -25,7 +28,7 @@ def init_data_store(show_messages=False):
2528 try :
2629 os .makedirs (settings .data_folder )
2730 messages .append (f"Created data folder: { settings .data_folder } " )
28- except :
31+ except Exception as _ :
2932 messages .append (f"Data folder already exists: { settings .data_folder } " )
3033 if not os .path .exists (settings .data_filepath ):
3134 data_handler .init_data (settings .data_filepath )
@@ -59,7 +62,7 @@ def print_version(ctx, param, value):
5962 return
6063 console .print ("\n [bold green]✨ PyTM ✨" )
6164 console .print (f"version { __version__ } " )
62- console .print (f "docs: https://pytm.rtfd.org" )
65+ console .print ("docs: https://pytm.rtfd.org" )
6366 ctx .exit ()
6467
6568
@@ -184,7 +187,7 @@ def config_invoice():
184187 invoice ["logo" ], os .path .join (settings .data_folder , "invoice-logo.png" )
185188 )
186189 invoice ["logo" ] = os .path .join (settings .data_folder , "invoice-logo.png" )
187- except Exception as e :
190+ except Exception as _ :
188191 console .print ("[bold red] Error occured while saving the logo." )
189192 console .print_exception ()
190193
@@ -274,7 +277,7 @@ def auto(project_name):
274277 "invoice_number"
275278 ] = f'{ int (state .get ("config" ).get ("invoice" ).get ("invoice_number" , "13" )) + 1 } '
276279 data_handler .save_data (state , settings .state_filepath )
277- except :
280+ except Exception as _ :
278281 pass
279282
280283 invoice_texts ["title" ] = Prompt .ask (
@@ -329,7 +332,7 @@ def auto(project_name):
329332 )
330333 try :
331334 os .makedirs (os .path .join (settings .data_folder , "invoices" ))
332- except :
335+ except Exception as _ :
333336 pass
334337
335338 html_file = os .path .join (
@@ -365,7 +368,7 @@ def manual():
365368 "invoice_number"
366369 ] = f'{ int (state .get ("config" ).get ("invoice" ).get ("invoice_number" )) + 1 } '
367370 data_handler .save_data (state , settings .state_filepath )
368- except :
371+ except Exception as _ :
369372 pass
370373
371374 invoice_texts ["title" ] = Prompt .ask (
@@ -420,7 +423,7 @@ def manual():
420423 )
421424 try :
422425 os .makedirs (os .path .join (settings .data_folder , "invoices" ))
423- except :
426+ except Exception as _ :
424427 pass
425428 html_file = os .path .join (
426429 settings .data_folder , "invoices" , f"{ invoice_texts ['title' ]} .html"
@@ -431,12 +434,57 @@ def manual():
431434 webbrowser .open (f"file:///{ html_file } " , autoraise = True )
432435
433436
437+ @click .command ()
438+ def summary ():
439+ """
440+ - shows summary of all projects.
441+ """
442+ data = data_handler .load_data ()
443+ layout = Layout ()
444+
445+ count = 0
446+ left , right = [], []
447+ for project_name in data :
448+ project_data = data .get (project_name , {}).get ("tasks" , {})
449+ tree = Tree (
450+ f'[bold blue]{ project_name } [/bold blue] ([i]{ data .get (project_name , {})["status" ]} [/i])'
451+ )
452+ if project_data == {}:
453+ tree .add ("[red] No tasks yet. [/red]" )
454+ right .append (Panel (tree , title = f"{ project_name } " ))
455+ continue
456+ duration = 0
457+ for task_name , t in project_data .items ():
458+ task_duration = int (round (t ["duration" ]))
459+ duration += task_duration
460+ tree .add (
461+ f"[green]{ task_name } [/green]: { get_duration_str (task_duration )} ([i]{ t ['status' ]} [/i])"
462+ )
463+ left .append (
464+ Panel (
465+ tree ,
466+ title = f"{ project_name } " ,
467+ subtitle = f"[blue bold]Total time[/blue bold]: { get_duration_str (duration )} " ,
468+ expand = False ,
469+ )
470+ )
471+ count += 1
472+ layout .split_row ( # *p)
473+ Layout (name = "left" , size = 45 ),
474+ Layout (name = "right" , size = 55 ),
475+ )
476+ layout ["left" ].split_column (* left )
477+ layout ["right" ].split_column (* right )
478+ console .print (layout )
479+
480+
434481cli .add_command (init )
435482cli .add_command (project )
436483cli .add_command (task )
437484cli .add_command (show )
438485cli .add_command (config )
439486cli .add_command (invoice )
487+ cli .add_command (summary )
440488
441489if __name__ == "__main__" :
442490 cli ()
0 commit comments