Support multiple locator methods

This commit is contained in:
Teemu Ikonen
2023-03-10 17:09:06 +02:00
parent 2ff735aeaa
commit 04b48952e9
3 changed files with 57 additions and 44 deletions

View File

@@ -150,9 +150,17 @@ def get_config():
f"Cell resolver '{resolver}' in "
f"locator '{locator}' not found in config")
if conf.get('method') not in conf['locator'].keys():
raise MissingConfigException(
"Method not defined in config, or it's not in configured locators")
methods = ([conf.get('method')] if conf.get('method') is not None
else conf.get('methods'))
if not methods:
raise MissingConfigException("Locator methods not defined in config")
for method in methods:
if method not in conf['locator'].keys():
raise MissingConfigException(
f"Method '{method}' is not in configured locators")
conf['methods'] = methods
if isinstance(conf['datadir'], str):
if conf['datadir'].startswith('~'):

View File

@@ -2,7 +2,7 @@ port = 8088
host = "127.0.0.1"
datadir = "~/.local/share/ols/"
# obsdb = "obsdb.db" # DB file (in datadir) to store all incoming observations
method = "clustering" # Must be a name of a locator subsection
methods = ["clustering"] # Methods are names of locator subsections
debuglevel = "warning" # critical,error,warning,info,debug
logtimestamps = true # Set to false if logging to journald
@@ -14,6 +14,7 @@ logtimestamps = true # Set to false if logging to journald
[locator.clustering]
# Aggregates wifi and cell coordinates and calculates a probable location
type = "clustering"
# Resolvers are resolver subsection names
wifiresolvers = ["wigle"]
cellresolvers = ["wigle"]

View File

@@ -12,7 +12,7 @@ from . import config
from . import obsdb
from . import schemas
locator = None
locators = None
observationdb = None
geolocate_validate = fastjsonschema.compile(schemas.geolocate_v1_schema)
geosubmit_validate = fastjsonschema.compile(schemas.geosubmit_v2_schema)
@@ -25,7 +25,7 @@ async def all_handler(request):
async def locate_handler(request):
global hint
global locator
global locators
global observationdb
notfound_error_res = {
@@ -78,12 +78,15 @@ async def locate_handler(request):
observationdb.insert_locate(data)
try:
async with asyncio.timeout(20):
latlon, accuracy = await locator.locate(data, hint=hint)
except asyncio.TimeoutError:
log.warning('Locator timeout')
latlon, accuracy = None, None
for locator in locators:
try:
async with asyncio.timeout(20):
latlon, accuracy = await locator.locate(data, hint=hint)
except asyncio.TimeoutError:
log.warning('Locator timeout')
latlon, accuracy = None, None
if latlon is not None:
break
if latlon is not None:
hint = latlon
@@ -140,7 +143,7 @@ async def submit_handler(request):
def main():
global locator
global locators
global observationdb
global log
@@ -181,37 +184,38 @@ def main():
log.error(f"Unknown resolver type '{rtype}'")
return None
# FIXME: Add support for multiple locators
method_conf = conf['locator'][conf['method']]
mtype = method_conf.get('type')
if mtype is None:
raise config.MissingConfigException
elif mtype == 'clustering':
from .locator.clustering import ClusteringLocator
wlist = method_conf.get('wifiresolvers', [])
wifiresolvers = [get_resolver(e) for e in wlist]
clist = method_conf.get('cellresolvers', [])
cellresolvers = [get_resolver(e) for e in clist]
locator = ClusteringLocator(wifiresolvers, cellresolvers)
elif mtype == 'strongestcell':
from .locator.single import StrongestCellLocator
clist = method_conf.get('cellresolvers', [])
cellresolvers = [get_resolver(e) for e in clist]
locator = StrongestCellLocator(cellresolvers)
elif mtype == 'strongestwifi':
from .locator.single import StrongestWifiLocator
wlist = method_conf.get('wifiresolvers', [])
wifiresolvers = [get_resolver(e) for e in wlist]
locator = StrongestWifiLocator(wifiresolvers)
elif mtype == 'm8b':
from .locator.m8b import M8BLocator
locator = M8BLocator(os.path.expanduser(method_conf['datafile']))
elif mtype == 'web':
from .locator.web import WebLocator
locator = WebLocator(method_conf['locateurl'], method_conf['apikey'])
else:
raise ValueError(f'Unknown locator type in config: {mtype}')
log.info(f"Using '{mtype}' locator")
locators = []
for method in conf['methods']:
method_conf = conf['locator'][method]
mtype = method_conf.get('type')
if mtype is None:
raise config.MissingConfigException
elif mtype == 'clustering':
from .locator.clustering import ClusteringLocator
wlist = method_conf.get('wifiresolvers', [])
wifiresolvers = [get_resolver(e) for e in wlist]
clist = method_conf.get('cellresolvers', [])
cellresolvers = [get_resolver(e) for e in clist]
locators.append(ClusteringLocator(wifiresolvers, cellresolvers))
elif mtype == 'strongestcell':
from .locator.single import StrongestCellLocator
clist = method_conf.get('cellresolvers', [])
cellresolvers = [get_resolver(e) for e in clist]
locators.append(StrongestCellLocator(cellresolvers))
elif mtype == 'strongestwifi':
from .locator.single import StrongestWifiLocator
wlist = method_conf.get('wifiresolvers', [])
wifiresolvers = [get_resolver(e) for e in wlist]
locators.append(StrongestWifiLocator(wifiresolvers))
elif mtype == 'm8b':
from .locator.m8b import M8BLocator
locators.append(M8BLocator(os.path.expanduser(method_conf['datafile'])))
elif mtype == 'web':
from .locator.web import WebLocator
locators.append(WebLocator(method_conf['locateurl'], method_conf['apikey']))
else:
raise ValueError(f'Unknown locator type in config: {mtype}')
log.info(f"Using '{mtype}' locator")
if conf['obsdb'] is None:
# Use the dummy obsdb class