Represents a particular Flesh and Blood player profile (Gem ID).
Warning
At this time PlayerProfile
objects created via the from_gemid()
or
search()
methods work by parsing the HTML tables embedded on the
official website. Please be respectful
by limiting query volumes to numbers comparable to what could be done
manually via the browser.
Attributes:
Name |
Type |
Description |
country |
str
|
The country code of the player. |
id |
int
|
The Gem ID of the player. |
name |
str
|
The name of the player. |
elo_cc |
Optional[int]
|
The Constructed Elo Rating of the player. |
elo_lim |
Optional[int]
|
The Limited Elo Rating of the player. |
rank_elo_cc |
Optional[int]
|
The rank of the player's Constructed Elo Rating. |
rank_elo_lim |
Optional[int]
|
The rank of the player's Limited Elo Rating. |
rank_xp |
Optional[int]
|
The lifetime rank of the player in total XP. |
rank_xp_90 |
Optional[int]
|
The 90-day XP rank of the player. |
xp |
Optional[int]
|
The lifetime total XP of the player. |
xp_90 |
Optional[int]
|
The XP of the player over the last 90 days. |
Source code in fab/gemid.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117 | @dataclasses.dataclass
class PlayerProfile:
'''
Represents a particular Flesh and Blood player profile (Gem ID).
Tip: Warning
At this time `PlayerProfile` objects created via the `from_gemid()` or
`search()` methods work by parsing the HTML tables embedded on [the
official website](https://fabtcg.com/leaderboards/). Please be respectful
by limiting query volumes to numbers comparable to what could be done
manually via the browser.
Attributes:
country: The country code of the player.
id: The Gem ID of the player.
name: The name of the player.
elo_cc: The Constructed Elo Rating of the player.
elo_lim: The Limited Elo Rating of the player.
rank_elo_cc: The rank of the player's Constructed Elo Rating.
rank_elo_lim: The rank of the player's Limited Elo Rating.
rank_xp: The lifetime rank of the player in total XP.
rank_xp_90: The 90-day XP rank of the player.
xp: The lifetime total XP of the player.
xp_90: The XP of the player over the last 90 days.
'''
country: str
id: int
name: str
elo_cc: Optional[int] = None
elo_lim: Optional[int] = None
rank_elo_cc: Optional[int] = None
rank_elo_lim: Optional[int] = None
rank_xp: Optional[int] = None
rank_xp_90: Optional[int] = None
xp: Optional[int] = None
xp_90: Optional[int] = None
@staticmethod
def from_gemid(id: int) -> PlayerProfile:
'''
Creates a `PlayerProfile` object from the specified Gem ID.
Args:
id: The Gem ID of the player.
Returns:
A player profile record associated with the specified Gem ID.
'''
try:
results = [p for p in PlayerProfile.search(id) if p.id == id]
except Exception as e:
raise Exception(f'unable to fetch player profile - {e}')
if not results:
raise Exception(f'unable to locate player profile associated with id "{id}"')
return results[0]
@staticmethod
def search(query: int | str) -> list[PlayerProfile]:
'''
Searches the offical leaderboards for player profiles by player name or
Gem ID.
Args:
query: The player name or Gem ID to search for.
Returns:
A list of player profiles matching the search query.
'''
agg_data: dict[int, PlayerProfile] = {}
_query = quote(query) if isinstance(query, str) else str(query)
for mode in ['xpall', 'xp90', 'elo_cons', 'elo_lim']:
try:
data = pandas.read_html(
f'{LEADERBOARDS_URL}/?mode={mode}&query={_query}'
)[0].to_dict('records')
except ValueError:
pass
except Exception as e:
raise Exception(f'unable to fetch leaderboard data - {e}')
for entry in data:
name_parts = entry['Name'].rsplit(' ', 1)
name = name_parts[0]
gem_id = int(name_parts[1].replace('(', '').replace(')', ''))
if not gem_id in agg_data:
agg_data[gem_id] = PlayerProfile(
country = entry['Country'],
id = gem_id,
name = name
)
if mode == 'xpall':
agg_data[gem_id].rank_xp = entry.get('Rank (Lifetime)')
agg_data[gem_id].xp = entry.get('XP (Lifetime)')
elif mode == 'xp90':
agg_data[gem_id].rank_xp = entry.get('Rank (90 Days)')
agg_data[gem_id].xp = entry.get('XP (90 Days)')
elif mode == 'elo_cons':
agg_data[gem_id].elo_cc = entry.get('Rating')
agg_data[gem_id].rank_elo_cc = entry.get('Rank')
elif mode == 'elo_lim':
agg_data[gem_id].elo_lim = entry.get('Rating')
agg_data[gem_id].rank_elo_lim = entry.get('Rank')
return list(agg_data.values())
|
from_gemid(id)
staticmethod
Creates a PlayerProfile
object from the specified Gem ID.
Parameters:
Name |
Type |
Description |
Default |
id |
int
|
The Gem ID of the player. |
required
|
Returns:
Type |
Description |
PlayerProfile
|
A player profile record associated with the specified Gem ID. |
Source code in fab/gemid.py
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 | @staticmethod
def from_gemid(id: int) -> PlayerProfile:
'''
Creates a `PlayerProfile` object from the specified Gem ID.
Args:
id: The Gem ID of the player.
Returns:
A player profile record associated with the specified Gem ID.
'''
try:
results = [p for p in PlayerProfile.search(id) if p.id == id]
except Exception as e:
raise Exception(f'unable to fetch player profile - {e}')
if not results:
raise Exception(f'unable to locate player profile associated with id "{id}"')
return results[0]
|
search(query)
staticmethod
Searches the offical leaderboards for player profiles by player name or
Gem ID.
Parameters:
Name |
Type |
Description |
Default |
query |
int | str
|
The player name or Gem ID to search for. |
required
|
Returns:
Type |
Description |
list[PlayerProfile]
|
A list of player profiles matching the search query. |
Source code in fab/gemid.py
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117 | @staticmethod
def search(query: int | str) -> list[PlayerProfile]:
'''
Searches the offical leaderboards for player profiles by player name or
Gem ID.
Args:
query: The player name or Gem ID to search for.
Returns:
A list of player profiles matching the search query.
'''
agg_data: dict[int, PlayerProfile] = {}
_query = quote(query) if isinstance(query, str) else str(query)
for mode in ['xpall', 'xp90', 'elo_cons', 'elo_lim']:
try:
data = pandas.read_html(
f'{LEADERBOARDS_URL}/?mode={mode}&query={_query}'
)[0].to_dict('records')
except ValueError:
pass
except Exception as e:
raise Exception(f'unable to fetch leaderboard data - {e}')
for entry in data:
name_parts = entry['Name'].rsplit(' ', 1)
name = name_parts[0]
gem_id = int(name_parts[1].replace('(', '').replace(')', ''))
if not gem_id in agg_data:
agg_data[gem_id] = PlayerProfile(
country = entry['Country'],
id = gem_id,
name = name
)
if mode == 'xpall':
agg_data[gem_id].rank_xp = entry.get('Rank (Lifetime)')
agg_data[gem_id].xp = entry.get('XP (Lifetime)')
elif mode == 'xp90':
agg_data[gem_id].rank_xp = entry.get('Rank (90 Days)')
agg_data[gem_id].xp = entry.get('XP (90 Days)')
elif mode == 'elo_cons':
agg_data[gem_id].elo_cc = entry.get('Rating')
agg_data[gem_id].rank_elo_cc = entry.get('Rank')
elif mode == 'elo_lim':
agg_data[gem_id].elo_lim = entry.get('Rating')
agg_data[gem_id].rank_elo_lim = entry.get('Rank')
return list(agg_data.values())
|