1
0
mirror of https://github.com/EDCD/EDMarketConnector.git synced 2025-04-13 07:47:14 +03:00

CAPI: Use CAPI-Live-<endpoint> game_version for market & shipyard

This commit is contained in:
Athanasius 2022-12-01 15:30:46 +00:00
parent 4b31b67042
commit b40d3b889f
No known key found for this signature in database
GPG Key ID: 772697E181BB2767
3 changed files with 84 additions and 28 deletions

View File

@ -1172,6 +1172,7 @@ class AppWindow(object):
monitor.state['Loan'] = capi_response.capi_data['commander'].get('debt', 0) monitor.state['Loan'] = capi_response.capi_data['commander'].get('debt', 0)
# stuff we can do when not docked # stuff we can do when not docked
# TODO: Use plug.notify_capi_legacy if Legacy host
err = plug.notify_newdata(capi_response.capi_data, monitor.is_beta) err = plug.notify_newdata(capi_response.capi_data, monitor.is_beta)
self.status['text'] = err and err or '' self.status['text'] = err and err or ''
if err: if err:

View File

@ -66,24 +66,29 @@ class CAPIData(UserDict):
def __init__( def __init__(
self, self,
data: Union[str, Dict[str, Any], 'CAPIData', None] = None, source_endpoint: str = None data: Union[str, Dict[str, Any], 'CAPIData', None] = None,
source_host: str = None,
source_endpoint: str = None
) -> None: ) -> None:
if data is None: if data is None:
super().__init__() super().__init__()
elif isinstance(data, str): elif isinstance(data, str):
super().__init__(json.loads(data)) super().__init__(json.loads(data))
else: else:
super().__init__(data) super().__init__(data)
self.original_data = self.data.copy() # Just in case self.original_data = self.data.copy() # Just in case
self.source_host = source_host
self.source_endpoint = source_endpoint self.source_endpoint = source_endpoint
if source_endpoint is None: if source_endpoint is None:
return return
if source_endpoint == Session.FRONTIER_CAPI_PATH_SHIPYARD and self.data.get('lastStarport'): if source_endpoint == Session.FRONTIER_CAPI_PATH_SHIPYARD and self.data.get('lastStarport'):
# All the other endpoints may or may not have a lastStarport, but definitely wont have valid data # All the other endpoints may or may not have a lastStarport, but definitely won't have valid data
# for this check, which means it'll just make noise for no reason while we're working on other things # for this check, which means it'll just make noise for no reason while we're working on other things
self.check_modules_ships() self.check_modules_ships()
@ -557,7 +562,8 @@ class EDMCCAPIRequest(EDMCCAPIReturn):
REQUEST_WORKER_SHUTDOWN = '__EDMC_WORKER_SHUTDOWN' REQUEST_WORKER_SHUTDOWN = '__EDMC_WORKER_SHUTDOWN'
def __init__( def __init__(
self, endpoint: str, query_time: int, self, capi_host: str, endpoint: str,
query_time: int,
tk_response_event: Optional[str] = None, tk_response_event: Optional[str] = None,
play_sound: bool = False, auto_update: bool = False play_sound: bool = False, auto_update: bool = False
): ):
@ -565,6 +571,7 @@ class EDMCCAPIRequest(EDMCCAPIReturn):
query_time=query_time, tk_response_event=tk_response_event, query_time=query_time, tk_response_event=tk_response_event,
play_sound=play_sound, auto_update=auto_update play_sound=play_sound, auto_update=auto_update
) )
self.capi_host: str = capi_host # The CAPI host to use.
self.endpoint: str = endpoint # The CAPI query to perform. self.endpoint: str = endpoint # The CAPI query to perform.
@ -606,7 +613,6 @@ class Session(object):
def __init__(self) -> None: def __init__(self) -> None:
self.state = Session.STATE_INIT self.state = Session.STATE_INIT
self.server: Optional[str] = None
self.credentials: Optional[Dict[str, Any]] = None self.credentials: Optional[Dict[str, Any]] = None
self.requests_session: Optional[requests.Session] = None self.requests_session: Optional[requests.Session] = None
self.auth: Optional[Auth] = None self.auth: Optional[Auth] = None
@ -744,17 +750,20 @@ class Session(object):
logger.debug('CAPI worker thread starting') logger.debug('CAPI worker thread starting')
def capi_single_query( def capi_single_query(
capi_endpoint: str, timeout: int = capi_default_requests_timeout capi_host: str,
capi_endpoint: str,
timeout: int = capi_default_requests_timeout
) -> CAPIData: ) -> CAPIData:
""" """
Perform a *single* CAPI endpoint query within the thread worker. Perform a *single* CAPI endpoint query within the thread worker.
:param capi_host: CAPI host to query.
:param capi_endpoint: An actual Frontier CAPI endpoint to query. :param capi_endpoint: An actual Frontier CAPI endpoint to query.
:param timeout: requests query timeout to use. :param timeout: requests query timeout to use.
:return: The resulting CAPI data, of type CAPIData. :return: The resulting CAPI data, of type CAPIData.
""" """
capi_data: CAPIData capi_data: CAPIData
if not monitor.is_live_galaxy(): if capi_host == SERVER_LEGACY:
logger.warning("Dropping CAPI request because this is the Legacy galaxy") logger.warning("Dropping CAPI request because this is the Legacy galaxy")
return capi_data return capi_data
@ -768,7 +777,7 @@ class Session(object):
# This is one-shot # This is one-shot
conf_module.capi_debug_access_token = None conf_module.capi_debug_access_token = None
r = self.requests_session.get(self.server + capi_endpoint, timeout=timeout) # type: ignore r = self.requests_session.get(capi_host + capi_endpoint, timeout=timeout) # type: ignore
logger.trace_if('capi.worker', '... got result...') logger.trace_if('capi.worker', '... got result...')
r.raise_for_status() # Typically 403 "Forbidden" on token expiry r.raise_for_status() # Typically 403 "Forbidden" on token expiry
@ -776,7 +785,7 @@ class Session(object):
# r.status_code = 401 # r.status_code = 401
# raise requests.HTTPError # raise requests.HTTPError
capi_json = r.json() capi_json = r.json()
capi_data = CAPIData(capi_json, capi_endpoint) capi_data = CAPIData(capi_json, capi_host, capi_endpoint)
self.capi_raw_data.record_endpoint( self.capi_raw_data.record_endpoint(
capi_endpoint, r.content.decode(encoding='utf-8'), capi_endpoint, r.content.decode(encoding='utf-8'),
datetime.datetime.utcnow() datetime.datetime.utcnow()
@ -822,7 +831,9 @@ class Session(object):
return capi_data return capi_data
def capi_station_queries(timeout: int = capi_default_requests_timeout) -> CAPIData: # noqa: CCR001 def capi_station_queries( # noqa: CCR001
capi_host: str, timeout: int = capi_default_requests_timeout
) -> CAPIData:
""" """
Perform all 'station' queries for the caller. Perform all 'station' queries for the caller.
@ -835,7 +846,7 @@ class Session(object):
:param timeout: requests timeout to use. :param timeout: requests timeout to use.
:return: CAPIData instance with what we retrieved. :return: CAPIData instance with what we retrieved.
""" """
station_data = capi_single_query(self.FRONTIER_CAPI_PATH_PROFILE, timeout=timeout) station_data = capi_single_query(capi_host, self.FRONTIER_CAPI_PATH_PROFILE, timeout=timeout)
if not station_data['commander'].get('docked') and not monitor.state['OnFoot']: if not station_data['commander'].get('docked') and not monitor.state['OnFoot']:
return station_data return station_data
@ -876,7 +887,7 @@ class Session(object):
last_starport_id = int(last_starport.get('id')) last_starport_id = int(last_starport.get('id'))
if services.get('commodities'): if services.get('commodities'):
market_data = capi_single_query(self.FRONTIER_CAPI_PATH_MARKET, timeout=timeout) market_data = capi_single_query(capi_host, self.FRONTIER_CAPI_PATH_MARKET, timeout=timeout)
if last_starport_id != int(market_data['id']): if last_starport_id != int(market_data['id']):
logger.warning(f"{last_starport_id!r} != {int(market_data['id'])!r}") logger.warning(f"{last_starport_id!r} != {int(market_data['id'])!r}")
raise ServerLagging() raise ServerLagging()
@ -886,7 +897,7 @@ class Session(object):
station_data['lastStarport'].update(market_data) station_data['lastStarport'].update(market_data)
if services.get('outfitting') or services.get('shipyard'): if services.get('outfitting') or services.get('shipyard'):
shipyard_data = capi_single_query(self.FRONTIER_CAPI_PATH_SHIPYARD, timeout=timeout) shipyard_data = capi_single_query(capi_host, self.FRONTIER_CAPI_PATH_SHIPYARD, timeout=timeout)
if last_starport_id != int(shipyard_data['id']): if last_starport_id != int(shipyard_data['id']):
logger.warning(f"{last_starport_id!r} != {int(shipyard_data['id'])!r}") logger.warning(f"{last_starport_id!r} != {int(shipyard_data['id'])!r}")
raise ServerLagging() raise ServerLagging()
@ -913,10 +924,10 @@ class Session(object):
capi_data: CAPIData capi_data: CAPIData
try: try:
if query.endpoint == self._CAPI_PATH_STATION: if query.endpoint == self._CAPI_PATH_STATION:
capi_data = capi_station_queries() capi_data = capi_station_queries(query.capi_host)
else: else:
capi_data = capi_single_query(self.FRONTIER_CAPI_PATH_PROFILE) capi_data = capi_single_query(query.capi_host, self.FRONTIER_CAPI_PATH_PROFILE)
except Exception as e: except Exception as e:
self.capi_response_queue.put( self.capi_response_queue.put(
@ -951,6 +962,7 @@ class Session(object):
"""Ask the CAPI query thread to finish.""" """Ask the CAPI query thread to finish."""
self.capi_request_queue.put( self.capi_request_queue.put(
EDMCCAPIRequest( EDMCCAPIRequest(
capi_host='',
endpoint=EDMCCAPIRequest.REQUEST_WORKER_SHUTDOWN, endpoint=EDMCCAPIRequest.REQUEST_WORKER_SHUTDOWN,
query_time=int(time.time()) query_time=int(time.time())
) )
@ -968,22 +980,15 @@ class Session(object):
:param play_sound: Whether the app should play a sound on error. :param play_sound: Whether the app should play a sound on error.
:param auto_update: Whether this request was triggered automatically. :param auto_update: Whether this request was triggered automatically.
""" """
if self.credentials is not None and self.credentials['beta']: capi_host = self.capi_host_for_galaxy()
self.server = SERVER_BETA if not capi_host:
elif monitor.is_live_galaxy():
self.server = SERVER_LIVE
else:
logger.warning("Dropping CAPI request because this is the Legacy galaxy, which is not yet supported")
# self.server = SERVER_LEGACY
self.server = None
return return
# Ask the thread worker to perform all three queries # Ask the thread worker to perform all three queries
logger.trace_if('capi.worker', 'Enqueueing request') logger.trace_if('capi.worker', 'Enqueueing request')
self.capi_request_queue.put( self.capi_request_queue.put(
EDMCCAPIRequest( EDMCCAPIRequest(
capi_host=capi_host,
endpoint=self._CAPI_PATH_STATION, endpoint=self._CAPI_PATH_STATION,
tk_response_event=tk_response_event, tk_response_event=tk_response_event,
query_time=query_time, query_time=query_time,
@ -1064,6 +1069,28 @@ class Session(object):
indent=2, indent=2,
sort_keys=True, sort_keys=True,
separators=(',', ': ')).encode('utf-8')) separators=(',', ': ')).encode('utf-8'))
def capi_host_for_galaxy(self) -> str:
"""
Determine the correct CAPI host.
This is based on the current state of beta and game galaxy.
:return: The required CAPI host.
"""
if self.credentials is None:
# Can't tell if beta or not
return ''
if self.credentials['beta']:
return SERVER_BETA
if monitor.is_live_galaxy():
return SERVER_LIVE
# return SERVER_LEGACY # Not Yet
logger.warning("Dropping CAPI request because this is the Legacy galaxy, which is not yet supported")
return ""
###################################################################### ######################################################################

View File

@ -41,6 +41,7 @@ from typing import Tuple, Union
import requests import requests
import companion
import edmc_data import edmc_data
import killswitch import killswitch
import myNotebook as nb # noqa: N813 import myNotebook as nb # noqa: N813
@ -610,7 +611,7 @@ class EDDN:
logger.debug('Done.') logger.debug('Done.')
def export_commodities(self, data: Mapping[str, Any], is_beta: bool) -> None: # noqa: CCR001 def export_commodities(self, data: CAPIData, is_beta: bool) -> None: # noqa: CCR001
""" """
Update EDDN with the commodities on the current (lastStarport) station. Update EDDN with the commodities on the current (lastStarport) station.
@ -675,10 +676,19 @@ class EDDN:
if 'prohibited' in data['lastStarport']: if 'prohibited' in data['lastStarport']:
message['prohibited'] = sorted(x for x in (data['lastStarport']['prohibited'] or {}).values()) message['prohibited'] = sorted(x for x in (data['lastStarport']['prohibited'] or {}).values())
if data.source_host == companion.SERVER_LIVE:
gv = 'CAPI-Live-market'
elif data.source_host == companion.SERVER_LEGACY:
gv = 'CAPI-Legacy-market'
else:
gv = 'CAPI-market'
self.send_message(data['commander']['name'], { self.send_message(data['commander']['name'], {
'$schemaRef': f'https://eddn.edcd.io/schemas/commodity/3{"/test" if is_beta else ""}', '$schemaRef': f'https://eddn.edcd.io/schemas/commodity/3{"/test" if is_beta else ""}',
'message': message, 'message': message,
'header': self.standard_header(game_version='CAPI-market', game_build=''), 'header': self.standard_header(game_version=gv, game_build=''),
}) })
this.commodities = commodities this.commodities = commodities
@ -761,6 +771,15 @@ class EDDN:
# Don't send empty modules list - schema won't allow it # Don't send empty modules list - schema won't allow it
if outfitting and this.outfitting != (horizons, outfitting): if outfitting and this.outfitting != (horizons, outfitting):
if data.source_host == companion.SERVER_LIVE:
gv = 'CAPI-Live-shipyard'
elif data.source_host == companion.SERVER_LEGACY:
gv = 'CAPI-Legacy-shipyard'
else:
gv = 'CAPI-shipyard'
self.send_message(data['commander']['name'], { self.send_message(data['commander']['name'], {
'$schemaRef': f'https://eddn.edcd.io/schemas/outfitting/2{"/test" if is_beta else ""}', '$schemaRef': f'https://eddn.edcd.io/schemas/outfitting/2{"/test" if is_beta else ""}',
'message': OrderedDict([ 'message': OrderedDict([
@ -772,7 +791,7 @@ class EDDN:
('modules', outfitting), ('modules', outfitting),
('odyssey', this.odyssey), ('odyssey', this.odyssey),
]), ]),
'header': self.standard_header(game_version='CAPI-shipyard', game_build=''), 'header': self.standard_header(game_version=gv, game_build=''),
}) })
this.outfitting = (horizons, outfitting) this.outfitting = (horizons, outfitting)
@ -806,6 +825,15 @@ class EDDN:
) )
# Don't send empty ships list - shipyard data is only guaranteed present if user has visited the shipyard. # Don't send empty ships list - shipyard data is only guaranteed present if user has visited the shipyard.
if shipyard and this.shipyard != (horizons, shipyard): if shipyard and this.shipyard != (horizons, shipyard):
if data.source_host == companion.SERVER_LIVE:
gv = 'CAPI-Live-shipyard'
elif data.source_host == companion.SERVER_LEGACY:
gv = 'CAPI-Legacy-shipyard'
else:
gv = 'CAPI-shipyard'
self.send_message(data['commander']['name'], { self.send_message(data['commander']['name'], {
'$schemaRef': f'https://eddn.edcd.io/schemas/shipyard/2{"/test" if is_beta else ""}', '$schemaRef': f'https://eddn.edcd.io/schemas/shipyard/2{"/test" if is_beta else ""}',
'message': OrderedDict([ 'message': OrderedDict([
@ -817,7 +845,7 @@ class EDDN:
('ships', shipyard), ('ships', shipyard),
('odyssey', this.odyssey), ('odyssey', this.odyssey),
]), ]),
'header': self.standard_header(game_version='CAPI-shipyard', game_build=''), 'header': self.standard_header(game_version=gv, game_build=''),
}) })
this.shipyard = (horizons, shipyard) this.shipyard = (horizons, shipyard)