def get_or_create(alliance_id): from eveauth.esi import ESI api = ESI() db_alliance = Alliance.objects.filter(id=alliance_id) if len(db_alliance) == 0: alliance = api.get("/v3/alliances/%s/" % alliance_id) db_alliance = Alliance(id=alliance_id, name=alliance['name'], ticker=alliance['ticker']) # Make django group group = Group(name="Alliance: %s" % db_alliance.name) group.save() db_alliance.group = group db_alliance.save() return db_alliance else: db_alliance = db_alliance[0] if db_alliance.last_updated < now() - timedelta(days=2): alliance = api.get("/v3/alliances/%s/" % alliance_id) db_alliance.name = alliance['name'] db_alliance.ticker = alliance['ticker'] db_alliance.save() db_alliance.group.name = "Alliance: %s" % db_alliance.name db_alliance.group.save() return db_alliance
def update_groups(user_id): user = User.objects.get(id=user_id) print "Updating groups for %s" % user.username social = user.social_auth.filter(provider="eveonline").first() # Queue character updates for char in user.characters.all(): update_character.delay(char.id) # Update char/corp/alliance api = ESI() char_id = social.extra_data['id'] char = api.get("/v4/characters/%s/" % char_id) user.profile.character = Character.get_or_create(char_id) user.profile.corporation = Corporation.get_or_create( char['corporation_id']) if "alliance_id" in char: user.profile.alliance = Alliance.get_or_create(char['alliance_id']) else: user.profile.alliance = None # Update groups for group in user.groups.filter(name__startswith="Corp: ").all(): user.groups.remove(group) for group in user.groups.filter(name__startswith="Alliance: ").all(): user.groups.remove(group) if user.profile.corporation != None: user.groups.add(user.profile.corporation.group) if user.profile.alliance != None: user.groups.add(user.profile.alliance.group) # Update access level char_id = user.profile.character_id corp_id = user.profile.corporation_id alliance_id = user.profile.alliance_id if corp_id in members['corps'] or alliance_id in members[ 'alliances'] or char_id in members['chars']: user.profile.level = 2 elif corp_id in blues['corps'] or alliance_id in blues[ 'alliances'] or char_id in members['chars']: user.profile.level = 1 else: user.profile.level = 0 user.profile.save() # Update IPB User if ipb.is_active(): if user.profile.forum_id: forum_api = ipb.IPBUser(user) forum_api.update_access_level() update_discord.delay(user.id)
def get_or_create(id): from eveauth.esi import ESI db_char = Character.objects.filter(id=id) if len(db_char) == 0: api = ESI() char = api.get("/v4/characters/%s/" % id) db_char = Character(id=id, name=char['name']) db_char.save() else: db_char = db_char[0] return db_char
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_location(character_id): # Get the db objects we need db_char = Character.objects.get(id=character_id) api = ESI(db_char.token) # 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'] db_char.save() print "Updated location info for character %s" % db_char.name
def structure_attacked(notification, api=ESI()): data = notification.data system = System.objects.get(id=data['solarsystemID']) structure_type = Type.objects.get(id=data['structureShowInfoData'][1]) structure = Station.get_or_create(data['structureID'], api) attacker = Character.get_or_create(data['charID']) out = { "username": "******", "embeds": [{ "type": "rich", "title": "%s in %s is under attack" % ( structure_type.name, system.name, ), "description": "%s (%s)" % (structure.name, system.region.name), "url": "https://zkillboard.com/character/%s/" % attacker.id, "thumbnail": { "url": "https://imageserver.eveonline.com/Render/%s_128.png" % structure_type.id }, "color": 0xff0000, "fields": [{ "name": "Owner", "value": structure.corp_structure.corporation.name, "inline": True, }, { "name": "Time", "value": data.date.strftime("%H:%M"), "inline": True, }, { "name": "Attacker", "value": attacker.name, "inline": True, }, { "name": "Attacker Corp", "value": data['corpName'], "inline": True, }] }] } if "allianceName" in data: out['embeds'][0]['fields'].append({ "name": "Attacker Alliance", "value": data['allianceName'], "inline": True, }) return out
def get_or_create(corporation_id): from eveauth.esi import ESI corporation = Corporation.objects.filter(id=corporation_id) if len(corporation) == 0: api = ESI() corporation = api.get("/v4/corporations/%s/" % corporation_id) db_corporation = Corporation(id=corporation_id, name=corporation['name'], ticker=corporation['ticker']) # Make Django Group group = Group(name="Corp: %s" % db_corporation.name) group.save() db_corporation.group = group db_corporation.save() return db_corporation else: db_corporation = corporation[0] if db_corporation.last_updated < now() - timedelta(days=2): old_name = db_corporation.name api = ESI() corporation = api.get("/v4/corporations/%s/" % corporation_id) db_corporation.name = corporation['name'] db_corporation.ticker = corporation['ticker'] db_corporation.save() # Update group db_corporation.group.name = "Corp: %s" % db_corporation.name db_corporation.group.save() return db_corporation
def corpaudit_search(request): search = request.GET.get("search", False) if search == False: return render(request, "eveauth/corpaudit_search.html", {}) # Get corp info for live search corps = Corporation.objects.filter( Q(name__istartswith=search) | Q(ticker__istartswith=search), characters__owner__isnull=False, id__gt=1001000 ).annotate( chars=Count('characters') ).filter( chars__gt=0 ).order_by( '-chars' ).all() api = ESI() def get_member_count(id): r = api.get("/v4/corporations/%s/" % id) return r['member_count'] corps = map( lambda x: { "id": x.id, "name": x.name, "tickers": x.ticker, "chars": x.chars, "members": get_member_count(x.id) }, corps ) context = { "search": search, "corps": corps } return render(request, "eveauth/corpaudit_search.html", context)
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
def corpaudit_view(request, id, connected="all"): r = ESI().get("/v4/corporations/%s/" % id) corp = Corporation.objects.prefetch_related( 'characters', 'characters__owner' ).get(id=id) order_by = { "character": "name", "owner": "owner", "location": "location", "ship": "ship" }[request.GET.get("orderby", "character")] # Populate corp object with extra data corp.member_count = r['member_count'] corp.ceo = Character.get_or_create(r['ceo_id']) corp.description = r['description'] corp.tax_rate = r['tax_rate'] corp.founder = Character.get_or_create(r['creator_id']) if "alliance_id" in r: corp.alliance = Alliance.get_or_create(r['alliance_id']) # Call evewho r = requests.get("https://evewho.com/api.php?type=corplist&id=%s&page=0" % id).json() chars = r['characters'] if int(r['info']['memberCount']) > 200: for i in range(1, int(math.ceil((int(r['info']['memberCount'])) / 200) + 1)): r = requests.get("https://evewho.com/api.php?type=corplist&id=%s&page=%s" % (id, i)).json() chars = chars + r['characters'] for char in chars: try: char['char'] = Character.objects.select_related( "owner", "ship", "system" ).get( id=char['character_id'], owner__isnull=False ) char['owner'] = char['char'].owner.username char['location'] = char['char'].system.name char['ship'] = char['char'].ship.name except Exception: char['owner'] = "zzzzzzzzz" char['location'] = "zzzzzzzzz" char['ship'] = "zzzzzzzzz" if connected == "yes": chars = filter(lambda char: char.get('char') is not None, chars) elif connected == "no": chars = filter(lambda char: char.get('char') is None, chars) context = { "corp": corp, "char_count": corp.characters.filter( owner__isnull=False ).count(), "chars": sorted(chars, key=lambda x: x[order_by]), "order_by": "?orderby=%s" % request.GET.get("orderby", "character"), "connected": connected } return render(request, "eveauth/corpaudit_view.html", context)