예제 #1
0
def update_kills(char_id):
    char = Character.objects.get(id=char_id)
    kills = requests.get("https://zkillboard.com/api/kills/characterID/%s/" %
                         char_id).json()

    new = 0
    for kill in kills:
        if "character_id" in kill['victim']:
            db_kill, created = Kill.objects.get_or_create(
                id=kill['killmail_id'],
                defaults={
                    'victim':
                    Character.get_or_create(kill['victim']['character_id']),
                    'ship_id':
                    kill['victim']['ship_type_id'],
                    'system_id':
                    kill['solar_system_id'],
                    'price':
                    kill['zkb']['totalValue'],
                    'date':
                    parse_api_date(kill['killmail_time'])
                })

            if created:
                new = new + 1
                for attacker in kill['attackers']:
                    if "character_id" in attacker:
                        db_kill.killers.add(
                            Character.get_or_create(attacker['character_id']))

    print "Added %s new kills for %s" % (new, char.name)
예제 #2
0
def update_character_notifications(character_id):
    # Get the db objects we need
    db_char = Character.objects.prefetch_related('token').get(id=character_id)
    api = ESI(db_char.token)

    # Check token has the scope
    if "esi-characters.read_notifications.v1" in db_char.token.extra_data[
            'scopes']:
        notifications = api.get("/v2/characters/$id/notifications/")

        # Add notifications that don't exist
        existing = set(
            Notification.objects.filter(id__in=map(
                lambda x: x['notification_id'], notifications)).values_list(
                    'id', flat=True))

        for notification in notifications:
            with transaction.atomic():
                if notification['notification_id'] not in existing:
                    db_notification = Notification(
                        id=notification['notification_id'],
                        text=notification['text'],
                        sender_id=notification['sender_id'],
                        sender_type=notification['sender_type'],
                        date=parse_api_date(notification['timestamp']),
                        type=notification['type'])
                    db_notification.save()

                    # StructureUnderAttack webhook
                    if db_notification.type == "StructureUnderAttack":
                        # Check its within the last 30 mins
                        if db_notification.date > timezone.now() - timedelta(
                                minutes=30):
                            Webhook.send(
                                "structure_attacked",
                                embeds.structure_attacked(
                                    db_notification, api))

        # Add character to notifications it doesn't yet belong to
        #existing = set(
        #    db_char.notifications.filter(
        #        id__in=map(lambda x: x['notification_id'], notifications)
        #    ).values_list(
        #        'id',
        #        flat=True
        #    )
        #)
        #new = set(map(lambda x: x['notification_id'], notifications)) - existing

        print "Updated notifications for character %s" % db_char.name
