@@ -13,8 +13,6 @@ import { checkBrowserNotificationSettings } from './settings';
1313interface ICellExecutionMetadata {
1414 index : number ;
1515 scheduledTime : Date ;
16- endTime ?: Date ;
17- startTime ?: Date ;
1816}
1917
2018/**
@@ -27,7 +25,8 @@ function displayNotification(
2725 reportCellNumber : boolean ,
2826 reportCellExecutionTime : boolean ,
2927 failedExecution : boolean ,
30- error : KernelError | null
28+ error : KernelError | null ,
29+ lastCellOnly : boolean
3130) : void {
3231 const notificationPayload = {
3332 icon : '/static/favicon.ico' ,
@@ -40,6 +39,8 @@ function displayNotification(
4039
4140 if ( failedExecution ) {
4241 message = error ? `${ error . errorName } ${ error . errorValue } ` : '' ;
42+ } else if ( lastCellOnly ) {
43+ message = `Total Duration: ${ cellDuration } ` ;
4344 } else if ( reportCellNumber && reportCellExecutionTime ) {
4445 message = `Cell[${ cellNumber } ] Duration: ${ cellDuration } ` ;
4546 } else if ( reportCellNumber ) {
@@ -58,36 +59,58 @@ function displayNotification(
5859function triggerNotification (
5960 cell : Cell ,
6061 notebook : Notebook ,
61- executionMetadata : ICellExecutionMetadata ,
62+ cellExecutionMetadataTable : LRU < string , ICellExecutionMetadata > ,
63+ recentNotebookExecutionTimes : LRU < string , Date > ,
6264 minimumCellExecutionTime : number ,
6365 reportCellNumber : boolean ,
6466 reportCellExecutionTime : boolean ,
6567 cellNumberType : string ,
6668 failedExecution : boolean ,
67- error : KernelError | null
69+ error : KernelError | null ,
70+ lastCellOnly : boolean
6871) {
69- const { startTime , endTime , index : cellIndex } = executionMetadata ;
72+ const cellEndTime = new Date ( ) ;
7073 const codeCellModel = cell . model as ICodeCellModel ;
71- const cellDuration = moment
72- . utc ( moment ( endTime ) . diff ( startTime ) )
73- . format ( 'HH:mm:ss' ) ;
74- const diffSeconds = moment . duration ( cellDuration ) . asSeconds ( ) ;
75- console . log ( cellDuration , diffSeconds ) ;
76- if ( diffSeconds >= minimumCellExecutionTime ) {
77- const cellNumber =
78- cellNumberType === 'cell_index'
79- ? cellIndex
80- : codeCellModel . executionCount ;
81- const notebookName = notebook . title . label . replace ( / \. [ ^ / . ] + $ / , '' ) ;
82- displayNotification (
83- cellDuration ,
84- cellNumber ,
85- notebookName ,
86- reportCellNumber ,
87- reportCellExecutionTime ,
88- failedExecution ,
89- error
90- ) ;
74+ const codeCell = codeCellModel . type === 'code' ;
75+ const nonEmptyCell = codeCellModel . value . text . length > 0 ;
76+ if ( codeCell && nonEmptyCell ) {
77+ const cellId = codeCellModel . id ;
78+ const notebookId = notebook . id ;
79+ const cellExecutionMetadata = cellExecutionMetadataTable . get ( cellId ) ;
80+ const scheduledTime = cellExecutionMetadata . scheduledTime ;
81+ // Get the cell's execution scheduled time if the recent notebook execution state doesn't exist.
82+ // This happens commonly for first time notebook executions or notebooks that haven't been executed for a while.
83+ const recentExecutedCellTime =
84+ recentNotebookExecutionTimes . get ( notebookId ) || scheduledTime ;
85+
86+ // Multiple cells can be scheduled at the same time, and the schedule time doesn't necessarily equate to the actual start time.
87+ // If another cell has been executed more recently than the current cell's scheduled time, treat the recent execution as the cell's start time.
88+ const cellStartTime =
89+ scheduledTime >= recentExecutedCellTime
90+ ? scheduledTime
91+ : recentExecutedCellTime ;
92+ recentNotebookExecutionTimes . set ( notebookId , cellEndTime ) ;
93+ const cellDuration = moment
94+ . utc ( moment ( cellEndTime ) . diff ( cellStartTime ) )
95+ . format ( 'HH:mm:ss' ) ;
96+ const diffSeconds = moment . duration ( cellDuration ) . asSeconds ( ) ;
97+ if ( diffSeconds >= minimumCellExecutionTime ) {
98+ const cellNumber =
99+ cellNumberType === 'cell_index'
100+ ? cellExecutionMetadata . index
101+ : codeCellModel . executionCount ;
102+ const notebookName = notebook . title . label . replace ( / \. [ ^ / . ] + $ / , '' ) ;
103+ displayNotification (
104+ cellDuration ,
105+ cellNumber ,
106+ notebookName ,
107+ reportCellNumber ,
108+ reportCellExecutionTime ,
109+ failedExecution ,
110+ error ,
111+ lastCellOnly
112+ ) ;
113+ }
91114 }
92115}
93116
@@ -102,6 +125,7 @@ const extension: JupyterFrontEndPlugin<void> = {
102125 let reportCellExecutionTime = true ;
103126 let reportCellNumber = true ;
104127 let cellNumberType = 'cell_index' ;
128+ let lastCellOnly = false ;
105129 const cellExecutionMetadataTable : LRU <
106130 string ,
107131 ICellExecutionMetadata
@@ -123,6 +147,7 @@ const extension: JupyterFrontEndPlugin<void> = {
123147 reportCellNumber = setting . get ( 'report_cell_number' )
124148 . composite as boolean ;
125149 cellNumberType = setting . get ( 'cell_number_type' ) . composite as string ;
150+ lastCellOnly = setting . get ( 'last_cell_only' ) . composite as boolean ;
126151 } ;
127152 updateSettings ( ) ;
128153 setting . changed . connect ( updateSettings ) ;
@@ -139,42 +164,41 @@ const extension: JupyterFrontEndPlugin<void> = {
139164 } ) ;
140165
141166 NotebookActions . executed . connect ( ( _ , args ) => {
142- if ( enabled ) {
143- const cellEndTime = new Date ( ) ;
167+ if ( enabled && ! lastCellOnly ) {
144168 const { cell, notebook, success, error } = args ;
145- const codeCell = cell . model . type === 'code' ;
146- const nonEmptyCell = cell . model . value . text . length > 0 ;
147- if ( codeCell && nonEmptyCell ) {
148- const cellId = cell . model . id ;
149- const notebookId = notebook . id ;
150- const cellExecutionMetadata = cellExecutionMetadataTable . get ( cellId ) ;
151- const scheduledTime = cellExecutionMetadata . scheduledTime ;
152- // Get the cell's execution scheduled time if the recent notebook execution state doesn't exist.
153- // This happens commonly for first time notebook executions or notebooks that haven't been executed for a while.
154- const recentExecutedCellTime =
155- recentNotebookExecutionTimes . get ( notebookId ) || scheduledTime ;
156-
157- // Multiple cells can be scheduled at the same time, and the schedule time doesn't necessarily equate to the actual start time.
158- // If another cell has been executed more recently than the current cell's scheduled time, treat the recent execution as the cell's start time.
159- cellExecutionMetadata . startTime =
160- scheduledTime >= recentExecutedCellTime
161- ? scheduledTime
162- : recentExecutedCellTime ;
163- cellExecutionMetadata . endTime = cellEndTime ;
164- recentNotebookExecutionTimes . set ( notebookId , cellEndTime ) ;
169+ triggerNotification (
170+ cell ,
171+ notebook ,
172+ cellExecutionMetadataTable ,
173+ recentNotebookExecutionTimes ,
174+ minimumCellExecutionTime ,
175+ reportCellNumber ,
176+ reportCellExecutionTime ,
177+ cellNumberType ,
178+ ! success ,
179+ error ,
180+ lastCellOnly
181+ ) ;
182+ }
183+ } ) ;
165184
166- triggerNotification (
167- cell ,
168- notebook ,
169- cellExecutionMetadata ,
170- minimumCellExecutionTime ,
171- reportCellNumber ,
172- reportCellExecutionTime ,
173- cellNumberType ,
174- ! success ,
175- error
176- ) ;
177- }
185+ NotebookActions . selectionExecuted . connect ( ( _ , args ) => {
186+ if ( enabled && lastCellOnly ) {
187+ const { lastCell, notebook } = args ;
188+ const failedExecution = false ;
189+ triggerNotification (
190+ lastCell ,
191+ notebook ,
192+ cellExecutionMetadataTable ,
193+ recentNotebookExecutionTimes ,
194+ minimumCellExecutionTime ,
195+ reportCellNumber ,
196+ reportCellExecutionTime ,
197+ cellNumberType ,
198+ failedExecution ,
199+ null ,
200+ lastCellOnly
201+ ) ;
178202 }
179203 } ) ;
180204 }
0 commit comments