class Activation: """Class holding information about an activation or a chase Activations contain information about the date and place of activation, callsign used and all qsos. Also a link to the previous activation is stored In a chase multiple qsos can be merged from a single day. """ def __init__(self, string, prev=None): """Initialize the activation from the string At least callsign, date, and sota reference are needed, other information is optional. If a previous activation is given then the callsign and date can be preserved from it, but new sota reference is mandatory. An asterisk instead of sota reference means a chase """ self.previous = prev # start splitting the string into words w, pos, end = find_word(string) # callsign m = call.fullmatch(w) if m: self.callsign = w.upper() w, pos, end = find_word(string, end) elif prev: self.callsign = prev.callsign else: raise LogException( "Error in activation definition, missing callsign", pos) # date m = date_reg.fullmatch(w) if m: try: self.date = date(int(m.group(1)), int(m.group(3)), int(m.group(4))) except ValueError: raise LogException( "Error in activation definition, invalid date format", pos) w, pos, end = find_word(string, end) elif prev: self.date = prev.date else: raise LogException("Error in activation definition, missing date", pos) # sota reference is mandatory m = sota_ref.fullmatch(w) if m: self.ref = w.upper() elif w == '*': self.ref = '' else: raise LogException( "Error in activation definition, invalid SOTA reference detected", pos) notes = string[end:].strip() m = contest.search(notes) if m: self.contest = Contest(m.group(1)) notes = notes[:m.start()] + notes[m.end():] else: self.contest = None self.notes = notes self.qsos = [] # TODO: other information self.wwff = None self.locator = None def add_qso(self, string): """Add a QSO to list of qsos Consider the last qso as the previous one for the new qso """ prev_qso = self.qsos[-1] if self.qsos else None if self.contest: self.qsos.append(QSO(string, prev_qso, self.contest.exchange)) else: self.qsos.append(QSO(string, prev_qso)) def print_qsos(self, format='SOTA_v2', config=None, handle=None, qsl_info=None): if self.previous: self.previous.print_qsos(format, config, handle, qsl_info) # TODO: trace, remove it from final code #print("Processing {} from {} with callsign {}".format( # "chase" if not self.ref else "activation of {}".format(self.ref), # self.date.strftime("%Y-%m-%d"), self.callsign)) # TODO: only SOTA_v2 is understood as of now if format == 'SOTA_v2': sota_line = [ 'v2', self.callsign, self.ref, self.date.strftime("%d/%m/%Y") ] + [''] * 6 for qso in self.qsos: sota_line[4] = '{:02}{:02}'.format(qso.time[0], qso.time[1]) sota_line[5] = qso.freq sota_line[6] = qso.mode sota_line[7] = qso.callsign sota_line[8] = getattr(qso, 'ref', '') sota_line[9] = quote_text(qso.notes) #sota_line[9] = quote_text(' '.join((qso.sent, qso.rcvd, qso.notes))) print(','.join(sota_line), file=handle) # contest format: if a contest was specified for an activation # use the contest rules to determine the output format elif format == 'contest' and self.contest: self.contest.configure(self, config) for qso in self.qsos: self.contest.add_qso(self.callsign, self.date, qso) print(self.contest, file=handle) # qsl status format: # group callsigns by country and add qsl marker: # * - sent, but not confirmed yet # ** - confirmed # an additional config parameter is a dictionary with previous qsl # information elif format == 'qsl': if not qsl_info: qsl_info = qslinfo.QSL() print_stat = True else: print_stat = False qsl_info.add_qsos(self.qsos, self.date) if print_stat: qsl_info.print_stat(handle) else: raise ValueError("Unrecognized output format")
class Activation: """Class holding information about an activation or a chase Activations contain information about the date and place of activation, callsign used and all qsos. Also a link to the previous activation is stored In a chase multiple qsos can be merged from a single day. """ def __init__(self, string, prev=None): """Initialize the activation from the string At least callsign, date, and sota reference are needed, other information is optional. If a previous activation is given then the callsign and date can be preserved from it, but new sota reference is mandatory. An asterisk instead of sota reference means a chase """ self.previous = prev # start splitting the string into words w, pos, end = find_word(string) # callsign m = call.fullmatch(w) if m: self.callsign = w.upper() w, pos, end = find_word(string, end) elif prev: self.callsign = prev.callsign else: raise LogException("Error in activation definition, missing callsign", pos) # date m = date_reg.fullmatch(w) if m: try: self.date = date(int(m.group(1)), int(m.group(3)), int(m.group(4))) except ValueError: raise LogException("Error in activation definition, invalid date format", pos) w, pos, end = find_word(string, end) elif prev: self.date = prev.date else: raise LogException("Error in activation definition, missing date", pos) # sota reference is mandatory m = sota_ref.fullmatch(w) if m: self.ref = w.upper() elif w == '*': self.ref = '' else: raise LogException("Error in activation definition, invalid SOTA reference detected", pos) notes = string[end:].strip() m = contest.search(notes) if m: self.contest = Contest(m.group(1)) notes = notes[:m.start()] + notes[m.end():] else: self.contest = None self.notes = notes self.qsos = [] # TODO: other information self.wwff = None self.locator = None def add_qso(self, string): """Add a QSO to list of qsos Consider the last qso as the previous one for the new qso """ prev_qso = self.qsos[-1] if self.qsos else None if self.contest: self.qsos.append(QSO(string, prev_qso, self.contest.exchange)) else: self.qsos.append(QSO(string, prev_qso)) def print_qsos(self, format='SOTA_v2', config=None, handle=None, qsl_info=None): if self.previous: self.previous.print_qsos(format, config, handle, qsl_info) # TODO: trace, remove it from final code #print("Processing {} from {} with callsign {}".format( # "chase" if not self.ref else "activation of {}".format(self.ref), # self.date.strftime("%Y-%m-%d"), self.callsign)) # TODO: only SOTA_v2 is understood as of now if format == 'SOTA_v2': sota_line = ['v2', self.callsign, self.ref, self.date.strftime("%d/%m/%Y")] + [''] * 6 for qso in self.qsos: sota_line[4] = '{:02}{:02}'.format(qso.time[0], qso.time[1]) sota_line[5] = qso.freq sota_line[6] = qso.mode sota_line[7] = qso.callsign sota_line[8] = getattr(qso, 'ref', '') sota_line[9] = quote_text(qso.notes) #sota_line[9] = quote_text(' '.join((qso.sent, qso.rcvd, qso.notes))) print(','.join(sota_line), file=handle) # contest format: if a contest was specified for an activation # use the contest rules to determine the output format elif format == 'contest' and self.contest: self.contest.configure(self, config) for qso in self.qsos: self.contest.add_qso(self.callsign, self.date, qso) print(self.contest, file=handle) # qsl status format: # group callsigns by country and add qsl marker: # * - sent, but not confirmed yet # ** - confirmed # an additional config parameter is a dictionary with previous qsl # information elif format == 'qsl': if not qsl_info: qsl_info = qslinfo.QSL() print_stat = True else: print_stat = False qsl_info.add_qsos(self.qsos, self.date) if print_stat: qsl_info.print_stat(handle) else: raise ValueError("Unrecognized output format")