Rewrite scores backends to use a single format string (#833)
* Rewrite scores backends to use a single format string Since the game status is almost always the only thing that differs, this simplifies things greatly by using a single format string and building a game_status formatter depending on format strings set for each game status type. * Use formatp on game_status * Make postponed games appear last by default * Add score formatters back to defaults * Fix conditional display of zero scores by treating them as strings
This commit is contained in:
parent
34af13547d
commit
c4876ed551
@ -118,11 +118,13 @@ class ScoresBackend(SettingsBase):
|
|||||||
return f'{number}{suffix}'
|
return f'{number}{suffix}'
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def force_int(value):
|
def zero_fallback(value):
|
||||||
try:
|
try:
|
||||||
return int(value)
|
int(value)
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
return 0
|
return '0'
|
||||||
|
else:
|
||||||
|
return str(value)
|
||||||
|
|
||||||
def get_nested(self, data, expr, callback=None, default=''):
|
def get_nested(self, data, expr, callback=None, default=''):
|
||||||
if callback is None:
|
if callback is None:
|
||||||
@ -219,7 +221,7 @@ class Scores(Module):
|
|||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
from i3pystatus import Status
|
from i3pystatus import Status
|
||||||
from i3pystatus.scores import mlb, nhl
|
from i3pystatus.scores import mlb, nhl, nba
|
||||||
|
|
||||||
status = Status()
|
status = Status()
|
||||||
|
|
||||||
@ -228,9 +230,11 @@ class Scores(Module):
|
|||||||
hints={'markup': 'pango'},
|
hints={'markup': 'pango'},
|
||||||
colorize_teams=True,
|
colorize_teams=True,
|
||||||
favorite_icon='<span size="small" color="#F5FF00">★</span>',
|
favorite_icon='<span size="small" color="#F5FF00">★</span>',
|
||||||
|
team_format='abbreviation',
|
||||||
backends=[
|
backends=[
|
||||||
mlb.MLB(
|
mlb.MLB(
|
||||||
teams=['CWS', 'SF'],
|
teams=['CWS', 'SF'],
|
||||||
|
team_format='name',
|
||||||
format_no_games='No games today :(',
|
format_no_games='No games today :(',
|
||||||
inning_top='⬆',
|
inning_top='⬆',
|
||||||
inning_bottom='⬇',
|
inning_bottom='⬇',
|
||||||
@ -240,7 +244,6 @@ class Scores(Module):
|
|||||||
teams=['GSW'],
|
teams=['GSW'],
|
||||||
all_games=False,
|
all_games=False,
|
||||||
),
|
),
|
||||||
epl.EPL(),
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -362,6 +365,7 @@ class Scores(Module):
|
|||||||
'shown by the module) when refreshing scores. '
|
'shown by the module) when refreshing scores. '
|
||||||
'**NOTE:** Depending on how quickly the update is '
|
'**NOTE:** Depending on how quickly the update is '
|
||||||
'performed, the icon may not be displayed.'),
|
'performed, the icon may not be displayed.'),
|
||||||
|
('team_format', 'One of ``name``, ``abbreviation``, or ``city``'),
|
||||||
)
|
)
|
||||||
|
|
||||||
backends = []
|
backends = []
|
||||||
@ -371,6 +375,7 @@ class Scores(Module):
|
|||||||
colorize_teams = False
|
colorize_teams = False
|
||||||
scroll_arrow = '⬍'
|
scroll_arrow = '⬍'
|
||||||
refresh_icon = '⟳'
|
refresh_icon = '⟳'
|
||||||
|
team_format = 'name'
|
||||||
|
|
||||||
output = {'full_text': ''}
|
output = {'full_text': ''}
|
||||||
game_map = {}
|
game_map = {}
|
||||||
@ -417,6 +422,9 @@ class Scores(Module):
|
|||||||
)
|
)
|
||||||
backend.display_order[index] = order_lc
|
backend.display_order[index] = order_lc
|
||||||
|
|
||||||
|
if backend.team_format is None:
|
||||||
|
backend.team_format = self.team_format
|
||||||
|
|
||||||
self.condition = threading.Condition()
|
self.condition = threading.Condition()
|
||||||
self.thread = threading.Thread(target=self.update_thread, daemon=True)
|
self.thread = threading.Thread(target=self.update_thread, daemon=True)
|
||||||
self.thread.start()
|
self.thread.start()
|
||||||
@ -566,7 +574,14 @@ class Scores(Module):
|
|||||||
self.show_refresh_icon()
|
self.show_refresh_icon()
|
||||||
cur_id = self.current_game_id
|
cur_id = self.current_game_id
|
||||||
cur_games = self.current_backend.games.keys()
|
cur_games = self.current_backend.games.keys()
|
||||||
|
|
||||||
self.current_backend.check_scores()
|
self.current_backend.check_scores()
|
||||||
|
for game in self.current_backend.games.values():
|
||||||
|
if game['status'] in ('pregame', 'postponed'):
|
||||||
|
# Allow formatp to conditionally hide the score when game
|
||||||
|
# hasn't started (or has been postponed)
|
||||||
|
game['home_score'] = game['away_score'] = ''
|
||||||
|
|
||||||
if cur_games == self.current_backend.games.keys():
|
if cur_games == self.current_backend.games.keys():
|
||||||
# Set the index to the scroll position of the current game (it
|
# Set the index to the scroll position of the current game (it
|
||||||
# may have changed due to this game or other games changing
|
# may have changed due to this game or other games changing
|
||||||
@ -623,31 +638,55 @@ class Scores(Module):
|
|||||||
else:
|
else:
|
||||||
game = copy.copy(self.current_game)
|
game = copy.copy(self.current_game)
|
||||||
|
|
||||||
fstr = str(getattr(self.current_backend, f'format_{game["status"]}'))
|
# Set the game_status using the formatter
|
||||||
|
game_status_opt = f'status_{game["status"]}'
|
||||||
|
try:
|
||||||
|
game['game_status'] = formatp(
|
||||||
|
str(getattr(self.current_backend, game_status_opt)),
|
||||||
|
**game
|
||||||
|
)
|
||||||
|
except AttributeError:
|
||||||
|
self.logger.error(
|
||||||
|
f'Unable to find {self.current_backend.name} option '
|
||||||
|
f'{game_status_opt}'
|
||||||
|
)
|
||||||
|
game['game_status'] = 'Unknown Status'
|
||||||
|
|
||||||
for team in ('home', 'away'):
|
for team in ('home', 'away'):
|
||||||
abbrev_key = f'{team}_abbrev'
|
team_abbrev = game[f'{team}_abbreviation']
|
||||||
# Set favorite icon, if applicable
|
# Set favorite icon, if applicable
|
||||||
game[f'{team}_favorite'] = self.favorite_icon \
|
game[f'{team}_favorite'] = self.favorite_icon \
|
||||||
if game[abbrev_key] in self.current_backend.favorite_teams \
|
if team_abbrev in self.current_backend.favorite_teams \
|
||||||
else ''
|
else ''
|
||||||
|
|
||||||
if self.colorize_teams:
|
try:
|
||||||
# Wrap in Pango markup
|
game[f'{team}_team'] = game[f'{team}_{self.current_backend.team_format}']
|
||||||
color = self.current_backend.team_colors.get(
|
except KeyError:
|
||||||
game.get(abbrev_key)
|
self.logger.debug(
|
||||||
|
f'Unable to find {self.current_backend.team_format} '
|
||||||
|
f'value, falling back to {team_abbrev}'
|
||||||
)
|
)
|
||||||
if color is not None:
|
game[f'{team}_team'] = team_abbrev
|
||||||
for item in ('abbrev', 'city', 'name', 'name_short'):
|
|
||||||
key = f'{team}_{item}'
|
if self.colorize_teams:
|
||||||
if key in game:
|
try:
|
||||||
game[key] = f'<span color="{color}">{game[key]}</span>'
|
color = self.current_backend.team_colors[team_abbrev]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
for val in ('team', 'name', 'city', 'abbreviation'):
|
||||||
|
# Wrap in Pango markup
|
||||||
|
game[f'{team}_{val}'] = ''.join((
|
||||||
|
f'<span color="{color}">',
|
||||||
|
game[f'{team}_{val}'],
|
||||||
|
'</span>',
|
||||||
|
))
|
||||||
|
|
||||||
game['scroll'] = self.scroll_arrow \
|
game['scroll'] = self.scroll_arrow \
|
||||||
if len(self.current_backend.games) > 1 \
|
if len(self.current_backend.games) > 1 \
|
||||||
else ''
|
else ''
|
||||||
|
|
||||||
output = formatp(fstr, **game).strip()
|
output = formatp(self.current_backend.format, **game).strip()
|
||||||
|
|
||||||
self.output = {'full_text': output, 'color': self.color}
|
self.output = {'full_text': output, 'color': self.color}
|
||||||
|
|
||||||
|
@ -21,18 +21,16 @@ class MLB(ScoresBackend):
|
|||||||
|
|
||||||
.. rubric:: Available formatters
|
.. rubric:: Available formatters
|
||||||
|
|
||||||
* `{home_name}` — Name of home team
|
* `{home_team}` — Depending on the value of the ``team_format`` option,
|
||||||
* `{home_city}` — Name of home team's city
|
will contain either the home team's name, abbreviation, or city
|
||||||
* `{home_abbrev}` — 2 or 3-letter abbreviation for home team's city
|
|
||||||
* `{home_score}` — Home team's current score
|
* `{home_score}` — Home team's current score
|
||||||
* `{home_wins}` — Home team's number of wins
|
* `{home_wins}` — Home team's number of wins
|
||||||
* `{home_losses}` — Home team's number of losses
|
* `{home_losses}` — Home team's number of losses
|
||||||
* `{home_favorite}` — Displays the value for the :py:mod:`.scores` module's
|
* `{home_favorite}` — Displays the value for the :py:mod:`.scores` module's
|
||||||
``favorite`` attribute, if the home team is one of the teams being
|
``favorite`` attribute, if the home team is one of the teams being
|
||||||
followed. Otherwise, this formatter will be blank.
|
followed. Otherwise, this formatter will be blank.
|
||||||
* `{away_name}` — Name of away team
|
* `{away_team}` — Depending on the value of the ``team_format`` option,
|
||||||
* `{away_city}` — Name of away team's city
|
will contain either the away team's name, abbreviation, or city
|
||||||
* `{away_abbrev}` — 2 or 3-letter abbreviation for away team's city
|
|
||||||
* `{away_score}` — Away team's current score
|
* `{away_score}` — Away team's current score
|
||||||
* `{away_wins}` — Away team's number of wins
|
* `{away_wins}` — Away team's number of wins
|
||||||
* `{away_losses}` — Away team's number of losses
|
* `{away_losses}` — Away team's number of losses
|
||||||
@ -51,6 +49,8 @@ class MLB(ScoresBackend):
|
|||||||
this formatter will be blank.
|
this formatter will be blank.
|
||||||
* `{postponed}` — Reason for postponement, if game has been postponed.
|
* `{postponed}` — Reason for postponement, if game has been postponed.
|
||||||
Otherwise, this formatter will be blank.
|
Otherwise, this formatter will be blank.
|
||||||
|
* `{suspended}` — Reason for suspension, if game has been suspended.
|
||||||
|
Otherwise, this formatter will be blank.
|
||||||
* `{extra_innings}` — When a game lasts longer than 9 innings, this
|
* `{extra_innings}` — When a game lasts longer than 9 innings, this
|
||||||
formatter will show that number of innings. Otherwise, it will blank.
|
formatter will show that number of innings. Otherwise, it will blank.
|
||||||
|
|
||||||
@ -105,11 +105,17 @@ class MLB(ScoresBackend):
|
|||||||
('format_no_games', 'Format used when no tracked games are scheduled '
|
('format_no_games', 'Format used when no tracked games are scheduled '
|
||||||
'for the current day (does not support formatter '
|
'for the current day (does not support formatter '
|
||||||
'placeholders)'),
|
'placeholders)'),
|
||||||
('format_pregame', 'Format used when the game has not yet started'),
|
('format', 'Format used to display game information'),
|
||||||
('format_in_progress', 'Format used when the game is in progress'),
|
('status_pregame', 'Format string used for the ``{game_status}`` '
|
||||||
('format_final', 'Format used when the game is complete'),
|
'formatter when the game has not started '),
|
||||||
('format_postponed', 'Format used when the game has been postponed'),
|
('status_in_progress', 'Format string used for the ``{game_status}`` '
|
||||||
('format_suspended', 'Format used when the game has been suspended'),
|
'formatter when the game is in progress'),
|
||||||
|
('status_final', 'Format string used for the ``{game_status}`` '
|
||||||
|
'formatter when the game has finished'),
|
||||||
|
('status_postponed', 'Format string used for the ``{game_status}`` '
|
||||||
|
'formatter when the game has been postponed'),
|
||||||
|
('status_suspended', 'Format string used for the ``{game_status}`` '
|
||||||
|
'formatter when the game has been suspended'),
|
||||||
('inning_top', 'Value for the ``{top_bottom}`` formatter when game '
|
('inning_top', 'Value for the ``{top_bottom}`` formatter when game '
|
||||||
'is in the top half of an inning'),
|
'is in the top half of an inning'),
|
||||||
('inning_bottom', 'Value for the ``{top_bottom}`` formatter when game '
|
('inning_bottom', 'Value for the ``{top_bottom}`` formatter when game '
|
||||||
@ -118,6 +124,9 @@ class MLB(ScoresBackend):
|
|||||||
'codes. If overridden, the passed values will be '
|
'codes. If overridden, the passed values will be '
|
||||||
'merged with the defaults, so it is not necessary to '
|
'merged with the defaults, so it is not necessary to '
|
||||||
'define all teams if specifying this value.'),
|
'define all teams if specifying this value.'),
|
||||||
|
('team_format', 'One of ``name``, ``abbreviation``, or ``city``. If '
|
||||||
|
'not specified, takes the value from the ``scores`` '
|
||||||
|
'module.'),
|
||||||
('date', 'Date for which to display game scores, in **YYYY-MM-DD** '
|
('date', 'Date for which to display game scores, in **YYYY-MM-DD** '
|
||||||
'format. If unspecified, the current day\'s games will be '
|
'format. If unspecified, the current day\'s games will be '
|
||||||
'displayed starting at 10am Eastern time, with last '
|
'displayed starting at 10am Eastern time, with last '
|
||||||
@ -169,15 +178,16 @@ class MLB(ScoresBackend):
|
|||||||
}
|
}
|
||||||
|
|
||||||
_valid_teams = [x for x in _default_colors]
|
_valid_teams = [x for x in _default_colors]
|
||||||
_valid_display_order = ['in_progress', 'suspended', 'final', 'postponed', 'pregame']
|
_valid_display_order = ['in_progress', 'suspended', 'final', 'pregame', 'postponed']
|
||||||
|
|
||||||
display_order = _valid_display_order
|
display_order = _valid_display_order
|
||||||
format_no_games = 'MLB: No games'
|
format_no_games = 'MLB: No games'
|
||||||
format_pregame = '[{scroll} ]MLB: [{away_favorite} ]{away_abbrev} ({away_wins}-{away_losses}) at [{home_favorite} ]{home_abbrev} ({home_wins}-{home_losses}) {start_time:%H:%M %Z}[ ({delay} Delay)]'
|
format = '[{scroll} ]MLB: [{away_favorite} ]{away_team} [{away_score} ]({away_wins}-{away_losses}) at [{home_favorite} ]{home_team} [{home_score} ]({home_wins}-{home_losses}) {game_status}'
|
||||||
format_in_progress = '[{scroll} ]MLB: [{away_favorite} ]{away_abbrev} {away_score}, [{home_favorite} ]{home_abbrev} {home_score} ({top_bottom} {inning}, {outs} Out)[ ({delay} Delay)]'
|
status_pregame = '{start_time:%H:%M %Z}[ ({delay} Delay)]'
|
||||||
format_final = '[{scroll} ]MLB: [{away_favorite} ]{away_abbrev} {away_score} ({away_wins}-{away_losses}) at [{home_favorite} ]{home_abbrev} {home_score} ({home_wins}-{home_losses}) (Final[/{extra_innings}])'
|
status_in_progress = '({top_bottom} {inning}, {outs} Out)[ ({delay} Delay)]'
|
||||||
format_postponed = '[{scroll} ]MLB: [{away_favorite} ]{away_abbrev} ({away_wins}-{away_losses}) at [{home_favorite} ]{home_abbrev} ({home_wins}-{home_losses}) (PPD: {postponed})'
|
status_final = '(Final[/{extra_innings}])'
|
||||||
format_suspended = '[{scroll} ]MLB: [{away_favorite} ]{away_abbrev} {away_score} ({away_wins}-{away_losses}) at [{home_favorite} ]{home_abbrev} {home_score} ({home_wins}-{home_losses}) (Suspended: {suspended})'
|
status_postponed = '(PPD: {postponed})'
|
||||||
|
status_suspended = '(Suspended: {suspended})'
|
||||||
inning_top = 'Top'
|
inning_top = 'Top'
|
||||||
inning_bottom = 'Bot'
|
inning_bottom = 'Bot'
|
||||||
team_colors = _default_colors
|
team_colors = _default_colors
|
||||||
@ -185,6 +195,9 @@ class MLB(ScoresBackend):
|
|||||||
scoreboard_url = SCOREBOARD_URL
|
scoreboard_url = SCOREBOARD_URL
|
||||||
api_url = API_URL
|
api_url = API_URL
|
||||||
|
|
||||||
|
# These will inherit from the Scores class if not overridden
|
||||||
|
team_format = None
|
||||||
|
|
||||||
@require(internet)
|
@require(internet)
|
||||||
def check_scores(self):
|
def check_scores(self):
|
||||||
self.get_api_date()
|
self.get_api_date()
|
||||||
@ -252,7 +265,7 @@ class MLB(ScoresBackend):
|
|||||||
ret[f'{team}_name'] = self.get_nested(
|
ret[f'{team}_name'] = self.get_nested(
|
||||||
team_data,
|
team_data,
|
||||||
'team:teamName')
|
'team:teamName')
|
||||||
ret[f'{team}_abbrev'] = self.get_nested(
|
ret[f'{team}_abbreviation'] = self.get_nested(
|
||||||
team_data,
|
team_data,
|
||||||
'team:abbreviation')
|
'team:abbreviation')
|
||||||
|
|
||||||
@ -268,7 +281,7 @@ class MLB(ScoresBackend):
|
|||||||
ret[f'{team}_score'] = self.get_nested(
|
ret[f'{team}_score'] = self.get_nested(
|
||||||
linescore,
|
linescore,
|
||||||
f'teams:{team}:runs',
|
f'teams:{team}:runs',
|
||||||
default=0)
|
default='0')
|
||||||
|
|
||||||
for key in ('delay', 'postponed', 'suspended'):
|
for key in ('delay', 'postponed', 'suspended'):
|
||||||
ret[key] = ''
|
ret[key] = ''
|
||||||
|
@ -18,9 +18,8 @@ class NBA(ScoresBackend):
|
|||||||
|
|
||||||
.. rubric:: Available formatters
|
.. rubric:: Available formatters
|
||||||
|
|
||||||
* `{home_name}` — Name of home team
|
* `{home_team}` — Depending on the value of the ``team_format`` option,
|
||||||
* `{home_city}` — Name of home team's city
|
will contain either the home team's name, abbreviation, or city
|
||||||
* `{home_abbrev}` — 3-letter abbreviation for home team's city
|
|
||||||
* `{home_score}` — Home team's current score
|
* `{home_score}` — Home team's current score
|
||||||
* `{home_wins}` — Home team's number of wins
|
* `{home_wins}` — Home team's number of wins
|
||||||
* `{home_losses}` — Home team's number of losses
|
* `{home_losses}` — Home team's number of losses
|
||||||
@ -29,9 +28,8 @@ class NBA(ScoresBackend):
|
|||||||
* `{home_favorite}` — Displays the value for the :py:mod:`.scores` module's
|
* `{home_favorite}` — Displays the value for the :py:mod:`.scores` module's
|
||||||
``favorite`` attribute, if the home team is one of the teams being
|
``favorite`` attribute, if the home team is one of the teams being
|
||||||
followed. Otherwise, this formatter will be blank.
|
followed. Otherwise, this formatter will be blank.
|
||||||
* `{away_name}` — Name of away team
|
* `{away_team}` — Depending on the value of the ``team_format`` option,
|
||||||
* `{away_city}` — Name of away team's city
|
will contain either the away team's name, abbreviation, or city
|
||||||
* `{away_abbrev}` — 2 or 3-letter abbreviation for away team's city
|
|
||||||
* `{away_score}` — Away team's current score
|
* `{away_score}` — Away team's current score
|
||||||
* `{away_wins}` — Away team's number of wins
|
* `{away_wins}` — Away team's number of wins
|
||||||
* `{away_losses}` — Away team's number of losses
|
* `{away_losses}` — Away team's number of losses
|
||||||
@ -99,14 +97,22 @@ class NBA(ScoresBackend):
|
|||||||
('format_no_games', 'Format used when no tracked games are scheduled '
|
('format_no_games', 'Format used when no tracked games are scheduled '
|
||||||
'for the current day (does not support formatter '
|
'for the current day (does not support formatter '
|
||||||
'placeholders)'),
|
'placeholders)'),
|
||||||
('format_pregame', 'Format used when the game has not yet started'),
|
('format', 'Format used to display game information'),
|
||||||
('format_in_progress', 'Format used when the game is in progress'),
|
('status_pregame', 'Format string used for the ``{game_status}`` '
|
||||||
('format_final', 'Format used when the game is complete'),
|
'formatter when the game has not started '),
|
||||||
('format_postponed', 'Format used when the game has been postponed'),
|
('status_in_progress', 'Format string used for the ``{game_status}`` '
|
||||||
|
'formatter when the game is in progress'),
|
||||||
|
('status_final', 'Format string used for the ``{game_status}`` '
|
||||||
|
'formatter when the game has finished'),
|
||||||
|
('status_postponed', 'Format string used for the ``{game_status}`` '
|
||||||
|
'formatter when the game has been postponed'),
|
||||||
('team_colors', 'Dictionary mapping team abbreviations to hex color '
|
('team_colors', 'Dictionary mapping team abbreviations to hex color '
|
||||||
'codes. If overridden, the passed values will be '
|
'codes. If overridden, the passed values will be '
|
||||||
'merged with the defaults, so it is not necessary to '
|
'merged with the defaults, so it is not necessary to '
|
||||||
'define all teams if specifying this value.'),
|
'define all teams if specifying this value.'),
|
||||||
|
('team_format', 'One of ``name``, ``abbreviation``, or ``city``. If '
|
||||||
|
'not specified, takes the value from the ``scores`` '
|
||||||
|
'module.'),
|
||||||
('date', 'Date for which to display game scores, in **YYYY-MM-DD** '
|
('date', 'Date for which to display game scores, in **YYYY-MM-DD** '
|
||||||
'format. If unspecified, the current day\'s games will be '
|
'format. If unspecified, the current day\'s games will be '
|
||||||
'displayed starting at 10am Eastern time, with last '
|
'displayed starting at 10am Eastern time, with last '
|
||||||
@ -155,18 +161,22 @@ class NBA(ScoresBackend):
|
|||||||
}
|
}
|
||||||
|
|
||||||
_valid_teams = [x for x in _default_colors]
|
_valid_teams = [x for x in _default_colors]
|
||||||
_valid_display_order = ['in_progress', 'final', 'postponed', 'pregame']
|
_valid_display_order = ['in_progress', 'final', 'pregame', 'postponed']
|
||||||
|
|
||||||
display_order = _valid_display_order
|
display_order = _valid_display_order
|
||||||
format_no_games = 'NBA: No games'
|
format_no_games = 'NBA: No games'
|
||||||
format_pregame = '[{scroll} ]NBA: [{away_favorite} ][{away_seed} ]{away_abbrev} ({away_wins}-{away_losses}) at [{home_favorite} ][{home_seed} ]{home_abbrev} ({home_wins}-{home_losses}) {start_time:%H:%M %Z}'
|
format = '[{scroll} ]NBA: [{away_favorite} ][{away_seed} ]{away_team} [{away_score} ]({away_wins}-{away_losses}) at [{home_favorite} ][{home_seed} ]{home_team} [{home_score} ]({home_wins}-{home_losses}) {game_status}'
|
||||||
format_in_progress = '[{scroll} ]NBA: [{away_favorite} ]{away_abbrev} {away_score}[ ({away_power_play})], [{home_favorite} ]{home_abbrev} {home_score}[ ({home_power_play})] ({time_remaining} {quarter})'
|
status_pregame = '{start_time:%H:%M %Z}'
|
||||||
format_postponed = '[{scroll} ]NBA: [{away_favorite} ]{away_abbrev} ({away_wins}-{away_losses}) at [{home_favorite} ]{home_abbrev} ({home_wins}-{home_losses}) PPD'
|
status_in_progress = '({time_remaining} {quarter})'
|
||||||
format_final = '[{scroll} ]NBA: [{away_favorite} ]{away_abbrev} {away_score} ({away_wins}-{away_losses}) at [{home_favorite} ]{home_abbrev} {home_score} ({home_wins}-{home_losses}) (Final[/{overtime}])'
|
status_final = '(Final[/{overtime}])'
|
||||||
|
status_postponed = 'PPD'
|
||||||
team_colors = _default_colors
|
team_colors = _default_colors
|
||||||
live_url = LIVE_URL
|
live_url = LIVE_URL
|
||||||
api_url = API_URL
|
api_url = API_URL
|
||||||
|
|
||||||
|
# These will inherit from the Scores class if not overridden
|
||||||
|
team_format = None
|
||||||
|
|
||||||
def check_scores(self):
|
def check_scores(self):
|
||||||
self.get_api_date()
|
self.get_api_date()
|
||||||
|
|
||||||
@ -257,20 +267,20 @@ class NBA(ScoresBackend):
|
|||||||
for key in ('home', 'away'):
|
for key in ('home', 'away'):
|
||||||
team_key = f'{key}Team'
|
team_key = f'{key}Team'
|
||||||
_update(f'{key}_score', f'{team_key}:score',
|
_update(f'{key}_score', f'{team_key}:score',
|
||||||
callback=self.force_int, default=0)
|
callback=self.zero_fallback, default='0')
|
||||||
_update(f'{key}_city', f'{team_key}:teamCity')
|
_update(f'{key}_city', f'{team_key}:teamCity')
|
||||||
_update(f'{key}_name', f'{team_key}:teamName')
|
_update(f'{key}_name', f'{team_key}:teamName')
|
||||||
_update(f'{key}_abbrev', f'{team_key}:teamTricode')
|
_update(f'{key}_abbreviation', f'{team_key}:teamTricode')
|
||||||
if 'playoffs' in game:
|
if 'playoffs' in game:
|
||||||
_update(f'{key}_wins', f'playoffs:{key}_wins',
|
_update(f'{key}_wins', f'playoffs:{key}_wins',
|
||||||
callback=self.force_int, default=0)
|
callback=self.zero_fallback, default='0')
|
||||||
_update(f'{key}_seed', f'playoffs:{key}_seed',
|
_update(f'{key}_seed', f'playoffs:{key}_seed',
|
||||||
callback=self.force_int, default=0)
|
callback=self.zero_fallback, default='0')
|
||||||
else:
|
else:
|
||||||
_update(f'{key}_wins', f'{team_key}:wins',
|
_update(f'{key}_wins', f'{team_key}:wins',
|
||||||
callback=self.force_int, default=0)
|
callback=self.zero_fallback, default='0')
|
||||||
_update(f'{key}_losses', f'{team_key}:losses',
|
_update(f'{key}_losses', f'{team_key}:losses',
|
||||||
callback=self.force_int, default=0)
|
callback=self.zero_fallback, default='0')
|
||||||
ret[f'{key}_seed'] = ''
|
ret[f'{key}_seed'] = ''
|
||||||
|
|
||||||
if 'playoffs' in game:
|
if 'playoffs' in game:
|
||||||
|
@ -21,9 +21,8 @@ class NHL(ScoresBackend):
|
|||||||
|
|
||||||
.. rubric:: Available formatters
|
.. rubric:: Available formatters
|
||||||
|
|
||||||
* `{home_name}` — Name of home team
|
* `{home_team}` — Depending on the value of the ``team_format`` option,
|
||||||
* `{home_city}` — Name of home team's city
|
will contain either the home team's name, abbreviation, or city
|
||||||
* `{home_abbrev}` — 3-letter abbreviation for home team's city
|
|
||||||
* `{home_score}` — Home team's current score
|
* `{home_score}` — Home team's current score
|
||||||
* `{home_wins}` — Home team's number of wins
|
* `{home_wins}` — Home team's number of wins
|
||||||
* `{home_losses}` — Home team's number of losses
|
* `{home_losses}` — Home team's number of losses
|
||||||
@ -33,9 +32,8 @@ class NHL(ScoresBackend):
|
|||||||
followed. Otherwise, this formatter will be blank.
|
followed. Otherwise, this formatter will be blank.
|
||||||
* `{home_empty_net}` — Shows the value from the ``empty_net`` parameter
|
* `{home_empty_net}` — Shows the value from the ``empty_net`` parameter
|
||||||
when the home team's net is empty.
|
when the home team's net is empty.
|
||||||
* `{away_name}` — Name of away team
|
* `{away_team}` — Depending on the value of the ``team_format`` option,
|
||||||
* `{away_city}` — Name of away team's city
|
will contain either the away team's name, abbreviation, or city
|
||||||
* `{away_abbrev}` — 2 or 3-letter abbreviation for away team's city
|
|
||||||
* `{away_score}` — Away team's current score
|
* `{away_score}` — Away team's current score
|
||||||
* `{away_wins}` — Away team's number of wins
|
* `{away_wins}` — Away team's number of wins
|
||||||
* `{away_losses}` — Away team's number of losses
|
* `{away_losses}` — Away team's number of losses
|
||||||
@ -74,8 +72,7 @@ class NHL(ScoresBackend):
|
|||||||
backends=[
|
backends=[
|
||||||
nhl.NHL(
|
nhl.NHL(
|
||||||
favorite_teams=['CHI'],
|
favorite_teams=['CHI'],
|
||||||
format_pregame = '[{scroll} ]NHL: [{away_favorite} ]{away_abbrev} ({away_wins}) at [{home_favorite} ]{home_abbrev} ({home_wins}) {start_time:%H:%M %Z}',
|
format='[{scroll} ]NHL: [{away_favorite} ]{away_team} ({away_wins}) at [{home_favorite} ]{home_team} ({home_wins}) {game_status}'
|
||||||
format_final = '[{scroll} ]NHL: [{away_favorite} ]{away_abbrev} {away_score} ({away_wins}) at [{home_favorite} ]{home_abbrev} {home_score} ({home_wins}) (Final[/{overtime}])',
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -133,10 +130,15 @@ class NHL(ScoresBackend):
|
|||||||
('format_no_games', 'Format used when no tracked games are scheduled '
|
('format_no_games', 'Format used when no tracked games are scheduled '
|
||||||
'for the current day (does not support formatter '
|
'for the current day (does not support formatter '
|
||||||
'placeholders)'),
|
'placeholders)'),
|
||||||
('format_pregame', 'Format used when the game has not yet started'),
|
('format', 'Format used to display game information'),
|
||||||
('format_in_progress', 'Format used when the game is in progress'),
|
('status_pregame', 'Format string used for the ``{game_status}`` '
|
||||||
('format_final', 'Format used when the game is complete'),
|
'formatter when the game has not started '),
|
||||||
('format_postponed', 'Format used when the game has been postponed'),
|
('status_in_progress', 'Format string used for the ``{game_status}`` '
|
||||||
|
'formatter when the game is in progress'),
|
||||||
|
('status_final', 'Format string used for the ``{game_status}`` '
|
||||||
|
'formatter when the game has finished'),
|
||||||
|
('status_postponed', 'Format string used for the ``{game_status}`` '
|
||||||
|
'formatter when the game has been postponed'),
|
||||||
('empty_net', 'Value for the ``{away_empty_net}`` or '
|
('empty_net', 'Value for the ``{away_empty_net}`` or '
|
||||||
'``{home_empty_net}`` formatter when the net is empty. '
|
'``{home_empty_net}`` formatter when the net is empty. '
|
||||||
'When the net is not empty, these formatters will be '
|
'When the net is not empty, these formatters will be '
|
||||||
@ -145,6 +147,9 @@ class NHL(ScoresBackend):
|
|||||||
'codes. If overridden, the passed values will be '
|
'codes. If overridden, the passed values will be '
|
||||||
'merged with the defaults, so it is not necessary to '
|
'merged with the defaults, so it is not necessary to '
|
||||||
'define all teams if specifying this value.'),
|
'define all teams if specifying this value.'),
|
||||||
|
('team_format', 'One of ``name``, ``abbreviation``, or ``city``. If '
|
||||||
|
'not specified, takes the value from the ``scores`` '
|
||||||
|
'module.'),
|
||||||
('date', 'Date for which to display game scores, in **YYYY-MM-DD** '
|
('date', 'Date for which to display game scores, in **YYYY-MM-DD** '
|
||||||
'format. If unspecified, the current day\'s games will be '
|
'format. If unspecified, the current day\'s games will be '
|
||||||
'displayed starting at 10am Eastern time, with last '
|
'displayed starting at 10am Eastern time, with last '
|
||||||
@ -198,20 +203,24 @@ class NHL(ScoresBackend):
|
|||||||
}
|
}
|
||||||
|
|
||||||
_valid_teams = [x for x in _default_colors]
|
_valid_teams = [x for x in _default_colors]
|
||||||
_valid_display_order = ['in_progress', 'final', 'postponed', 'pregame']
|
_valid_display_order = ['in_progress', 'final', 'pregame', 'postponed']
|
||||||
|
|
||||||
display_order = _valid_display_order
|
display_order = _valid_display_order
|
||||||
format_no_games = 'NHL: No games'
|
format_no_games = 'NHL: No games'
|
||||||
format_pregame = '[{scroll} ]NHL: [{away_favorite} ]{away_abbrev} ({away_wins}-{away_losses}-{away_otl}) at [{home_favorite} ]{home_abbrev} ({home_wins}-{home_losses}-{home_otl}) {start_time:%H:%M %Z}'
|
format = '[{scroll} ]NHL: [{away_favorite} ]{away_team} [{away_score} ]({away_wins}-{away_losses}-{away_otl}) at [{home_favorite} ]{home_team} [{home_score} ]({home_wins}-{home_losses}-{home_otl}) {game_status}'
|
||||||
format_in_progress = '[{scroll} ]NHL: [{away_favorite} ]{away_abbrev} {away_score}[ ({away_power_play})][ ({away_empty_net})], [{home_favorite} ]{home_abbrev} {home_score}[ ({home_power_play})][ ({home_empty_net})] ({time_remaining} {period})'
|
status_pregame = '{start_time:%H:%M %Z}'
|
||||||
format_final = '[{scroll} ]NHL: [{away_favorite} ]{away_abbrev} {away_score} ({away_wins}-{away_losses}-{away_otl}) at [{home_favorite} ]{home_abbrev} {home_score} ({home_wins}-{home_losses}-{home_otl}) (Final[/{overtime}])'
|
status_in_progress = '({time_remaining} {period})'
|
||||||
format_postponed = '[{scroll} ]NHL: [{away_favorite} ]{away_abbrev} ({away_wins}-{away_losses}-{away_otl}) at [{home_favorite} ]{home_abbrev} ({home_wins}-{home_losses}-{home_otl}) PPD'
|
status_final = '(Final[/{overtime}])'
|
||||||
|
status_postponed = 'PPD'
|
||||||
empty_net = 'EN'
|
empty_net = 'EN'
|
||||||
team_colors = _default_colors
|
team_colors = _default_colors
|
||||||
live_url = LIVE_URL
|
live_url = LIVE_URL
|
||||||
scoreboard_url = SCOREBOARD_URL
|
scoreboard_url = SCOREBOARD_URL
|
||||||
api_url = API_URL
|
api_url = API_URL
|
||||||
|
|
||||||
|
# These will inherit from the Scores class if not overridden
|
||||||
|
team_format = None
|
||||||
|
|
||||||
@require(internet)
|
@require(internet)
|
||||||
def check_scores(self):
|
def check_scores(self):
|
||||||
self.get_api_date()
|
self.get_api_date()
|
||||||
@ -265,48 +274,48 @@ class NHL(ScoresBackend):
|
|||||||
pp_strength = self.get_nested(linescore, 'powerPlayStrength')
|
pp_strength = self.get_nested(linescore, 'powerPlayStrength')
|
||||||
|
|
||||||
for team in ('away', 'home'):
|
for team in ('away', 'home'):
|
||||||
team_data = self.get_nested(game, 'teams:%s' % team, default={})
|
team_data = self.get_nested(game, f'teams:{team}', default={})
|
||||||
|
|
||||||
if team == 'home':
|
if team == 'home':
|
||||||
ret['venue'] = self.get_nested(team_data, 'venue:name')
|
ret['venue'] = self.get_nested(team_data, 'venue:name')
|
||||||
|
|
||||||
ret['%s_score' % team] = self.get_nested(
|
ret[f'{team}_score'] = self.get_nested(
|
||||||
team_data,
|
team_data,
|
||||||
'score',
|
'score',
|
||||||
callback=self.force_int,
|
callback=self.zero_fallback,
|
||||||
default=0)
|
default=0)
|
||||||
ret['%s_wins' % team] = self.get_nested(
|
ret[f'{team}_wins'] = self.get_nested(
|
||||||
team_data,
|
team_data,
|
||||||
'leagueRecord:wins',
|
'leagueRecord:wins',
|
||||||
callback=self.force_int,
|
callback=self.zero_fallback,
|
||||||
default=0)
|
default=0)
|
||||||
ret['%s_losses' % team] = self.get_nested(
|
ret[f'{team}_losses'] = self.get_nested(
|
||||||
team_data,
|
team_data,
|
||||||
'leagueRecord:losses',
|
'leagueRecord:losses',
|
||||||
callback=self.force_int,
|
callback=self.zero_fallback,
|
||||||
default=0)
|
default=0)
|
||||||
ret['%s_otl' % team] = self.get_nested(
|
ret[f'{team}_otl'] = self.get_nested(
|
||||||
team_data,
|
team_data,
|
||||||
'leagueRecord:ot',
|
'leagueRecord:ot',
|
||||||
callback=self.force_int,
|
callback=self.zero_fallback,
|
||||||
default=0)
|
default=0)
|
||||||
|
|
||||||
ret['%s_city' % team] = self.get_nested(
|
ret[f'{team}_city'] = self.get_nested(
|
||||||
team_data,
|
team_data,
|
||||||
'team:shortName')
|
'team:shortName')
|
||||||
ret['%s_name' % team] = self.get_nested(
|
ret[f'{team}_name'] = self.get_nested(
|
||||||
team_data,
|
team_data,
|
||||||
'team:teamName')
|
'team:teamName')
|
||||||
ret['%s_abbrev' % team] = self.get_nested(
|
ret[f'{team}_abbreviation'] = self.get_nested(
|
||||||
team_data,
|
team_data,
|
||||||
'team:abbreviation')
|
'team:abbreviation')
|
||||||
ret['%s_power_play' % team] = self.get_nested(
|
ret[f'{team}_power_play'] = self.get_nested(
|
||||||
linescore,
|
linescore,
|
||||||
'teams:%s:powerPlay' % team,
|
f'teams:{team}:powerPlay',
|
||||||
callback=lambda x: pp_strength if x and pp_strength != 'Even' else '')
|
callback=lambda x: pp_strength if x and pp_strength != 'Even' else '')
|
||||||
ret['%s_empty_net' % team] = self.get_nested(
|
ret[f'{team}_empty_net'] = self.get_nested(
|
||||||
linescore,
|
linescore,
|
||||||
'teams:%s:goaliePulled' % team,
|
f'teams:{team}:goaliePulled',
|
||||||
callback=lambda x: self.empty_net if x else '')
|
callback=lambda x: self.empty_net if x else '')
|
||||||
|
|
||||||
if game.get('gameType') == 'P':
|
if game.get('gameType') == 'P':
|
||||||
|
Loading…
Reference in New Issue
Block a user