Skip to content

Commit

Permalink
Added squad numbers API (#62)
Browse files Browse the repository at this point in the history
* Added squad numbers API

* Fixed comments
  • Loading branch information
sthewissen committed Mar 19, 2024
1 parent 9612588 commit e9788d8
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 0 deletions.
8 changes: 8 additions & 0 deletions app/api/endpoints/players.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from app.services.players.achievements import TransfermarktPlayerAchievements
from app.services.players.injuries import TransfermarktPlayerInjuries
from app.services.players.jersey_numbers import TransfermarktPlayerJerseyNumbers
from app.services.players.market_value import TransfermarktPlayerMarketValue
from app.services.players.profile import TransfermarktPlayerProfile
from app.services.players.search import TransfermarktPlayerSearch
Expand Down Expand Up @@ -41,6 +42,13 @@ def get_player_transfers(player_id: str):
return player_market_value


@router.get("/{player_id}/jersey_numbers")
def get_player_jersey_numbers(player_id: str):
tfmkt = TransfermarktPlayerJerseyNumbers(player_id=player_id)
player_jerseynumbers = tfmkt.get_player_jersey_numbers()
return player_jerseynumbers


@router.get("/{player_id}/stats")
def get_player_stats(player_id: str):
tfmkt = TransfermarktPlayerStats(player_id=player_id)
Expand Down
60 changes: 60 additions & 0 deletions app/services/players/jersey_numbers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from dataclasses import dataclass
from datetime import datetime

from app.services.base import TransfermarktBase
from app.utils.utils import clean_response, extract_from_url, to_camel_case, zip_lists_into_dict
from app.utils.xpath import Players


@dataclass
class TransfermarktPlayerJerseyNumbers(TransfermarktBase):
"""
A class for retrieving and parsing the players jersey numbers from Transfermarkt.
Args:
player_id (str): The unique identifier of the player.
URL (str): The URL template for the player's stats page on Transfermarkt.
"""

player_id: str = None
URL: str = "https://www.transfermarkt.com/-/rueckennummern/spieler/{player_id}"

def __post_init__(self) -> None:
"""Initialize the TransfermarktJerseyNumbers class."""
self.URL = self.URL.format(player_id=self.player_id)
self.page = self.request_url_page()
self.raise_exception_if_not_found(xpath=Players.Profile.URL)

def __parse_player_jersey_numbers(self) -> list:
"""
Parse and extract player jersey numbers data from the Transfermarkt player stats page.
Returns:
list: A list of dictionaries where each dictionary represents the jersey number for a specific season/club.
Each dictionary includes keys for seasons, clubs and jersey numbers for the player.
"""
headers = to_camel_case(
["Season", "Club", "Jersey number"] + self.get_list_by_xpath(Players.JerseyNumbers.HEADERS),
)

seasons = self.get_list_by_xpath(Players.JerseyNumbers.SEASONS)
clubs_urls = self.get_list_by_xpath(Players.JerseyNumbers.CLUBS_URLS)
clubs_ids = [extract_from_url(url) for url in clubs_urls]
jerseynumbers = self.get_list_by_xpath(Players.JerseyNumbers.DATA)
data = [[season, club_id, number] for season, club_id, number in list(zip(seasons, clubs_ids, jerseynumbers))]

return [zip_lists_into_dict(headers, stat) for stat in data]

def get_player_jersey_numbers(self) -> dict:
"""
Retrieve and parse player jersey numbers data for the specified player from Transfermarkt.
Returns:
dict: A dictionary containing the player's unique identifier, parsed player jersey numbers, and
the timestamp of when the data was last updated.
"""
self.response["id"] = self.player_id
self.response["jerseyNumbers"] = self.__parse_player_jersey_numbers()
self.response["updatedAt"] = datetime.now()

return clean_response(self.response)
6 changes: 6 additions & 0 deletions app/utils/xpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ class Injuries:
GAMES_MISSED = ".//td[6]//span//text()"
GAMES_MISSED_CLUBS_URLS = ".//td[6]//a//@href"

class JerseyNumbers:
HEADERS = "//table[@class='items']//thead//tr//@title"
SEASONS = "//table[@class='items']//td[@class='zentriert']//text()"
CLUBS_URLS = "//table[@class='items']//td[@class='hauptlink no-border-links']//a//@href"
DATA = "//table[@class='items']//td[@class='zentriert hauptlink']//text()"

class Profile:
ID = "//tm-subnavigation[@controller='spieler']//@id"
URL = "//link[@rel='canonical']//@href"
Expand Down

0 comments on commit e9788d8

Please sign in to comment.