Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add important dates feature #85

Merged
merged 21 commits into from
Apr 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion mlbgame/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
#!python
from __future__ import print_function
import mlbgame

game = mlbgame.day(2015, 11, 1, home='Mets')[0]
stats = mlbgame.player_stats(game.game_id)
for player in stats.home_batting:
Expand Down Expand Up @@ -228,6 +228,13 @@ def game_events(game_id):
return [mlbgame.events.Inning(data[x], x) for x in data]


def important_dates(year=None):
"""Return ImportantDates object that contains MLB important dates"""
year = datetime.now().year if not year else year
data = mlbgame.info.important_dates(year)
return mlbgame.info.ImportantDates(data)


def league():
"""Return Info object that contains league information"""
return mlbgame.info.Info(mlbgame.info.league_info())
Expand Down
54 changes: 32 additions & 22 deletions mlbgame/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"""

import os

try:
from urllib.request import urlopen
from urllib.error import HTTPError
Expand All @@ -21,21 +20,33 @@
PROPERTY_URL = 'http://mlb.mlb.com/properties/mlb_properties.xml'
ROSTER_URL = 'http://mlb.mlb.com/lookup/json/named.roster_40.bam?team_id={0}'
INJURY_URL = 'http://mlb.mlb.com/fantasylookup/json/named.wsfb_news_injury.bam'
STANDINGS_URL = ('http://mlb.mlb.com/lookup/json/named.standings_schedule_date.bam?season={0}&'
'schedule_game_date.game_date=%27{1}%27&sit_code=%27h0%27&league_id=103&'
'league_id=104&all_star_sw=%27N%27&version=2')
STANDINGS_HISTORICAL_URL = ('http://mlb.mlb.com/lookup/json/named.historical_standings_schedule_date.bam?season={0}&'
'game_date=%27{1}%27&sit_code=%27h0%27&league_id=103&'
'league_id=104&all_star_sw=%27N%27&version=48')
STANDINGS_URL = ('http://mlb.mlb.com/lookup/json/named.'
'standings_schedule_date.bam?season={0}&'
'schedule_game_date.game_date=%27{1}%27&sit_code='
'%27h0%27&league_id=103&'
'league_id=104&all_star_sw=%27N%27&version=2')
STANDINGS_HISTORICAL_URL = ('http://mlb.mlb.com/lookup/json/'
'named.historical_standings_schedule_date.bam?'
'season={0}&game_date=%27{1}%27&sit_code=%27h0%27&'
'league_id=103&league_id=104&all_star_sw=%27N%27&'
'version=48')
IMPORTANT_DATES = ('http://lookup-service-prod.mlb.com/named.org_history.bam?'
'org_id=1&season={0}')
# Local Directory
PWD = os.path.join(os.path.dirname(__file__))


def get_important_dates(year):
try:
return urlopen(IMPORTANT_DATES.format(year))
except HTTPError:
raise ValueError('Failed to retrieve MLB important dates information.')


def get_scoreboard(year, month, day):
"""Return the game file for a certain day matching certain criteria."""
try:
data = urlopen(BASE_URL.format(year, month, day
) + 'scoreboard.xml')
data = urlopen(BASE_URL.format(year, month, day) + 'scoreboard.xml')
except HTTPError:
data = os.path.join(PWD, 'default.xml')
return data
Expand All @@ -45,18 +56,17 @@ def get_box_score(game_id):
"""Return the box score file of a game with matching id."""
year, month, day = get_date_from_game_id(game_id)
try:
return urlopen(GAME_URL.format(year, month, day,
game_id,
return urlopen(GAME_URL.format(year, month, day, game_id,
'boxscore.xml'))
except HTTPError:
raise ValueError('Could not find a game with that id.')


def get_raw_box_score(game_id):
"""Return the raw box score file of a game with matching id."""
year, month, day = get_date_from_game_id(game_id)
try:
return urlopen(GAME_URL.format(year, month, day,
game_id,
return urlopen(GAME_URL.format(year, month, day, game_id,
'rawboxscore.xml'))
except HTTPError:
raise ValueError('Could not find a game with that id.')
Expand All @@ -66,8 +76,7 @@ def get_game_events(game_id):
"""Return the game events file of a game with matching id."""
year, month, day = get_date_from_game_id(game_id)
try:
return urlopen(GAME_URL.format(year, month, day,
game_id,
return urlopen(GAME_URL.format(year, month, day, game_id,
'game_events.xml'))
except HTTPError:
raise ValueError('Could not find a game with that id.')
Expand All @@ -77,8 +86,7 @@ def get_overview(game_id):
"""Return the linescore file of a game with matching id."""
year, month, day = get_date_from_game_id(game_id)
try:
return urlopen(GAME_URL.format(year, month, day,
game_id,
return urlopen(GAME_URL.format(year, month, day, game_id,
'linescore.xml'))
except HTTPError:
raise ValueError('Could not find a game with that id.')
Expand All @@ -88,9 +96,8 @@ def get_players(game_id):
"""Return the players file of a game with matching id."""
year, month, day = get_date_from_game_id(game_id)
try:
return urlopen(GAME_URL.format(year, month, day,
game_id,
"players.xml"))
return urlopen(GAME_URL.format(year, month, day, game_id,
'players.xml'))
except HTTPError:
raise ValueError('Could not find a game with that id.')

Expand All @@ -117,7 +124,8 @@ def get_roster(team_id):
def get_standings(date):
"""Return the standings file for current standings (given current date)."""
try:
return urlopen(STANDINGS_URL.format(date.year, date.strftime('%Y/%m/%d')))
return urlopen(STANDINGS_URL.format(date.year,
date.strftime('%Y/%m/%d')))
except HTTPError:
ValueError('Could not find the standings file. '
'mlb.com does not provide the file that '
Expand All @@ -127,7 +135,9 @@ def get_standings(date):
def get_historical_standings(date):
"""Return the historical standings file for specified date."""
try:
return urlopen(STANDINGS_HISTORICAL_URL.format(date.year, date.strftime('%Y/%m/%d')))
url = STANDINGS_HISTORICAL_URL.format(date.year,
date.strftime('%Y/%m/%d'))
return urlopen(url)
except HTTPError:
ValueError('Could not find standings for that date.')

Expand Down
4 changes: 2 additions & 2 deletions mlbgame/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
that occured throughout games.
"""

