99
1010from utt .api import _v1
1111
12+ DEFAULT_CURRENT_ACTIVITY_NAME = "-- Current Activity --"
13+
1214if TYPE_CHECKING :
1315 from collections .abc import Sequence
1416
@@ -85,10 +87,10 @@ def _aggregate_projects(self, activities: Sequence[_v1.Activity]) -> list[Projec
8587
8688 def _extract_current (self , activities : Sequence [_v1 .Activity ]) -> CurrentActivity | None :
8789 """Extract current activity if present."""
88- for activity in activities :
89- if activity .is_current_activity :
90- return CurrentActivity ( activity . name . name , activity . duration )
91- return None
90+ return next (
91+ ( CurrentActivity ( a . name . name , a . duration ) for a in activities if a .is_current_activity ),
92+ None ,
93+ )
9294
9395 def _compute_total (self ) -> timedelta :
9496 """Sum all project durations plus current activity."""
@@ -101,9 +103,17 @@ def _compute_total(self) -> timedelta:
101103class ProjectSummaryView :
102104 """Render project summary output."""
103105
104- def __init__ (self , model : ProjectSummaryModel , show_perc : bool = False ) -> None :
106+ def __init__ (
107+ self ,
108+ model : ProjectSummaryModel ,
109+ show_perc : bool = False ,
110+ show_current : bool = True ,
111+ current_activity_name : str = DEFAULT_CURRENT_ACTIVITY_NAME ,
112+ ) -> None :
105113 self ._model = model
106114 self ._show_perc = show_perc
115+ self ._show_current = show_current
116+ self ._current_activity_name = current_activity_name
107117
108118 def render (self , output : _v1 .Output ) -> None :
109119 """Render the project summary to output stream."""
@@ -128,13 +138,13 @@ def render(self, output: _v1.Output) -> None:
128138 dur_str = f"{ dur_str :<{max_dur_len }} ({ perc :5.1f} %)"
129139 print (f"{ project .name :<{max_name_len }} : { dur_str } " , file = output )
130140
131- if self ._model .current_activity :
141+ if self ._show_current and self . _model .current_activity :
132142 ca = self ._model .current_activity
133143 dur_str = ca .formatted
134144 if self ._show_perc and total_secs > 0 :
135145 perc = (ca .duration .total_seconds () / total_secs ) * 100
136- dur_str = f"{ dur_str } ({ perc :5.1f} %)"
137- print (f"{ ca . name :<{max_name_len }} : { dur_str } " , file = output )
146+ dur_str = f"{ dur_str :<{ max_dur_len } } ({ perc :5.1f} %)"
147+ print (f"{ self . _current_activity_name :<{max_name_len }} : { dur_str } " , file = output )
138148
139149 print (file = output )
140150 total_str = format_duration (self ._model .total_duration )
@@ -160,7 +170,13 @@ def __init__(
160170 def __call__ (self ) -> None :
161171 """Execute command."""
162172 model = ProjectSummaryModel (self ._activities )
163- ProjectSummaryView (model , self ._args .show_perc ).render (self ._output )
173+ view = ProjectSummaryView (
174+ model ,
175+ show_perc = self ._args .show_perc ,
176+ show_current = not self ._args .no_current_activity ,
177+ current_activity_name = self ._args .current_activity ,
178+ )
179+ view .render (self ._output )
164180
165181
166182def add_args (parser : argparse .ArgumentParser ) -> None :
@@ -176,9 +192,9 @@ def add_args(parser: argparse.ArgumentParser) -> None:
176192 )
177193 parser .add_argument (
178194 "--current-activity" ,
179- default = "-- Current Activity --" ,
195+ default = DEFAULT_CURRENT_ACTIVITY_NAME ,
180196 type = str ,
181- help = "Set the current activity" ,
197+ help = "Set the current activity name " ,
182198 )
183199 parser .add_argument (
184200 "--no-current-activity" ,
@@ -224,6 +240,8 @@ def add_args(parser: argparse.ArgumentParser) -> None:
224240 )
225241
226242
243+ # Note: type: ignore needed because _v1.Command expects a specific handler protocol
244+ # that differs from our implementation's signature (uses filtered_activities vs activities)
227245project_summary_command = _v1 .Command (
228246 name = "project-summary" ,
229247 description = "Show projects sorted by time spent" ,
0 commit comments