[py3] Remove generic_xml driver

This never really caught on, nor got the attention or maintenance it really needed.
I dunno if it even works in py2 for much anymore, but I don't think converting it
to py3 makes any sense.

#495
This commit is contained in:
Dan Smith 2019-02-15 09:47:36 -08:00
parent de220fd5cd
commit 89c85eeeb4
6 changed files with 0 additions and 583 deletions

View File

@ -1,47 +0,0 @@
<!--
CHIRP XML Schema
Copyright 2008 Dan Smith <dsmith@danplanet.com>
-->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:include schemaLocation="chirp_memory.xsd"/>
<xsd:include schemaLocation="chirp_banks.xsd"/>
<xsd:element name="radio" type="radioType"/>
<xsd:complexType name="radioType">
<xsd:sequence>
<xsd:element name="comment" type="xsd:string"
minOccurs="0" maxOccurs="1"/>
<xsd:element name="memories" type="memoryList"
minOccurs="1" maxOccurs="1"/>
<xsd:element name="banks" type="bankList"
minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="version" type="chirpSchemaVersionType"/>
</xsd:complexType>
<xsd:complexType name="memoryList">
<xsd:sequence>
<xsd:element name="memory" type="memoryType"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="bankList">
<xsd:sequence>
<xsd:element name="bank" type="bankType"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name="chirpSchemaVersionType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="[0-9][0-9]*.[0-9][0-9]*.[0-9]{1,4}"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

View File

@ -1,149 +0,0 @@
# Copyright 2008 Dan Smith <dsmith@danplanet.com>
#
# 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 os
import libxml2
import logging
from chirp import chirp_common, errors, xml_ll, platform, directory
LOG = logging.getLogger(__name__)
def validate_doc(doc):
"""Validate the document"""
path = platform.get_platform().find_resource("chirp.xsd")
try:
ctx = libxml2.schemaNewParserCtxt(path)
schema = ctx.schemaParse()
except libxml2.parserError, e:
LOG.error("Unable to load schema: %s" % e)
LOG.error("Path: %s" % path)
raise errors.RadioError("Unable to load schema")
del ctx
errs = []
warnings = []
def _err(msg, *_args):
errs.append("ERROR: %s" % msg)
def _wrn(msg, *_args):
warnings.append("WARNING: %s" % msg)
validctx = schema.schemaNewValidCtxt()
validctx.setValidityErrorHandler(_err, _wrn)
err = validctx.schemaValidateDoc(doc)
for w in warnings:
LOG.warn(w)
if err:
for l in ["--- DOC ---",
doc.serialize(format=1).split("\n"),
"-----------",
errs]:
LOG.error(l)
raise errors.RadioError("Schema error")
def default_banks():
"""Return an empty set of banks"""
banks = []
for i in range(0, 26):
banks.append("Bank-%s" % (chr(ord("A") + i)))
return banks
@directory.register
class XMLRadio(chirp_common.FileBackedRadio, chirp_common.IcomDstarSupport):
"""Generic XML driver"""
VENDOR = "Generic"
MODEL = "XML"
FILE_EXTENSION = "chirp"
def __init__(self, pipe):
chirp_common.FileBackedRadio.__init__(self, None)
self._filename = pipe
if self._filename and os.path.exists(self._filename):
self.doc = libxml2.parseFile(self._filename)
validate_doc(self.doc)
else:
self.doc = libxml2.newDoc("1.0")
radio = self.doc.newChild(None, "radio", None)
radio.newChild(None, "memories", None)
radio.newChild(None, "banks", None)
radio.newProp("version", "0.1.1")
def get_features(self):
rf = chirp_common.RadioFeatures()
rf.has_bank = False
# rf.has_bank_index = True
rf.requires_call_lists = False
rf.has_implicit_calls = False
rf.memory_bounds = (0, 1000)
rf.valid_characters = chirp_common.CHARSET_ASCII
rf.valid_name_length = 999
rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"]
return rf
def load(self, filename=None):
if not self._filename and not filename:
raise errors.RadioError("Need a location to load from")
if filename:
self._filename = filename
self.doc = libxml2.parseFile(self._filename)
validate_doc(self.doc)
def save(self, filename=None):
if not self._filename and not filename:
raise errors.RadioError("Need a location to save to")
if filename:
self._filename = filename
f = file(self._filename, "w")
f.write(self.doc.serialize(format=1))
f.close()
def get_memories(self, lo=0, hi=999):
mems = []
for i in range(lo, hi):
try:
mems.append(xml_ll.get_memory(self.doc, i))
except errors.InvalidMemoryLocation:
pass
return mems
def get_memory(self, number):
mem = xml_ll.get_memory(self.doc, number)
return mem
def set_memory(self, mem):
xml_ll.set_memory(self.doc, mem)
def erase_memory(self, number):
xml_ll.del_memory(self.doc, number)
@classmethod
def match_model(cls, _filedata, filename):
"""Match this driver if the extension matches"""
return filename.lower().endswith("." + cls.FILE_EXTENSION)

