def open_fleet(character_id, motd, free_move, name, groups): required_scopes = ["esi-fleets.read_fleet.v1", "esi-fleets.write_fleet.v1"] c = esi.client token = Token.get_token(character_id, required_scopes) fleet_result = c.Fleets.get_characters_character_id_fleet( character_id=token.character_id, token=token.valid_access_token()).result() fleet_id = fleet_result.pop("fleet_id") fleet_role = fleet_result.pop("role") if fleet_id == None or fleet_role == None or fleet_role != "fleet_commander": return fleet = Fleet( fleet_id=fleet_id, created_at=timezone.now(), motd=motd, is_free_move=free_move, fleet_commander_id=token.character_id, name=name, ) fleet.save() fleet.groups.set(groups) esiFleet = {"is_free_move": free_move, "motd": motd} c.Fleets.put_fleets_fleet_id(fleet_id=fleet_id, token=token.valid_access_token(), new_settings=esiFleet).result()
def get_current_ship_location(character_id): audit_char = CharacterAudit.objects.get(character__character_id=character_id) req_scopes = ['esi-location.read_location.v1', 'esi-location.read_ship_type.v1'] token = Token.get_token(character_id, req_scopes) if not token: return False ship = providers.esi.client.Location.get_characters_character_id_ship(character_id=character_id, token=token.valid_access_token()).result() location = providers.esi.client.Location.get_characters_character_id_location(character_id=character_id, token=token.valid_access_token()).result() location_id = location.get('solar_system_id') location_flag = "solar_system" location_type = "unlocked" if location.get('structure_id') is not None: location_id = location.get('structure_id') location_flag = "item" location_type = "hangar" elif location.get('station_id') is not None: location_id = location.get('station_id') location_flag = "station" location_type = "hangar" current_ship = { "item_id": ship.get('ship_item_id'), "type_id": ship.get('ship_type_id'), "name": ship.get('ship_name'), "system_id": location.get('solar_system_id'), "location_id": location_id, "location_flag": location_flag, "location_type": location_type, } return current_ship
def update_character(char_id): character = CharacterAudit.objects.filter( character__character_id=char_id).first() if character is None: token = Token.get_token(char_id, app_settings.get_character_scopes()) if token: try: if token.valid_access_token(): character, created = CharacterAudit.objects.update_or_create( character=EveCharacter.objects.get_character_by_id( token.character_id)) except TokenExpiredError: return False logger.info("Starting Updates for {}".format( character.character.character_name)) que = [] que.append(update_char_roles.si(character.character.character_id)) que.append(update_char_corp_history.si(character.character.character_id)) que.append(update_char_notifications.si(character.character.character_id)) que.append(update_char_skill_list.si(character.character.character_id)) que.append(update_char_skill_queue.si(character.character.character_id)) que.append(update_clones.si(character.character.character_id)) que.append(update_char_wallet.si(character.character.character_id)) que.append(update_char_orders.si(character.character.character_id)) que.append(update_char_order_history.si(character.character.character_id)) que.append(update_char_assets.si(character.character.character_id)) que.append(update_char_mail.si(character.character.character_id)) chain(que).apply_async(priority=6)
def update_character_skill_list(character_id): audit_char = CharacterAudit.objects.get( character__character_id=character_id) logger.debug("Updating Skills for: {}".format( audit_char.character.character_name)) req_scopes = ['esi-skills.read_skills.v1'] token = Token.get_token(character_id, req_scopes) if not token: return "No Tokens" skills = providers.esi.client.Skills.get_characters_character_id_skills( character_id=character_id, token=token.valid_access_token()).result() Skill.objects.filter( character=audit_char).delete() # Delete current SkillList SkillTotals.objects.update_or_create(character=audit_char, defaults={ 'total_sp': skills.get('total_sp', 0), 'unallocated_sp': skills.get('unallocated_sp', 0) }) _check_skills = [] _create_skills = [] for skill in skills.get('skills', []): _check_skills.append(skill.get('skill_id')) _skill = Skill(character=audit_char, skill_id=skill.get('skill_id'), skill_name_id=skill.get('skill_id'), active_skill_level=skill.get('active_skill_level'), skillpoints_in_skill=skill.get('skillpoints_in_skill'), trained_skill_level=skill.get('trained_skill_level')) _create_skills.append(_skill) EveItemType.objects.create_bulk_from_esi(_check_skills) Skill.objects.bulk_create(_create_skills) audit_char.last_update_skills = timezone.now() audit_char.save() audit_char.is_active() return "Finished skills for: {}".format( audit_char.character.character_name)
def get_fleet_composition(fleet_id): required_scopes = ["esi-fleets.read_fleet.v1", "esi-fleets.write_fleet.v1"] c = esi.client fleet = Fleet.objects.get(fleet_id=fleet_id) token = Token.get_token(fleet.fleet_commander_id, required_scopes) fleet_infos = c.Fleets.get_fleets_fleet_id_members( fleet_id=fleet_id, token=token.valid_access_token()).result() characters = {} systems = {} ship_type = {} for member in fleet_infos: characters[member["character_id"]] = "" systems[member["solar_system_id"]] = "" ship_type[member["ship_type_id"]] = "" ids = [] ids.extend(list(characters.keys())) ids.extend(list(systems.keys())) ids.extend(list(ship_type.keys())) ids_to_name = c.Universe.post_universe_names(ids=ids).result() for member in fleet_infos: index = [x["id"] for x in ids_to_name].index(member["character_id"]) member["character_name"] = ids_to_name[index]["name"] for member in fleet_infos: index = [x["id"] for x in ids_to_name].index(member["solar_system_id"]) member["solar_system_name"] = ids_to_name[index]["name"] for member in fleet_infos: index = [x["id"] for x in ids_to_name].index(member["ship_type_id"]) member["ship_type_name"] = ids_to_name[index]["name"] aggregate = get_fleet_aggregate(fleet_infos) differential = dict() for key, value in aggregate.items(): fleet_info_agg = FleetInformation.objects.filter( fleet__fleet_id=fleet_id, ship_type_name=key) if fleet_info_agg.count() > 0: differential[key] = value - fleet_info_agg.latest("date").count else: differential[key] = value FleetInformation.objects.create(fleet=fleet, ship_type_name=key, count=value) return FleetViewAggregate(fleet_infos, aggregate, differential)
def update_character_skill_queue(character_id): audit_char = CharacterAudit.objects.get( character__character_id=character_id) logger.debug("Updating Skill Queue for: {}".format( audit_char.character.character_name)) req_scopes = ['esi-skills.read_skillqueue.v1'] token = Token.get_token(character_id, req_scopes) if not token: return "No Tokens" queue = providers.esi.client.Skills.get_characters_character_id_skillqueue( character_id=character_id, token=token.valid_access_token()).result() SkillQueue.objects.filter( character=audit_char).delete() # Delete current SkillList items = [] _check_skills = [] for item in queue: _check_skills.append(item.get('skill_id')) queue_item = SkillQueue( character=audit_char, finish_level=item.get('finished_level'), queue_position=item.get('queue_position'), skill_id=item.get('skill_id'), skill_name_id=item.get('skill_id'), finish_date=item.get('finish_date', None), level_end_sp=item.get('level_end_sp', None), level_start_sp=item.get('level_start_sp', None), start_date=item.get('start_date', None), training_start_sp=item.get('training_start_sp', None)) items.append(queue_item) EveItemType.objects.create_bulk_from_esi(_check_skills) SkillQueue.objects.bulk_create(items) audit_char.last_update_skill_que = timezone.now() audit_char.save() audit_char.is_active() return "Finished skill queue for: {}".format( audit_char.character.character_name)
def send_fleet_invitation(character_ids, fleet_id): required_scopes = ["esi-fleets.write_fleet.v1"] c = esi.client fleet = Fleet.objects.get(fleet_id=fleet_id) fleet_commander_token = Token.get_token(fleet.fleet_commander_id, required_scopes) _processes = [] with ThreadPoolExecutor(max_workers=50) as ex: for _chracter_id in character_ids: _processes.append( ex.submit( send_invitation, character_id=_chracter_id, fleet_commander_token=fleet_commander_token, fleet_id=fleet_id, )) for item in as_completed(_processes): _ = item.result()
def check_fleet_adverts(): required_scopes = ["esi-fleets.read_fleet.v1", "esi-fleets.write_fleet.v1"] c = esi.client fleets = Fleet.objects.all() for fleet in fleets: token = Token.get_token(fleet.fleet_commander_id, required_scopes) try: fleet_result = c.Fleets.get_characters_character_id_fleet( character_id=token.character_id, token=token.valid_access_token()).result() fleet_id = fleet_result["fleet_id"] if fleet_id != fleet.fleet_id: fleet.delete() except Exception as e: if e.status_code == 404: # 404 means the character is not in a fleet fleet.delete() logger.info( "Character is not in a fleet - fleet advert removed")
def search_names(request): add_perms = request.user.has_perm('toolbox.add_basic_eve_notes') add_global_perms = request.user.has_perm('toolbox.add_new_eve_notes') if not (add_perms or add_global_perms): messages.info(request, "No Permissions") return redirect('toolbox:eve_note_board') names = None searched = False message = False if request.method == 'POST': # check whether it's valid: name = request.POST.get('name') try: search_char = get_search_char(request.user) token = Token.get_token(search_char.character_id, ['esi-search.search_structures.v1']) hits = providers.provider.client.Search.get_characters_character_id_search( search=name, categories=['character', 'corporation', 'alliance'], character_id=search_char.character_id, token=token.valid_access_token()).result() corps = hits.get('corporation', []) chars = hits.get('character', []) alliance = hits.get('alliance', []) names_list = [] if corps: names_list += corps if chars: names_list += chars if alliance: names_list += alliance if len(names_list) > 0: names = providers.provider.client.Universe.post_universe_names(ids=names_list).result() searched = name except Exception as e: logger.error(e) message = e.message #messages.error(request, # "ESI Error. Please Try again later.") #return redirect('toolbox:eve_note_board') context = {'names': names, 'searched': searched, 'message': message, 'restricted_perms': add_global_perms } return HttpResponse(render_to_string('toolbox/search_name.html', context, request=request))
def update_character_notifications(character_id): audit_char = CharacterAudit.objects.get( character__character_id=character_id) logger.debug("Updating Notifications for: {}".format( audit_char.character.character_name)) req_scopes = ['esi-characters.read_notifications.v1'] token = Token.get_token(character_id, req_scopes) if not token: return "No Tokens" notifications = providers.esi.client.Character.get_characters_character_id_notifications( character_id=character_id, token=token.valid_access_token()).results() last_five_hundred = list( Notification.objects.filter( character=audit_char).order_by('-timestamp')[:500].values_list( 'notification_id', flat=True)) _creates = [] for note in notifications: if not note.get('notification_id') in last_five_hundred: _creates.append( Notification(character=audit_char, notification_id=note.get('notification_id'), sender_id=note.get('sender_id'), sender_type=note.get('sender_type'), notification_text=note.get('text'), timestamp=note.get('timestamp'), notification_type=note.get('type'), is_read=note.get('is_read'))) Notification.objects.bulk_create(_creates, batch_size=500) audit_char.last_update_clones = timezone.now() audit_char.save() audit_char.is_active() return "Finished notifications for: {0}".format( audit_char.character.character_name)
def update_character_roles(character_id): audit_char = CharacterAudit.objects.get(character__character_id=character_id) req_scopes = ['esi-characters.read_corporation_roles.v1'] token = Token.get_token(character_id, req_scopes) if not token: return False roles = providers.esi.client.Character.get_characters_character_id_roles(character_id=character_id, token=token.valid_access_token()).result() director = False accountant = False station_manager = False personnel_manager = False if "Director" in roles.get('roles', []): director = True if "Accountant" in roles.get('roles', []): accountant = True if "Station_Manager" in roles.get('roles', []): station_manager = True if "Personnel_Manager" in roles.get('roles', []): personnel_manager = True role_model, create = CharacterRoles.objects.update_or_create(character=audit_char, director=director, accountant=accountant, station_manager=station_manager, personnel_manager=personnel_manager) audit_char.last_update_roles = timezone.now() audit_char.save() audit_char.is_active() return "Finished roles for: {0}".format(audit_char.character.character_name)
def update_character(char_id): character = CharacterAudit.objects.filter( character__character_id=char_id).first() if character is None: token = Token.get_token(char_id, views.CHAR_REQUIRED_SCOPES) if token: character, created = CharacterAudit.objects.update_or_create( character=EveCharacter.objects.get_character_by_id( token.character_id)) logger.info("Starting Updates for {}".format( character.character.character_name)) que = [] que.append(update_char_corp_history.si(character.character.character_id)) que.append(update_char_notifications.si(character.character.character_id)) que.append(update_char_skill_list.si(character.character.character_id)) que.append(update_char_skill_queue.si(character.character.character_id)) que.append(update_clones.si(character.character.character_id)) que.append(update_char_wallet.si(character.character.character_id)) que.append(update_char_orders.si(character.character.character_id)) que.append(update_char_order_history.si(character.character.character_id)) que.append(update_char_assets.si(character.character.character_id)) chain(que).apply_async(priority=6)
def click_link(request: WSGIRequest, token, fatlink_hash: str = None): """ click fatlink helper :param request: :param token: :param fatlink_hash: :return: """ if fatlink_hash is None: request.session["msg"] = ["warning", "No FAT link hash provided."] return redirect("afat:dashboard") try: try: fleet = AFatLink.objects.get(hash=fatlink_hash) except AFatLink.DoesNotExist: request.session["msg"] = ["warning", "The hash provided is not valid."] return redirect("afat:dashboard") dur = ClickAFatDuration.objects.get(fleet=fleet) now = timezone.now() - timedelta(minutes=dur.duration) if now >= fleet.afattime: request.session["msg"] = [ "warning", ( "Sorry, that FAT Link is expired. If you were on that fleet, " "contact your FC about having your FAT manually added." ), ] return redirect("afat:dashboard") character = EveCharacter.objects.get(character_id=token.character_id) try: required_scopes = [ "esi-location.read_location.v1", "esi-location.read_online.v1", "esi-location.read_ship_type.v1", ] esi_token = Token.get_token(token.character_id, required_scopes) # check if character is online character_online = esi.client.Location.get_characters_character_id_online( character_id=token.character_id, token=esi_token.valid_access_token() ).result() if character_online["online"] is True: # character location location = esi.client.Location.get_characters_character_id_location( character_id=token.character_id, token=esi_token.valid_access_token(), ).result() # current ship ship = esi.client.Location.get_characters_character_id_ship( character_id=token.character_id, token=esi_token.valid_access_token(), ).result() # system information system = esi.client.Universe.get_universe_systems_system_id( system_id=location["solar_system_id"] ).result()["name"] ship_name = provider.get_itemtype(ship["ship_type_id"]).name try: fat = AFat( afatlink=fleet, character=character, system=system, shiptype=ship_name, ) fat.save() if fleet.fleet is not None: name = fleet.fleet else: name = fleet.hash request.session["msg"] = [ "success", ( "FAT registered for {character_name} " "at {fleet_name}".format( character_name=character.character_name, fleet_name=name ) ), ] logger.info( "Fleetparticipation for fleet {fleet_name} " "registered for pilot {character_name}".format( fleet_name=name, character_name=character.character_name ) ) return redirect("afat:dashboard") except Exception: request.session["msg"] = [ "warning", ( "A FAT already exists for the selected character " "({character_name}) and fleet combination.".format( character_name=character.character_name ) ), ] return redirect("afat:dashboard") else: request.session["msg"] = [ "warning", ( "Cannot register the fleet participation for {character_name}. " "The character needs to be online.".format( character_name=character.character_name ) ), ] return redirect("afat:dashboard") except Exception: request.session["msg"] = [ "warning", ( "There was an issue with the token for {character_name}. " "Please try again.".format(character_name=character.character_name) ), ] return redirect("afat:dashboard") except Exception: request.session["msg"] = [ "warning", "The hash provided is not for a clickable FAT Link.", ] return redirect("afat:dashboard")
def link_create_esi(request: WSGIRequest, token, fatlink_hash: str): """ helper: create ESI link :param request: :param token: :param fatlink_hash: :return: """ # Check if there is a fleet try: required_scopes = ["esi-fleets.read_fleet.v1"] esi_token = Token.get_token(token.character_id, required_scopes) fleet_from_esi = esi.client.Fleets.get_characters_character_id_fleet( character_id=token.character_id, token=esi_token.valid_access_token() ).result() except Exception: # Not in a fleet request.session["msg"] = [ "warning", "To use the ESI function, you neeed to be in fleet and you need to be " "the fleet boss! You can create a clickable FAT link and share it, " "if you like.", ] # return to "Add FAT Link" view return redirect("afat:link_add") # Check if this character already has a fleet creator_character = EveCharacter.objects.get(character_id=token.character_id) registered_fleets_for_creator = AFatLink.objects.filter( is_esilink=True, is_registered_on_esi=True, character__character_name=creator_character.character_name, ) fleet_already_registered = False character_has_registered_fleets = False registered_fleets_to_close = list() if registered_fleets_for_creator.count() > 0: character_has_registered_fleets = True for registered_fleet in registered_fleets_for_creator: if registered_fleet.esi_fleet_id == fleet_from_esi["fleet_id"]: # Character already has a fleet fleet_already_registered = True else: registered_fleets_to_close.append( {"registered_fleet": registered_fleet} ) if fleet_already_registered is True: request.session["msg"] = [ "warning", "Fleet with ID {fleet_id} for your character {character_name} " "has already been registered and pilots joining this " "fleet are automatically tracked.".format( fleet_id=fleet_from_esi["fleet_id"], character_name=creator_character.character_name, ), ] # return to "Add FAT Link" view return redirect("afat:link_add") # remove all former registered fleets if there are any if ( character_has_registered_fleets is True and fleet_already_registered is False and len(registered_fleets_to_close) > 0 ): for registered_fleet_to_close in registered_fleets_to_close: logger.info( "Closing ESI FAT link with hash {fatlink_hash}. Reason: {reason}".format( fatlink_hash=registered_fleet_to_close["registered_fleet"].hash, reason=( "FC has opened a new fleet with the character {character}" ).format(character=creator_character.character_name), ) ) registered_fleet_to_close["registered_fleet"].is_registered_on_esi = False registered_fleet_to_close["registered_fleet"].save() # Check if we deal with the fleet boss here try: esi_fleet_member = esi.client.Fleets.get_fleets_fleet_id_members( fleet_id=fleet_from_esi["fleet_id"], token=esi_token.valid_access_token(), ).result() except Exception: request.session["msg"] = [ "warning", "Not Fleet Boss! Only the fleet boss can utilize the ESI function. " "You can create a clickable FAT link and share it, if you like.", ] # return to "Add FAT Link" view return redirect("afat:link_add") creator_character = EveCharacter.objects.get(character_id=token.character_id) # create the fatlink fatlink = AFatLink( afattime=timezone.now(), fleet=request.session["fatlink_form__name"], creator=request.user, character=creator_character, hash=fatlink_hash, is_esilink=True, is_registered_on_esi=True, esi_fleet_id=fleet_from_esi["fleet_id"], ) # add fleet type if there is any if ( request.session["fatlink_form__type"] is not None and request.session["fatlink_form__type"] != -1 ): fatlink.link_type = AFatLinkType.objects.get( id=request.session["fatlink_form__type"] ) # save it fatlink.save() # clear session del request.session["fatlink_form__name"] del request.session["fatlink_form__type"] # process fleet members process_fats.delay( data_list=esi_fleet_member, data_source="esi", fatlink_hash=fatlink_hash ) request.session[ "{fatlink_hash}-creation-code".format(fatlink_hash=fatlink_hash) ] = 200 logger.info( "ESI FAT link {fatlink_hash} created by {user}".format( fatlink_hash=fatlink_hash, user=request.user ) ) return redirect("afat:link_edit", fatlink_hash=fatlink_hash)
def update_character_mail(character_id): # This function will deal with ALL mail related updates audit_char = CharacterAudit.objects.get(character__character_id=character_id) req_scopes = ['esi-mail.read_mail.v1'] token = Token.get_token(character_id, req_scopes) if not token: return False _current_eve_ids = list(EveName.objects.all().values_list('eve_id', flat=True)) # Mail Labels labels = providers.esi.client.Mail.get_characters_character_id_mail_labels(character_id=character_id, token=token.valid_access_token()).result() for label in labels.get('labels'): MailLabel.objects.update_or_create(character=audit_char, label_id=label.get('label_id'), defaults={ 'label_name': label.get('name', None), 'label_color': label.get('color', None), 'unread_count': label.get('unread_count', None) }) # Get all mail ids mail_ids = [] try: last_id_db = MailMessage.objects.filter(character=audit_char).order_by('-mail_id')[0].mail_id except IndexError: last_id_db = None last_id = None while True: if last_id is None: mail = providers.esi.client.Mail.get_characters_character_id_mail(character_id=character_id, token=token.valid_access_token()).result() else: mail = providers.esi.client.Mail.get_characters_character_id_mail(character_id=character_id, last_mail_id=last_id, token=token.valid_access_token()).result() if len(mail) == 0: # If there are 0 and this is not the first page, then we have reached the # end of retrievable mail. break stop = False for msg in mail: if msg.get('mail_id') == last_id_db: # Break both loops if we have reached the most recent mail in the db. print("Found {} in database for user {}.".format(msg.get('mail_id'), character_id)) stop = True break mail_ids.append(msg.get('mail_id')) last_id = msg.get('mail_id') if stop is True: # Break the while loop if we reach the last mail message that is in the db. break audit_char.last_update_mails = timezone.now() audit_char.save() audit_char.is_active() if len(mail_ids) is 0: logger.debug("No new mails for {}".format(character_id)) return return mail_ids
def process_mail_list(character_id: int, ids: list): """ Takes list of mail ids to process :param character_id: int :param ids: list of ids to process :return: Nothing """ audit_char = CharacterAudit.objects.get(character__character_id=character_id) req_scopes = ['esi-mail.read_mail.v1'] token = Token.get_token(character_id, req_scopes) if not token: return False _current_eve_ids = list(EveName.objects.all().values_list('eve_id', flat=True)) _current_mail_rec = list(MailRecipient.objects.all().values_list('recipient_id', flat=True)) messages = [] m_l_map = {} m_r_map = {} for id in ids: msg = providers.esi.client.Mail.get_characters_character_id_mail_mail_id(character_id=character_id, mail_id=id, token=token.valid_access_token()).result() id_k = int(str(audit_char.character.character_id)+str(id)) if msg.get('from', 0) not in _current_eve_ids: EveName.objects.get_or_create_from_esi(msg.get('from')) _current_eve_ids.append(msg.get('from', 0)) msg_obj = MailMessage(character=audit_char, id_key=id_k, mail_id=id, from_id=msg.get('from', None), from_name_id=msg.get('from', None), is_read=msg.get('read', None), timestamp=msg.get('timestamp'), subject=msg.get('subject', None), body=msg.get('body', None)) messages.append(msg_obj) if msg.get('labels'): labels = msg.get('labels') m_l_map[id] = labels m_r_map[id] = [(r.get('recipient_id'),r.get('recipient_type')) for r in msg.get('recipients')] msgs = MailMessage.objects.bulk_create(messages) logger.debug("Message Objects for {} to {} created".format(ids[0], ids[-1])) LabelThroughModel = MailMessage.labels.through lms = [] for msg in msgs: if msg.mail_id in m_l_map: for label in m_l_map[msg.mail_id]: lm = LabelThroughModel(mailmessage_id=msg.id_key, maillabel_id=MailLabel.objects.get(character=audit_char, label_id=label).pk) lms.append(lm) LabelThroughModel.objects.bulk_create(lms) RecipThroughModel = MailMessage.recipients.through rms = [] for msg in msgs: if msg.mail_id in m_r_map: for recip,r_type in m_r_map[msg.mail_id]: recip_name = None if r_type != "mailing_list": if recip not in _current_eve_ids: EveName.objects.get_or_create_from_esi(recip) _current_eve_ids.append(recip) recip_name = recip if recip not in _current_mail_rec: MailRecipient.objects.get_or_create(recipient_id=recip, recipient_name_id=recip_name, recipient_type=r_type) _current_mail_rec.append(recip) rm = RecipThroughModel(mailmessage_id=msg.id_key, mailrecipient_id=recip) rms.append(rm) RecipThroughModel.objects.bulk_create(rms) return "Completed mail fetch for: %s" % str(character_id)
def update_character_order_history(character_id): audit_char = CharacterAudit.objects.get(character__character_id=character_id) logger.debug("Updating Market Order History for: {}".format(audit_char.character.character_name)) req_scopes = ['esi-markets.read_character_orders.v1'] token = Token.get_token(character_id, req_scopes) if not token: return "No Tokens" order_history = providers.esi.client.Market.get_characters_character_id_orders_history(character_id=character_id, token=token.valid_access_token()).results() closed_ids = list(CharacterMarketOrder.objects.filter(character=audit_char).exclude(state='active').values_list("order_id", flat=True)) all_locations = list(EveLocation.objects.all().values_list('location_id', flat=True)) updates = [] creates = [] type_ids = [] tracked_ids = [] for order in order_history: tracked_ids.append(order.get('order_id')) if order.get('type_id') not in type_ids: type_ids.append(order.get('type_id')) _order = CharacterMarketOrder( character = audit_char, order_id = order.get('order_id'), duration = order.get('duration'), escrow = order.get('escrow'), is_buy_order = order.get('is_buy_order'), issued = order.get('issued'), location_id = order.get('location_id'), min_volume = order.get('min_volume'), price = order.get('price'), order_range = order.get('range'), region_id = order.get('region_id'), region_name_id = order.get('region_id'), type_id = order.get('type_id'), type_name_id = order.get('type_id'), volume_remain = order.get('volume_remain'), volume_total = order.get('volume_total'), is_corporation = order.get('is_corporation'), state = order.get('state') ) if order.get('location_id') in all_locations: _order.location_name_id = order.get('location_id') if order.get('order_id') in closed_ids: updates.append(_order) else: creates.append(_order) EveItemType.objects.create_bulk_from_esi(type_ids) if len(updates)>0: CharacterMarketOrder.objects.bulk_update(updates, fields=['duration', 'escrow', 'min_volume', 'price', 'order_range', 'volume_remain', 'volume_total', 'state']) if len(creates)>0: CharacterMarketOrder.objects.bulk_create(creates) return "Finished Order History for: {}".format(audit_char.character.character_name)
def create_esi_fatlink_callback(request: WSGIRequest, token, fatlink_hash: str) -> HttpResponseRedirect: """ helper: create ESI link (callback, used when coming back from character selection) :param request: :type request: :param token: :type token: :param fatlink_hash: :type fatlink_hash: :return: :rtype: """ # check if there is a fleet try: required_scopes = ["esi-fleets.read_fleet.v1"] esi_token = Token.get_token(token.character_id, required_scopes) fleet_from_esi = esi.client.Fleets.get_characters_character_id_fleet( character_id=token.character_id, token=esi_token.valid_access_token()).result() except Exception: # not in a fleet request.session["msg"] = [ "warning", "To use the ESI function, you neeed to be in fleet and you need to be " "the fleet boss! You can create a clickable FAT link and share it, " "if you like.", ] # return to "Add FAT Link" view return redirect("afat:fatlinks_add_fatlink") # check if this character already has a fleet creator_character = EveCharacter.objects.get( character_id=token.character_id) registered_fleets_for_creator = AFatLink.objects.filter( is_esilink=True, is_registered_on_esi=True, character__character_name=creator_character.character_name, ) fleet_already_registered = False character_has_registered_fleets = False registered_fleets_to_close = list() if registered_fleets_for_creator.count() > 0: character_has_registered_fleets = True for registered_fleet in registered_fleets_for_creator: if registered_fleet.esi_fleet_id == fleet_from_esi["fleet_id"]: # Character already has a fleet fleet_already_registered = True else: registered_fleets_to_close.append( {"registered_fleet": registered_fleet}) # if the FC already has a fleet and it is the same as already registered, # just throw a warning if fleet_already_registered is True: request.session["msg"] = [ "warning", "Fleet with ID {fleet_id} for your character {character_name} " "has already been registered and pilots joining this " "fleet are automatically tracked.".format( fleet_id=fleet_from_esi["fleet_id"], character_name=creator_character.character_name, ), ] # return to "Add FAT Link" view return redirect("afat:fatlinks_add_fatlink") # if it's a new fleet, remove all former registered fleets if there are any if (character_has_registered_fleets is True and fleet_already_registered is False and len(registered_fleets_to_close) > 0): for registered_fleet_to_close in registered_fleets_to_close: reason = (f"FC has opened a new fleet with the " f"character {creator_character.character_name}") logger.info( (f"Closing ESI FAT link with hash " f'"{registered_fleet_to_close["registered_fleet"].hash}". ' f"Reason: {reason}")) registered_fleet_to_close[ "registered_fleet"].is_registered_on_esi = False registered_fleet_to_close["registered_fleet"].save() # check if we deal with the fleet boss here try: esi_fleet_member = esi.client.Fleets.get_fleets_fleet_id_members( fleet_id=fleet_from_esi["fleet_id"], token=esi_token.valid_access_token(), ).result() except Exception: request.session["msg"] = [ "warning", "Not Fleet Boss! Only the fleet boss can utilize the ESI function. " "You can create a clickable FAT link and share it, if you like.", ] # return to "Add FAT Link" view return redirect("afat:fatlinks_add_fatlink") creator_character = EveCharacter.objects.get( character_id=token.character_id) # create the fatlink fatlink = AFatLink( afattime=timezone.now(), fleet=request.session["fatlink_form__name"], creator=request.user, character=creator_character, hash=fatlink_hash, is_esilink=True, is_registered_on_esi=True, esi_fleet_id=fleet_from_esi["fleet_id"], ) # add fleet type if there is any if request.session["fatlink_form__type"] is not None: fatlink.link_type_id = request.session["fatlink_form__type"] # save it fatlink.save() # writing DB log fleet_type = "" if fatlink.link_type: fleet_type = f" (Fleet Type: {fatlink.link_type.name})" write_log( request=request, log_event=AFatLogEvent.CREATE_FATLINK, log_text=( f'ESI FAT link with name "{request.session["fatlink_form__name"]}"' f"{fleet_type} was created by {request.user}"), fatlink_hash=fatlink.hash, ) logger.info((f'ESI FAT link "{fatlink_hash}" with name ' f'"{request.session["fatlink_form__name"]}"{fleet_type} ' f"was created by {request.user}")) # clear session del request.session["fatlink_form__name"] del request.session["fatlink_form__type"] # process fleet members in the background process_fats.delay(data_list=esi_fleet_member, data_source="esi", fatlink_hash=fatlink_hash) request.session["{fatlink_hash}-creation-code".format( fatlink_hash=fatlink_hash)] = 200 return redirect("afat:fatlinks_details_fatlink", fatlink_hash=fatlink_hash)
def create_esi_fatlink_callback(request: WSGIRequest, token, fatlink_hash: str) -> HttpResponseRedirect: """ Helper :: create ESI link (callback, used when coming back from character selection) :param request: :type request: :param token: :type token: :param fatlink_hash: :type fatlink_hash: :return: :rtype: """ # Check if there is a fleet try: required_scopes = ["esi-fleets.read_fleet.v1"] esi_token = Token.get_token(token.character_id, required_scopes) fleet_from_esi = esi.client.Fleets.get_characters_character_id_fleet( character_id=token.character_id, token=esi_token.valid_access_token()).result() except Exception: # Not in a fleet messages.warning( request, mark_safe( _("<h4>Warning!</h4>" "<p>To use the ESI function, you need to be in fleet and you need " "to be the fleet boss! You can create a clickable FAT link and " "share it, if you like.</p>")), ) # Return to "Add FAT Link" view return redirect("afat:fatlinks_add_fatlink") # check if this character already has a fleet creator_character = EveCharacter.objects.get( character_id=token.character_id) registered_fleets_for_creator = AFatLink.objects.select_related_default( ).filter( is_esilink=True, is_registered_on_esi=True, character__character_name=creator_character.character_name, ) fleet_already_registered = False character_has_registered_fleets = False registered_fleets_to_close = [] if registered_fleets_for_creator.count() > 0: character_has_registered_fleets = True for registered_fleet in registered_fleets_for_creator: if registered_fleet.esi_fleet_id == fleet_from_esi["fleet_id"]: # Character already has a fleet fleet_already_registered = True else: registered_fleets_to_close.append( {"registered_fleet": registered_fleet}) # If the FC already has a fleet, and it is the same as already registered, # just throw a warning if fleet_already_registered is True: messages.warning( request, mark_safe( _(f'<h4>Warning!</h4><p>Fleet with ID "{fleet_from_esi["fleet_id"]}" for your character {creator_character.character_name} has already been registered and pilots joining this fleet are automatically tracked.</p>' )), ) # Return to "Add FAT Link" view return redirect("afat:fatlinks_add_fatlink") # If it's a new fleet, remove all former registered fleets, if there are any if (character_has_registered_fleets is True and fleet_already_registered is False and len(registered_fleets_to_close) > 0): for registered_fleet_to_close in registered_fleets_to_close: reason = (f"FC has opened a new fleet with the " f"character {creator_character.character_name}") logger.info( f"Closing ESI FAT link with hash " f'"{registered_fleet_to_close["registered_fleet"].hash}". ' f"Reason: {reason}") registered_fleet_to_close[ "registered_fleet"].is_registered_on_esi = False registered_fleet_to_close["registered_fleet"].save() # Check if we deal with the fleet boss here try: esi_fleet_member = esi.client.Fleets.get_fleets_fleet_id_members( fleet_id=fleet_from_esi["fleet_id"], token=esi_token.valid_access_token(), ).result() except Exception: messages.warning( request, mark_safe( _("<h4>Warning!</h4>" "<p>Not Fleet Boss! Only the fleet boss can utilize the ESI " "function. You can create a clickable FAT link and share it, " "if you like.</p>")), ) # Return to "Add FAT Link" view return redirect("afat:fatlinks_add_fatlink") creator_character = EveCharacter.objects.get( character_id=token.character_id) # Create the fat link fatlink = AFatLink( afattime=timezone.now(), fleet=request.session["fatlink_form__name"], creator=request.user, character=creator_character, hash=fatlink_hash, is_esilink=True, is_registered_on_esi=True, esi_fleet_id=fleet_from_esi["fleet_id"], ) # Add fleet type, if there is any if request.session["fatlink_form__type"] is not None: fatlink.link_type_id = request.session["fatlink_form__type"] # Save it fatlink.save() # Writing DB log fleet_type = "" if fatlink.link_type: fleet_type = f"(Fleet Type: {fatlink.link_type.name})" write_log( request=request, log_event=AFatLog.Event.CREATE_FATLINK, log_text=( f'ESI FAT link with name "{request.session["fatlink_form__name"]}" ' f"{fleet_type} was created by {request.user}"), fatlink_hash=fatlink.hash, ) logger.info(f'ESI FAT link "{fatlink_hash}" with name ' f'"{request.session["fatlink_form__name"]}"{fleet_type} ' f"was created by {request.user}") # Clear session del request.session["fatlink_form__name"] del request.session["fatlink_form__type"] # Process fleet members in background process_fats.delay(data_list=esi_fleet_member, data_source="esi", fatlink_hash=fatlink_hash) messages.success( request, mark_safe( _("<h4>Success!</h4>" "<p>FAT Link Created!</p>" "<p>FATs have been queued, they may take a few mins to show up.</p>" "<p>Pilots who join later will be automatically added until you " "close or leave the fleet in-game.</p>")), ) return redirect("afat:fatlinks_details_fatlink", fatlink_hash=fatlink_hash)
def update_character_assets(character_id): audit_char = CharacterAudit.objects.get(character__character_id=character_id) logger.debug("Updating Assets for: {}".format(audit_char.character.character_name)) req_scopes = ['esi-assets.read_assets.v1'] token = Token.get_token(character_id, req_scopes) if not token: return "No Tokens" assets = providers.esi.client.Assets.get_characters_character_id_assets(character_id=character_id, token=token.valid_access_token()).results() delete_query = CharacterAsset.objects.filter(character=audit_char) # Flush Assets if delete_query.exists(): delete_query._raw_delete(delete_query.db) # speed and we are not caring about f-keys or signals on these models location_names = list(EveLocation.objects.all().values_list('location_id', flat=True)) _current_type_ids = [] item_ids = [] items = [] for item in assets: if item.get('type_id') not in _current_type_ids: _current_type_ids.append(item.get('type_id')) item_ids.append(item.get('item_id')) asset_item = CharacterAsset(character=audit_char, blueprint_copy=item.get('is_blueprint_copy'), singleton=item.get('is_singleton'), item_id=item.get('item_id'), location_flag=item.get('location_flag'), location_id=item.get('location_id'), location_type=item.get('location_type'), quantity=item.get('quantity'), type_id=item.get('type_id'), type_name_id=item.get('type_id') ) if item.get('location_id') in location_names: asset_item.location_name_id = item.get('location_id') items.append(asset_item) ship = get_current_ship_location(character_id) # current ship doesn't show if in space sometimes if ship: if ship.get('item_id') not in item_ids: if ship.get('type_id') not in _current_type_ids: _current_type_ids.append(ship.get('type_id')) asset_item = CharacterAsset(character=audit_char, singleton=True, item_id=ship.get('item_id'), location_flag=ship.get('location_flag'), location_id=ship.get('location_id'), location_type=ship.get('location_type'), quantity=1, type_id=ship.get('type_id'), type_name_id=ship.get('type_id') ) if ship.get('location_id') in location_names: asset_item.location_name_id = ship.get('location_id') items.append(asset_item) EveItemType.objects.create_bulk_from_esi(_current_type_ids) CharacterAsset.objects.bulk_create(items) audit_char.last_update_assets = timezone.now() audit_char.save() audit_char.is_active() return "Finished assets for: {}".format(audit_char.character.character_name)
def update_esi_fatlinks() -> None: """ checking ESI fat links for changes :return: :rtype: """ required_scopes = ["esi-fleets.read_fleet.v1"] try: esi_fatlinks = AFatLink.objects.filter( is_esilink=True, is_registered_on_esi=True ) for fatlink in esi_fatlinks: initialize_caches(fatlink=fatlink) logger.info(f'Processing ESI FAT link with hash "{fatlink.hash}"') if fatlink.creator.profile.main_character is not None: # Check if there is a fleet try: fleet_commander_id = fatlink.character.character_id esi_token = Token.get_token(fleet_commander_id, required_scopes) fleet_from_esi = ( esi.client.Fleets.get_characters_character_id_fleet( character_id=fleet_commander_id, token=esi_token.valid_access_token(), ).result() ) if fatlink.esi_fleet_id == fleet_from_esi["fleet_id"]: # Check if we deal with the fleet boss here try: esi_fleet_member = ( esi.client.Fleets.get_fleets_fleet_id_members( fleet_id=fleet_from_esi["fleet_id"], token=esi_token.valid_access_token(), ).result() ) # process fleet members process_fats.delay( data_list=esi_fleet_member, data_source="esi", fatlink_hash=fatlink.hash, ) except Exception: esi_fatlinks_error_handling( cache_key=CACHE_KEY_NO_FLEETBOSS_ERROR, fatlink=fatlink, logger_message="FC is no longer the fleet boss.", ) else: esi_fatlinks_error_handling( cache_key=CACHE_KEY_FLEET_CHANGED_ERROR, fatlink=fatlink, logger_message="FC switched to another fleet", ) except HTTPNotFound: esi_fatlinks_error_handling( cache_key=CACHE_KEY_NOT_IN_FLEET_ERROR, fatlink=fatlink, logger_message=( "FC is not in the registered fleet anymore or " "fleet is no longer available." ), ) except Exception: esi_fatlinks_error_handling( cache_key=CACHE_KEY_NO_FLEET_ERROR, fatlink=fatlink, logger_message="Registered fleet is no longer available.", ) else: close_esi_fleet(fatlink=fatlink, reason="No fatlink creator available.") except AFatLink.DoesNotExist: pass
def fetch_location_name(location_id, location_flag, character_id): """Takes a location_id and character_id and returns a location model for items in a station/structure or in space""" existing = EveLocation.objects.filter(location_id=location_id) if existing.exists(): return existing.first() req_scopes = ['esi-universe.read_structures.v1'] token = Token.get_token(character_id, req_scopes) if not token: return None accepted_location_flags = [ 'AssetSafety', 'Deliveries', 'Hangar', 'HangarAll' ] if location_flag not in accepted_location_flags: if location_flag is not None: return None # ship fits or in cargo holds or what ever also dont care if location_id == 2004: # ASSET SAFETY return EveLocation(location_id=location_id, location_name="Asset Safety") elif 30000000 < location_id < 33000000: # Solar System system = MapSystem.objects.filter(system_id=location_id) if not system.exists(): logger.error("Unknown System, Have you populated the map?") #TODO Do i fire the map population task here? return None else: system = system.first() return EveLocation(location_id=location_id, location_name=system.name, system=system) elif 60000000 < location_id < 64000000: # Station ID station = providers.esi.client.Universe.get_universe_stations_station_id( station_id=location_id).result() system = MapSystem.objects.filter(system_id=station.get('system_id')) if not system.exists(): logger.error("Unknown System, Have you populated the map?") #TODO Do i fire the map population task here? return None return EveLocation(location_id=location_id, location_name=station.get('name'), system_id=station.get('system_id')) else: # Structure id? try: structure = providers.esi.client.Universe.get_universe_structures_structure_id( structure_id=location_id, token=token.valid_access_token()).result() except HTTPForbidden as e: # no access if int(e.response.headers.get('x-esi-error-limit-remain')) < 50: set_error_count_flag() logger.debug( "Failed to get location:{}, Error:{}, Errors Remaining:{}, Time Remaining: {}" .format(location_id, e.message, e.response.headers.get('x-esi-error-limit-remain'), e.response.headers.get('x-esi-error-limit-reset'))) return None system = MapSystem.objects.filter( system_id=structure.get('solar_system_id')) if not system.exists(): logger.error("Unknown System, Have you populated the map?") #TODO Do i fire the map population task here? return None return EveLocation(location_id=location_id, location_name=structure.get('name'), system_id=structure.get('solar_system_id'))
def update_character_clones(character_id): audit_char = CharacterAudit.objects.get(character__character_id=character_id) logger.debug("Updating Clones and Implants for: {}".format(audit_char.character.character_name)) req_scopes = ['esi-clones.read_clones.v1', 'esi-clones.read_implants.v1'] token = Token.get_token(character_id, req_scopes) if not token: return "No Tokens" jump_clones = providers.esi.client.Clones.get_characters_character_id_clones(character_id=character_id, token=token.valid_access_token()).result() active_clone = providers.esi.client.Clones.get_characters_character_id_implants(character_id=character_id, token=token.valid_access_token()).result() all_locations = list(EveLocation.objects.all().values_list('location_id', flat=True)) clones = {} clones[0] = active_clone char_clone, created = Clone.objects.update_or_create(character=audit_char, defaults={ 'last_clone_jump_date': jump_clones.get('last_clone_jump_date'), 'last_station_change_date': jump_clones.get('last_station_change_date'), 'location_id': jump_clones.get('home_location').get('location_id'), 'location_type': jump_clones.get('home_location').get('location_type'), }) JumpClone.objects.filter(character=audit_char).delete() # remove all implants = [] type_ids = [] for clone in jump_clones.get('jump_clones'): _jumpclone = JumpClone(character=audit_char, jump_clone_id=clone.get('jump_clone_id'), location_id=clone.get('location_id'), location_type=clone.get('location_type'), name=clone.get('name')) if clone.get('location_id') in all_locations: _jumpclone.location_name_id = clone.get('location_id') _jumpclone.save() for implant in clone.get('implants'): if implant not in type_ids: type_ids.append(implant) implants.append(Implant(clone=_jumpclone, type_name_id=implant ) ) _jumpclone = JumpClone.objects.create(character=audit_char, jump_clone_id=0, name="Active Clone") for implant in active_clone: if implant not in type_ids: type_ids.append(implant) implants.append(Implant(clone=_jumpclone, type_name_id=implant, ) ) EveItemType.objects.create_bulk_from_esi(type_ids) Implant.objects.bulk_create(implants) audit_char.last_update_clones = timezone.now() audit_char.save() audit_char.is_active() return "Finished clones for: {}".format(audit_char.character.character_name)
def update_character_orders(character_id): audit_char = CharacterAudit.objects.get(character__character_id=character_id) logger.debug("Updating Market Orders for: {}".format(audit_char.character.character_name)) req_scopes = ['esi-markets.read_character_orders.v1'] token = Token.get_token(character_id, req_scopes) if not token: return "No Tokens" open_orders = providers.esi.client.Market.get_characters_character_id_orders(character_id=character_id, token=token.valid_access_token()) open_orders.request_config.also_return_response = True open_orders, result = open_orders.result() open_ids = list(CharacterMarketOrder.objects.filter(character=audit_char, state='active').values_list("order_id", flat=True)) all_locations = list(EveLocation.objects.all().values_list('location_id', flat=True)) updates = [] creates = [] type_ids = [] tracked_ids = [] for order in open_orders: tracked_ids.append(order.get('order_id')) if order.get('type_id') not in type_ids: type_ids.append(order.get('type_id')) _order = CharacterMarketOrder( character = audit_char, order_id = order.get('order_id'), duration = order.get('duration'), escrow = order.get('escrow'), is_buy_order = order.get('is_buy_order'), issued = order.get('issued'), location_id = order.get('location_id'), min_volume = order.get('min_volume'), price = order.get('price'), order_range = order.get('range'), region_id = order.get('region_id'), region_name_id = order.get('region_id'), type_id = order.get('type_id'), type_name_id = order.get('type_id'), volume_remain = order.get('volume_remain'), volume_total = order.get('volume_total'), is_corporation = order.get('is_corporation'), state = 'active' ) if order.get('location_id') in all_locations: _order.location_name_id = order.get('location_id') if order.get('order_id') in open_ids: updates.append(_order) else: creates.append(_order) EveItemType.objects.create_bulk_from_esi(type_ids) if len(updates)>0: CharacterMarketOrder.objects.bulk_update(updates, fields=['duration', 'escrow', 'min_volume', 'price', 'order_range', 'volume_remain', 'volume_total', 'state']) if len(creates)>0: CharacterMarketOrder.objects.bulk_create(creates) CharacterMarketOrder.objects.filter(character=audit_char, state='active').exclude(order_id__in=tracked_ids).delete() audit_char.last_update_orders = timezone.now() audit_char.cache_expire_orders = datetime.datetime.strptime(str(result.headers['expires']), '%a, %d %b %Y %H:%M:%S %Z') audit_char.save() audit_char.is_active() return "Finished Orders for: {}".format(audit_char.character.character_name)
def update_character_wallet(character_id): audit_char = CharacterAudit.objects.get(character__character_id=character_id) logger.debug("Updating wallet transactions for: {}".format(audit_char.character.character_name)) req_scopes = ['esi-wallet.read_character_wallet.v1'] token = Token.get_token(character_id, req_scopes) if not token: return "No Tokens" journal_items = providers.esi.client.Wallet.get_characters_character_id_wallet_journal(character_id=character_id, token=token.valid_access_token()).results() _current_journal = CharacterWalletJournalEntry.objects.filter(character=audit_char).values_list('entry_id', flat=True) # TODO add time filter _current_eve_ids = list(EveName.objects.all().values_list('eve_id', flat=True)) _new_names = [] items = [] for item in journal_items: if item.get('id') not in _current_journal: if item.get('second_party_id') not in _current_eve_ids: _new_names.append(item.get('second_party_id')) _current_eve_ids.append(item.get('second_party_id')) if item.get('first_party_id') not in _current_eve_ids: _new_names.append(item.get('first_party_id')) _current_eve_ids.append(item.get('first_party_id')) asset_item = CharacterWalletJournalEntry(character=audit_char, amount=item.get('amount'), balance=item.get('balance'), context_id=item.get('context_id'), context_id_type=item.get('context_id_type'), date=item.get('date'), description=item.get('description'), first_party_id=item.get('first_party_id'), first_party_name_id=item.get('first_party_id'), entry_id=item.get('id'), reason=item.get('reason'), ref_type=item.get('ref_type'), second_party_id=item.get('second_party_id'), second_party_name_id=item.get('second_party_id'), tax=item.get('tax'), tax_receiver_id=item.get('tax_receiver_id'), ) items.append(asset_item) created_names = EveName.objects.create_bulk_from_esi(_new_names) wallet_ballance = providers.esi.client.Wallet.get_characters_character_id_wallet(character_id=character_id, token=token.valid_access_token()).result() audit_char.balance=wallet_ballance audit_char.save() if created_names: CharacterWalletJournalEntry.objects.bulk_create(items) else: raise Exception("ESI Fail") audit_char.last_update_wallet = timezone.now() audit_char.save() audit_char.is_active() return "Finished wallet transactions for: {}".format(audit_char.character.character_name)
def add_fat(request: WSGIRequest, token, fatlink_hash: str = None) -> HttpResponseRedirect: """ Click fat link helper :param request: :type request: :param token: :type token: :param fatlink_hash: :type fatlink_hash: :return: :rtype: """ if fatlink_hash is None: messages.warning( request, mark_safe(_("<h4>Warning!</h4><p>No FAT link hash provided.</p>")), ) return redirect("afat:dashboard") try: fleet = AFatLink.objects.get(hash=fatlink_hash, is_esilink=False) except AFatLink.DoesNotExist: messages.warning( request, mark_safe( _("<h4>Warning!</h4><p>The hash provided is not valid.</p>")), ) return redirect("afat:dashboard") dur = ClickAFatDuration.objects.get(fleet=fleet) now = timezone.now() - timedelta(minutes=dur.duration) if now >= fleet.afattime: messages.warning( request, mark_safe( _("<h4>Warning!</h4>" "<p>Sorry, that FAT Link is expired. " "If you were on that fleet, contact your FC about " "having your FAT manually added.</p>")), ) return redirect("afat:dashboard") character = EveCharacter.objects.get(character_id=token.character_id) try: required_scopes = [ "esi-location.read_location.v1", "esi-location.read_online.v1", "esi-location.read_ship_type.v1", ] esi_token = Token.get_token(token.character_id, required_scopes) except Exception: messages.warning( request, mark_safe( _(f"<h4>Warning!</h4><p>There was an issue with the ESI token for {character.character_name}. Please try again.</p>" )), ) return redirect("afat:dashboard") # Check if character is online character_online = esi.client.Location.get_characters_character_id_online( character_id=token.character_id, token=esi_token.valid_access_token()).result() if character_online["online"] is True: # Character location location = esi.client.Location.get_characters_character_id_location( character_id=token.character_id, token=esi_token.valid_access_token(), ).result() # Current ship ship = esi.client.Location.get_characters_character_id_ship( character_id=token.character_id, token=esi_token.valid_access_token(), ).result() # System information system = esi.client.Universe.get_universe_systems_system_id( system_id=location["solar_system_id"]).result()["name"] ship_name = provider.get_itemtype(ship["ship_type_id"]).name try: AFat(afatlink=fleet, character=character, system=system, shiptype=ship_name).save() except IntegrityError: messages.warning( request, mark_safe( _(f"<h4>Warning!</h4><p>A FAT already exists for the selected character ({character.character_name}) and fleet combination.</p>" )), ) else: if fleet.fleet is not None: fleet_name = fleet.fleet else: fleet_name = fleet.hash messages.success( request, mark_safe( _(f"<h4>Success!</h4><p>FAT registered for {character.character_name} at {fleet_name}</p>" )), ) logger.info( f'Participation for fleet "{fleet_name}" registered for ' f"pilot {character.character_name}") else: messages.warning( request, mark_safe( _(f"<h4>Warning!</h4><p>Cannot register the fleet participation for {character.character_name}. The character needs to be online.</p>" )), ) return redirect("afat:dashboard")