Update corp/alliance models using adapters.

This commit is contained in:
Adarnof 2016-12-17 20:51:59 -05:00
parent ec9b43b083
commit 8379fdd7d5
3 changed files with 240 additions and 258 deletions

View File

@ -3,17 +3,35 @@ from eveonline.models import EveCharacter
from eveonline.models import EveApiKeyPair
from eveonline.models import EveAllianceInfo
from eveonline.models import EveCorporationInfo
from eveonline.providers import eve_adapter_factory
from services.managers.eve_api_manager import EveApiManager
import logging
logger = logging.getLogger(__name__)
adapter = eve_adapter_factory()
class EveManager:
def __init__(self):
pass
@staticmethod
def create_character(id, user, api_id):
return EveManager.create_character_obj(adapter.get_character(id), user, api_id)
@staticmethod
def create_character_obj(character, user, api_id):
EveCharacter.objects.create(
character_id = character.id,
character_name = character.name,
corporation_id = character.corp.id,
corporation_name = character.corp.name,
alliance_id = character.alliance.id,
alliance_name = character.alliance.name,
user = user,
api_id = api_id,
)
@staticmethod
def create_character(character_id, character_name, corporation_id,
corporation_name, corporation_ticker, alliance_id,
@ -50,6 +68,20 @@ class EveManager:
chars.result[char]['alliance']['name'],
user, api_id)
@staticmethod
def update_character(id):
return EveManager.update_character_obj(adapter.get_character(id))
@staticmethod
def update_character_obj(char):
model = EveCharacter.objects.get(character_id=char.id)
model.character_name = char.name
model.corporation_id = char.corp.id
model.corporation_name = char.corp.name
model.alliance_id = char.alliance.id
model.alliance_name = char.alliance.name
model.save()
@staticmethod
def update_characters_from_list(chars):
logger.debug("Updating characters from list: %s" % chars.result)
@ -83,64 +115,74 @@ class EveManager:
logger.warn("Attempting to create existing api keypair with id %s" % api_id)
@staticmethod
def create_alliance_info(alliance_id, alliance_name, alliance_ticker, alliance_executor_corp_id,
alliance_member_count, is_blue):
logger.debug("Creating alliance info for alliance %s id %s" % (alliance_name, alliance_id))
if not EveManager.check_if_alliance_exists_by_id(alliance_id):
alliance_info = EveAllianceInfo()
alliance_info.alliance_id = alliance_id
alliance_info.alliance_name = alliance_name
alliance_info.alliance_ticker = alliance_ticker
alliance_info.executor_corp_id = alliance_executor_corp_id
alliance_info.member_count = alliance_member_count
alliance_info.is_blue = is_blue
alliance_info.save()
logger.info("Created alliance model for %s" % alliance_info)
else:
logger.warn("Attempting to create existing alliance model with id %s" % alliance_id)
def create_alliance(id, is_blue=False):
return EveManager.create_alliance_obj(adapter.get_alliance(id), is_blue=is_blue)
@staticmethod
def update_alliance_info(alliance_id, alliance_executor_corp_id, alliance_member_count, is_blue):
logger.debug("Updating alliance model with id %s" % alliance_id)
if EveManager.check_if_alliance_exists_by_id(alliance_id):
alliance_info = EveAllianceInfo.objects.get(alliance_id=alliance_id)
alliance_info.executor_corp_id = alliance_executor_corp_id
alliance_info.member_count = alliance_member_count
alliance_info.is_blue = is_blue
alliance_info.save()
logger.debug("Updated alliance model %s" % alliance_info)
else:
logger.warn("Attempting to update non-existing alliance model with id %s" % alliance_id)
def create_alliance_obj(alliance, is_blue=False):
EveAllianceInfo.objects.create(
alliance_id = alliance.id,
alliance_name = alliance.name,
alliance_ticker = alliance.ticker,
executor_corp_id = alliance.executor_corp_id,
is_blue = is_blue,
)
@staticmethod
def create_corporation_info(corp_id, corp_name, corp_ticker, corp_member_count, is_blue, alliance):
logger.debug("Creating corp info for corp %s id %s" % (corp_name, corp_id))
if not EveManager.check_if_corporation_exists_by_id(corp_id):
corp_info = EveCorporationInfo()
corp_info.corporation_id = corp_id
corp_info.corporation_name = corp_name
corp_info.corporation_ticker = corp_ticker
corp_info.member_count = corp_member_count
corp_info.is_blue = is_blue
if alliance:
corp_info.alliance = alliance
corp_info.save()
logger.info("Created corp model for %s" % corp_info)
else:
logger.warn("Attempting to create existing corp model with id %s" % corp_id)
def update_alliance(id, is_blue=None):
return EveManager.update_alliance_obj(adapter.get_alliance(id), is_blue=is_blue)
@staticmethod
def update_corporation_info(corp_id, corp_member_count, alliance, is_blue):
logger.debug("Updating corp model with id %s" % corp_id)
if EveManager.check_if_corporation_exists_by_id(corp_id):
corp_info = EveCorporationInfo.objects.get(corporation_id=corp_id)
corp_info.member_count = corp_member_count
corp_info.alliance = alliance
corp_info.is_blue = is_blue
corp_info.save()
logger.debug("Updated corp model %s" % corp_info)
else:
logger.warn("Attempting to update non-existant corp model with id %s" % corp_id)
def update_alliance_obj(alliance, is_blue=None):
model = EveAllianceInfo.objects.get(alliance_id=alliance.id)
model.executor_corp_id = alliance.executor_corp_id
model.is_blue = model.is_blue if is_blue == None else is_blue
model.save()
@staticmethod
def populate_alliance(id):
alliance_model = EveAllianceInfo.objects.get(alliance_id=id)
alliance = adapter.get_alliance(id)
for corp_id in alliance.corp_ids:
if not EveCorporationInfo.objects.filter(corporation_id=corp_id).exists():
EveManager.create_corporation(corp_id, is_blue=alliance_model.is_blue)
EveCorporationInfo.objects.filter(corporation_id__in=alliance.corp_ids).update(alliance=alliance_model)
EveCorporationInfo.objects.filter(alliance=alliance_model).exclude(corporation_id__in=alliance.corp_ids).update(alliance=None)
@staticmethod
def create_corporation(id, is_blue=False):
return EveManager.create_corporation_obj(adapter.get_corp(id), is_blue=is_blue)
@staticmethod
def create_corporation_obj(corp, is_blue=False):
try:
alliance = EveAllianceInfo.objects.get(alliance_id=corp.alliance_id)
except EveAllianceInfo.DoesNotExist:
alliance = None
EveCorporationInfo.objects.create(
corporation_id = corp.id,
corporation_name = corp.name,
corporation_ticker = corp.ticker,
member_count = corp.members,
alliance = alliance,
is_blue = is_blue,
)
@staticmethod
def update_corporation(id, is_blue=None):
return EveManager.update_corporation_obj(adapter.get_corp(id), is_blue=is_blue)
@staticmethod
def update_corporation_obj(corp, is_blue=None):
model = EveCorporationInfo.objects.get(corporation_id=corp.id)
model.member_count = corp.members
try:
model.alliance = EveAllianceInfo.objects.get(alliance_id=corp.alliance_id)
except EveAllianceInfo.DoesNotExist:
model.alliance = None
model.is_blue = model.is_blue if is_blue == None else is_blue
model.save()
@staticmethod
def get_api_key_pairs(user):

