44
55import os
66import re
7+ import sys
78import json
89from copy import deepcopy
910import datetime
@@ -27,15 +28,25 @@ def __read_json__(file) -> list:
2728MODES = __read_json__ ('data/modes.json' )
2829
2930
31+ def get_cur_adif_dt () -> tuple [str , str ]:
32+ """Get current date in ADIF format independant of Python version"""
33+ if sys .version_info [0 ] == 3 and sys .version_info [1 ] < 11 :
34+ # noinspection PyDeprecation
35+ dt = datetime .datetime .utcnow ()
36+ else :
37+ dt = datetime .datetime .now (datetime .UTC )
38+ return dt .strftime ('%Y%m%d' ), dt .strftime ('%H%M' )
39+
40+
3041def adif_date2iso (date : str ) -> str | None :
3142 if not date or len (date ) != 8 :
32- return
43+ return None
3344 return date [:4 ] + '-' + date [4 :6 ] + '-' + date [6 :8 ]
3445
3546
3647def adif_time2iso (time : str ) -> str | None :
3748 if not time or len (time ) != 4 :
38- return
49+ return None
3950 return time [:2 ] + ':' + time [2 :4 ]
4051
4152
@@ -95,7 +106,7 @@ class CassiopeiaConsole:
95106
96107 def __init__ (self , my_call : str = '' , my_loc : str = '' , my_name : str = '' ,
97108 event : str = '' , event_ref : int = 1 ,
98- init_qso : dict [str , str ] = None , init_worked : dict [str , tuple [str , str ]] = None ):
109+ init_qso : dict [str , str ] = None , init_worked : dict [str , tuple [str , str ]] = None , online = False ):
99110 logger .debug ('Initialising...' )
100111 if my_call and not self .check_format (self .REGEX_CALL , my_call ):
101112 raise Exception ('Wrong call format' )
@@ -121,10 +132,16 @@ def __init__(self, my_call: str = '', my_loc: str = '', my_name: str = '',
121132 self .__my_name__ = my_name
122133
123134 self .__qsos__ : list [dict ] = []
135+ self .__online__ = online
124136
125137 # Mandatory
126- self .__date__ = init_qso .get ('QSO_DATE' , datetime .datetime .utcnow ().strftime ('%Y%m%d' ))
127- self .__time__ = init_qso .get ('TIME_ON' , datetime .datetime .utcnow ().strftime ('%H%M' ))
138+ date , time = get_cur_adif_dt ()
139+ self .__date__ = init_qso .get ('QSO_DATE' , date )
140+ self .__time__ = init_qso .get ('TIME_ON' , time )
141+ if self .__online__ :
142+ self .__date__ += '*'
143+ self .__time__ += '*'
144+
128145 self .__band__ = init_qso .get ('BAND' , '' )
129146 self .__mode__ = init_qso .get ('MODE' , '' )
130147
@@ -153,9 +170,12 @@ def __init__(self, my_call: str = '', my_loc: str = '', my_name: str = '',
153170 self .__qso_active__ = False
154171 self .clear ()
155172
156- def is_sig (self ):
173+ def is_sig (self ) -> bool :
157174 return self .__event__ in ('POTA' , 'SOTA' )
158175
176+ def is_online (self ) -> bool :
177+ return self .__online__
178+
159179 def append_char (self , char : str ) -> str :
160180 """Append a single char to the sequence stack
161181 If a backspace \\ b is appended, and it is possible to delete from the end of the sequence a \\ b will be returned
@@ -215,6 +235,8 @@ def check_qth(self, qth_loc: str) -> None | tuple:
215235 m = re .fullmatch (self .REGEX_QTH , qth_loc .strip ())
216236 if m :
217237 return m .groups ()[:2 ]
238+ else :
239+ return None
218240
219241 def clear (self ):
220242 """Clear current QSO (input cache)"""
@@ -223,6 +245,11 @@ def clear(self):
223245 self .__qso_active__ = False
224246 self .__long_mode__ = False
225247
248+ if self .__online__ :
249+ date , time = get_cur_adif_dt ()
250+ self .__date__ = date + '*'
251+ self .__time__ = time + '*'
252+
226253 # Mandatory
227254 self .__cur_qso__ = {'STATION_CALLSIGN' : self .__my_call__ ,
228255 'MY_GRIDSQUARE' : self .__my_loc__ ,
@@ -324,6 +351,12 @@ def finalize_qso(self) -> str:
324351 else :
325352 res = 'Warning: Callsign missing for last QSO'
326353
354+ date , time = get_cur_adif_dt ()
355+ if '*' in qso ['QSO_DATE' ]:
356+ qso ['QSO_DATE' ] = date
357+ if '*' in qso ['TIME_ON' ]:
358+ qso ['TIME_ON' ] = time
359+
327360 if self .__edit_pos__ == - 1 :
328361 self .__qsos__ .append (qso )
329362 if qso ["CALL" ]:
@@ -534,6 +567,8 @@ def evaluate_extended(self, seq: str) -> str:
534567 return ''
535568 self .__my_name__ = seq [2 :].replace ('_' , ' ' )
536569 self .__cur_qso__ ['MY_NAME' ] = self .__my_name__
570+ elif seq == '-o' :
571+ return self .set_online (not self .is_online ())
537572 elif seq .startswith ('-N' ): # Start contest qso ID
538573 if self .__event__ :
539574 self .evaluate_own_event_ref (seq )
@@ -545,6 +580,18 @@ def evaluate_extended(self, seq: str) -> str:
545580 return 'Error: Unknown prefix'
546581 return ''
547582
583+ def set_online (self , state : bool = True ) -> str :
584+ self .__online__ = state
585+ date , time = get_cur_adif_dt ()
586+ self .__date__ = date
587+ self .__time__ = time
588+ if self .__online__ :
589+ self .__date__ += '*'
590+ self .__time__ += '*'
591+ self .__cur_qso__ ['QSO_DATE' ] = self .__date__
592+ self .__cur_qso__ ['TIME_ON' ] = self .__time__
593+ return 'Online mode' if self .is_online () else 'Offline mode'
594+
548595 def evaluate_locator (self , seq : str ) -> str :
549596 if seq == '' :
550597 self .__cur_qso__ .pop ('GRIDSQUARE' , '' )
@@ -631,8 +678,9 @@ def evaluate(self, seq: str) -> str:
631678 else :
632679 self .__cur_qso__ ['QSL_RCVD' ] = 'Y'
633680 elif seq == '=' : # Sync date/time to now
634- self .__date__ = datetime .datetime .utcnow ().strftime ('%Y%m%d' )
635- self .__time__ = datetime .datetime .utcnow ().strftime ('%H%M' )
681+ date , time = get_cur_adif_dt ()
682+ self .__date__ = date
683+ self .__time__ = time
636684 self .__cur_qso__ ['QSO_DATE' ] = self .__date__
637685 self .__cur_qso__ ['TIME_ON' ] = self .__time__
638686 elif seq [0 ] == '-' : # different extended infos and commands
0 commit comments