implement slots, implement sorting to Availability
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
from .availability import Availability
|
||||
from .availability import Availability, AvailabilityStatusCode
|
||||
from .availabilitysummary import AvailabilitySummary
|
||||
from .event import Event
|
||||
from .eventlineup import EventLineup
|
||||
@@ -13,7 +13,7 @@ from .team import Team
|
||||
from .user import User
|
||||
|
||||
__all__ = [
|
||||
"Availability",
|
||||
"Availability", "AvailabilityStatusCode",
|
||||
"AvailabilitySummary",
|
||||
"Event",
|
||||
"EventLineup",
|
||||
|
||||
@@ -1,22 +1,56 @@
|
||||
from .base import BaseApiObject
|
||||
from enum import Enum
|
||||
|
||||
class AvailabilityStatusCode(Enum):
|
||||
YES = 1
|
||||
MAYBE = 2
|
||||
NO = 0
|
||||
|
||||
class Availability(BaseApiObject):
|
||||
rel = "availabilities"
|
||||
type = "availability"
|
||||
version = "3.866.0"
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""Data dictionary for object
|
||||
__slots__ = [
|
||||
"event_id",
|
||||
"member_id",
|
||||
"notes",
|
||||
"notes_author_member_id",
|
||||
"status",
|
||||
"status_code",
|
||||
"team_id",
|
||||
"is_current_user",
|
||||
]
|
||||
|
||||
:return: dict: dict with keys:
|
||||
- event_id
|
||||
- member_id
|
||||
- notes
|
||||
- notes_author_member_id
|
||||
- source
|
||||
- status_code
|
||||
- type
|
||||
"""
|
||||
return super().data
|
||||
def __str__(self):
|
||||
return self.data.get('status')
|
||||
|
||||
def __repr__(self):
|
||||
return f'<TeamSnap {self.__class__.__name__} id={self.id} status_code={self.data.get("status_code")} status_="{self.data.get("status")}">'
|
||||
|
||||
@classmethod
|
||||
def __sort_value(cls, availability_obj):
|
||||
if not isinstance(availability_obj, Availability):
|
||||
raise TypeError(f"Cannot compare type {availability_obj.__class__} with {cls.__class__}")
|
||||
return [
|
||||
AvailabilityStatusCode.YES.value,
|
||||
AvailabilityStatusCode.MAYBE.value,
|
||||
AvailabilityStatusCode.NO.value,
|
||||
None,
|
||||
].index(availability_obj.status_code)
|
||||
|
||||
def __lt__(self, obj):
|
||||
return (self.__sort_value(self) < (self.__sort_value(obj)))
|
||||
|
||||
def __gt__(self, obj):
|
||||
return ((self.__sort_value(self)) > (self.__sort_value(obj)))
|
||||
|
||||
def __le__(self, obj):
|
||||
return ((self.__sort_value(self)) <= (self.__sort_value(obj)))
|
||||
|
||||
def __ge__(self, obj):
|
||||
return ((self.__sort_value(self)) >= (self.__sort_value(obj)))
|
||||
|
||||
def __eq__(self, obj):
|
||||
|
||||
return (self.__sort_value(self) == self.__sort_value(obj))
|
||||
|
||||
@@ -6,10 +6,15 @@ class AvailabilitySummary(BaseApiObject):
|
||||
type = "availability_summary"
|
||||
version = "3.866.0"
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""Data dictionary for object
|
||||
|
||||
:return: dict: dict with keys:
|
||||
"""
|
||||
return super().data
|
||||
__slots__ = [
|
||||
"event_id",
|
||||
"team_id",
|
||||
"going_count",
|
||||
"not_going_count",
|
||||
"maybe_count",
|
||||
"unknown_count",
|
||||
"player_going_count",
|
||||
"player_not_going_count",
|
||||
"player_maybe_count",
|
||||
"player_unknown_count",
|
||||
]
|
||||
|
||||
@@ -4,17 +4,28 @@ from apiclient import (
|
||||
APIClient,
|
||||
)
|
||||
import typing as T
|
||||
import copy
|
||||
from abc import ABC
|
||||
from itertools import chain
|
||||
|
||||
|
||||
# Import "preview" of Self typing
|
||||
# https://stackoverflow.com/a/70932112
|
||||
from typing_extensions import Self
|
||||
|
||||
class NotPossibleError(Exception):
|
||||
"""Raised for actions that are not possible to perform this action per API"""
|
||||
pass
|
||||
|
||||
class BaseApiObject:
|
||||
class BaseApiObject(ABC):
|
||||
rel: str = None
|
||||
version: str = None
|
||||
|
||||
__slots__ = [
|
||||
'client',
|
||||
'id',
|
||||
'id_',
|
||||
]
|
||||
|
||||
def __init__(
|
||||
self, client: APIClient, data: T.Dict[str, T.Union[str, list]] = {}
|
||||
) -> None:
|
||||
@@ -24,31 +35,28 @@ class BaseApiObject:
|
||||
:param data: Data to instantiate instance, defaults to empty dict.
|
||||
"""
|
||||
self.client = client
|
||||
|
||||
slots = list(chain.from_iterable(getattr(cls, '__slots__', []) for cls in self.__class__.__mro__))
|
||||
for k, v in data.items():
|
||||
if k == 'type': continue
|
||||
if k == 'id': continue
|
||||
setattr(self, k, v)
|
||||
self._internal_data_dict = copy.deepcopy(data)
|
||||
self.rel = self.__class__.rel
|
||||
"""rel: Relationship between a linked resource and the current document"""
|
||||
if k == "id" :
|
||||
setattr(self, 'id', v) #TODO remove this, here for backward compatibility, but bad idea
|
||||
setattr(self, 'id_', v)
|
||||
elif k in ['type', 'rel']: #read only, inherit to class type
|
||||
continue
|
||||
elif k in slots:
|
||||
setattr(self, k, v)
|
||||
else:
|
||||
# print(f'Warning: {k} not in {self}')
|
||||
pass
|
||||
pass
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def __repr__(self):
|
||||
return f'TeamSnap<{self.__class__.__name__}:{self.id}> "{self.data.get("name")}"'
|
||||
return f'<TeamSnap {self.__class__.__name__} id={self.id_} name="{self.rel}">'
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self._internal_data_dict.__getitem__(key)
|
||||
# return getattr(self, key)
|
||||
|
||||
def __setitem__(self, key, newvalue):
|
||||
return self._internal_data_dict.__setitem__(key, newvalue)
|
||||
# return setattr(self, key, newvalue)
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self._internal_data_dict.items())
|
||||
|
||||
@property
|
||||
def id(self) -> int:
|
||||
return self._internal_data_dict["id"]
|
||||
|
||||
@property
|
||||
def data(self) -> T.Dict[str, T.Union[str, list]]:
|
||||
@@ -56,7 +64,8 @@ class BaseApiObject:
|
||||
|
||||
:return: dict: dict with keys:
|
||||
"""
|
||||
return self._internal_data_dict
|
||||
slots = chain.from_iterable(getattr(cls, '__slots__', []) for cls in self.__class__.__mro__)
|
||||
return {k:getattr(self, k, None) for k in slots}
|
||||
|
||||
@classmethod
|
||||
def search(cls, client: APIClient, **kwargs):
|
||||
@@ -82,7 +91,6 @@ class BaseApiObject:
|
||||
}
|
||||
}
|
||||
r = self.client.post_item(self.rel, data=data)
|
||||
self._internal_data_dict = r
|
||||
return self
|
||||
|
||||
def put(self) -> Self:
|
||||
@@ -93,7 +101,6 @@ class BaseApiObject:
|
||||
}
|
||||
id = self.data.get("id")
|
||||
r = self.client.put_item(self.rel, id=id, data=data)
|
||||
self._internal_data_dict = r
|
||||
return self
|
||||
|
||||
def delete(self):
|
||||
|
||||
@@ -11,13 +11,15 @@ class Event(BaseApiObject):
|
||||
type = "event"
|
||||
version = "3.866.0"
|
||||
|
||||
__slots__ = (
|
||||
# "type",
|
||||
__slots__ = [
|
||||
"additional_location_details",
|
||||
"browser_time_zone",
|
||||
"arrival_date",
|
||||
"division_location_id",
|
||||
"doesnt_count_towards_record",
|
||||
"duration_in_minutes",
|
||||
"end_date",
|
||||
"formatted_results",
|
||||
"game_type",
|
||||
"game_type_code",
|
||||
"icon_color",
|
||||
"is_canceled",
|
||||
@@ -30,18 +32,12 @@ class Event(BaseApiObject):
|
||||
"minutes_to_arrive_early",
|
||||
"name",
|
||||
"notes",
|
||||
"notify_opponent",
|
||||
"notify_opponent_contacts_email",
|
||||
"notify_opponent_contacts_name",
|
||||
"notify_opponent_notes",
|
||||
"notify_team",
|
||||
"notify_team_as_member_id",
|
||||
"opponent_id",
|
||||
"points_for_opponent",
|
||||
"points_for_team",
|
||||
"repeating_include",
|
||||
"repeating_type",
|
||||
"repeating_type_code",
|
||||
"repeating_until",
|
||||
"repeating_uuid",
|
||||
"results",
|
||||
"results_url",
|
||||
"shootout_points_for_opponent",
|
||||
@@ -49,56 +45,20 @@ class Event(BaseApiObject):
|
||||
"start_date",
|
||||
"team_id",
|
||||
"time_zone",
|
||||
"time_zone_description",
|
||||
"time_zone_iana_name",
|
||||
"time_zone_offset",
|
||||
"source_time_zone_iana_name",
|
||||
"tracks_availability",
|
||||
"uniform",
|
||||
)
|
||||
"is_league_controlled",
|
||||
"opponent_name",
|
||||
"location_name",
|
||||
"formatted_title",
|
||||
"formatted_title_for_multi_team",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f'{self["formatted_title"]}'
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""Data dictionary for object
|
||||
|
||||
:return: dict: dict with strings:
|
||||
- type
|
||||
- additional_location_details
|
||||
- browser_time_zone
|
||||
- division_location_id
|
||||
- doesnt_count_towards_record
|
||||
- duration_in_minutes
|
||||
- game_type_code
|
||||
- icon_color
|
||||
- is_canceled
|
||||
- is_game
|
||||
- is_overtime
|
||||
- is_shootout
|
||||
- is_tbd
|
||||
- label
|
||||
- location_id
|
||||
- minutes_to_arrive_early
|
||||
- name
|
||||
- notes
|
||||
- notify_opponent
|
||||
- notify_opponent_contacts_email
|
||||
- notify_opponent_contacts_name
|
||||
- notify_opponent_notes
|
||||
- notify_team
|
||||
- notify_team_as_member_id
|
||||
- opponent_id
|
||||
- points_for_opponent
|
||||
- points_for_team
|
||||
- repeating_include
|
||||
- repeating_type_code
|
||||
- repeating_until
|
||||
- results
|
||||
- results_url
|
||||
- shootout_points_for_opponent
|
||||
- shootout_points_for_team
|
||||
- start_date
|
||||
- team_id
|
||||
- time_zone
|
||||
- tracks_availability
|
||||
- uniform
|
||||
"""
|
||||
return super().data
|
||||
return f'{self.formatted_title}'
|
||||
|
||||
@@ -5,11 +5,9 @@ class EventLineup(BaseApiObject):
|
||||
rel = "event_lineups"
|
||||
type = "event_lineup"
|
||||
version = "3.866.0"
|
||||
template = {}
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""
|
||||
:return: dict: dict with strings:
|
||||
"""
|
||||
return super().data
|
||||
__slots__ = [
|
||||
"event_id",
|
||||
"is_published",
|
||||
"entries_count"
|
||||
]
|
||||
|
||||
@@ -6,16 +6,16 @@ class EventLineupEntry(BaseApiObject):
|
||||
type = "event_lineup_entry"
|
||||
version = "3.866.0"
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""
|
||||
:return: dict: dict with strings:
|
||||
- member_id
|
||||
- sequence
|
||||
- label
|
||||
- type
|
||||
"""
|
||||
return super().data
|
||||
__slots__ = [
|
||||
"event_lineup_id",
|
||||
"event_id",
|
||||
"member_id",
|
||||
"sequence",
|
||||
"label",
|
||||
"member_name",
|
||||
"member_photo",
|
||||
"availability_status_code"
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def search(cls, client, **kwargs):
|
||||
|
||||
@@ -6,20 +6,14 @@ class Location(BaseApiObject):
|
||||
type = "location"
|
||||
version = "3.866.0"
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""Data dictionary for object
|
||||
|
||||
:return: dict: dict with keys:
|
||||
- name
|
||||
- url
|
||||
- phone
|
||||
- notes
|
||||
- address
|
||||
- latitude
|
||||
- longitude
|
||||
- team_id
|
||||
- is_retired
|
||||
- type
|
||||
"""
|
||||
return super().data
|
||||
__slots__ = [
|
||||
'name',
|
||||
'url',
|
||||
'phone',
|
||||
'notes',
|
||||
'address',
|
||||
'latitude',
|
||||
'longitude',
|
||||
'team_id',
|
||||
'is_retired',
|
||||
]
|
||||
|
||||
@@ -11,31 +11,31 @@ class Member(BaseApiObject):
|
||||
type = "member"
|
||||
version = "3.866.0"
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""Data dictionary for object
|
||||
__slots__ = [
|
||||
'first_name',
|
||||
'last_name',
|
||||
'address_city',
|
||||
'address_state',
|
||||
'address_street1',
|
||||
'address_street2',
|
||||
'address_zip',
|
||||
'birthday',
|
||||
'gender',
|
||||
'hide_address',
|
||||
'hide_age',
|
||||
'is_address_hidden',
|
||||
'is_age_hidden',
|
||||
'is_manager',
|
||||
'is_non_player',
|
||||
'is_ownership_pending',
|
||||
'jersey_number',
|
||||
'position',
|
||||
'source_action',
|
||||
'team_id',
|
||||
]
|
||||
|
||||
:return: dict: dict with keys:
|
||||
- first_name
|
||||
- last_name
|
||||
- address_city
|
||||
- address_state
|
||||
- address_street1
|
||||
- address_street2
|
||||
- address_zip
|
||||
- birthday
|
||||
- gender
|
||||
- hide_address
|
||||
- hide_age
|
||||
- is_address_hidden
|
||||
- is_age_hidden
|
||||
- is_manager
|
||||
- is_non_player
|
||||
- is_ownership_pending
|
||||
- jersey_number
|
||||
- position
|
||||
- source_action
|
||||
- team_id
|
||||
- type
|
||||
"""
|
||||
return super().data
|
||||
def __str__(self):
|
||||
return f"{self.first_name} {self.last_name}"
|
||||
|
||||
def __repr__(self):
|
||||
return f'<TeamSnap {self.__class__.__name__} id={self.id} first_name="{self.first_name}" last_name="{self.last_name}">'
|
||||
|
||||
@@ -3,3 +3,18 @@ from .base import BaseApiObject
|
||||
|
||||
class MemberStatistics(BaseApiObject):
|
||||
rel = "member_statistics"
|
||||
type = "member_statistic"
|
||||
|
||||
__slots__ = [
|
||||
"id",
|
||||
"count_games_played",
|
||||
"total",
|
||||
"average",
|
||||
"total_ranking",
|
||||
"average_ranking",
|
||||
"total_ranking_for_query",
|
||||
"average_ranking_for_query",
|
||||
"statistic_id",
|
||||
"member_id",
|
||||
"team_id",
|
||||
]
|
||||
|
||||
@@ -6,17 +6,11 @@ class Opponent(BaseApiObject):
|
||||
type = "opponent"
|
||||
version = "3.866.0"
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""Data dictionary for object
|
||||
|
||||
:return: dict: dict with keys:
|
||||
- name
|
||||
- contacts_name
|
||||
- contacts_phone
|
||||
- contacts_email
|
||||
- notes
|
||||
- team_id
|
||||
- type
|
||||
"""
|
||||
return super().data
|
||||
__slots__ = [
|
||||
'name',
|
||||
'contacts_name',
|
||||
'contacts_phone',
|
||||
'contacts_email',
|
||||
'notes',
|
||||
'team_id',
|
||||
]
|
||||
|
||||
@@ -6,24 +6,19 @@ class Statistics(BaseApiObject):
|
||||
type = "statistic"
|
||||
version = "3.866.0"
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""Data dictionary for object
|
||||
__slots__ = [
|
||||
'acronym',
|
||||
'always_display_decimals',
|
||||
'formula',
|
||||
'is_in_descending_order',
|
||||
'display_zero_totals',
|
||||
'is_percentage',
|
||||
'is_private',
|
||||
'is_team_statistic',
|
||||
'is_top_statistic',
|
||||
'name',
|
||||
'precision',
|
||||
'statistic_group_id',
|
||||
'team_id',
|
||||
]
|
||||
|
||||
:return: dict: dict with keys:
|
||||
- acronym
|
||||
- always_display_decimals
|
||||
- formula
|
||||
- is_in_descending_order
|
||||
- display_zero_totals
|
||||
- is_percentage
|
||||
- is_private
|
||||
- is_team_statistic
|
||||
- is_top_statistic
|
||||
- name
|
||||
- precision
|
||||
- statistic_group_id
|
||||
- team_id
|
||||
- type
|
||||
"""
|
||||
return super().data
|
||||
|
||||
@@ -12,32 +12,23 @@ class Team(BaseApiObject):
|
||||
type = "team"
|
||||
version = "3.866.0"
|
||||
|
||||
# Override this class property to add docstring
|
||||
# should not change functionality. Probably a better
|
||||
# to do this...
|
||||
@property
|
||||
def data(self):
|
||||
"""Data dictionary for object
|
||||
|
||||
:return: dict: dict with keys:
|
||||
- ad_unit_hero_id
|
||||
- ad_unit_hero_template_id
|
||||
- ad_unit_inline_id
|
||||
- division_id
|
||||
- division_name
|
||||
- is_ownership_pending
|
||||
- league_name
|
||||
- league_url
|
||||
- location_country
|
||||
- location_postal_code
|
||||
- name
|
||||
- owner_email
|
||||
- owner_first_name
|
||||
- owner_last_name
|
||||
- season_name
|
||||
- sport_id
|
||||
- team
|
||||
- time_zone
|
||||
- type
|
||||
"""
|
||||
return super().data
|
||||
__slots__ = [
|
||||
'ad_unit_hero_id',
|
||||
'ad_unit_hero_template_id',
|
||||
'ad_unit_inline_id',
|
||||
'division_id',
|
||||
'division_name',
|
||||
'is_ownership_pending',
|
||||
'league_name',
|
||||
'league_url',
|
||||
'location_country',
|
||||
'location_postal_code',
|
||||
'name',
|
||||
'owner_email',
|
||||
'owner_first_name',
|
||||
'owner_last_name',
|
||||
'season_name',
|
||||
'sport_id',
|
||||
'team',
|
||||
'time_zone',
|
||||
]
|
||||
|
||||
@@ -1,28 +1,38 @@
|
||||
from .base import BaseApiObject
|
||||
from .base import BaseApiObject, NotPossibleError
|
||||
|
||||
|
||||
class User(BaseApiObject):
|
||||
|
||||
rel = "users"
|
||||
type = "user"
|
||||
version = "3.866.0"
|
||||
|
||||
__slots__ = [
|
||||
'first_name',
|
||||
'last_name',
|
||||
'password',
|
||||
'birthday',
|
||||
'email',
|
||||
'facebook_id',
|
||||
'facebook_access_token',
|
||||
'is_lab_rat',
|
||||
'receives_newsletter',
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f'{self["first_name"]} {self["last_name"]}'
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""Data dictionary for object
|
||||
def delete(self):
|
||||
"""It is not possible to create or delete users via the API;
|
||||
however, it is possible to update data on a user's record."""
|
||||
raise NotPossibleError ('It is not possible to delete users via the API')
|
||||
|
||||
:return: dict: dict with keys:
|
||||
- first_name
|
||||
- last_name
|
||||
- password
|
||||
- birthday
|
||||
- email
|
||||
- facebook_id
|
||||
- facebook_access_token
|
||||
- type
|
||||
- is_lab_rat
|
||||
- receives_newsletter
|
||||
"""
|
||||
return super().data
|
||||
def new(self):
|
||||
"""It is not possible to create or delete users via the API;
|
||||
however, it is possible to update data on a user's record."""
|
||||
raise NotPossibleError('It is not possible to create users via the API')
|
||||
|
||||
def post(self):
|
||||
"""It is not possible to create or delete users via the API;
|
||||
however, it is possible to update data on a user's record."""
|
||||
raise NotPossibleError('It is not possible to create users via the API')
|
||||
|
||||
Reference in New Issue
Block a user