예제 #3
0
def update_character(character_id):
    # Get the db objects we need
    db_char = Character.objects.get(id=character_id)

    # Grab public info from API
    api = ESI()
    char = api.get("/v4/characters/%s/" % db_char.id)

    db_char.name = char['name']
    db_char.corp = Corporation.get_or_create(char['corporation_id'])
    if "alliance_id" in char:
        db_char.alliance = Alliance.get_or_create(char['alliance_id'])
    else:
        db_char.alliance = None
    db_char.save()

    # Grab non-public info
    if db_char.token != None:
        api = ESI(db_char.token)

        # Wallet
        db_char.wallet = api.get("/v1/characters/$id/wallet/")

        # Location
        location = api.get("/v1/characters/$id/location/")
        db_char.system_id = location['solar_system_id']

        # Ship
        ship = api.get("/v1/characters/$id/ship/")
        db_char.ship_id = ship['ship_type_id']

        # Fatigue
        fatigue = api.get("/v1/characters/$id/fatigue/")
        if "jump_fatigue_expire_date" in fatigue:
            db_char.fatigue_expire_date = parse_api_date(fatigue['jump_fatigue_expire_date'])
            db_char.last_jump_date = parse_api_date(fatigue['last_jump_date'])

        db_char.save()

        # Skills
        skills = api.get("/v4/characters/$id/skills/")
        with transaction.atomic():
            Skill.objects.filter(character=db_char).delete()
            for skill in skills['skills']:
                Skill(
                    character=db_char,
                    type_id=skill['skill_id'],
                    trained_skill_level=skill['trained_skill_level'],
                    active_skill_level=skill['active_skill_level'],
                    skillpoints_in_skill=skill['skillpoints_in_skill']
                ).save()

        # Assets
        with transaction.atomic():
            Asset.objects.filter(character=db_char).delete()

            page = 1
            while True:
                assets = api.get("/v3/characters/$id/assets/", get_vars={'page': page})
                if len(assets) < 1:
                    break

                for asset in assets:
                    db_asset = Asset(
                        character=db_char,
                        id=asset['item_id'],
                        type_id=asset['type_id'],
                        flag=asset['location_flag'],
                        quantity=asset['quantity'],
                        raw_quantity=asset['quantity'],
                        singleton=asset['is_singleton'],
                    )

                    if asset['location_flag'] == "Hangar":
                        station = Station.get_or_create(asset['location_id'], api)
                        db_asset.system = station.system
                    else:
                        db_asset.parent_id = asset['location_id']
                    db_asset.save()

                page = page + 1

            # Fetch names for all ships/containers
            items = list(
                Asset.objects.filter(
                    Q(character=db_char),
                    Q(type__group__category_id=6) | Q(type__group__in=[12 , 340, 448])
                ).values_list(
                    'id',
                    flat=True
                )
            )

            asset_names = api.post("/v1/characters/$id/assets/names/", data=json.dumps(items))
            for asset in asset_names:
                db_asset = Asset.objects.get(id=asset['item_id'])
                db_asset.name = asset['name']
                db_asset.save()

            # Fix systems
            db_assets = Asset.objects.filter(
                character=db_char,
                system__isnull=True
            ).all()
            for db_asset in db_assets:
                try:
                    if db_asset.parent != None:
                        db_asset.system = db_asset.parent.system
                except Asset.DoesNotExist:
                    pass
                    #print db_asset.parent_id
                db_asset.save()

        print "Updated all info for character %s" % db_char.name