View File

@ -1,256 +0,0 @@
# Copyright 2008 Dan Smith <dsmith@danplanet.com>
#
# 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 re
from chirp import chirp_common, errors
def get_memory(doc, number):
"""Extract a Memory object from @doc"""
ctx = doc.xpathNewContext()
base = "//radio/memories/memory[@location=%i]" % number
fields = ctx.xpathEval(base)
if len(fields) > 1:
raise errors.RadioError("%i memories claiming to be %i" % (len(fields),
number))
elif len(fields) == 0:
raise errors.InvalidMemoryLocation("%i does not exist" % number)
memnode = fields[0]
def _get(ext):
path = base + ext
result = ctx.xpathEval(path)
if result:
return result[0].getContent()
else:
return ""
if _get("/mode/text()") == "DV":
mem = chirp_common.DVMemory()
mem.dv_urcall = _get("/dv/urcall/text()")
mem.dv_rpt1call = _get("/dv/rpt1call/text()")
mem.dv_rpt2call = _get("/dv/rpt2call/text()")
try:
mem.dv_code = _get("/dv/digitalCode/text()")
except ValueError:
mem.dv_code = 0
else:
mem = chirp_common.Memory()
mem.number = int(memnode.prop("location"))
mem.name = _get("/longName/text()")
mem.freq = chirp_common.parse_freq(_get("/frequency/text()"))
mem.rtone = float(_get("/squelch[@id='rtone']/tone/text()"))
mem.ctone = float(_get("/squelch[@id='ctone']/tone/text()"))
mem.dtcs = int(_get("/squelch[@id='dtcs']/code/text()"), 10)
mem.dtcs_polarity = _get("/squelch[@id='dtcs']/polarity/text()")
try:
sql = _get("/squelchSetting/text()")
if sql == "rtone":
mem.tmode = "Tone"
elif sql == "ctone":
mem.tmode = "TSQL"
elif sql == "dtcs":
mem.tmode = "DTCS"
else:
mem.tmode = ""
except IndexError:
mem.tmode = ""
dmap = {"positive": "+", "negative": "-", "none": ""}
dupx = _get("/duplex/text()")
mem.duplex = dmap.get(dupx, "")
mem.offset = chirp_common.parse_freq(_get("/offset/text()"))
mem.mode = _get("/mode/text()")
mem.tuning_step = float(_get("/tuningStep/text()"))
skip = _get("/skip/text()")
if skip == "none":
mem.skip = ""
else:
mem.skip = skip
# FIXME: bank support in .chirp files needs to be re-written
# bank_id = _get("/bank/@bankId")
# if bank_id:
# mem.bank = int(bank_id)
# bank_index = _get("/bank/@bankIndex")
# if bank_index:
# mem.bank_index = int(bank_index)
return mem
def set_memory(doc, mem):
"""Set @mem in @doc"""
ctx = doc.xpathNewContext()
base = "//radio/memories/memory[@location=%i]" % mem.number
fields = ctx.xpathEval(base)
if len(fields) > 1:
raise errors.RadioError("%i memories claiming to be %i" % (len(fields),
mem.number))
elif len(fields) == 1:
fields[0].unlinkNode()
radio = ctx.xpathEval("//radio/memories")[0]
memnode = radio.newChild(None, "memory", None)
memnode.newProp("location", "%i" % mem.number)
sname_filter = "[^A-Z0-9/ >-]"
sname = memnode.newChild(None, "shortName", None)
sname.addContent(re.sub(sname_filter, "", mem.name.upper()[:6]))
lname_filter = "[^.A-Za-z0-9/ >-]"
lname = memnode.newChild(None, "longName", None)
lname.addContent(re.sub(lname_filter, "", mem.name[:16]))
freq = memnode.newChild(None, "frequency", None)
freq.newProp("units", "MHz")
freq.addContent(chirp_common.format_freq(mem.freq))
rtone = memnode.newChild(None, "squelch", None)
rtone.newProp("id", "rtone")
rtone.newProp("type", "repeater")
tone = rtone.newChild(None, "tone", None)
tone.addContent("%.1f" % mem.rtone)
ctone = memnode.newChild(None, "squelch", None)
ctone.newProp("id", "ctone")
ctone.newProp("type", "ctcss")
tone = ctone.newChild(None, "tone", None)
tone.addContent("%.1f" % mem.ctone)
dtcs = memnode.newChild(None, "squelch", None)
dtcs.newProp("id", "dtcs")
dtcs.newProp("type", "dtcs")
code = dtcs.newChild(None, "code", None)
code.addContent("%03i" % mem.dtcs)
polr = dtcs.newChild(None, "polarity", None)
polr.addContent(mem.dtcs_polarity)
sset = memnode.newChild(None, "squelchSetting", None)
if mem.tmode == "Tone":
sset.addContent("rtone")
elif mem.tmode == "TSQL":
sset.addContent("ctone")
elif mem.tmode == "DTCS":
sset.addContent("dtcs")
dmap = {"+": "positive", "-": "negative", "": "none"}
dupx = memnode.newChild(None, "duplex", None)
dupx.addContent(dmap[mem.duplex])
oset = memnode.newChild(None, "offset", None)
oset.newProp("units", "MHz")
oset.addContent(chirp_common.format_freq(mem.offset))
mode = memnode.newChild(None, "mode", None)
mode.addContent(mem.mode)
step = memnode.newChild(None, "tuningStep", None)
step.newProp("units", "kHz")
step.addContent("%.5f" % mem.tuning_step)
if mem.skip:
skip = memnode.newChild(None, "skip", None)
skip.addContent(mem.skip)
# FIXME: .chirp bank support needs to be redone
# if mem.bank is not None:
# bank = memnode.newChild(None, "bank", None)
# bank.newProp("bankId", str(int(mem.bank)))
# if mem.bank_index >= 0:
# bank.newProp("bankIndex", str(int(mem.bank_index)))
if isinstance(mem, chirp_common.DVMemory):
dv = memnode.newChild(None, "dv", None)
ur = dv.newChild(None, "urcall", None)
ur.addContent(mem.dv_urcall)
r1 = dv.newChild(None, "rpt1call", None)
if mem.dv_rpt1call and mem.dv_rpt1call != "*NOTUSE*":
r1.addContent(mem.dv_rpt1call)
r2 = dv.newChild(None, "rpt2call", None)
if mem.dv_rpt2call and mem.dv_rpt2call != "*NOTUSE*":
r2.addContent(mem.dv_rpt2call)
dc = dv.newChild(None, "digitalCode", None)
dc.addContent(str(mem.dv_code))
def del_memory(doc, number):
"""Remove memory @number from @doc"""
path = "//radio/memories/memory[@location=%i]" % number
ctx = doc.xpathNewContext()
fields = ctx.xpathEval(path)
for field in fields:
field.unlinkNode()
def _get_bank(node):
bank = chirp_common.Bank(node.prop("label"))
ident = int(node.prop("id"))
return ident, bank
def get_banks(doc):
"""Return a list of banks from @doc"""
path = "//radio/banks/bank"
ctx = doc.xpathNewContext()
fields = ctx.xpathEval(path)
banks = []
for field in fields:
banks.append(_get_bank(field))
def _cmp(itema, itemb):
return itema[0] - itemb[0]
banks.sort(cmp=_cmp)
return [x[1] for x in banks]
def set_banks(doc, banklist):
"""Set the list of banks in @doc"""
path = "//radio/banks/bank"
ctx = doc.xpathNewContext()
fields = ctx.xpathEval(path)
for field in fields:
field.unlinkNode()
path = "//radio/banks"
ctx = doc.xpathNewContext()
banks = ctx.xpathEval(path)[0]
i = 0
for bank in banklist:
banknode = banks.newChild(None, "bank", None)
banknode.newProp("id", "%i" % i)
banknode.newProp("label", "%s" % bank)
i += 1

