def check_citadels(corporation_id): """ Check citadels for fuel and services status """ structures = esi_api( 'Corporation.get_corporations_corporation_id_structures', token=access_token, corporation_id=corporation_id) now = datetime.datetime.utcnow().date() too_soon = datetime.timedelta(days=TOO_SOON) messages = [] for structure in structures: message = '' # Grab structure name structure_info = esi_api( 'Universe.get_universe_structures_structure_id', token=access_token, structure_id=structure['structure_id']) name = structure_info.get('name') # List online/offline services online_services = [] offline_services = [] for service in structure.get('services') or []: if service['state'] == 'online': online_services.append(service.get('name')) if service['state'] == 'offline': offline_services.append(service.get('name')) online = ', '.join([service for service in online_services]) offline = ', '.join([service for service in offline_services]) # Check when fuel expires fuel_expires = structure.get('fuel_expires', None) # Build message for fuel running out and offline services if fuel_expires: how_soon = fuel_expires - now if how_soon < too_soon: message = "{} runs out of fuel on {}".format( name, fuel_expires) if online_services: message += '\nOnline Services: {}'.format(online) if offline_services: message += '\nOffline Services: {}'.format(offline) elif offline_services: message = '{} has offline services: {}'.format(name, offline) if message: messages.append(message) return messages
def sov_systems(sov_holder): sov_holder_id = esi_api('Search.get_search', categories=['alliance'], search=sov_holder, strict=True).get('alliance')[0] map_sov = esi_api('Sovereignty.get_sovereignty_map') sov_systems = [] for system in map_sov: try: if system['alliance_id'] == sov_holder_id: sov_systems.append(system['system_id']) except KeyError: continue return sov_systems
def item_locations(ids): location_dict = {} chunks = 1000 for items in [ids[i:i+chunks] for i in range(0, len(ids), chunks)]: locations = esi_api('Assets.post_corporations_corporation_id_assets_locations', token=access_token, item_ids=items, corporation_id=CONFIG['CORP_ID']) for location in locations: i = int(location.get('item_id')) location_dict[i] = location return location_dict
def sov_systems(sov_holder_id): sov_systems = [] if sov_holder_id: map_sov = esi_api('Sovereignty.get_sovereignty_map') for system in map_sov: try: if system['alliance_id'] == sov_holder_id: sov_systems.append(system['system_id']) except KeyError: continue return sov_systems
def __init__(self, structure_id, structure_type_id=None, structure_type_name=None, token=access_token, system_id=None, services=None, fuel_expires=None, fitting=None): super(Structure, self).__init__() self.structure_id = structure_id self.structure_type_id = structure_type_id self.structure_type_name = structure_type_name self.system_id = system_id self.fitting = fitting self._fuel_rate = 0 # Grab structure name try: self.structure_info = esi_api('Universe.get_universe_structures_structure_id', token=access_token, structure_id=structure_id) self.name = self.structure_info.get('name') self.accessible = True except HTTPForbidden, e: self.name = "Inaccessible Structure" self.accessible = False
def from_corporation(cls, corporation_name, token=access_token, assets={}): corporation_id = name_to_id(corporation_name, 'corporation') structures = esi_api('Corporation.get_corporations_corporation_id_structures', token=token, corporation_id=corporation_id) structure_keys = ['structure_id', 'system_id', 'services', 'fuel_expires'] for s in structures: sid = s['structure_id'] kwargs = {k:v for k,v in s.items() if k in structure_keys} kwargs['token'] = token if 'children' in assets.get(sid).keys(): kwargs['fitting'] = Fitting.from_assets(assets[sid]['children']) kwargs['structure_type_id'] = assets[sid]['typeID'] kwargs['structure_type_name'] = assets[sid]['typeName'] else: kwargs['structure_type_id'] = s['type_id'] kwargs['structure_type_name'] = ids_to_names([s['type_id']])[s['type_id']] yield cls(**kwargs)
def pos_assets(): assets = esi_api('Assets.get_corporations_corporation_id_assets', token=access_token, corporation_id=CONFIG['CORP_ID']) pos = {} mods = {} for asset in assets: item_id = int(asset.get('item_id')) # location_flags are a bit of mystery. Trial and error for now location_flag = asset.get('location_flag') if location_flag not in ['AutoFit']: continue # Filter out things that aren't POS mods type_id = int(asset.get('type_id')) if type_id not in pos_mods: continue # Decorate POS mods with SDE data annotate_element(asset, pos_mods[type_id]) if asset.get('groupName') == 'Control Tower': pos_stuff = pos else: pos_stuff = mods pos_stuff[item_id] = asset locations = item_locations(pos.keys() + mods.keys()) for itemID, location in locations.iteritems(): try: pos[itemID].update(location) except KeyError: mods[itemID].update(location) pos_locations = {i: (pos[i]['position']['x'], pos[i]['position']['y'], pos[i]['position']['z']) for i in pos} for i, d in mods.iteritems(): try: location = (d['position']['x'], d['position']['y'], d['position']['z']) except KeyError: print '{} ({}) has no coordinates'.format(d['typeName'], i) continue nearest_pos = nearest(location, pos_locations) parent_pos_mods = pos[nearest_pos].setdefault('mods', []) parent_pos_mods.append(d) return pos
def check_citadels(): """ Check citadels for fuel and services status """ corporation_id = name_to_id(CORPORATION_NAME, 'corporation') structures = esi_api( 'Corporation.get_corporations_corporation_id_structures', token=access_token, corporation_id=corporation_id) detonations = esi_api( 'Industry.get_corporation_corporation_id_mining_extractions', token=access_token, corporation_id=corporation_id) detonations = {d['structure_id']: d for d in detonations} now = datetime.datetime.utcnow().replace(tzinfo=pytz.utc) too_soon = datetime.timedelta(days=TOO_SOON) messages = [] for structure in structures: structure_id = structure['structure_id'] message = [] # Grab structure name try: structure_info = esi_api( 'Universe.get_universe_structures_structure_id', token=access_token, structure_id=structure_id) except HTTPForbidden, e: messages.append( 'Found a citadel ({}) in {} that doesn\'t allow {} to dock!'. format(structure_id, structure['system_id'], CORPORATION_NAME)) continue name = structure_info.get('name') # List online/offline services online_services = [] offline_services = [] for service in structure.get('services') or []: if service['state'] == 'online': online_services.append(service.get('name')) if service['state'] == 'offline': offline_services.append(service.get('name')) online = ', '.join([service for service in online_services]) offline = ', '.join([service for service in offline_services]) # Check when fuel expires fuel_expires = structure.get('fuel_expires', None) # Check for upcoming detonations try: detonation = detonations[structure_id]['chunk_arrival_time'] if detonation - now < too_soon: message.append('Ready to detonate {}'.format(detonation)) except KeyError: pass # Build message for fuel running out and offline services if fuel_expires and (fuel_expires - now.date() < too_soon): message.append('Runs out of fuel on {}'.format(fuel_expires)) if online_services: message.append('Online Services: {}'.format(online)) if offline_services: message.append('Offline Services: {}'.format(offline)) elif offline_services: message.append('Offline services: {}'.format(offline)) if message: messages.append('\n'.join(['{}'.format(name)] + message))
def check_pos(): pos_list_xml = xml_api('/corp/StarbaseList.xml.aspx') poses = pos_assets() messages = [] sovs = sov_systems(SOV_HOLDER) for pos in pos_list_xml.findall('.//rowset[@name="starbases"]/row'): pos_id = int(pos.get('itemID')) type_id = int(pos.get('typeID')) location_id = int(pos.get('locationID')) states = ('Unanchored', 'Offline', 'Onlining', 'Reinforced', 'Online') state = states[int(pos.get('state'))] location_name = esi_api('Universe.get_universe_systems_system_id', system_id=location_id).get('name') moon_id = int(pos.get('moonID')) moon_name = esi_api('Universe.get_universe_moons_moon_id', moon_id=moon_id).get('name') sov = location_id in sovs poses[pos_id]['locationName'] = location_name poses[pos_id]['moonName'] = moon_name poses[pos_id]['moonID'] = moon_id for fuel in poses[pos_id]['contents']: fuel_type_id = int(fuel.get('typeID')) quantity = int(fuel.get('quantity')) multiplier = .75 if sov else 1.0 rate = pos_fuel[type_id][fuel_type_id] * multiplier fuel['hourly_rate'] = rate if fuel_type_id == 16275: reinforce_hours = int(quantity / rate) message = '{} has {} hours of stront'.format(moon_name, reinforce_hours) if reinforce_hours < STRONT_HOURS: messages.append(message) else: how_soon = int(quantity / (rate*24)) days = 'day' if how_soon == 1 else 'days' message = '{} has {} {} of fuel'.format(moon_name, how_soon, days) if how_soon < TOO_SOON: messages.append(message) for mod in poses[pos_id]['mods']: # Note this is currently only useful for # silos that are being filled (e.g. mining), # not emptied (e.g. reaction inputt) if mod['typeName'] == 'Silo': try: goo = mod['contents'][0] except KeyError: goo = None if goo: capacity = Decimal(mod['capacity']) name = goo['typeName'] volume = Decimal(goo['volume']) quantity = int(goo['quantity']) total_volume = volume*quantity rate = volume*100*24 remaining_capacity = capacity - total_volume days_remaining = int(remaining_capacity / rate) days = 'day' if days_remaining == 1 else 'days' message = "{} has {} {} of {} capacity left ({} current units)".format(moon_name, days_remaining, days, name, quantity) if days_remaining < TOO_SOON: messages.append(message) if state != 'Online': statetime = pos.get('stateTimestamp') message = '{} is {}'.format(moon_name, state) if statetime: message += ' until {}'.format(statetime) messages.append(message) return messages
def check_pos(): pos_list_xml = xml_api('/corp/StarbaseList.xml.aspx') poses = pos_assets() messages = [] corp_id = name_to_id(CORPORATION_NAME, 'corporation') alliance_id = esi_api('Corporation.get_corporations_corporation_id', corporation_id=corp_id).get('alliance_id', None) sovs = sov_systems(alliance_id) for pos in pos_list_xml.findall('.//rowset[@name="starbases"]/row'): pos_id = int(pos.get('itemID')) type_id = int(pos.get('typeID')) location_id = int(pos.get('locationID')) states = ('Unanchored', 'Offline', 'Onlining', 'Reinforced', 'Online') state = states[int(pos.get('state'))] if state == 'Unanchored': print 'POS {} is unanchored, skipping'.format(pos_id) continue location_name = esi_api('Universe.get_universe_systems_system_id', system_id=location_id).get('name') moon_id = int(pos.get('moonID')) moon_name = esi_api('Universe.get_universe_moons_moon_id', moon_id=moon_id).get('name') sov = location_id in sovs poses[pos_id]['locationName'] = location_name poses[pos_id]['moonName'] = moon_name poses[pos_id]['moonID'] = moon_id has_stront = False has_fuel = False has_defensive_mods = False # TODO: handle purposefully offlined POS by checking for fuel for fuel in poses[pos_id].get('contents', []): fuel_type_id = int(fuel.get('typeID')) quantity = int(fuel.get('quantity')) multiplier = .75 if sov else 1.0 rate = pos_fuel[type_id][fuel_type_id] * multiplier fuel['hourly_rate'] = rate if fuel_type_id == 16275: has_stront = True if state == 'Offline': continue reinforce_hours = int(quantity / rate) message = '{} has {} hours of stront'.format( moon_name, reinforce_hours) if reinforce_hours < STRONT_HOURS: messages.append(message) else: has_fuel = True if state == 'Offline': continue how_soon = int(quantity / (rate * 24)) days = 'day' if how_soon == 1 else 'days' message = '{} has {} {} of fuel'.format( moon_name, how_soon, days) if how_soon < TOO_SOON: messages.append(message) for mod in poses[pos_id].get('mods', []): # Note this is currently only useful for # silos that are being filled (e.g. mining), # not emptied (e.g. reaction inputt) if mod['typeName'] == 'Silo': try: goo = mod['contents'][0] except KeyError: goo = None if goo: capacity = Decimal(mod['capacity']) name = goo['typeName'] volume = Decimal(goo['volume']) quantity = int(goo['quantity']) total_volume = volume * quantity rate = volume * 100 * 24 remaining_capacity = capacity - total_volume days_remaining = int(remaining_capacity / rate) days = 'day' if days_remaining == 1 else 'days' message = "{} has {} {} of {} capacity left ({} current units)".format( moon_name, days_remaining, days, name, quantity) if days_remaining < TOO_SOON: messages.append(message) if mod['groupName'] == 'Shield Hardening Array': has_defensive_mods = True if state != 'Online': if has_fuel and state == 'Offline' and not has_defensive_mods: continue statetime = pos.get('stateTimestamp') message = '{} is {}'.format(moon_name, state) if statetime: state_predicates = {'Reinforced': 'until'} message += ' {} {}'.format( state_predicates.get(state, 'since'), statetime) messages.append(message) return messages
def check_pos(): corp_id = CONFIG['CORP_ID'] pos_list = esi_api('Corporation.get_corporations_corporation_id_starbases', token=access_token, corporation_id=corp_id) poses = pos_assets() messages = [] alliance_id = esi_api('Corporation.get_corporations_corporation_id', corporation_id=corp_id).get('alliance_id', None) sovs = sov_systems(alliance_id) for pos in pos_list: pos_id = int(pos.get('starbase_id')) type_id = int(pos.get('type_id')) system_id = int(pos.get('system_id')) state = pos.get('state') if not state: print 'POS {} is unanchored, skipping'.format(pos_id) continue location_name = esi_api('Universe.get_universe_systems_system_id', system_id=system_id).get('name') moon_id = int(pos.get('moon_id')) moon_name = esi_api('Universe.get_universe_moons_moon_id', moon_id=moon_id).get('name') sov = system_id in sovs poses[pos_id]['location_name'] = location_name poses[pos_id]['moon_name'] = moon_name poses[pos_id]['moon_id'] = moon_id has_stront = False has_fuel = False has_defensive_mods = False for fuel in esi_api('Corporation.get_corporations_corporation_id_starbases_starbase_id', token=access_token, corporation_id=corp_id, starbase_id=pos_id, system_id=system_id).get('fuels'): fuel_type_id = int(fuel.get('type_id')) quantity = int(fuel.get('quantity')) multiplier = .75 if sov else 1.0 rate = pos_fuel[type_id][fuel_type_id] * multiplier fuel['hourly_rate'] = rate if fuel_type_id == 16275: has_stront = True if state == 'offline': continue reinforce_hours = int(quantity / rate) message = '{} has {} hours of stront'.format(moon_name, reinforce_hours) if reinforce_hours < CONFIG['STRONT_HOURS']: messages.append(message) else: has_fuel = True if state == 'offline': continue how_soon = int(quantity / (rate*24)) days = 'day' if how_soon == 1 else 'days' message = '{} has {} {} of fuel'.format(moon_name, how_soon, days) if how_soon < CONFIG['TOO_SOON']: messages.append(message) for mod in poses[pos_id].get('mods', []): if mod['groupName'] == 'Shield Hardening Array': has_defensive_mods = True if state != 'online': if has_fuel and state == 'offline' and not has_defensive_mods: continue statetime = pos.get('stateTimestamp') message = '{} is {}'.format(moon_name, state) if statetime: state_predicates = { 'reinforced': 'until' } message += ' {} {}'.format(state_predicates.get(state, 'since'), statetime) messages.append(message) return messages