mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2026-10-29 18:14:56 +00:00
being moving some of corputils to openapi
This commit is contained in:
5 files changed
+87
-44
No files matched your search
@@ -0,0 +1 @@
|
||||
__esi_compatibility_date__ = "2025-12-16"
|
||||
@@ -1,31 +1,23 @@
|
||||
import logging
|
||||
import os
|
||||
from typing import ClassVar
|
||||
|
||||
from bravado.exception import HTTPForbidden
|
||||
|
||||
from django.db import models
|
||||
|
||||
from esi.errors import TokenError
|
||||
from esi.exceptions import HTTPClientError
|
||||
from esi.models import Token
|
||||
|
||||
from allianceauth.authentication.models import CharacterOwnership, UserProfile
|
||||
from allianceauth.corputils.managers import CorpStatsManager
|
||||
from allianceauth.eveonline.models import EveAllianceInfo, EveCharacter, EveCorporationInfo
|
||||
from allianceauth.corputils.providers import (
|
||||
get_characters_character_id, get_corporations_corporation_id_members,
|
||||
post_universe_names,
|
||||
)
|
||||
from allianceauth.eveonline.models import (
|
||||
EveAllianceInfo, EveCharacter, EveCorporationInfo,
|
||||
)
|
||||
from allianceauth.notifications import notify
|
||||
|
||||
SWAGGER_SPEC_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'swagger.json')
|
||||
"""
|
||||
Swagger spec operations:
|
||||
|
||||
Character
|
||||
get_characters_character_id
|
||||
get_corporations_corporation_id_members
|
||||
Universe
|
||||
post_universe_names
|
||||
"""
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -33,8 +25,9 @@ class CorpStats(models.Model):
|
||||
token = models.ForeignKey(Token, on_delete=models.CASCADE)
|
||||
corp = models.OneToOneField(EveCorporationInfo, on_delete=models.CASCADE)
|
||||
last_update = models.DateTimeField(auto_now=True)
|
||||
members: models.QuerySet["CorpMember"]
|
||||
|
||||
objects: ClassVar[CorpStatsManager] = CorpStatsManager()
|
||||
objects: ClassVar[CorpStatsManager] = CorpStatsManager() # pyright: ignore[reportIncompatibleVariableOverride]
|
||||
|
||||
class Meta:
|
||||
permissions = (
|
||||
@@ -42,24 +35,22 @@ class CorpStats(models.Model):
|
||||
('view_alliance_corpstats', 'Can view corp stats of members of their alliance.'),
|
||||
('view_state_corpstats', 'Can view corp stats of members of their auth state.'),
|
||||
)
|
||||
verbose_name = "corp stats"
|
||||
verbose_name_plural = "corp stats"
|
||||
verbose_name = "Corp Stat"
|
||||
verbose_name_plural = "Corp Stats"
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"{self.__class__.__name__} for {self.corp}"
|
||||
|
||||
def update(self) -> None:
|
||||
try:
|
||||
c = self.token.get_esi_client(spec_file=SWAGGER_SPEC_PATH)
|
||||
assert c.Character.get_characters_character_id(character_id=self.token.character_id).result()['corporation_id'] == int(self.corp.corporation_id)
|
||||
member_ids = c.Corporation.get_corporations_corporation_id_members(
|
||||
corporation_id=self.corp.corporation_id).result()
|
||||
assert get_characters_character_id(self.token.character_id).corporation_id == int(self.corp.corporation_id)
|
||||
member_ids = get_corporations_corporation_id_members(corporation_id=self.corp.corporation_id, token=self.token)
|
||||
|
||||
# requesting too many ids per call results in a HTTP400
|
||||
# the swagger spec doesn't have a maxItems count
|
||||
# manual testing says we can do over 350, but let's not risk it
|
||||
member_id_chunks = [member_ids[i:i + 255] for i in range(0, len(member_ids), 255)]
|
||||
member_name_chunks = [c.Universe.post_universe_names(ids=id_chunk).result() for id_chunk in member_id_chunks]
|
||||
member_name_chunks = [post_universe_names(ids=id_chunk).result() for id_chunk in member_id_chunks]
|
||||
member_list = {}
|
||||
for name_chunk in member_name_chunks:
|
||||
member_list.update({m['id']: m['name'] for m in name_chunk})
|
||||
@@ -83,11 +74,12 @@ class CorpStats(models.Model):
|
||||
message="Your token has expired or is no longer valid. Please add a new one to create a new CorpStats.",
|
||||
level="error")
|
||||
self.delete()
|
||||
except HTTPForbidden as e:
|
||||
logger.warning(f"{self} failed to update: {e}")
|
||||
if self.token.user:
|
||||
notify(self.token.user, f"{self} failed to update with your ESI token.", message=f"{e.status_code}: {e.message}", level="error")
|
||||
self.delete()
|
||||
except HTTPClientError as e:
|
||||
if e.status_code == 403:
|
||||
logger.warning(f"{self} failed to update: {e}")
|
||||
if self.token.user:
|
||||
notify(self.token.user, f"{self} failed to update with your ESI token.", message=f"{e.status_code}", level="error")
|
||||
self.delete()
|
||||
except AssertionError:
|
||||
logger.warning(f"{self} token character no longer in corp.")
|
||||
if self.token.user:
|
||||
@@ -97,7 +89,7 @@ class CorpStats(models.Model):
|
||||
self.delete()
|
||||
|
||||
@property
|
||||
def member_count(self):
|
||||
def member_count(self) -> int:
|
||||
return self.members.count()
|
||||
|
||||
@property
|
||||
@@ -109,15 +101,15 @@ class CorpStats(models.Model):
|
||||
return len(self.registered_members)
|
||||
|
||||
@property
|
||||
def registered_members(self):
|
||||
def registered_members(self) -> models.QuerySet["CorpMember"]:
|
||||
return self.members.filter(pk__in=[m.pk for m in self.members.all() if m.registered])
|
||||
|
||||
@property
|
||||
def unregistered_member_count(self):
|
||||
def unregistered_member_count(self) -> int:
|
||||
return self.member_count - self.registered_member_count
|
||||
|
||||
@property
|
||||
def unregistered_members(self):
|
||||
def unregistered_members(self) -> models.QuerySet["CorpMember"]:
|
||||
return self.members.filter(pk__in=[m.pk for m in self.members.all() if not m.registered])
|
||||
|
||||
@property
|
||||
@@ -125,13 +117,13 @@ class CorpStats(models.Model):
|
||||
return len(self.mains)
|
||||
|
||||
@property
|
||||
def mains(self):
|
||||
def mains(self) -> models.QuerySet["CorpMember"]:
|
||||
return self.members.filter(pk__in=[m.pk for m in self.members.all() if m.main_character and int(m.main_character.character_id) == int(m.character_id)])
|
||||
|
||||
def visible_to(self, user):
|
||||
def visible_to(self, user) -> bool:
|
||||
return CorpStats.objects.filter(pk=self.pk).visible_to(user).exists()
|
||||
|
||||
def can_update(self, user):
|
||||
def can_update(self, user) -> bool:
|
||||
return self.token.user == user or self.visible_to(user)
|
||||
|
||||
def corp_logo(self, size=128) -> str:
|
||||
@@ -150,6 +142,9 @@ class CorpMember(models.Model):
|
||||
corpstats = models.ForeignKey(CorpStats, on_delete=models.CASCADE, related_name='members')
|
||||
|
||||
class Meta:
|
||||
permissions = ()
|
||||
verbose_name = "Corp Member"
|
||||
verbose_name_plural = "Corp Members"
|
||||
# not making character_id unique in case a character moves between two corps while only one updates
|
||||
unique_together = ('corpstats', 'character_id')
|
||||
ordering = ['character_name']
|
||||
@@ -165,14 +160,14 @@ class CorpMember(models.Model):
|
||||
return None
|
||||
|
||||
@property
|
||||
def main_character(self):
|
||||
def main_character(self) -> EveCharacter | None:
|
||||
try:
|
||||
return self.character.character_ownership.user.profile.main_character
|
||||
except (CharacterOwnership.DoesNotExist, UserProfile.DoesNotExist, AttributeError):
|
||||
return None
|
||||
|
||||
@property
|
||||
def alts(self):
|
||||
def alts(self) -> list["EveCharacter"]:
|
||||
if self.main_character:
|
||||
return [co.character for co in self.main_character.character_ownership.user.character_ownerships.all()]
|
||||
else:
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from esi.models import Token
|
||||
from esi.openapi_clients import ESIClientProvider
|
||||
from esi.stubs import PostUniverseNamesOperation
|
||||
|
||||
from .. import __title__, __url__, __version__
|
||||
from . import __esi_compatibility_date__
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from esi.stubs import (
|
||||
CharactersDetail, CorporationsCorporationIdMembersGet,
|
||||
PostUniverseNamesOperationBody,
|
||||
)
|
||||
|
||||
esi = ESIClientProvider(
|
||||
ua_appname=__title__,
|
||||
ua_version=__version__,
|
||||
ua_url=__url__,
|
||||
compatibility_date=__esi_compatibility_date__,
|
||||
operations=[
|
||||
"GetCharactersCharacterId",
|
||||
"GetCorporationsCorporationIdMembers"
|
||||
"PostUniverseNames",
|
||||
])
|
||||
|
||||
"""
|
||||
Swagger spec operations:
|
||||
|
||||
Character
|
||||
get_characters_character_id
|
||||
get_corporations_corporation_id_members
|
||||
Universe
|
||||
post_universe_names
|
||||
"""
|
||||
|
||||
|
||||
def get_characters_character_id(character_id: int) -> CharactersDetail:
|
||||
return esi.client.Character.GetCharactersCharacterId(character_id).result()
|
||||
|
||||
|
||||
def get_corporations_corporation_id_members(corporation_id: int, token: Token) -> CorporationsCorporationIdMembersGet:
|
||||
return esi.client.Corporation.GetCorporationsCorporationIdMembers(corporation_id=corporation_id, token=token).result()
|
||||
|
||||
|
||||
def post_universe_names(ids: PostUniverseNamesOperationBody) -> PostUniverseNamesOperation:
|
||||
return esi.client.Universe.PostUniverseNames(body=ids).result()
|
||||
@@ -1,7 +1,5 @@
|
||||
from unittest import mock
|
||||
|
||||
from bravado.exception import HTTPForbidden
|
||||
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.test import TestCase
|
||||
|
||||
@@ -9,7 +7,9 @@ from esi.errors import TokenError
|
||||
from esi.models import Token
|
||||
|
||||
from allianceauth.authentication.models import CharacterOwnership
|
||||
from allianceauth.eveonline.models import EveAllianceInfo, EveCharacter, EveCorporationInfo
|
||||
from allianceauth.eveonline.models import (
|
||||
EveAllianceInfo, EveCharacter, EveCorporationInfo,
|
||||
)
|
||||
from allianceauth.tests.auth_utils import AuthUtils
|
||||
|
||||
from .models import CorpMember, CorpStats
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import os
|
||||
|
||||
from bravado.exception import HTTPError
|
||||
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required, permission_required, user_passes_test
|
||||
from django.contrib.auth.decorators import (
|
||||
login_required, permission_required, user_passes_test,
|
||||
)
|
||||
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
|
||||
from django.db import IntegrityError
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
|
||||
Reference in new issue
Block a user