19
19
20
20
# noinspection PyAttributeOutsideInit
21
21
class Nse :
22
+ version : str = '3.7'
23
+
22
24
def __init__ (self , window : Tk ) -> None :
23
25
self .intervals : List [int ] = [1 , 2 , 3 , 5 , 10 , 15 ]
24
26
self .stdout : TextIO = sys .stdout
@@ -55,6 +57,31 @@ def get_icon_path() -> str:
55
57
base_path = os .path .abspath ("." )
56
58
return os .path .join (base_path , 'nse_logo.ico' )
57
59
60
+ def check_for_updates (self , auto : bool = True ) -> None :
61
+ release_data : requests .Response = requests .get (
62
+ "https://api.github.com/repos/VarunS2002/Python-NSE-Option-Chain-Analyzer/releases/latest" )
63
+ latest_version : str = release_data .json ()['tag_name' ]
64
+
65
+ if float (latest_version ) > float (Nse .version ):
66
+ self .info .attributes ('-topmost' , False ) if not auto else None
67
+ update : bool = messagebox .askyesno (
68
+ title = "New Update Available" ,
69
+ message = f"You are running version: { Nse .version } \n "
70
+ f"Latest version: { latest_version } \n "
71
+ f"Do you want to update now ?\n "
72
+ f"{ 'You can disable auto check for updates from the menu.' if auto and self .update else '' } " )
73
+ if update :
74
+ webbrowser .open_new ("https://github.com/VarunS2002/Python-NSE-Option-Chain-Analyzer/releases/latest" )
75
+ self .info .attributes ('-topmost' , False ) if not auto else None
76
+ else :
77
+ self .info .attributes ('-topmost' , True ) if not auto else None
78
+ else :
79
+ if not auto :
80
+ self .info .attributes ('-topmost' , False )
81
+ messagebox .showinfo (title = "No Updates Available" , message = f"You are running the latest version.\n "
82
+ f"Version: { Nse .version } " )
83
+ self .info .attributes ('-topmost' , True )
84
+
58
85
def create_config (self , corrupted : bool = False ) -> None :
59
86
if corrupted :
60
87
os .remove ('NSE-OCA.ini' )
@@ -67,6 +94,7 @@ def create_config(self, corrupted: bool = False) -> None:
67
94
self .config_parser .set ('main' , 'live_export' , 'False' )
68
95
self .config_parser .set ('main' , 'notifications' , 'False' )
69
96
self .config_parser .set ('main' , 'auto_stop' , 'False' )
97
+ self .config_parser .set ('main' , 'update' , 'True' )
70
98
self .config_parser .set ('main' , 'logging' , 'False' )
71
99
72
100
with open ('NSE-OCA.ini' , 'w' ) as f :
@@ -80,6 +108,7 @@ def get_config(self) -> None:
80
108
self .live_export : bool = self .config_parser .getboolean ('main' , 'live_export' )
81
109
self .notifications : bool = self .config_parser .getboolean ('main' , 'notifications' )
82
110
self .auto_stop : bool = self .config_parser .getboolean ('main' , 'auto_stop' )
111
+ self .update : bool = self .config_parser .getboolean ('main' , 'update' )
83
112
self .logging : bool = self .config_parser .getboolean ('main' , 'logging' )
84
113
except (configparser .NoOptionError , configparser .NoSectionError , configparser .MissingSectionHeaderError ,
85
114
configparser .DuplicateSectionError , configparser .DuplicateOptionError ) as err :
@@ -386,6 +415,23 @@ def toggle_auto_stop(self, event: Optional[Event] = None) -> None:
386
415
with open ('NSE-OCA.ini' , 'w' ) as f :
387
416
self .config_parser .write (f )
388
417
418
+ # noinspection PyUnusedLocal
419
+ def toggle_updates (self , event : Optional [Event ] = None ) -> None :
420
+ if self .update :
421
+ self .update = False
422
+ self .options .entryconfig (self .options .index (6 ), label = "Auto Check for Updates: Off" )
423
+ messagebox .showinfo (title = "Auto Checking for Updates Disabled" ,
424
+ message = "Program will not check for updates at start." )
425
+ else :
426
+ self .update = True
427
+ self .options .entryconfig (self .options .index (6 ), label = "Auto Check for Updates: On" )
428
+ messagebox .showinfo (title = "Auto Checking for Updates Enabled" ,
429
+ message = "Program will check for updates at start." )
430
+
431
+ self .config_parser .set ('main' , 'update' , f'{ self .update } ' )
432
+ with open ('NSE-OCA.ini' , 'w' ) as f :
433
+ self .config_parser .write (f )
434
+
389
435
# noinspection PyUnusedLocal
390
436
def log (self , event : Optional [Event ] = None ) -> None :
391
437
if self .first_run and self .logging or not self .logging :
@@ -402,7 +448,7 @@ def log(self, event: Optional[Event] = None) -> None:
402
448
print ('.py version' )
403
449
404
450
try :
405
- self .options .entryconfig (self .options .index (6 ), label = "Debug Logging: On" )
451
+ self .options .entryconfig (self .options .index (7 ), label = "Debug Logging: On" )
406
452
messagebox .showinfo (title = "Debug Logging Enabled" ,
407
453
message = "Errors will be logged to NSE-OCA.log." )
408
454
except AttributeError :
@@ -413,7 +459,7 @@ def log(self, event: Optional[Event] = None) -> None:
413
459
sys .stderr = self .stderr
414
460
streamtologger ._is_redirected = False
415
461
self .logging = False
416
- self .options .entryconfig (self .options .index (6 ), label = "Debug Logging: Off" )
462
+ self .options .entryconfig (self .options .index (7 ), label = "Debug Logging: Off" )
417
463
messagebox .showinfo (title = "Debug Logging Disabled" , message = "Errors will not be logged." )
418
464
419
465
self .config_parser .set ('main' , 'logging' , f'{ self .logging } ' )
@@ -468,7 +514,7 @@ def about(self, event: Optional[Event] = None) -> None:
468
514
heading .grid (row = 0 , column = 0 , columnspan = 2 , sticky = N + S + W + E )
469
515
version_label : Label = Label (self .info , text = "Version:" , relief = RIDGE )
470
516
version_label .grid (row = 1 , column = 0 , sticky = N + S + W + E )
471
- version_val : Label = Label (self .info , text = "3.7 " , relief = RIDGE )
517
+ version_val : Label = Label (self .info , text = f" { Nse . version } " , relief = RIDGE )
472
518
version_val .grid (row = 1 , column = 1 , sticky = N + S + W + E )
473
519
dev_label : Label = Label (self .info , text = "Developer:" , relief = RIDGE )
474
520
dev_label .grid (row = 2 , column = 0 , sticky = N + S + W + E )
@@ -487,7 +533,9 @@ def about(self, event: Optional[Event] = None) -> None:
487
533
sources : Label = Label (self .info , text = "Sources" , fg = "blue" , cursor = "hand2" , relief = RIDGE )
488
534
sources .bind ("<Button-1>" , lambda click , link = "sources" : self .links (link , click ))
489
535
sources .grid (row = 4 , column = 1 , sticky = N + S + W + E )
490
-
536
+ updates : Button = Button (self .info , text = "Check for Updates" ,
537
+ command = lambda auto = False : self .check_for_updates (auto ))
538
+ updates .grid (row = 5 , column = 0 , columnspan = 2 , sticky = N + S + W + E )
491
539
self .info .mainloop ()
492
540
493
541
# noinspection PyUnusedLocal
@@ -528,6 +576,8 @@ def main_win(self) -> None:
528
576
self .options .add_command (label = f"Stop automatically at 3:30pm: { 'On' if self .auto_stop else 'Off' } " ,
529
577
accelerator = "(Ctrl+K)" , command = self .toggle_auto_stop )
530
578
self .options .add_separator ()
579
+ self .options .add_command (label = f"Auto Check for Updates: { 'On' if self .update else 'Off' } " ,
580
+ accelerator = "(Ctrl+U)" , command = self .toggle_updates )
531
581
self .options .add_command (label = f"Debug Logging: { 'On' if self .logging else 'Off' } " , accelerator = "(Ctrl+L)" ,
532
582
command = self .log )
533
583
self .options .add_command (label = "About" , accelerator = "(Ctrl+M)" , command = self .about )
@@ -540,6 +590,7 @@ def main_win(self) -> None:
540
590
self .root .bind ('<Control-b>' , self .toggle_live_export )
541
591
self .root .bind ('<Control-n>' , self .toggle_notifications )
542
592
self .root .bind ('<Control-k>' , self .toggle_auto_stop )
593
+ self .root .bind ('<Control-u>' , self .toggle_updates )
543
594
self .root .bind ('<Control-l>' , self .log )
544
595
self .root .bind ('<Control-m>' , self .about )
545
596
self .root .bind ('<Control-q>' , self .close )
@@ -1094,6 +1145,8 @@ def main(self) -> None:
1094
1145
self .set_values ()
1095
1146
1096
1147
if self .first_run :
1148
+ if self .update :
1149
+ self .check_for_updates ()
1097
1150
self .first_run = False
1098
1151
if self .str_current_time == '15:30:00' and not self .stop and self .auto_stop :
1099
1152
self .stop = True
0 commit comments