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"Cell resolver '{resolver}' in "
f"locator '{locator}' not found in config") f"locator '{locator}' not found in config")
if conf.get('method') not in conf['locator'].keys(): 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( raise MissingConfigException(
"Method not defined in config, or it's not in configured locators") f"Method '{method}' is not in configured locators")
conf['methods'] = methods
if isinstance(conf['datadir'], str): if isinstance(conf['datadir'], str):
if conf['datadir'].startswith('~'): if conf['datadir'].startswith('~'):

View File

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

View File

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