Source code for sni.user.jobs

"""
User and eve player structure management jobs.
"""

import logging

import mongoengine as me

from sni.esi.esi import esi_get
from sni.esi.scope import EsiScope
from sni.esi.token import (
    EsiRefreshToken,
    get_access_token,
)
from sni.scheduler import scheduler
from sni.uac.clearance import reset_clearance
import sni.utils as utils

from .models import (
    Alliance,
    Coalition,
    Corporation,
    User,
)
from .user import (
    ensure_alliance,
    ensure_autogroup,
    ensure_corporation,
    ensure_user,
)


[docs]def update_alliance_autogroup(alliance: Alliance): """ Updates an alliance autogroup. """ logging.debug("Updating autogroup of alliance %s", alliance.alliance_name) grp = ensure_autogroup(alliance.alliance_name) try: grp.owner = alliance.executor.ceo except me.DoesNotExist: grp.owner = None grp.members = list(alliance.user_iterator()) grp.save()
[docs]@scheduler.scheduled_job( "interval", hours=1, start_date=utils.now_plus(minutes=10) ) def update_alliance_autogroups(): """ Resets all the alliance autogroup. Instead of querying the ESI, it queries the database for all user in the corporations in that alliance, assuming the user and corporation records are up-to-date. """ for alliance in Alliance.objects(): scheduler.add_job(update_alliance_autogroup, args=(alliance,))
[docs]def ensure_alliance_members(alliance: Alliance): """ Makes sure all members of a given alliance exist in the database. """ logging.debug("Updating members of alliance %s", alliance.alliance_name) response = esi_get( f"latest/alliances/{alliance.alliance_id}/corporations/" ) for corporation_id in response.data: ensure_corporation(int(corporation_id))
[docs]@scheduler.scheduled_job("interval", hours=1) def ensure_alliances_members(): """ Iterates through all alliances (in the database) and makes sure their member corporations exist in the database. See :meth:`sni.user.jobs.ensure_alliance_members`. """ for alliance in Alliance.objects: scheduler.add_job(ensure_alliance_members, args=(alliance,))
[docs]def update_alliance_from_esi(alliance: Alliance): """ Updates an alliance's properties from the ESI. """ logging.debug("Updating properties of alliance %s", alliance.alliance_name) data = esi_get(f"latest/alliances/{alliance.alliance_id}").data old_executor = alliance.executor alliance.executor_corporation_id = int(data["executor_corporation_id"]) if old_executor.corporation_id != alliance.executor_corporation_id: reset_clearance(old_executor.ceo, save=True) alliance.save()
[docs]@scheduler.scheduled_job("interval", days=1) def update_alliances_from_esi(): """ Updates the alliances properties from the ESI. """ for alliance in Alliance.objects: scheduler.add_job(update_alliance_from_esi, args=(alliance,))
[docs]def update_coalition_autogroup(coalition: Coalition): """ Resets the coalition autogroup. Instead of querying the ESI, it queries the database for all user in that coalition, assuming the user, coalition, and alliance records are up-to-date. """ logging.debug( "Updating autogroup of coalition %s", coalition.coalition_name ) grp = ensure_autogroup(coalition.coalition_name) grp.members = list(coalition.user_iterator()) grp.save()
[docs]@scheduler.scheduled_job( "interval", hours=1, start_date=utils.now_plus(minutes=10) ) def update_coalition_autogroups(): """ Resets the coalition autogroups. """ for coalition in Coalition.objects(): scheduler.add_job(update_coalition_autogroup, args=(coalition,))
[docs]def update_corporation_autogroup(corporation: Corporation): """ Resets the corporations autogroup. Instead of querying the ESI, it queries the database for all user in that corporation, assuming the user records are up-to-date. """ logging.debug( "Updating autogroup of corporation %s", corporation.corporation_name ) grp = ensure_autogroup(corporation.corporation_name) try: grp.owner = corporation.ceo except me.DoesNotExist: grp.owner = None grp.members = list(corporation.user_iterator()) grp.save()
[docs]@scheduler.scheduled_job( "interval", hours=1, start_date=utils.now_plus(minutes=10) ) def update_corporation_autogroups(): """ Resets the corporations autogroups. """ for corporation in Corporation.objects(corporation_id__gte=2000000): scheduler.add_job(update_corporation_autogroup, args=(corporation,))
[docs]def ensure_corporation_members(corporation: Corporation): """ Ensure that all members of a corporation exist in the database. """ logging.debug( "Ensuring members of corporation %s", corporation.corporation_name ) scope = EsiScope.ESI_CORPORATIONS_READ_CORPORATION_MEMBERSHIP_V1 result = EsiRefreshToken.objects.aggregate( [ { "$lookup": { "as": "owner_data", "foreignField": "_id", "from": "user", "localField": "owner", }, }, { "$match": { "owner_data.corporation": corporation.pk, "scopes": scope.value, "valid": True, } }, {"$project": {"owner_data.character_id": 1}}, ] ) response = None for document in result: try: character_id = document["owner_data"][0]["character_id"] esi_access_token = get_access_token(character_id, scope) response = esi_get( f"latest/corporations/{corporation.corporation_id}/members/", token=esi_access_token.access_token, ) except Exception: response = None else: break if response is None: logging.debug( ( "Could not list members of corporation %s (%d): " 'no refresh token with scope "%s"' ), corporation.corporation_name, corporation.corporation_id, scope.value, ) return for character_id in response.data: scheduler.add_job(ensure_user, args=(int(character_id),))
[docs]@scheduler.scheduled_job("interval", hours=1) def ensure_corporations_members(): """ Iterates through all corporations (in the database) and makes sure their members exist in the database. See :meth:`sni.user.jobs.ensure_corporation_members`. """ for corporation in Corporation.objects(corporation_id__gte=2000000): scheduler.add_job(ensure_corporation_members, args=(corporation,))
[docs]def update_corporation_from_esi(corporation: Corporation): """ Updates a corporation properties from the ESI. """ logging.debug( "Updating properties of corproation %s", corporation.corporation_name ) data = esi_get(f"latest/corporations/{corporation.corporation_id}").data corporation.alliance = ( ensure_alliance(int(data["alliance_id"])) if "alliance_id" in data else None ) old_ceo = corporation.ceo corporation.ceo_character_id = int(data["ceo_id"]) if old_ceo.character_id != corporation.ceo_character_id: reset_clearance(old_ceo, save=True) corporation.save()
[docs]@scheduler.scheduled_job("interval", days=1) def update_corporations_from_esi(): """ Updates corporations properties. (yes) """ for corporation in Corporation.objects(corporation_id__gte=2000000): scheduler.add_job(update_corporation_from_esi, args=(corporation,))
[docs]def update_user_autogroup(usr: User): """ Makes sure a user belongs to its corporation, alliance, and coalitions autogroups. """ if usr.corporation is not None: ensure_autogroup(usr.corporation.corporation_name).modify( add_to_set__members=usr ) if usr.alliance is not None: ensure_autogroup(usr.alliance.alliance_name).modify( add_to_set__members=usr ) for coalition in usr.coalitions(): ensure_autogroup(coalition.coalition_name).modify( add_to_set__members=usr )
[docs]def update_user_from_esi(usr: User): """ Updates a user's information from the ESI """ data = esi_get(f"latest/characters/{usr.character_id}").data old_corporation = usr.corporation usr.corporation = ensure_corporation(int(data["corporation_id"])) usr.updated_on = utils.now() if usr.corporation != old_corporation: logging.debug("Corporation of user %s changed", usr.character_name) reset_clearance(usr) usr.save()
[docs]@scheduler.scheduled_job("interval", hours=1) def update_users_from_esi(): """ Iterated through all users and updates their field from ESI. """ for usr in User.objects(character_id__gt=0, clearance_level__gte=0): scheduler.add_job(update_user_from_esi, args=(usr,))