예제 #4
0
def update_corporation(corp_id):
    corp = Corporation.objects.get(id=corp_id)
    api = ESI()
    corp_details = api.get("/v4/corporations/%s/" % corp.id)
    if corp_details is not None:
        alliance_id = corp_details.get('alliance_id', None)

    # Structures
    director = corp.characters.filter(
        roles__name="Director",
        token__isnull=False,
        token__extra_data__contains="esi-corporations.read_structures.v1"
    ).first()

    if director != None:
        api = ESI(director.token)

        structures = api.get("/v2/corporations/%s/structures/" % corp.id)
        corp.structures.exclude(
            id__in=map(lambda x: x['structure_id'], structures)).delete()

        if len(structures) > 0:
            with transaction.atomic():
                for structure in structures:
                    db_structure = Structure.objects.filter(
                        id=structure['structure_id']).first()
                    if db_structure == None:
                        db_structure = Structure(id=structure['structure_id'])

                    previous_state = db_structure.state

                    db_structure.corporation = corp
                    db_structure.type_id = structure['type_id']
                    db_structure.station = Station.get_or_create(
                        structure['structure_id'], api)
                    db_structure.system_id = structure['system_id']
                    db_structure.profile_id = structure['profile_id']
                    db_structure.state = structure['state']
                    db_structure.reinforce_weekday = structure[
                        'reinforce_weekday']
                    db_structure.reinforce_hour = structure['reinforce_hour']

                    if "fuel_expires" in structure:
                        db_structure.fuel_expires = parse_api_date(
                            structure['fuel_expires'])
                    else:
                        db_structure.fuel_expires = None

                    if "state_timer_start" in structure:
                        db_structure.state_timer_start = parse_api_date(
                            structure['state_timer_start'])
                    else:
                        db_structure.state_timer_start = None

                    if "state_timer_end" in structure:
                        db_structure.state_timer_end = parse_api_date(
                            structure['state_timer_end'])
                    else:
                        db_structure.state_timer_end = None
                    db_structure.save()

                    db_structure.services.all().delete()
                    if "services" in structure:
                        for service in structure['services']:
                            Service(structure=db_structure,
                                    name=service['name'],
                                    state={
                                        'online': True,
                                        'offline': False
                                    }[service['state']]).save()

                    # Create timer if this is newly reinforced
                    if previous_state != structure['state']:
                        if "reinforce" in structure['state'] or structure[
                                'state'] == "anchoring":
                            timer = Timer(
                                structure_id=structure['type_id'],
                                name=db_structure.station.name.replace(
                                    "%s - " % db_structure.system.name, ""),
                                owner=corp.ticker,
                                side=0,
                                system_id=structure['system_id'],
                                date=db_structure.state_timer_end,
                                stage={
                                    "armor_reinforce": "AR",
                                    "hull_reinforce": "ST",
                                    "anchoring": "AN",
                                    "unanchoring": "UN"
                                }[structure['state']],
                                visible_to_level=2,
                                created_by=User.objects.first(),
                                generated=True)
                            timer.save()

                            # Structure reinforce webhook
                            if db_structure.state in [
                                    "armor_reinforce", "hull_reinforce"
                            ]:
                                Webhook.send(
                                    "structure_reinforce",
                                    embeds.structure_state(
                                        timer, db_structure))
                            # Structure anchoring webhook
                            if db_structure.state in [
                                    "anchoring", "unanchoring"
                            ]:
                                Webhook.send(
                                    "structure_anchoring",
                                    embeds.structure_state(
                                        timer, db_structure))

                    # Ping about fuel if necessary
                    if db_structure.fuel_expires != None:
                        time_left = db_structure.fuel_expires - timezone.now()
                        if time_left <= timedelta(hours=72):
                            hours_left = int(time_left.total_seconds() / 60 /
                                             60)
                            if hours_left % 12 == 0:
                                if db_structure.fuel_notifications:
                                    Webhook.send("low_fuel_filtered",
                                                 embeds.low_fuel(db_structure))

                                Webhook.send("low_fuel_all",
                                             embeds.low_fuel(db_structure))

        print "Updated structures for %s" % corp.name

    # Member Tracking
    director = corp.characters.filter(
        roles__name="Director",
        token__isnull=False,
        token__extra_data__contains=
        "esi-corporations.read_corporation_membership.v1").first()

    if director != None:
        api = ESI(director.token)

        # Work on differences
        character_ids = api.get("/v3/corporations/%s/members/" % corp.id)
        if character_ids is not None:
            # Create diffs
            new_character_ids = set(character_ids)
            db_character_ids = set(
                Character.objects.filter(corp=corp).values_list('id',
                                                                flat=True))
            joined_chars = new_character_ids - db_character_ids
            joined_chars = Character.objects.filter(id__in=joined_chars).all()
            left_chars = db_character_ids - new_character_ids
            left_chars = Character.objects.filter(id__in=left_chars).all()

            # Generate webhook events
            for joined_char in joined_chars:
                if joined_char.token is not None:
                    if joined_char.id in settings.members[
                            'alliances'] or corp.id in settings.members[
                                'corps'] or alliance_id in settings.members[
                                    'chars']:
                        Webhook.send("character_joined",
                                     character_joined(joined_char, corp))
            for left_char in left_chars:
                if left_chars.id in settings.members[
                        'alliances'] or corp.id in settings.members[
                            'corps'] or alliance_id in settings.members[
                                'chars']:
                    Webhook.send("character_left",
                                 character_left(left_char, corp))

            # Null the corp on chars that have left
            left_chars.update(corp=None, alliance=None)

        members = api.get("/v1/corporations/%s/membertracking/" % corp.id)

        if members is not None:
            with transaction.atomic():
                for member in members:
                    char = Character.get_or_create(member['character_id'])
                    char.corp = corp
                    char.last_login = parse_api_date(member['logon_date'])
                    char.last_logoff = parse_api_date(member['logoff_date'])
                    char.ship_id = member['ship_type_id']
                    char.save()

        print "Updated %s members for %s" % (len(members), corp.name)