View File

@ -1,8 +1,19 @@
from django.utils.encoding import python_2_unicode_compatible
from esi.clients import esi_client_factory
from django.conf import settings
from bravado.exception import HTTPNotFound, HTTPUnprocessableEntity
import evelink
@python_2_unicode_compatible
class ObjectNotFound(Exception):
def __init__(self, id, type):
self.id = id
self.type = type
def __str__(self):
return '%s with ID %s not found.' % (self.type, self.id)
@python_2_unicode_compatible
class Entity(object):
def __init__(self, id, name):
@ -43,11 +54,12 @@ class Corporation(Entity):
class Alliance(Entity):
def __init__(self, provider, id, name, ticker, corp_ids):
def __init__(self, provider, id, name, ticker, corp_ids, executor_corp_id):
super(Alliance, self).__init__(id, name)
self.provider = provider
self.ticker = ticker
self.corp_ids = corp_ids
self.executor_corp_id = executor_corp_id
def corp(self, id):
assert id in self.corp_ids
@ -57,6 +69,10 @@ class Alliance(Entity):
def corps(self):
return sorted([self.corp(id) for id in self.corp_ids], key=lambda x: x.name)
@property
def executor_corp(self):
return self.provider.get_corp(self.executor_corp_id)
class Character(Entity):
def __init__(self, provider, id, name, corp_id, alliance_id):
@ -105,23 +121,28 @@ class EveSwaggerProvider(EveProvider):
def __str__(self):
return 'esi'
def get_alliance(self, alliance_id):
data = self.client.Alliance.get_alliances_alliance_id(alliance_id=alliance_id).result()
corps = self.client.Alliance.get_alliances_alliance_id_corporations(alliance_id=alliance_id).result()
def get_alliance(self, id):
try:
data = self.client.Alliance.get_alliances_alliance_id(alliance_id=id).result()
corps = self.client.Alliance.get_alliances_alliance_id_corporations(alliance_id=id).result()
model = Alliance(
self.adapter,
alliance_id,
id,
data['alliance_name'],
data['ticker'],
corps,
data['executor_corp'],
)
return model
except HTTPNotFound:
raise ObjectNotFound(id, 'alliance')
def get_corp(self, corp_id):
data = self.client.Corporation.get_corporations_corporation_id(corporation_id=corp_id).result()
def get_corp(self, id):
try:
data = self.client.Corporation.get_corporations_corporation_id(corporation_id=id).result()
model = Corporation(
self.adapter,
corp_id,
id,
data['corporation_name'],
data['ticker'],
data['ceo_id'],
@ -129,18 +150,23 @@ class EveSwaggerProvider(EveProvider):
data['alliance_id'] if 'alliance_id' in data else None,
)
return model
except HTTPNotFound:
raise ObjectNotFound(id, 'corporation')
def get_character(self, character_id):
data = self.client.Character.get_characters_character_id(character_id=character_id).result()
def get_character(self, id):
try:
data = self.client.Character.get_characters_character_id(character_id=id).result()
alliance_id = self.adapter.get_corp(data['corporation_id']).alliance_id
model = Character(
self.adapter,
character_id,
id,
data['name'],
data['corporation_id'],
alliance_id,
)
return model
except (HTTPNotFound, HTTPUnprocessableEntity):
raise ObjectNotFound(id, 'character')
@python_2_unicode_compatible
@ -158,19 +184,28 @@ class EveXmlProvider(EveProvider):
def get_alliance(self, id):
api = evelink.eve.EVE(api=self.api)
alliances = api.alliances().result
try:
results = alliances[int(id)]
except KeyError:
raise ObjectNotFound(id, 'alliance')
model = Alliance(
self.adapter,
id,
results['name'],
results['ticker'],
results['member_corps'],
results['executor_id'],
)
return model
def get_corp(self, id):
api = evelink.corp.Corp(api=self.api)
try:
corpinfo = api.corporation_sheet(corp_id=int(id)).result
except evelink.api.APIError as e:
if int(e.code) == 523:
raise ObjectNotFound(id, 'corporation')
raise e
model = Corporation(
self.adapter,
id,
@ -184,7 +219,12 @@ class EveXmlProvider(EveProvider):
def get_character(self, id):
api = evelink.eve.EVE(api=self.api)
try:
charinfo = api.character_info_from_id(id).result
except evelink.api.APIError as e:
if int(e.code) == 105:
raise ObjectNotFound(id, 'character')
raise e
model = Character(
self.adapter,
id,

View File

@ -12,6 +12,7 @@ from services.managers.eve_api_manager import EveApiManager
from eveonline.models import EveCharacter
from eveonline.models import EveCorporationInfo
from eveonline.models import EveAllianceInfo
from eveonline.providers import eve_adapter_factory
from authentication.tasks import set_state
import logging
import evelink
@ -105,65 +106,14 @@ def run_api_refresh():
refresh_user_apis.delay(u)
def populate_alliance(id, blue=False):
logger.debug("Populating alliance model with id %s blue %s" % (id, blue))
alliance_info = EveApiManager.get_alliance_information(id)
if not alliance_info:
raise ValueError("Supplied alliance id %s is invalid" % id)
if not EveAllianceInfo.objects.filter(alliance_id=id).exists():
EveManager.create_alliance_info(alliance_info['id'], alliance_info['name'], alliance_info['ticker'],
alliance_info['executor_id'], alliance_info['member_count'], blue)
alliance = EveAllianceInfo.objects.get(alliance_id=id)
for member_corp in alliance_info['member_corps']:
if EveCorporationInfo.objects.filter(corporation_id=member_corp).exists():
corp = EveCorporationInfo.objects.get(corporation_id=member_corp)
if corp.alliance != alliance:
corp.alliance = alliance
corp.save()
else:
logger.info("Creating new alliance member corp id %s" % member_corp)
corpinfo = EveApiManager.get_corporation_information(member_corp)
EveManager.create_corporation_info(corpinfo['id'], corpinfo['name'], corpinfo['ticker'],
corpinfo['members']['current'], blue, alliance)
@task
def update_corp(id):
EveManager.update_corporation(id)
@task
def update_alliance(id):
alliance = EveAllianceInfo.objects.get(alliance_id=id)
corps = EveCorporationInfo.objects.filter(alliance=alliance)
logger.debug("Updating alliance %s with %s member corps" % (alliance, len(corps)))
allianceinfo = EveApiManager.get_alliance_information(alliance.alliance_id)
if allianceinfo:
EveManager.update_alliance_info(allianceinfo['id'], allianceinfo['executor_id'],
allianceinfo['member_count'], alliance.is_blue)
for corp in corps:
if corp.corporation_id in allianceinfo['member_corps'] is False:
logger.info("Corp %s no longer in alliance %s" % (corp, alliance))
corp.alliance = None
corp.save()
populate_alliance(alliance.alliance_id, blue=alliance.is_blue)
elif EveApiManager.check_if_alliance_exists(alliance.alliance_id) is False:
logger.info("Alliance %s has closed. Deleting model" % alliance)
alliance.delete()
@task
def update_corp(id):
corp = EveCorporationInfo.objects.get(corporation_id=id)
logger.debug("Updating corp %s" % corp)
corpinfo = EveApiManager.get_corporation_information(corp.corporation_id)
if corpinfo:
alliance = None
if EveAllianceInfo.objects.filter(alliance_id=corpinfo['alliance']['id']).exists():
alliance = EveAllianceInfo.objects.get(alliance_id=corpinfo['alliance']['id'])
EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], alliance, corp.is_blue)
elif EveApiManager.check_if_corp_exists(corp.corporation_id) is False:
logger.info("Corp %s has closed. Deleting model" % corp)
corp.delete()
# Run Every 2 hours
EveManager.update_alliance(id)
EveManager.populate_alliance(id)
@periodic_task(run_every=crontab(minute=0, hour="*/2"))
@ -172,71 +122,26 @@ def run_corp_update():
logger.warn("Aborted updating corp and alliance models: API server unreachable")
return
standing_level = 'alliance'
try:
# get corp info for owning corp if required
ownercorpinfo = {}
if settings.IS_CORP:
standing_level = 'corp'
logger.debug("Getting information for owning corp with id %s" % settings.CORP_ID)
ownercorpinfo = EveApiManager.get_corporation_information(settings.CORP_ID)
if not ownercorpinfo:
logger.error("Failed to retrieve corp info for owning corp id %s - bad corp id?" % settings.CORP_ID)
return
# check if we need to update an alliance model
alliance_id = ''
if ownercorpinfo and ownercorpinfo['alliance']['id']:
alliance_id = ownercorpinfo['alliance']['id']
elif settings.IS_CORP is False:
alliance_id = settings.ALLIANCE_ID
# get corp info for owning corp if required
if settings.IS_CORP:
standing_level = 'corp'
if EveCorporationInfo.objects.filter(corporation_id=settings.CORP_ID).exists():
update_corp(settings.CORP_ID)
else:
EveManager.create_corporation(settings.CORP_ID)
alliance_id = eve_adapter_factory().get_corp(settings.CORP_ID).alliance_id
# get and create alliance info for owning alliance if required
alliance = None
if alliance_id:
logger.debug("Getting information for owning alliance with id %s" % alliance_id)
ownerallianceinfo = EveApiManager.get_alliance_information(alliance_id)
if not ownerallianceinfo:
logger.error("Failed to retrieve corp info for owning alliance id %s - bad alliance id?" % alliance_id)
return
if EveAllianceInfo.objects.filter(alliance_id=ownerallianceinfo['id']).exists():
if EveAllianceInfo.objects.filter(alliance_id=alliance_id).exists():
logger.debug("Updating existing owner alliance model with id %s" % alliance_id)
EveManager.update_alliance_info(ownerallianceinfo['id'], ownerallianceinfo['executor_id'],
ownerallianceinfo['member_count'], False)
update_alliance(alliance_id)
else:
populate_alliance(alliance_id)
alliance = EveAllianceInfo.objects.get(alliance_id=alliance_id)
# create corp info for owning corp if required
if ownercorpinfo:
if EveCorporationInfo.objects.filter(corporation_id=ownercorpinfo['id']).exists():
logger.debug("Updating existing owner corp model with id %s" % ownercorpinfo['id'])
EveManager.update_corporation_info(ownercorpinfo['id'], ownercorpinfo['members']['current'], alliance,
False)
else:
logger.info("Creating model for owning corp with id %s" % ownercorpinfo['id'])
EveManager.create_corporation_info(ownercorpinfo['id'], ownercorpinfo['name'], ownercorpinfo['ticker'],
ownercorpinfo['members']['current'], False, alliance)
# validate and create corp models for member corps of owning alliance
if alliance:
current_corps = EveCorporationInfo.objects.filter(alliance=alliance)
for corp in current_corps:
if corp.corporation_id in ownerallianceinfo['member_corps'] is False:
logger.info("Corp %s is no longer in owning alliance %s - updating model." % (corp, alliance))
corp.alliance = None
corp.save()
for member_corp in ownerallianceinfo['member_corps']:
if EveCorporationInfo.objects.filter(corporation_id=member_corp).exists():
corp = EveCorporationInfo.objects.get(corporation_id=member_corp)
if corp.alliance == alliance is not True:
logger.info("Associating corp %s with owning alliance %s" % (corp, alliance))
corp.alliance = alliance
corp.save()
else:
corpinfo = EveApiManager.get_corporation_information(member_corp)
logger.info("Creating model for owning alliance member corp with id %s" % corpinfo['id'])
EveManager.create_corporation_info(corpinfo['id'], corpinfo['name'], corpinfo['ticker'],
corpinfo['members']['current'], False, alliance)
EveManager.create_alliance(id)
EveManager.populate_alliance(id)
# update existing corp models
for corp in EveCorporationInfo.objects.all():
@ -246,6 +151,7 @@ def run_corp_update():
for alliance in EveAllianceInfo.objects.all():
update_alliance.delay(alliance.alliance_id)
try:
# create standings
standings = EveApiManager.get_corp_standings()
if standings:
@ -262,7 +168,7 @@ def run_corp_update():
alliance.is_blue = True
alliance.save()
else:
populate_alliance(standing, blue=True)
EveManager.create_alliance(standing, blue=True)
elif EveApiManager.check_if_id_is_corp(standing):
logger.debug("Standing %s is a corp" % standing)
if EveCorporationInfo.objects.filter(corporation_id=standing).exists():
@ -273,13 +179,7 @@ def run_corp_update():
corp.save()
else:
logger.info("Creating model for blue corp with id %s" % standing)
corpinfo = EveApiManager.get_corporation_information(standing)
corp_alliance = None
if EveAllianceInfo.objects.filter(alliance_id=corpinfo['alliance']['id']).exists():
logger.debug("New corp model for standing %s has existing alliance model" % standing)
corp_alliance = EveAllianceInfo.objects.get(alliance_id=corpinfo['alliance']['id'])
EveManager.create_corporation_info(corpinfo['id'], corpinfo['name'], corpinfo['ticker'],
corpinfo['members']['current'], True, corp_alliance)
EveManager.create_corporation(standing, blue=True)
# update alliance standings
for alliance in EveAllianceInfo.objects.filter(is_blue=True):
@ -310,6 +210,8 @@ def run_corp_update():
logger.info("Corp %s is no longer blue" % corp)
corp.is_blue = False
corp.save()
except evelink.api.APIError as e:
logger.error("Model update failed with error code %s" % e.code)
# delete unnecessary alliance models
for alliance in EveAllianceInfo.objects.filter(is_blue=False):
@ -348,5 +250,3 @@ def run_corp_update():
corp.delete()
else:
logger.debug("Corp %s is owning corp" % corp)
except evelink.api.APIError as e:
logger.error("Model update failed with error code %s" % e.code)