# HG changeset patch # User Tom Hayward tom@tomh.us # Date 1360442666 28800 # Node ID 19cf8d11442dd5799a3d6759c8a544e6996e954f # Parent 26774d27b348c139a013114d3588173617d3ad1d Add support for Kenwood .itm files. #535
diff -r 26774d27b348 -r 19cf8d11442d chirp/kenwood_itm.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/chirp/kenwood_itm.py Sat Feb 09 12:44:26 2013 -0800 @@ -0,0 +1,130 @@ +# Copyright 2008 Dan Smith dsmith@danplanet.com +# Copyright 2012 Tom Hayward tom@tomh.us +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. + +import csv + +from chirp import chirp_common, errors, directory, generic_csv + +class OmittedHeaderError(Exception): + """An internal exception to indicate that a header was omitted""" + pass + +@directory.register +class ITMRadio(generic_csv.CSVRadio): + """Kenwood ITM format""" + VENDOR = "Kenwood" + MODEL = "ITM" + FILE_EXTENSION = "itm" + + ATTR_MAP = { + "CH" : (int, "number"), + "RXF" : (chirp_common.parse_freq, "freq"), + "NAME" : (str, "name"), + } + + def _clean_duplex(self, headers, line, mem): + try: + txfreq = chirp_common.parse_freq( + generic_csv.get_datum_by_header(headers, line, "TXF")) + except ValueError: + mem.duplex = "off" + return mem + + if mem.freq == txfreq: + mem.duplex = "" + elif txfreq: + mem.duplex = "split" + mem.offset = txfreq + + return mem + + def _clean_number(self, headers, line, mem): + zone = int(generic_csv.get_datum_by_header(headers, line, "ZN")) + mem.number = zone * 100 + mem.number + return mem + + def _clean_tmode(self, headers, line, mem): + rtone = eval(generic_csv.get_datum_by_header(headers, line, "TXSIG")) + ctone = eval(generic_csv.get_datum_by_header(headers, line, "RXSIG")) + + if rtone: + mem.tmode = "Tone" + if ctone: + mem.tmode = "TSQL" + + mem.rtone = rtone or 88.5 + mem.ctone = ctone or mem.rtone + + return mem + + def load(self, filename=None): + if filename is None and self._filename is None: + raise errors.RadioError("Need a location to load from") + + if filename: + self._filename = filename + + self._blank() + + f = file(self._filename, "r") + for line in f: + if line.strip() == "// Conventional Data": + break + + reader = csv.reader(f, delimiter=chirp_common.SEPCHAR, quotechar='"') + + good = 0 + lineno = 0 + for line in reader: + lineno += 1 + if lineno == 1: + header = line + continue + + if len(line) == 0: + # End of channel data + break + + if len(header) > len(line): + print "Line %i has %i columns, expected %i" % (lineno, + len(line), + len(header)) + self.errors.append("Column number mismatch on line %i" % lineno) + continue + + # fix EU decimal + line = [i.replace(',','.') for i in line] + + try: + mem = self._parse_csv_data_line(header, line) + if mem.number is None: + raise Exception("Invalid Location field" % lineno) + except Exception, e: + print "Line %i: %s" % (lineno, e) + self.errors.append("Line %i: %s" % (lineno, e)) + continue + + self._grow(mem.number) + self.memories[mem.number] = mem + good += 1 + + if not good: + print self.errors + raise errors.InvalidDataError("No channels found") + + @classmethod + def match_model(cls, filedata, filename): + return filename.lower().endswith("." + cls.FILE_EXTENSION) diff -r 26774d27b348 -r 19cf8d11442d chirpui/mainapp.py --- a/chirpui/mainapp.py Sat Feb 09 12:04:10 2013 -0800 +++ b/chirpui/mainapp.py Sat Feb 09 12:44:26 2013 -0800 @@ -718,6 +718,7 @@ (_("EVE Files (VX5)") + " (*.eve)", "*.eve"), (_("ICF Files") + " (*.icf)", "*.icf"), (_("Kenwood HMK Files") + " (*.hmk)", "*.hmk"), + (_("Kenwood ITM Files") + " (*.itm)", "*.itm"), (_("Travel Plus Files") + " (*.tpe)", "*.tpe"), (_("VX5 Commander Files") + " (*.vx5)", "*.vx5"), (_("VX6 Commander Files") + " (*.vx6)", "*.vx6"),