View File

@ -1,8 +0,0 @@
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="bankType">
<xsd:attribute name="id" type="xsd:nonNegativeInteger" use="required"/>
<xsd:attribute name="label" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:schema>

View File

@ -1,121 +0,0 @@
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="memoryType">
<xsd:sequence>
<xsd:element name="shortName" type="shortNameType"/>
<xsd:element name="longName" type="longNameType" minOccurs="0"/>
<xsd:element name="frequency" type="frequencyType"/>
<xsd:element name="squelch" type="squelchType"
minOccurs="0" maxOccurs="3"/>
<xsd:element name="squelchSetting" type="xsd:string" minOccurs="0"/>
<xsd:element name="duplex" type="duplexType"/>
<xsd:element name="offset" type="frequencyType"/>
<xsd:element name="mode" type="modeType"/>
<xsd:element name="tuningStep" type="frequencyType"/>
<xsd:element name="skip" type="skipType" minOccurs="0" maxOccurs="1"/>
<xsd:element name="bank" type="bankInfoType" minOccurs="0" maxOccurs="1"/>
<xsd:element name="dv" type="dvType" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="location" type="xsd:nonNegativeInteger"/>
</xsd:complexType>
<xsd:simpleType name="shortNameType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="[A-Z0-9/ >-]{0,6}"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="frequencyType">
<xsd:simpleContent>
<xsd:extension base="xsd:decimal">
<xsd:attribute name="units" type="freqUnitsType" use="required"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:simpleType name="freqUnitsType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Hz"/>
<xsd:enumeration value="kHz"/>
<xsd:enumeration value="MHz"/>
<xsd:enumeration value="GHz"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="longNameType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="[.A-Za-z0-9/ >-]{0,16}"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="squelchType">
<xsd:sequence>
<xsd:element name="tone" type="xsd:decimal" minOccurs="0"/>
<xsd:element name="code" type="xsd:positiveInteger" minOccurs="0"/>
<xsd:element name="polarity" type="dtcsPolarityType" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="id"/>
<xsd:attribute name="type"/>
</xsd:complexType>
<xsd:simpleType name="dtcsPolarityType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="[RN]{2}"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="duplexType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="positive"/>
<xsd:enumeration value="negative"/>
<xsd:enumeration value="none"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="modeType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="FM"/>
<xsd:enumeration value="NFM"/>
<xsd:enumeration value="WFM"/>
<xsd:enumeration value="AM"/>
<xsd:enumeration value="NAM"/>
<xsd:enumeration value="DV"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="dvType">
<xsd:sequence>
<xsd:element name="urcall" type="callsignType"/>
<xsd:element name="rpt1call" type="callsignType"/>
<xsd:element name="rpt2call" type="callsignType"/>
<xsd:element name="digitalCode" type="digitalCodeType" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name="callsignType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="[A-Z0-9/ ]*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="digitalCodeType">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="0"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="skipType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="S"/>
<xsd:enumeration value="P"/>
<xsd:enumeration value=""/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="bankInfoType">
<xsd:attribute name="bankId" type="xsd:nonNegativeInteger" use="required"/>
<xsd:attribute name="bankIndex" type="xsd:nonNegativeInteger"/>
</xsd:complexType>
</xsd:schema>

View File

@ -31,7 +31,6 @@
./chirp/drivers/ftm350.py
./chirp/drivers/generic_csv.py
./chirp/drivers/generic_tpe.py
./chirp/drivers/generic_xml.py
./chirp/drivers/h777.py
./chirp/drivers/ic208.py
./chirp/drivers/ic2100.py
@ -121,7 +120,6 @@
./chirp/ui/settingsedit.py
./chirp/ui/shiftdialog.py
./chirp/util.py
./chirp/xml_ll.py
./chirpc
./chirpw
./locale/check_parameters.py