if __name__ == "__main__": print("This is a library not an executable.") exit(1) def cleanupXmlName(name): nameOut = "" for c in name: if c in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-_.:;/()[]": nameOut += c else: nameOut += f"&#{ord(c)};" return nameOut def cleanupPathName(name): nameOut = "" for c in name: if c in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-_.": nameOut += c else: nameOut += "_" return nameOut def formatTime(text): if ":" in text: return text t = "" if len(text) >= 2: t += text[0:2] if len(text) >= 4: t += ":" + text[2:4] if len(text) >= 6: t += ":" + text[4:6] else: t += ":00" else: t = "__:__" return t def formatDate(text): if "." in text: return text y = text[0:4] m = int(text[4:6]) d = text[6:8] month = ["___", "Jan", "Feb", "Mar", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] if m < 1 or m > 12: m = 0 return f"{d}.{month[m]}.{y}" class AdiRow: def __init__(self): self.CALL = "" self.Date = "" self.Time = "" self.Band = "" self.MHz = "" self.Mode = "" self.RST = "" def fileName(self, card_name="{_CALL_}_{_Date_}_{_Time_}"): return cleanupPathName(self.fillTemplate(card_name)) def subPath(self): name = cleanupPathName(f"{self.CALL}") if len(name) >= 2: return f"{name[0]}/{name[0:2]}/{name}" if len(name) == 1: return f"{name}/_/{name}" return "_/_/_" def fillTemplate(self, template): template = template.replace("{_CALL_}", cleanupXmlName(self.CALL)) template = template.replace("{_Date_}", cleanupXmlName(self.Date)) template = template.replace("{_Time_}", cleanupXmlName(self.Time)) template = template.replace("{_Band_}", cleanupXmlName(self.Band)) template = template.replace("{_MHz_}", cleanupXmlName(self.MHz)) template = template.replace("{_Mode_}", cleanupXmlName(self.Mode)) template = template.replace("{_RST_}", cleanupXmlName(self.RST)) return template def isValid(self): return self.CALL != "" and self.Date != "" and self.Time != "" def setValue(self, k, v): k = k.upper() if k == "CALL": self.CALL = v elif k == "QSO_DATE": self.Date = formatDate(v) elif k == "TIME_ON": self.Time = formatTime(v) elif k == "BAND": self.Band = v elif k == "FREQ": self.MHz = v elif k == "MODE": self.Mode = v elif k == "RST_SENT": self.RST = v def guessBand(self, freq=None): bands = [ ("160m", 1.8, 2.0) , ( "80m", 3.5, 3.8) , ( "60m", 5.3, 5.4) , ( "40m", 7.0, 7.2) , ( "30m", 10.1, 10.2) , ( "20m", 14.0, 14.5) , ( "17m", 18.0, 18.2) , ( "15m", 21.0, 21.5) , ( "12m", 24.0, 25.0) , ( "10m", 28.0, 29.7) , ( "6m", 50.0, 52.0) , ( "4m", 70.0, 70.3) , ( "2m", 144.0, 146.0) , ("70cm", 430.0, 440.0) ] if self.Band != "": return if freq is None: freq = self.MHz try: freq = float(freq.replace(",",".")) except: return for (name, lower, upper) in bands: if freq >= lower and freq <= upper: self.Band = name return def parseRow(row): state = 0 key = "" value = "" adiRow = AdiRow() while row != "": c = row[0] row = row[1:] if state == 0: if c == '<': state = 1 key = "" else: if c != ">": key += c else: state = 0 pair = key.split(":") if len(pair) != 2: continue key = pair[0] try: size = int(pair[1]) if size < 1 or size > 100: continue value = row[0:size] row = row[(size+1):] adiRow.setValue(key, value) finally: pass if adiRow.isValid(): adiRow.guessBand() return adiRow return None def loadAdi(fileName): adiText = "" with open(fileName) as f: adiText = f.read() adi = adiText.split("") if len(adi) < 2: return None adi = "".join(adi[1:]) data = [] for row in adi.split(""): row = parseRow(row) if row is not None: data.append(row) return data