예제 #5
0
def update_character(character_id):
    # Get the db objects we need
    db_char = Character.objects.get(id=character_id)

    # Grab public info from API
    api = ESI()
    char = api.get("/v4/characters/%s/" % db_char.id)

    db_char.name = char['name']
    db_char.corp = Corporation.get_or_create(char['corporation_id'])
    if "alliance_id" in char:
        db_char.alliance = Alliance.get_or_create(char['alliance_id'])
    else:
        db_char.alliance = None
    db_char.save()

    # Grab non-public info
    if db_char.token != None:
        api = ESI(db_char.token)

        # Check refresh token to see if it's still valid
        if api._refresh_access_token() == False:
            # Check if we've had 24 within the last 72hrs failures. This runs hourly so that means EVE would need to be dead for a full day.
            cache_key = "fail_history_character_%s" % db_char.id
            fail_history = cache.get(cache_key, [])
            if len(fail_history) > 24:
                token = db_char.token

                user = db_char.owner

                db_char.owner = None
                db_char.token = None
                db_char.save()

                token.delete()

                Webhook.send("character_expired",
                             embeds.character_expired(user, db_char))

                fail_history = []
            else:
                fail_history.append(now())

            cache.set(cache_key, fail_history, 259200)
            return

        # Wallet
        db_char.wallet = api.get("/v1/characters/$id/wallet/")

        # Location
        location = api.get("/v1/characters/$id/location/")
        db_char.system_id = location['solar_system_id']

        # Ship
        ship = api.get("/v1/characters/$id/ship/")
        db_char.ship_id = ship['ship_type_id']

        # Fatigue
        fatigue = api.get("/v1/characters/$id/fatigue/")
        if "jump_fatigue_expire_date" in fatigue:
            db_char.fatigue_expire_date = parse_api_date(
                fatigue['jump_fatigue_expire_date'])
            db_char.last_jump_date = parse_api_date(fatigue['last_jump_date'])

        # Roles
        with transaction.atomic():
            roles = api.get("/v2/characters/$id/roles/")
            db_char.roles.all().delete()

            if "roles" in roles:
                for role in roles['roles']:
                    Role(character=db_char, name=role).save()

        db_char.save()

        # Skills
        skills = api.get("/v4/characters/$id/skills/")
        with transaction.atomic():
            Skill.objects.filter(character=db_char).delete()
            for skill in skills['skills']:
                Skill(
                    character=db_char,
                    type_id=skill['skill_id'],
                    trained_skill_level=skill['trained_skill_level'],
                    active_skill_level=skill['active_skill_level'],
                    skillpoints_in_skill=skill['skillpoints_in_skill']).save()

        # Assets
        with transaction.atomic():
            Asset.objects.filter(character=db_char).delete()

            page = 1
            while True:
                assets = api.get("/v3/characters/$id/assets/",
                                 get_vars={'page': page})
                if len(assets) < 1:
                    break

                for asset in assets:
                    db_asset = Asset(
                        character=db_char,
                        id=asset['item_id'],
                        type_id=asset['type_id'],
                        flag=asset['location_flag'],
                        quantity=asset['quantity'],
                        raw_quantity=asset['quantity'],
                        singleton=asset['is_singleton'],
                    )

                    if asset['location_flag'] == "Hangar":
                        station = Station.get_or_create(
                            asset['location_id'], api)
                        db_asset.system = station.system
                    else:
                        db_asset.parent_id = asset['location_id']
                    db_asset.save()

                page = page + 1

            # Fetch names for all ships/containers
            items = list(
                Asset.objects.filter(
                    Q(character=db_char),
                    Q(type__group__category_id=6)
                    | Q(type__group__in=[12, 340, 448])).values_list(
                        'id', flat=True))

            asset_names = api.post("/v1/characters/$id/assets/names/",
                                   data=json.dumps(items))
            for asset in asset_names:
                db_asset = Asset.objects.get(id=asset['item_id'])
                db_asset.name = asset['name']
                db_asset.save()

            # Fix systems
            db_assets = Asset.objects.filter(character=db_char,
                                             system__isnull=True).all()
            for db_asset in db_assets:
                try:
                    if db_asset.parent != None:
                        db_asset.system = db_asset.parent.system
                except Asset.DoesNotExist:
                    pass
                    #print db_asset.parent_id
                db_asset.save()

        # Implants
        with transaction.atomic():
            implants = api.get("/v1/characters/$id/implants/")
            db_char.implants.all().delete()
            for implant in implants:
                Implant(character=db_char, type_id=implant).save()

        # Clones
        info_sync = db_char.skills.filter(type_id=33399).first()
        if info_sync != None:
            info_sync = timedelta(hours=info_sync.trained_skill_level)
        else:
            info_sync = timedelta(hours=0)

        clones = api.get("/v3/characters/$id/clones/")
        db_char.home = Station.get_or_create(
            clones['home_location']['location_id'], api)
        if "last_clone_jump_date" in clones:
            db_char.clone_jump_ready = parse_api_date(
                clones['last_clone_jump_date']) - info_sync + timedelta(
                    hours=24)
        db_char.save()

        db_char.clones.all().delete()
        for clone in clones['jump_clones']:
            if "name" in clone:
                name = clone['name']
            else:
                name = ""

            db_clone = Clone(id=clone['jump_clone_id'],
                             character=db_char,
                             name=name,
                             location=Station.get_or_create(
                                 clone['location_id'], api))
            db_clone.save()

            for implant in clone['implants']:
                CloneImplant(clone=db_clone, type_id=implant).save()

        print "Updated all info for character %s" % db_char.name
