def import_corp_members(key_id, character_id): """ This function pulls all corporation members from the EVE API using a director's API key. It'll add as much information as it can about the character. """ log = import_corp_members.get_logger() try: acc = EVEAccount.objects.get(pk=key_id) except EVEAccount.DoesNotExist: return # grab and decode /corp/MemberTracking.xml.aspx if gargoyle.is_active('eve-cak') and acc.api_keytype == API_KEYTYPE_CORPORATION: if not acc.has_access(11) and not acc.has_access(25): log.error('Key does not have access to MemberTrackingLimited or MemberTrackingExtended', extra={'data': {'key_id': key_id, 'character_id': character_id}}) return auth_params = {'keyid': acc.api_user_id, 'vcode': acc.api_key, 'characterID': character_id } if acc.has_access(25): auth_params['extended'] = 1 else: auth_params = {'userID': acc.api_user_id, 'apiKey': acc.api_key, 'characterID': character_id } try: char_doc = CachedDocument.objects.api_query('/corp/MemberTracking.xml.aspx', params=auth_params, no_cache=False, timeout=60) except DocumentRetrievalError: log.error('Error retreiving MemberTracking', exc_info=sys.exc_info(), extra={'data': {'keyid': acc.api_user_id, 'character': character_id}}) return pdoc = basic_xml_parse_doc(char_doc) if not 'eveapi' in pdoc or not 'result' in pdoc['eveapi']: log.error('Invalid XML document / API Error recceived', extra={'data': {'xml': char_doc.body, 'key_id': key_id, 'character_id': character_id}}) return corp = EVEPlayerCharacter.objects.get(id=character_id).corporation charlist = [] for character in pdoc['eveapi']['result']['members']: charlist.append(int(character['characterID'])) charobj, created = EVEPlayerCharacter.objects.get_or_create(id=character['characterID']) if created: charobj.name = character['name'] charobj.corporation = corp charobj.corporation_date = datetime.strptime(character['startDateTime'], "%Y-%m-%d %H:%M:%S").replace(tzinfo=utc) if 'logonDateTime' in character: charobj.last_login = datetime.strptime(character['logonDateTime'], "%Y-%m-%d %H:%M:%S").replace(tzinfo=utc) charobj.last_logoff = datetime.strptime(character['logoffDateTime'], "%Y-%m-%d %H:%M:%S").replace(tzinfo=utc) charobj.current_location_id = int(character['locationID']) else: charobj.last_login = None charobj.last_logoff = None charobj.current_location_id = None charobj.save() if created: import_eve_character.delay(character['characterID']) leftlist = set(corp.eveplayercharacter_set.all().values_list('id', flat=True)) - set(charlist) for id in leftlist: import_eve_character.delay(id)
def import_corp_details_func(corp_id, log=logging.getLogger(__name__)): corpobj, created = EVEPlayerCorporation.objects.get_or_create(id=corp_id) if created or not corpobj.api_last_updated or corpobj.api_last_updated < (datetime.utcnow() - timedelta(hours=12)): try: doc = CachedDocument.objects.api_query('/corp/CorporationSheet.xml.aspx', {'corporationID': corp_id}) except DocumentRetrievalError, exc: log.error('Error retrieving CorporationSheet.xml.aspx for ID %s - %s' % (corp_id, exc)) raise APIAccessException d = basic_xml_parse_doc(doc)['eveapi'] if 'error' in d: log.error("Error importing Corp %s: %s" % (corp_id, d['error'])) raise APIAccessException else: d = d['result'] tag_mappings = ( ('corporationName', 'name'), ('ticker', 'ticker'), ('url', 'url'), ('description', 'description'), ('memberCount', 'member_count'), ) for tag_map in tag_mappings: setattr(corpobj, tag_map[1], d[tag_map[0]]) logo_mappings = ( ('graphicID', 'logo_graphic_id'), ('shape1', 'logo_shape1'), ('shape2', 'logo_shape2'), ('shape3', 'logo_shape3'), ('color1', 'logo_color1'), ('color2', 'logo_color2'), ('color3', 'logo_color3'), ) for logo_map in logo_mappings: setattr(corpobj, logo_map[1], d['logo'][logo_map[0]]) if int(d['allianceID']): corpobj.alliance, created = EVEPlayerAlliance.objects.get_or_create(id=d['allianceID']) if int(d['ceoID']) > 1: import_eve_character.delay(d['ceoID'], callback=link_ceo.subtask(corporation=corpobj.id)) else: corpobj.ceo_character = None corpobj.api_last_updated = datetime.utcnow() corpobj.save()
def get_context_data(self, **kwargs): ctx = super(EVEAPIAccessView, self).get_context_data(**kwargs) calls = basic_xml_parse_doc(CachedDocument.objects.api_query('/api/CallList.xml.aspx'))['eveapi']['result'] if self.object.api_keytype == API_KEYTYPE_CORPORATION: typ = 'Corporation' else: typ = 'Character' ctx['access'] = [] for row in [x for x in calls['calls'] if x['type'] == typ]: bit = self.lowestSet(int(row['accessMask'])) ctx['access'].append((row['name'], self.object.has_access(bit))) return ctx
def import_eve_skills(): """ Imports the skill tree and groups """ char_doc = CachedDocument.objects.api_query('/eve/SkillTree.xml.aspx') d = basic_xml_parse_doc(char_doc)['eveapi'] if 'error' in d: return values = d['result'] for group in values['skillGroups']: gobj, created = EVESkillGroup.objects.get_or_create(id=group['groupID']) if created or not gobj.name or not gobj.name == group['groupName']: gobj.name = group['groupName'] gobj.save() for skill in group['skills']: skillobj, created = EVESkill.objects.get_or_create(id=skill['typeID']) if created or not skillobj.name or not skillobj.group or not skillobj.name == skill['typeName']: skillobj.name = skill['typeName'] skillobj.group = gobj skillobj.save()
import_eve_characters.retry(args=[character_list, key_id, callback], exc=exc, kwargs=kwargs) if callback: subtask(callback).delay(characters=results) else: return results def import_eve_character_func(character_id, key_id=None, logger=logging.getLogger(__name__)): try: char_doc = CachedDocument.objects.api_query('/eve/CharacterInfo.xml.aspx', params={'characterID': character_id}, no_cache=False) except DocumentRetrievalError, exc: logger.error('Error retrieving CharacterInfo.xml.aspx for Character ID %s - %s' % (character_id, exc)) raise APIAccessException d = basic_xml_parse_doc(char_doc)['eveapi'] if 'error' in d: logger.debug('EVE API Error enountered in API document') return values = d['result'] pchar, created = EVEPlayerCharacter.objects.get_or_create(id=character_id) # Set the character's name, avoid oddities in the XML feed if not values['characterName'] == {}: pchar.name = values['characterName'] else: pchar.name = "" pchar.security_status = values['securityStatus'] # Set corporation and join date
from django.core.exceptions import ValidationError @task(ignore_result=True, default_retry_delay=10 * 60) def import_alliance_details(): """ Imports all in-game alliances and links their related corporations """ try: doc = CachedDocument.objects.api_query('/eve/AllianceList.xml.aspx') except DocumentRetrievalError, exc: import_alliance_details.retry(exc=exc) return parsedoc = basic_xml_parse_doc(doc) if 'eveapi' in parsedoc and not 'error' in parsedoc['eveapi']: for alliance in parsedoc['eveapi']['result']['alliances']: allobj, created = EVEPlayerAlliance.objects.get_or_create(pk=alliance['allianceID']) allobj.name = alliance['name'] allobj.ticker = alliance['shortName'] allobj.date_founded = datetime.strptime(alliance['startDate'], "%Y-%m-%d %H:%M:%S") allobj.executor, created = EVEPlayerCorporation.objects.get_or_create(id=alliance['executorCorpID']) allobj.member_count = alliance['memberCount'] allobj.api_last_updated = datetime.utcnow() allobj.save() members = [int(corp['corporationID']) for corp in alliance['memberCorporations']] EVEPlayerCorporation.objects.filter(id__in=members).update(alliance=allobj) EVEPlayerCorporation.objects.filter(alliance=allobj).exclude(id__in=members).update(alliance=None)
def import_apikey_func(api_userid, api_key, user=None, force_cache=False, log=logging.getLogger(__name__)): log.debug('Importing %s/%s' % (api_userid, api_key)) try: account = EVEAccount.objects.get(pk=api_userid) except EVEAccount.DoesNotExist: account = None # Use CAK if enabled and either a new key or flagged as so if (gargoyle.is_active('eve-cak') and (not account or account.is_cak)): auth_params = {'keyid': api_userid, 'vcode': api_key} keycheck = CachedDocument.objects.api_query('/account/APIKeyInfo.xml.aspx', params=auth_params, no_cache=True) doc = basic_xml_parse_doc(keycheck)['eveapi'] if not 'error' in doc: if not account: account, created = EVEAccount.objects.get_or_create(pk=api_userid) if user: account.user = User.objects.get(id=user) if not account.api_key == api_key: account.api_key = api_key keydoc = doc['result']['key'] if keydoc['type'] == 'Character': account.api_keytype = API_KEYTYPE_CHARACTER elif keydoc['type'] == 'Corporation': account.api_keytype = API_KEYTYPE_CORPORATION elif keydoc['type'] == 'Account': account.api_keytype = API_KEYTYPE_ACCOUNT account.api_accessmask = int(keydoc['accessMask']) if not keydoc['expires'] == '': account.api_expiry = datetime.strptime(keydoc['expires'], '%Y-%m-%d %H:%M:%S').replace(tzinfo=utc) # Checks account status to see if the account is still active if not account.api_keytype == API_KEYTYPE_CORPORATION: if account.has_access(25): status = CachedDocument.objects.api_query('/account/AccountStatus.xml.aspx', params=auth_params, no_cache=True) status = basic_xml_parse_doc(status)['eveapi'] if not status.get('error', None): paiddate = datetime.strptime(status['result']['paidUntil'], '%Y-%m-%d %H:%M:%S').replace(tzinfo=utc) if paiddate <= now(): account.api_status = API_STATUS_ACC_EXPIRED else: account.api_status = API_STATUS_OK else: account.api_status = API_STATUS_INVALID_PERMISSIONS if not account.check_access(getattr(settings, 'EVE_API_MINIMUM_KEYMASK', 59638024)): account.api_status = API_STATUS_INVALID_PERMISSIONS else: # If its a corp key, and we've not errored so far, assume is OK. account.api_status = API_STATUS_OK # Remove deleted or traded characters newcharlist = [int(char['characterID']) for char in doc['result']['key']['characters']] for char in account.characters.all().exclude(id__in=newcharlist): account.characters.remove(char) # Schedule a task to update the characters if account.user: cb = update_user_access.subtask(kwargs={'user': account.user.id }) else: cb = None import_eve_characters.delay(newcharlist, key_id=account.pk, callback=cb) else: # No account object, just return if not account: return if not account.api_key == api_key: # Attempted change of key failed, ignore return error = doc['error']['code'] if int(error) >= 500: # API disabled, down or rejecting, return without changes return elif error in ['202', '203', '204', '205', '212']: account.api_status = API_STATUS_AUTH_ERROR elif error == '211': account.api_status = API_STATUS_ACC_EXPIRED elif error in ['222', '223']: account.api_status = API_STATUS_KEY_EXPIRED elif error in ['221']: account.api_status = API_STATUS_INVALID_PERMISSIONS else: account.api_status = API_STATUS_OTHER_ERROR if account.user: update_user_access.delay(account.user.id) else: auth_params = {'userid': api_userid, 'apikey': api_key} account_doc = CachedDocument.objects.api_query('/account/Characters.xml.aspx', params=auth_params, no_cache=force_cache) doc = basic_xml_parse_doc(account_doc)['eveapi'] if not 'error' in doc: if not account: account, created = EVEAccount.objects.get_or_create(pk=api_userid) if user and not account.user: account.user = User.objects.get(id=user) if not account.api_key == api_key: account.api_key = api_key account.api_status = API_STATUS_OK if not account.api_keytype or account.api_keytype == API_KEYTYPE_UNKNOWN: keycheck = CachedDocument.objects.api_query('/account/AccountStatus.xml.aspx', params=auth_params, no_cache=True) keydoc = basic_xml_parse_doc(keycheck)['eveapi'] if 'error' in keydoc: account.api_keytype = API_KEYTYPE_LIMITED elif not 'error' in keydoc: account.api_keytype = API_KEYTYPE_FULL else: account.api_keytype = API_KEYTYPE_UNKNOWN # Remove deleted or traded characters newcharlist = [int(char['characterID']) for char in doc['result']['characters']] for char in account.characters.all().exclude(id__in=newcharlist): account.characters.remove(char) # Schedule a task to update the characters if account.user: cb = update_user_access.subtask(kwargs={'user': account.user.id }) else: cb = None import_eve_characters.delay(newcharlist, key_id=account.pk, callback=cb) else: # No account object, just return if not account: return if not account.api_key == api_key: # Attempted change of key failed, ignore return error = doc['error']['code'] if int(error) >= 500: # API disabled, down or rejecting, return without changes return elif error in ['202', '203', '204', '205', '212']: account.api_status = API_STATUS_AUTH_ERROR elif error in ['211', '223']: account.api_status = API_STATUS_ACC_EXPIRED else: account.api_status = API_STATUS_OTHER_ERROR if account.user: update_user_access.delay(account.user.id) account.api_last_updated = now() account.save() return account