@@ -2,13 +2,49 @@ import {
22  JupyterFrontEnd , 
33  JupyterFrontEndPlugin 
44}  from  '@jupyterlab/application' ; 
5- 
65import  {  NotebookActions  }  from  '@jupyterlab/notebook' ; 
7- 
6+ import   {   IObservableJSON   }   from   '@jupyterlab/observables' ; 
87import  {  ISettingRegistry  }  from  '@jupyterlab/settingregistry' ; 
98
109import  {  checkBrowserNotificationSettings  }  from  './settings' ; 
1110
11+ /** 
12+  * Extracts Code Cell Start and End Time 
13+  */ 
14+ function  extractExecutionMetadata ( metadata : IObservableJSON ) : [ Date ,  Date ]  { 
15+   const  executionMetadata  =  Object . assign ( { } ,  metadata . get ( 'execution' )  as  any ) ; 
16+   const  cellStartTime  =  new  Date ( 
17+     executionMetadata [ 'shell.execute_reply.started' ] 
18+   ) ; 
19+   const  cellEndTime  =  new  Date ( executionMetadata [ 'shell.execute_reply' ] ) ; 
20+   return  [ cellStartTime ,  cellEndTime ] ; 
21+ } 
22+ 
23+ /** 
24+  * Constructs notification message and displays it. 
25+  */ 
26+ function  displayNotification ( 
27+   cellDuration : string , 
28+   cellNumber : number , 
29+   reportCellNumber : boolean , 
30+   reportCellExecutionTime : boolean 
31+ ) : void { 
32+   const  notificationPayload  =  { 
33+     icon : '/static/favicon.ico' , 
34+     body : '' 
35+   } ; 
36+   let  message  =  '' ; 
37+   if  ( reportCellNumber  &&  reportCellExecutionTime )  { 
38+     message  =  `Cell[${ cellNumber } ${ cellDuration }  ; 
39+   }  else  if  ( reportCellNumber )  { 
40+     message  =  `Cell Number: ${ cellNumber }  ; 
41+   }  else  if  ( reportCellExecutionTime )  { 
42+     message  =  `Cell Duration: ${ cellDuration }  ; 
43+   } 
44+   notificationPayload . body  =  message ; 
45+   new  Notification ( 'Notebook Cell Completed!' ,  notificationPayload ) ; 
46+ } 
47+ 
1248const  extension : JupyterFrontEndPlugin < void >  =  { 
1349  id : 'jupyterlab-notifications:plugin' , 
1450  autoStart : true , 
@@ -37,42 +73,31 @@ const extension: JupyterFrontEndPlugin<void> = {
3773    NotebookActions . executed . connect ( ( _ ,  args )  =>  { 
3874      if  ( enabled )  { 
3975        const  {  cell,  notebook }  =  args ; 
76+         const  codeCell  =  cell . model . type  ===  'code' ; 
77+         const  nonEmptyCell  =  cell . model . value . text . length  >  0 ; 
4078        const  metadata  =  cell . model . metadata ; 
41-         if  ( metadata . has ( 'execution' ) )  { 
42-           const  executionMetadata  =  Object . assign ( 
43-             { } , 
44-             metadata . get ( 'execution' )  as  any 
45-           ) ; 
46-           const  cellStartTime  =  new  Date ( 
47-             executionMetadata [ 'shell.execute_reply.started' ] 
48-           ) ; 
49-           const  cellEndTime  =  new  Date ( 
50-             executionMetadata [ 'shell.execute_reply' ] 
51-           ) ; 
52-           const  diff  =  new  Date ( < any > cellEndTime  -  < any > cellStartTime ) ; 
53-           if  ( diff . getSeconds ( )  >=  minimumCellExecutionTime )  { 
54-             const  notificationPayload  =  { 
55-               icon : '/static/favicon.ico' , 
56-               body : '' 
57-             } ; 
58-             let  message  =  '' ; 
59-             const  cellDuration  =  diff . toISOString ( ) . substr ( 11 ,  8 ) ; 
60-             const  cellNumber  =  notebook . activeCellIndex ; 
61-             if  ( reportCellNumber  &&  reportCellExecutionTime )  { 
62-               message  =  `Cell[${ cellNumber } ${ cellDuration }  ; 
63-             }  else  if  ( reportCellNumber )  { 
64-               message  =  `Cell Number: ${ cellNumber }  ; 
65-             }  else  if  ( reportCellExecutionTime )  { 
66-               message  =  `Cell Duration: ${ cellDuration }  ; 
79+         if  ( codeCell  &&  nonEmptyCell )  { 
80+           if  ( metadata . has ( 'execution' ) )  { 
81+             const  [ cellStartTime ,  cellEndTime ]  =  extractExecutionMetadata ( 
82+               metadata 
83+             ) ; 
84+             const  diff  =  new  Date ( < any > cellEndTime  -  < any > cellStartTime ) ; 
85+             if  ( diff . getSeconds ( )  >=  minimumCellExecutionTime )  { 
86+               const  cellDuration  =  diff . toISOString ( ) . substr ( 11 ,  8 ) ; 
87+               const  cellNumber  =  notebook . activeCellIndex ; 
88+               displayNotification ( 
89+                 cellDuration , 
90+                 cellNumber , 
91+                 reportCellNumber , 
92+                 reportCellExecutionTime 
93+               ) ; 
6794            } 
68-             notificationPayload . body  =  message ; 
69-             new  Notification ( 'Notebook Cell Completed!' ,  notificationPayload ) ; 
95+           }  else  { 
96+             alert ( 
97+               'Notebook Cell Timing needs to be enabled for Jupyterlab Notifications to work. '  + 
98+                 'Please go to Settings -> Advanced Settings Editor -> Notebook and update setting to {"recordTiming": true}' 
99+             ) ; 
70100          } 
71-         }  else  { 
72-           alert ( 
73-             'Notebook Cell Timing needs to be enabled for Jupyterlab Notifications to work. '  + 
74-               'Please go to Settings -> Advanced Settings Editor -> Notebook and update setting to {"recordTiming": true}' 
75-           ) ; 
76101        } 
77102      } 
78103    } ) ; 
0 commit comments