kopia lustrzana https://github.com/n1ywb/python-hamtools
update fccreferencer to use callook.info
rodzic
3773a15fc6
commit
2b098e0137
|
@ -22,18 +22,18 @@ import logging
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from pkg_resources import resource_stream
|
from pkg_resources import resource_stream
|
||||||
|
|
||||||
import geojson as gj
|
import geojson as gj
|
||||||
|
from hamtools import adif
|
||||||
|
from hamtools.ctydat import CtyDat, InvalidDxcc, InvalidCallsign
|
||||||
|
from hamtools import kml
|
||||||
|
from hamtools import qrz
|
||||||
|
import requests
|
||||||
|
import requests_cache
|
||||||
|
|
||||||
import adif
|
|
||||||
from ctydat import CtyDat, InvalidDxcc, InvalidCallsign
|
|
||||||
import kml
|
|
||||||
import qrz
|
|
||||||
|
|
||||||
log = logging.getLogger('geolog')
|
log = logging.getLogger('geolog')
|
||||||
#log.setLevel(logging.INFO)
|
# log.setLevel(logging.INFO)
|
||||||
|
|
||||||
# 1. Load log
|
# 1. Load log
|
||||||
# 2. Georeference log
|
# 2. Georeference log
|
||||||
|
@ -41,18 +41,24 @@ log = logging.getLogger('geolog')
|
||||||
# 4. Output GeoJSON
|
# 4. Output GeoJSON
|
||||||
|
|
||||||
CABRILLO_FIELDS = ['header', 'freq', 'mode', 'date', 'time',
|
CABRILLO_FIELDS = ['header', 'freq', 'mode', 'date', 'time',
|
||||||
'from_call', 'sent_rst', 'sent_ex', 'call', 'receved_rst',
|
'from_call', 'sent_rst', 'sent_ex', 'call', 'receved_rst',
|
||||||
'received_ex']
|
'received_ex']
|
||||||
|
|
||||||
CACHEPATH = os.path.join(os.environ['HOME'], '.qrz_cache')
|
CACHEPATH = os.path.join(os.environ['HOME'], '.qrz_cache')
|
||||||
|
|
||||||
|
|
||||||
class OperatorGeoRefFail(Exception): pass
|
class OperatorGeoRefFail(Exception): pass
|
||||||
|
|
||||||
|
|
||||||
class GeoRefFail(Exception): pass
|
class GeoRefFail(Exception): pass
|
||||||
|
|
||||||
|
|
||||||
class GeoRefError(Exception): pass
|
class GeoRefError(Exception): pass
|
||||||
|
|
||||||
|
|
||||||
class NullLoc(GeoRefError): pass
|
class NullLoc(GeoRefError): pass
|
||||||
|
|
||||||
|
|
||||||
class NotFound(GeoRefError): pass
|
class NotFound(GeoRefError): pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,17 +97,27 @@ class CtyDatReferencer(object):
|
||||||
return lon, lat
|
return lon, lat
|
||||||
|
|
||||||
|
|
||||||
# from hamtools.ushams import ushams
|
class FCCReferencer(object):
|
||||||
# from hamtools.ziplocs import ziplocs
|
PREFIXES = list('aknw')
|
||||||
#
|
CACHEPATH = os.path.join(os.environ.get('XDG_CACHE_HOME', os.environ['HOME']), '.callook_cache')
|
||||||
# class FCCReferencer(object):
|
requests_cache.install_cache(CACHEPATH)
|
||||||
# def reference(self, callsign):
|
def reference(self, callsign):
|
||||||
# try:
|
if callsign[0].lower() not in self.PREFIXES:
|
||||||
# zip = ushams[callsign][:5]
|
raise NotFound(callsign)
|
||||||
# lat, lon = ziplocs[zip]
|
r = requests.get("https://callook.info/%s/json" % callsign)
|
||||||
# except KeyError:
|
if r.status_code == 404:
|
||||||
# raise NotFound(callsign)
|
raise NotFound(callsign)
|
||||||
# return lon, lat
|
if r.status_code != 200:
|
||||||
|
raise GeoRefError(r.status_code)
|
||||||
|
try:
|
||||||
|
data = r.json()
|
||||||
|
except ValueError:
|
||||||
|
raise GeoRefError('bad json')
|
||||||
|
if data['status'] != 'VALID':
|
||||||
|
raise GeoRefError('invalid')
|
||||||
|
lon = float(data['location']['longitude'])
|
||||||
|
lat = float(data['location']['latitude'])
|
||||||
|
return lon, lat
|
||||||
|
|
||||||
|
|
||||||
class Log(object):
|
class Log(object):
|
||||||
|
@ -134,10 +150,14 @@ class Log(object):
|
||||||
self = Log()
|
self = Log()
|
||||||
log = adif.Reader(logfile)
|
log = adif.Reader(logfile)
|
||||||
for qso in log:
|
for qso in log:
|
||||||
try: del qso['app_datetime_on']
|
try:
|
||||||
except KeyError: pass
|
del qso['app_datetime_on']
|
||||||
try: del qso['app_datetime_off']
|
except KeyError:
|
||||||
except KeyError: pass
|
pass
|
||||||
|
try:
|
||||||
|
del qso['app_datetime_off']
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
self.qsos.append(qso)
|
self.qsos.append(qso)
|
||||||
self.callsign = qso['operator']
|
self.callsign = qso['operator']
|
||||||
return self
|
return self
|
||||||
|
@ -147,14 +167,14 @@ class Log(object):
|
||||||
try:
|
try:
|
||||||
return d.reference(callsign)
|
return d.reference(callsign)
|
||||||
except GeoRefError, e:
|
except GeoRefError, e:
|
||||||
log.warning("%r failed on call %s", d, callsign)
|
log.warning("%r failed on call %s: %s", d, callsign, e)
|
||||||
else:
|
else:
|
||||||
raise GeoRefFail(callsign)
|
raise GeoRefFail(callsign)
|
||||||
|
|
||||||
def georeference(self, sess, ctydat):
|
def georeference(self, sess, ctydat):
|
||||||
drivers = self.drivers = []
|
drivers = self.drivers = []
|
||||||
sess and drivers.append(QrzReferencer(sess))
|
sess and drivers.append(QrzReferencer(sess))
|
||||||
# drivers.append(FCCReferencer())
|
drivers.append(FCCReferencer())
|
||||||
ctydat and drivers.append(CtyDatReferencer(ctydat))
|
ctydat and drivers.append(CtyDatReferencer(ctydat))
|
||||||
|
|
||||||
if not drivers:
|
if not drivers:
|
||||||
|
@ -167,7 +187,7 @@ class Log(object):
|
||||||
|
|
||||||
for qso in self.qsos:
|
for qso in self.qsos:
|
||||||
try:
|
try:
|
||||||
qso['lon'], qso['lat'] = self._georef(qso['call'])
|
qso['lon'], qso['lat'] = self._georef(qso['call'])
|
||||||
except GeoRefFail:
|
except GeoRefFail:
|
||||||
log.warning("Failed to georef call %s", qso['call'])
|
log.warning("Failed to georef call %s", qso['call'])
|
||||||
|
|
||||||
|
@ -221,6 +241,7 @@ class Log(object):
|
||||||
folder.appendChild(callnode)
|
folder.appendChild(callnode)
|
||||||
dom.writepretty(file)
|
dom.writepretty(file)
|
||||||
|
|
||||||
|
|
||||||
def geolog(logfilepath, outfile, username, password, cachepath, ctydatflo):
|
def geolog(logfilepath, outfile, username, password, cachepath, ctydatflo):
|
||||||
with open(logfilepath) as logfile:
|
with open(logfilepath) as logfile:
|
||||||
line = logfile.next()
|
line = logfile.next()
|
||||||
|
@ -260,18 +281,18 @@ def main(argv=None):
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description=
|
description=
|
||||||
"""Read ham log and output GIS data for callsigns worked. Output files will be
|
"""Read ham log and output GIS data for callsigns worked. Output files will be
|
||||||
prefixed with output path. E.g. given "foo/bar", the following files will be
|
prefixed with output path. E.g. given "foo/bar", the following files will be
|
||||||
created: "foo/bar_points.geojson", "foo/bar_lines.geojson", and "foo/bar.kml"
|
created: "foo/bar_points.geojson", "foo/bar_lines.geojson", and "foo/bar.kml"
|
||||||
""")
|
""")
|
||||||
parser.add_argument('infile', type=str,
|
parser.add_argument('infile', type=str,
|
||||||
help='Input log file (ADIF or Cabrillo)')
|
help='Input log file (ADIF or Cabrillo)')
|
||||||
parser.add_argument('outpath', type=str,
|
parser.add_argument('outpath', type=str,
|
||||||
help='Output path prefix')
|
help='Output path prefix')
|
||||||
parser.add_argument('-c', '--cfg', type=str,
|
parser.add_argument('-c', '--cfg', type=str,
|
||||||
help='Config file path', default=os.path.join(os.environ['HOME'], '.geologrc'))
|
help='Config file path', default=os.path.join(os.environ['HOME'], '.geologrc'))
|
||||||
parser.add_argument('-v', '--verbose', type=bool,
|
parser.add_argument('-v', '--verbose', type=bool,
|
||||||
help='Turn on additional output', default=False)
|
help='Turn on additional output', default=False)
|
||||||
args = parser.parse_args(argv[1:])
|
args = parser.parse_args(argv[1:])
|
||||||
|
|
||||||
cfg = ConfigParser.SafeConfigParser()
|
cfg = ConfigParser.SafeConfigParser()
|
||||||
|
@ -313,4 +334,3 @@ created: "foo/bar_points.geojson", "foo/bar_lines.geojson", and "foo/bar.kml"
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,6 @@ class Session(object):
|
||||||
hc = httplib.HTTPConnection("xml.qrz.com")
|
hc = httplib.HTTPConnection("xml.qrz.com")
|
||||||
headers = {"Content-type": "application/x-www-form-urlencoded",
|
headers = {"Content-type": "application/x-www-form-urlencoded",
|
||||||
"Accept": "text/plain"}
|
"Accept": "text/plain"}
|
||||||
|
|
||||||
hc.request("POST", "/xml", urllib.urlencode(params), headers)
|
hc.request("POST", "/xml", urllib.urlencode(params), headers)
|
||||||
resp = hc.getresponse()
|
resp = hc.getresponse()
|
||||||
if resp.status != httplib.OK:
|
if resp.status != httplib.OK:
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -12,7 +12,7 @@ setup(
|
||||||
packages = ['hamtools'],
|
packages = ['hamtools'],
|
||||||
package_data={'hamtools': ['ctydat/cty.dat']},
|
package_data={'hamtools': ['ctydat/cty.dat']},
|
||||||
scripts = ['geolog', 'vk'],
|
scripts = ['geolog', 'vk'],
|
||||||
install_requires = ['geojson'],
|
install_requires = ['geojson', 'requests', 'requests-cache'],
|
||||||
long_description = (
|
long_description = (
|
||||||
"""Collection of amateur radio tools. Includes ability to read ADIF and
|
"""Collection of amateur radio tools. Includes ability to read ADIF and
|
||||||
Cabrillo log files, cty.dat files, georeference callsigns via QRZ.com and
|
Cabrillo log files, cty.dat files, georeference callsigns via QRZ.com and
|
||||||
|
|
Ładowanie…
Reference in New Issue