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)
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
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
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)
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
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