예제 #6
0
def update_corporation(corp_id):
    # Look for character with the right roles
    corp = Corporation.objects.get(id=corp_id)
    director = corp.characters.filter(
        roles__name="Director",
        token__isnull=False,
        token__extra_data__contains="esi-corporations.read_structures.v1"
    ).first()

    if director != None:
        api = ESI(director.token)

        # Structures
        structures = api.get("/v2/corporations/%s/structures/" % corp.id)
        corp.structures.exclude(
            id__in=map(lambda x: x['structure_id'], structures)).delete()

        for structure in structures:
            with transaction.atomic():
                db_structure = Structure.objects.filter(
                    id=structure['structure_id']).first()
                if db_structure == None:
                    db_structure = Structure(id=structure['structure_id'])

                previous_state = db_structure.state

                db_structure.corporation = corp
                db_structure.type_id = structure['type_id']
                db_structure.station = Station.get_or_create(
                    structure['structure_id'], api)
                db_structure.system_id = structure['system_id']
                db_structure.profile_id = structure['profile_id']
                db_structure.state = structure['state']
                db_structure.reinforce_weekday = structure['reinforce_weekday']
                db_structure.reinforce_hour = structure['reinforce_hour']

                if "fuel_expires" in structure:
                    db_structure.fuel_expires = parse_api_date(
                        structure['fuel_expires'])
                else:
                    db_structure.fuel_expires = None

                if "state_timer_start" in structure:
                    db_structure.state_timer_start = parse_api_date(
                        structure['state_timer_start'])
                else:
                    db_structure.state_timer_start = None

                if "state_timer_end" in structure:
                    db_structure.state_timer_end = parse_api_date(
                        structure['state_timer_end'])
                else:
                    db_structure.state_timer_end = None
                db_structure.save()

                db_structure.services.all().delete()
                if "services" in structure:
                    for service in structure['services']:
                        Service(structure=db_structure,
                                name=service['name'],
                                state={
                                    'online': True,
                                    'offline': False
                                }[service['state']]).save()

                # Create timer if this is newly reinforced
                if previous_state != structure['state']:
                    if "reinforce" in structure['state'] or structure[
                            'state'] == "anchoring":
                        timer = Timer(structure_id=structure['type_id'],
                                      name=db_structure.station.name.replace(
                                          "%s - " % db_structure.system.name,
                                          ""),
                                      owner=corp.ticker,
                                      side=0,
                                      system_id=structure['system_id'],
                                      date=db_structure.state_timer_end,
                                      stage={
                                          "armor_reinforce": "AR",
                                          "hull_reinforce": "ST",
                                          "anchoring": "AN",
                                          "unanchoring": "UN"
                                      }[structure['state']],
                                      visible_to_level=2,
                                      created_by=User.objects.first(),
                                      generated=True)
                        timer.save()

                        # Structure reinforce webhook
                        if db_structure.state in [
                                "armor_reinforce", "hull_reinforce"
                        ]:
                            Webhook.send(
                                "structure_reinforce",
                                embeds.structure_state(timer, db_structure))
                        # Structure anchoring webhook
                        if db_structure.state in ["anchoring", "unanchoring"]:
                            Webhook.send(
                                "structure_anchoring",
                                embeds.structure_state(timer, db_structure))

                # Ping about fuel if necessary
                if db_structure.fuel_expires != None:
                    time_left = db_structure.fuel_expires - timezone.now()
                    if time_left <= timedelta(hours=72):
                        hours_left = int(time_left.total_seconds() / 60 / 60)
                        if hours_left % 12 == 0:
                            if db_structure.fuel_notifications:
                                Webhook.send("low_fuel_filtered",
                                             embeds.low_fuel(db_structure))

                            Webhook.send("low_fuel_all",
                                         embeds.low_fuel(db_structure))

        print "Updated all info for Corporation %s" % corp.name