Skip to content
This repository has been archived by the owner on Dec 28, 2021. It is now read-only.

Commit

Permalink
Add partial Create-a-Class functionality (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ethan Chrisp authored and Ethan Chrisp committed Feb 1, 2020
1 parent 43f390c commit e1652a3
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 2 deletions.
1 change: 1 addition & 0 deletions callofduty/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from .enums import *
from .errors import *
from .leaderboard import Leaderboard, LeaderboardEntry
from .loadout import Loadout, LoadoutItem, LoadoutWeapon
from .loot import LootItem, Season
from .match import Match
from .player import Player
Expand Down
6 changes: 5 additions & 1 deletion callofduty/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ def __init__(self, email: str, password: str):
self.email: str = email
self.password: str = password

self.session: httpx.AsyncClient = httpx.AsyncClient()
# Certain endpoints, such as the one used by GetPlayerLoadouts,
# take a bit longer to recieve data; Hence the increased read_timeout.
self.session: httpx.AsyncClient = httpx.AsyncClient(
timeout=httpx.Timeout(read_timeout=10)
)

@property
def AccessToken(self) -> Optional[str]:
Expand Down
44 changes: 43 additions & 1 deletion callofduty/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from .enums import GameType, Language, Mode, Platform, TimeFrame, Title
from .leaderboard import Leaderboard
from .loadout import Loadout
from .loot import Season
from .match import Match
from .player import Player
Expand Down Expand Up @@ -846,7 +847,7 @@ async def GetLootSeason(self, title: Title, season: int, **kwargs) -> Season:
VerifyPlatform(platform)
VerifyLanguage(language)

data = (
data: dict = (
await self.http.GetLootSeason(
title.value, season, platform.value, language.value
)
Expand All @@ -861,6 +862,47 @@ async def GetLootSeason(self, title: Title, season: int, **kwargs) -> Season:

return Season(self, data)

async def GetPlayerLoadouts(
self, platform: Platform, username: str, title: Title, **kwargs
) -> List[Loadout]:
"""
Get a Call of Duty player's loadouts for the specified title and mode.
Parameters
----------
platform : callofduty.Platform
Platform to get the player from.
username : str
Player's username for the designated platform.
title : callofduty.Title
Call of Duty title to get the player's loadouts from.
mode: callofduty.Mode, optional
Call of Duty mode to get the player's loadouts from (default is Multiplayer.)
Returns
-------
list
Array of loadout objects.
"""

mode: Mode = kwargs.get("mode", Mode.Multiplayer)

VerifyPlatform(platform)
VerifyTitle(title)
VerifyMode(mode, title)

data: dict = (
await self.http.GetPlayerLoadouts(
platform.value, username, title.value, mode.value
)
)["data"]

loadouts: List[Loadout] = []
for _loadout in data["loadouts"]:
loadouts.append(Loadout(self, _loadout))

return loadouts

async def GetSquad(self, name: str) -> Squad:
"""
Get a Call of Duty Squad using its name.
Expand Down
10 changes: 10 additions & 0 deletions callofduty/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,16 @@ async def GetLootSeason(
)
)

async def GetPlayerLoadouts(
self, platform: str, username: str, title: str, mode: str
) -> Union[dict, str]:
return await self.Send(
Request(
"GET",
f"api/papi-client/loadouts/v3/title/{title}/platform/{platform}/gamer/{urllib.parse.quote(username)}/mode/{mode}",
)
)

async def GetSquad(self, name: str) -> Union[dict, str]:
return await self.Send(
Request(
Expand Down
115 changes: 115 additions & 0 deletions callofduty/loadout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import logging
from typing import List, Optional

from .object import Object

log: logging.Logger = logging.getLogger(__name__)


class Loadout(Object):
"""
Represents a Call of Duty loadout object.
Parameters
----------
name : str
Name of the loadout.
primary : callofduty.LoadoutWeapon
Primary weapon slot of the loadout.
secondary : callofduty.LoadoutWeapon
Secondary weapon slot of the loadout.
equipment : list
Array of LoadoutItem objects of the loadout's equipment.
perks : list
Array of LoadoutItem objects of the loadout's perks.
wildcards : list
Array of LoadoutItem objects of the loadout's wildcards.
unlocked : bool
Boolean value indicating whether the loadout slot is unlocked.
"""

_type: str = "Loadout"

def __init__(self, client, data: dict):
super().__init__(client)

self.name: str = data.pop("customClassName")
self.primary: LoadoutWeapon = LoadoutWeapon(self, data.pop("primaryWeapon"))
self.secondary: LoadoutWeapon = LoadoutWeapon(self, data.pop("secondaryWeapon"))
self.equipment: List[LoadoutItem] = []
self.perks: List[LoadoutItem] = []
self.wildcards: List[LoadoutItem] = []
self.unlocked: bool = data.pop("unlocked")

if (_equipment := data.pop("equipment")) is not None:
self.equipment.append(LoadoutItem(self, _equipment))

if (_gear := data.pop("gear")) is not None:
self.equipment.append(LoadoutItem(self, _gear))

for _perk in data.pop("perks"):
self.perks.append(LoadoutItem(self, _perk))

for _wildcard in data.pop("wildcards"):
self.wildcards.append(LoadoutItem(self, _wildcard))


class LoadoutWeapon(Object):
"""
Represents a Call of Duty loadout weapon object.
Parameters
----------
id : str
ID of the weapon.
variant : str, optional
ID of the weapon variant (default is None.)
attachments : list
Array of LoadoutItem objects for the weapon's attachments.
camo : bool
Boolean value indicating whether a camo is equipped to the weapon.
"""

_type: str = "LoadoutWeapon"

def __init__(self, client, data: dict):
super().__init__(client)

self.id: str = data.pop("id")
self.variant: Optional[str] = None
self.attachments: List[LoadoutItem] = []
self.camo: bool = data.pop("camoEquipped")

if (_variant := data.pop("variant")) is not None:
self.variant: Optional[str] = _variant["id"]

# Optics and Operator Mods are attachments, there's no reason to
# seperate them from the attachments array.
# This is also to (hopefully) make Modern Warfare support easier.
if (_optic := data.pop("optic")) is not None:
self.attachments.append(LoadoutItem(self, _optic))

if (_opMod := data.pop("operatorMod")) is not None:
self.attachments.append(LoadoutItem(self, _opMod))

if (_attachments := data.pop("attachments")) is not None:
for _attachment in _attachments:
self.attachments.append(LoadoutItem(self, _attachment))


class LoadoutItem(Object):
"""
Represents a Call of Duty loadout item object.
Parameters
----------
id : str
ID of the item.
"""

_type: str = "LoadoutItem"

def __init__(self, client, data: dict):
super().__init__(client)

self.id: str = data.pop("id")
26 changes: 26 additions & 0 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,32 @@ async def main():
# localize = await client.GetLocalize()
# print(localize)

# loadouts = await client.GetPlayerLoadouts(Platform.PlayStation, "ImMotive__", Title.BlackOps4)
# for loadout in loadouts:
# if loadout.name != "":
# print(f"Class: {loadout.name} (Unlocked: {loadout.unlocked})")
# if loadout.primary.id is not None:
# print(f" - Primary Weapon: {loadout.primary.id} (Variant: {loadout.primary.variant})")
# print(f" - Camo: {loadout.primary.camo}")
# for attachment in loadout.primary.attachments:
# if attachment.id is not None:
# print(f" - Attachment: {attachment.id}")
# if loadout.secondary.id is not None:
# print(f" - Secondary Weapon: {loadout.secondary.id} (Variant: {loadout.secondary.variant})")
# print(f" - Camo: {loadout.secondary.camo}")
# for attachment in loadout.secondary.attachments:
# if attachment.id is not None:
# print(f" - Attachment: {attachment.id}")
# for equipment in loadout.equipment:
# if equipment.id is not None:
# print(f" - Equipment: {equipment.id}")
# for perk in loadout.perks:
# if perk.id is not None:
# print(f" - Perk: {perk.id}")
# for wildcard in loadout.wildcards:
# if wildcard.id is not None:
# print(f" - Wildcard: {wildcard.id}")

# squad = await client.GetSquad("Autists")
# print(f"{squad.name} - {squad.description}")
# print(f"Owner: {squad.owner.username} ({squad.owner.platform.name})")
Expand Down

0 comments on commit e1652a3

Please sign in to comment.