def process_event(self, event: journal.Event, state: GameStateData) -> EDDNSchema: """ Process journal events into journal message """ strip_localized = lambda d: utils.dict_subset( d, *(k for k in d.keys() if not k.endswith('_Localised'))) filter_faction = lambda d: strip_localized( utils.drop_keys(d, 'HappiestSystem', 'HomeSystem', 'MyReputation', 'SquadronFaction')) optional = utils.drop_keys(event.data, "ActiveFine", "CockpitBreach", "BoostUsed", "FuelLevel", "FuelUsed", "JumpDist", "Latitude", "Longitude", "Wanted") optional = strip_localized(optional) if 'StationEconomies' in optional: optional['StationEconomies'] = [ strip_localized(d) for d in optional['StationEconomies'] ] if utils.has_keys(event.data, 'StarPos', 'SystemAddress'): self._starpos_db[ event.data['SystemAddress']] = event.data['StarPos'] star_system = event.data.get('StarSystem', None) or state.location.system system_address = event.data.get('SystemAddress', None) or state.location.address star_pos = event.data.get('StarPos', None) or self._starpos_db.get(system_address or 0, None) \ or state.location.pos if not star_system or not star_pos or not system_address: raise ValueError( 'Got falsy StarPos or StarSystem or SystemAddress') message = JournalMessageSchema( timestamp=utils.to_ed_timestamp(event.timestamp), event=event.name, StarSystem=star_system, StarPos=star_pos, SystemAddress=system_address, Factions=[ filter_faction(f) for f in event.data.get('Factions', []) ], optional=optional, horizons=state.horizons, odyssey=state.odyssey, ) payload_dataclass = EDDNSchema( header=SchemaHeader(uploaderID=state.commander.name or 'unknown', ), schemaRef='https://eddn.edcd.io/schemas/journal/1', message=message) return payload_dataclass
def on_reputation_event(event: journal.Event) -> InaraEvent: """From journal Reputation event create inara setCommanderReputationMajorFaction event""" return InaraEvent( eventName='setCommanderReputationMajorFaction', eventTimestamp=event.data['timestamp'], eventData=[{ 'majorfactionName': k, 'majorfactionReputation': v / 100 } for k, v in dict_subset(event.data, 'Empire', 'Federation', 'Alliance').items()])
def on_statistict_event(event: journal.Event) -> InaraEvent: """From journal Statistics event create inara setCommanderGameStatistics event""" return InaraEvent(eventName='setCommanderGameStatistics', eventTimestamp=event.data['timestamp'], eventData=dict_subset(event.data, 'Combat', 'Bank_Account', 'Crime', 'Smuggling', 'Trading', 'Mining', 'Exploration', 'Passengers', 'Search_And_Rescue', 'Crafting', 'Crew', 'Multicrew'))
def on_rank_event(event: journal.Event) -> InaraEvent: """From journal Rank event create inara setCommanderRankPilot event""" rank_keys = ('Combat', 'Trade', 'Explore', 'Empire', 'Federation', 'CQC') return InaraEvent( eventName='setCommanderRankPilot', eventTimestamp=event.data['timestamp'], eventData=[{ 'rankName': k, 'rankValue': v } for k, v in dict_subset(event.data, *rank_keys).items()])
def _handshake(self) -> bool: """Do a handshake routine. Return True if successful""" ret_op, ret_data = self.request({ 'v': 1, 'client_id': self._client_id }, op=RPC_OP.OP_HANDSHAKE) if RPC_OP(ret_op) is RPC_OP.OP_FRAME and \ dict_subset(ret_data, 'cmd', 'evt') == {'cmd': 'DISPATCH', 'evt': 'READY'}: return True if RPC_OP(ret_op) is RPC_OP.OP_CLOSE: self.close() return False return False
def test_subset(d, k, result): assert utils.dict_subset(d, *k) == result
def test_subset_strict(d, k, result, raises): if not raises: assert utils.dict_subset(d, *k, strict=True) == result else: with pytest.raises(KeyError): assert utils.dict_subset(d, *k, strict=True)
def on_capi_market_info_commodities(self, data: dict): """Send commodities eddn message from CAPI market information""" gamestate = get_gamestate() if not gamestate.location.system or not gamestate.location.station.name \ or not gamestate.location.station.market: logger.warning('System and station info not set in gamestate') return commodities: List[Dict[str, Any]] = [] economies: List[Dict[str, Any]] = [] required_fields = [ 'name', 'meanPrice', 'buyPrice', 'stock', 'stockBracket', 'sellPrice', 'demand', 'demandBracket' ] for commodity in data.get('commodities', []): if not utils.has_keys(commodity, *required_fields) or not commodity.get('name') \ or commodity.get('legality') or commodity.get('categoryname') == 'NonMarketable': continue commodity_data = utils.dict_subset(commodity, *required_fields) status_flags: List[Union[int, str]] = list( set(filter(None, commodity.get('statusFlags', [])))) if status_flags: commodity_data['statusFlags'] = status_flags commodities.append(commodity_data) for economy in data.get('economies', {}).values(): name = economy.get('name') proportion = economy.get('proportion') if name and proportion is not None: economies.append({'name': name, 'proportion': proportion}) prohibited = {p for p in data.get('prohibited', {}).values() if p} optional = {} if prohibited: optional['prohibited'] = list(prohibited) message = CommodityMessageSchema( systemName=gamestate.location.system, stationName=gamestate.location.station.name, marketId=gamestate.location.station.market, horizons=gamestate.horizons, timestamp=datetime.datetime.utcnow().isoformat(timespec='seconds') + 'Z', commodities=commodities, economies=economies, optional=optional, odyssey=gamestate.odyssey, ) payload_dataclass = EDDNSchema( header=SchemaHeader(uploaderID=gamestate.commander.name or 'unknown', ), schemaRef='https://eddn.edcd.io/schemas/commodity/3', message=message) response = self.send_payload(payload_dataclass.to_dict()) if 400 <= response.status_code < 500: logger.error(data)