import lxml.etree as etree

import mlbgame.data
import mlbgame.object

import lxml.etree as etree


def __inning_info(inning, part):
# info
Expand Down
10 changes: 5 additions & 5 deletions mlbgame/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
such as the scoreboard and the box score.
"""

import mlbgame.data
import mlbgame.object

import datetime
import lxml.etree as etree

import mlbgame.data
import mlbgame.object


def scoreboard(year, month, day, home=None, away=None):
"""Return the scoreboard information for games matching the parameters
Expand Down Expand Up @@ -326,15 +326,15 @@ def overview(game_id):
# parse data
overview_root = etree.parse(overview).getroot()
raw_box_score_root = etree.parse(raw_box_score).getroot()

output = {}
# get overview attributes
for x in overview_root.attrib:
output[x] = overview_root.attrib[x]
# get raw box score attributes
for x in raw_box_score_root.attrib:
output[x] = raw_box_score_root.attrib[x]

# Get probable starter attributes if they exist
home_pitcher_tree = overview_root.find('home_probable_pitcher')
if home_pitcher_tree is not None:
Expand Down
99 changes: 94 additions & 5 deletions mlbgame/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,89 @@ def team_info():
return output


def important_dates(year):
"""Returns a dictionary of important dates"""
output = {}
data = mlbgame.data.get_important_dates(year)
important_dates = etree.parse(data).getroot().\
find('queryResults').find('row')
try:
for x in important_dates.attrib:
output[x] = important_dates.attrib[x]
except AttributeError:
raise ValueError('Unable to find important dates for {}.'.format(year))
return output


class ImportantDates(mlbgame.object.Object):
"""Holds information about important MLB dates and other info.
Properties:
all_star_date
all_star_sw
file_code
first_date_2ndh
first_date_seas
games
games_1sth
games_2ndh
last_date_1sth
last_date_seas
name_abbrev
name_full
name_short
org_code
org_type
organization_id
parent_abbrev
parent_org
playoff_games
playoff_points_sw
playoff_rounds
playoff_sw
playoff_teams
playoffs_end_date
playoffs_start_date
point_values
split_season_sw
wildcard_sw
wildcard_teams
year
"""
def nice_output(self):
"""Return a string for printing"""
dates = [
str_format('Opening Day {0}: {1}.',
[self.year, date_format(self.first_date_seas)]),
str_format('Last day of the 1st half: {0}.',
[date_format(self.last_date_1sth)]),
str_format('{0} All Star Game: {1}.',
[self.year, date_format(self.all_star_date)]),
str_format('First day of the 2nd half: {}.',
[date_format(self.first_date_2ndh)]),
str_format('Last day of the {0} season: {1}.',
[self.year, date_format(self.last_date_seas)]),
str_format('{0} Playoffs start: {1}.',
[self.year, date_format(self.playoffs_start_date)]),
str_format('{0} Playoffs end: {1}.',
[self.year, date_format(self.playoffs_end_date)])
]
return '\n'.join(dates)

def __str__(self):
return self.nice_output()


def date_format(my_date):
try:
my_date = datetime.strptime(my_date, '%Y-%m-%dT%H:%M:%S')
except ValueError:
return ''
return my_date.strftime('%A, %B %d')

def str_format(my_str, args):
return my_str.format(*args)


class Info(mlbgame.object.Object):
"""Holds information about the league or teams

Expand Down Expand Up @@ -204,14 +287,18 @@ def standings(date):
}
now = datetime.now()
divisions = []
if date.year == now.year and date.month == now.month and date.day == now.day:
if date.year == now.year and \
date.month == now.month and \
date.day == now.day:
data = mlbgame.data.get_standings(date)
standings_schedule_date = 'standings_schedule_date'
else:
data = mlbgame.data.get_historical_standings(date)
standings_schedule_date = 'historical_standings_schedule_date'
parsed = json.loads(data.read().decode('utf-8'))
sjson = parsed[standings_schedule_date]['standings_all_date_rptr']['standings_all_date']
all_date_rptr = 'standings_all_date_rptr'
all_date = 'standings_all_date'
sjson = parsed[standings_schedule_date][all_date_rptr][all_date]
for league in sjson:
if league['league_id'] == '103':
divs = DIVISIONS['AL']
Expand Down Expand Up @@ -240,11 +327,12 @@ class Standings(object):

def __init__(self, data):
"""Creates a standings object for info specified in `data`.

`data` should be a dictionary of values
"""
self.standings_schedule_date = data['standings_schedule_date']
self.divisions = [Division(x['division'], x['teams']) for x in data['divisions']]
self.divisions = [Division(x['division'],
x['teams']) for x in data['divisions']]


class Division(object):
Expand Down Expand Up @@ -314,6 +402,7 @@ class Team(mlbgame.object.Object):
"""
pass


def injury():
data = mlbgame.data.get_injuries()
parsed = json.loads(data.read().decode('utf-8'))
Expand All @@ -329,7 +418,7 @@ class Injuries(object):

def __init__(self, injuries):
"""Creates an Injuries object for given data.

`injuries` should be a list of injuries.
"""
self.injuries = [Injury(x) for x in injuries]
Expand Down
Loading