Пример #1
0
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
Пример #2
0
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
Пример #3
0
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
Пример #4
0
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
Пример #5
0
 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
Пример #6
0
 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)
Пример #7
0
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
Пример #8
0
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))
Пример #9
0
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
Пример #10
0
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
Пример #11
0
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