summaryrefslogtreecommitdiff
path: root/plugin.video.nfl.gamepass/default.py
diff options
context:
space:
mode:
authorAlex Waite <Alexqw85@gmail.com>2017-01-09 15:31:14 +0100
committerAlex Waite <Alexqw85@gmail.com>2017-01-10 11:04:55 +0100
commit2e232f12364a1f0a253e0a1f522d5b53f7eda2ec (patch)
tree47c88eafda614ff530d1fedaa4542abf665ba5a8 /plugin.video.nfl.gamepass/default.py
parentf5e966f91c77dde6516858a6e2f03899b7578f77 (diff)
[plugin.video.nfl.gamepass] 0.10.1
Diffstat (limited to 'plugin.video.nfl.gamepass/default.py')
-rw-r--r--plugin.video.nfl.gamepass/default.py629
1 files changed, 629 insertions, 0 deletions
diff --git a/plugin.video.nfl.gamepass/default.py b/plugin.video.nfl.gamepass/default.py
new file mode 100644
index 0000000..7950cf9
--- /dev/null
+++ b/plugin.video.nfl.gamepass/default.py
@@ -0,0 +1,629 @@
+# -*- coding: utf-8 -*-
+"""
+A Kodi addon/skin for NFL Game Pass
+"""
+import calendar
+from datetime import datetime
+import os
+import sys
+import time
+from traceback import format_exc
+
+import xbmc
+import xbmcaddon
+import xbmcgui
+import xbmcvfs
+
+from resources.lib.pigskin import pigskin
+
+addon = xbmcaddon.Addon()
+language = addon.getLocalizedString
+ADDON_PATH = xbmc.translatePath(addon.getAddonInfo('path'))
+ADDON_PROFILE = xbmc.translatePath(addon.getAddonInfo('profile'))
+LOGGING_PREFIX = '[%s-%s]' % (addon.getAddonInfo('id'), addon.getAddonInfo('version'))
+
+if not xbmcvfs.exists(ADDON_PROFILE):
+ xbmcvfs.mkdir(ADDON_PROFILE)
+
+cookie_file = os.path.join(ADDON_PROFILE, 'cookie_file')
+username = addon.getSetting('email')
+password = addon.getSetting('password')
+
+proxy_config = None
+if addon.getSetting('proxy_enabled') == 'true':
+ proxy_config = {
+ 'scheme': addon.getSetting('proxy_scheme'),
+ 'host': addon.getSetting('proxy_host'),
+ 'port': addon.getSetting('proxy_port'),
+ 'auth': {
+ 'username': addon.getSetting('proxy_username'),
+ 'password': addon.getSetting('proxy_password'),
+ },
+ }
+ if addon.getSetting('proxy_auth') == 'false':
+ proxy_config['auth'] = None
+
+gp = pigskin(proxy_config, cookie_file=cookie_file, debug=True)
+
+
+def addon_log(string):
+ msg = '%s: %s' % (LOGGING_PREFIX, string)
+ xbmc.log(msg=msg, level=xbmc.LOGDEBUG)
+
+
+class GamepassGUI(xbmcgui.WindowXML):
+ def __init__(self, *args, **kwargs):
+ self.season_list = None
+ self.season_items = []
+ self.clicked_season = -1
+ self.weeks_list = None
+ self.weeks_items = []
+ self.clicked_week = -1
+ self.games_list = None
+ self.games_items = []
+ self.clicked_game = -1
+ self.live_list = None
+ self.live_items = []
+ self.selected_season = ''
+ self.selected_week = ''
+ self.main_selection = None
+ self.player = None
+ self.list_refill = False
+ self.focusId = 100
+ self.seasons_and_weeks = gp.get_seasons_and_weeks()
+
+ xbmcgui.WindowXML.__init__(self, *args, **kwargs)
+ self.action_previous_menu = (9, 10, 92, 216, 247, 257, 275, 61467, 61448)
+
+ def onInit(self): # pylint: disable=invalid-name
+ self.window = xbmcgui.Window(xbmcgui.getCurrentWindowId())
+ self.season_list = self.window.getControl(210)
+ self.weeks_list = self.window.getControl(220)
+ self.games_list = self.window.getControl(230)
+ self.live_list = self.window.getControl(240)
+
+ if gp.subscription == 'domestic':
+ self.window.setProperty('domestic', 'true')
+
+ if self.list_refill:
+ self.season_list.reset()
+ self.season_list.addItems(self.season_items)
+ self.weeks_list.reset()
+ self.weeks_list.addItems(self.weeks_items)
+ self.games_list.reset()
+ self.games_list.addItems(self.games_items)
+ self.live_list.reset()
+ self.live_list.addItems(self.live_items)
+ else:
+ self.window.setProperty('NW_clicked', 'false')
+ self.window.setProperty('GP_clicked', 'false')
+
+ xbmc.executebuiltin("Dialog.Close(busydialog)")
+
+ try:
+ self.setFocus(self.window.getControl(self.focusId))
+ except:
+ addon_log('Focus not possible: %s' % self.focusId)
+
+ def coloring(self, text, meaning):
+ """Return the text wrapped in appropriate color markup."""
+ if meaning == "disabled":
+ color = "FF000000"
+ elif meaning == "disabled-info":
+ color = "FF111111"
+ colored_text = "[COLOR=%s]%s[/COLOR]" % (color, text)
+ return colored_text
+
+ def display_seasons(self):
+ """List seasons"""
+ self.season_items = []
+ for season in sorted(self.seasons_and_weeks.keys(), reverse=True):
+ listitem = xbmcgui.ListItem(season)
+ self.season_items.append(listitem)
+
+ self.season_list.addItems(self.season_items)
+
+ def display_nfln_seasons(self):
+ """List seasons"""
+ self.season_items = []
+ # sort so that years are first (descending) followed by text
+ for season in sorted(gp.nflnSeasons, key=lambda x: (x[0].isdigit(), x), reverse=True):
+ listitem = xbmcgui.ListItem(season)
+ self.season_items.append(listitem)
+
+ self.season_list.addItems(self.season_items)
+
+ def display_nfl_network_archive(self):
+ """List shows for a given season"""
+ self.weeks_items = []
+ shows = gp.get_shows(self.selected_season)
+ for show_name in shows:
+ listitem = xbmcgui.ListItem(show_name)
+ self.weeks_items.append(listitem)
+
+ self.weeks_list.addItems(self.weeks_items)
+
+ def display_weeks_games(self):
+ """Show games for a given season/week"""
+ self.games_items = []
+ games = gp.get_weeks_games(self.selected_season, self.selected_week)
+
+ date_time_format = '%Y-%m-%dT%H:%M:%S.000'
+ if games:
+ for game in games:
+ if game['homeTeam']['id'] is None: # sometimes the first item is empty
+ continue
+
+ game_info = ''
+ game_id = game['id']
+ game_versions = []
+ isPlayable = 'true'
+ isBlackedOut = 'false'
+ home_team = game['homeTeam']
+ away_team = game['awayTeam']
+
+ # Pro-bowl doesn't have a team "name" only a team city, which is the
+ # team name... wtf
+ if game['homeTeam']['name'] is None:
+ game_name_shrt = '[B]%s[/B] at [B]%s[/B]' % (away_team['city'], home_team['city'])
+ game_name_full = game_name_shrt
+ else:
+ game_name_shrt = '[B]%s[/B] at [B]%s[/B]' % (away_team['name'], home_team['name'])
+ game_name_full = '[B]%s %s[/B] at [B]%s %s[/B]' % (away_team['city'], away_team['name'], home_team['city'], home_team['name'])
+
+ for key, value in {'Condensed': 'condensedId', 'Full': 'programId'}.items():
+ if value in game:
+ game_versions.append(key)
+
+ if 'isLive' in game:
+ game_versions.append('Live')
+
+ if 'gameEndTimeGMT' in game:
+ # Show game duration only if user wants to see it
+ if addon.getSetting('hide_game_length') == 'false':
+ try:
+ start_time = datetime(*(time.strptime(game['gameTimeGMT'], date_time_format)[0:6]))
+ end_time = datetime(*(time.strptime(game['gameEndTimeGMT'], date_time_format)[0:6]))
+ game_info = 'Final [CR] Duration: %s' % time.strftime('%H:%M:%S', time.gmtime((end_time - start_time).seconds))
+ except:
+ addon_log(format_exc())
+ if 'result' in game:
+ game_info = 'Final'
+ else:
+ game_info = 'Final'
+ else:
+ if 'isLive' in game:
+ game_info = '» Live «'
+
+ try:
+ if addon.getSetting('local_tz') == '0': # don't localize
+ game_datetime = datetime(*(time.strptime(game['date'], date_time_format)[0:6]))
+ game_info = game_datetime.strftime('%A, %b %d - %I:%M %p')
+ else:
+ game_gmt = time.strptime(game['gameTimeGMT'], date_time_format)
+ secs = calendar.timegm(game_gmt)
+ game_local = time.localtime(secs)
+
+ if addon.getSetting('local_tz') == '1': # localize and use 12-hour clock
+ game_info = time.strftime('%A, %b %d - %I:%M %p', game_local)
+ else: # localize and use 24-hour clock
+ game_info = time.strftime('%A, %b %d - %H:%M', game_local)
+ except: # all else fails, just use their raw date value
+ game_datetime = game['date'].split('T')
+ game_info = game_datetime[0] + '[CR]' + game_datetime[1].split('.')[0] + ' ET'
+
+ if 'hasProgram' not in game: # if subscription doesn't allow
+ isPlayable = 'false'
+ game_name_full = self.coloring(game_name_full, "disabled")
+ game_name_shrt = self.coloring(game_name_shrt, "disabled")
+ game_info = self.coloring(game_info, "disabled-info")
+
+ try:
+ if game['blocked'] == 'true':
+ isPlayable = 'false'
+ isBlackedOut = 'true'
+ game_info = '» Blacked Out «'
+ game_name_full = self.coloring(game_name_full, "disabled")
+ game_name_shrt = self.coloring(game_name_shrt, "disabled")
+ game_info = self.coloring(game_info, "disabled-info")
+ except KeyError:
+ pass
+
+ listitem = xbmcgui.ListItem(game_name_shrt, game_name_full)
+ listitem.setProperty('away_thumb', 'http://i.nflcdn.com/static/site/7.4/img/logos/teams-matte-144x96/%s.png' % away_team['id'])
+ listitem.setProperty('home_thumb', 'http://i.nflcdn.com/static/site/7.4/img/logos/teams-matte-144x96/%s.png' % home_team['id'])
+ listitem.setProperty('game_info', game_info)
+ listitem.setProperty('is_game', 'true')
+ listitem.setProperty('is_show', 'false')
+ listitem.setProperty('isPlayable', isPlayable)
+ listitem.setProperty('isBlackedOut', isBlackedOut)
+ listitem.setProperty('game_id', game_id)
+ listitem.setProperty('game_date', game['date'].split('T')[0])
+ listitem.setProperty('game_versions', ' '.join(game_versions))
+ self.games_items.append(listitem)
+
+ self.games_list.addItems(self.games_items)
+
+ else:
+ dialog = xbmcgui.Dialog()
+ dialog.ok(language(30021), language(30046))
+
+ def display_seasons_weeks(self):
+ """List weeks for a given season"""
+ weeks = self.seasons_and_weeks[self.selected_season]
+
+ for week_code, week in sorted(weeks.iteritems()):
+ future = 'false'
+ try:
+ # convert EST to GMT by adding 6 hours
+ week_date = week['@start'] + ' 06:00'
+ # avoid super annoying bug http://forum.kodi.tv/showthread.php?tid=112916
+ week_datetime = datetime(*(time.strptime(week_date, '%Y%m%d %H:%M')[0:6]))
+ now_datetime = datetime.utcnow()
+
+ if week_datetime > now_datetime:
+ future = 'true'
+ except KeyError: # some old seasons don't provide week dates
+ pass
+
+ listitem = xbmcgui.ListItem(week['@label'].title())
+ listitem.setProperty('week_code', week_code)
+ listitem.setProperty('future', future)
+ self.weeks_items.append(listitem)
+ self.weeks_list.addItems(self.weeks_items)
+
+ def display_shows_episodes(self, show_name, season):
+ """Show episodes for a given season/show"""
+ self.games_items = []
+ items = gp.get_shows_episodes(show_name, season)
+
+ for i in items:
+ try:
+ listitem = xbmcgui.ListItem('[B]%s[/B]' % show_name)
+ listitem.setProperty('game_info', i['name'])
+ listitem.setProperty('away_thumb', gp.image_url + i['image'])
+ listitem.setProperty('url', i['publishPoint'])
+ listitem.setProperty('id', i['id'])
+ listitem.setProperty('type', i['type'])
+ listitem.setProperty('is_game', 'false')
+ listitem.setProperty('is_show', 'true')
+ listitem.setProperty('isPlayable', 'true')
+ self.games_items.append(listitem)
+ except:
+ addon_log('Exception adding archive directory: %s' % format_exc())
+ addon_log('Directory name: %s' % i['name'])
+ self.games_list.addItems(self.games_items)
+
+ def play_url(self, url):
+ xbmc.executebuiltin("Dialog.Close(busydialog)")
+ self.list_refill = True
+ xbmc.Player().play(url)
+
+ def init(self, level):
+ if level == 'season':
+ self.weeks_items = []
+ self.weeks_list.reset()
+ self.games_list.reset()
+ self.clicked_week = -1
+ self.clicked_game = -1
+
+ if self.clicked_season > -1: # unset previously selected season
+ self.season_list.getListItem(self.clicked_season).setProperty('clicked', 'false')
+
+ self.season_list.getSelectedItem().setProperty('clicked', 'true')
+ self.clicked_season = self.season_list.getSelectedPosition()
+ elif level == 'week/show':
+ self.games_list.reset()
+ self.clicked_game = -1
+
+ if self.clicked_week > -1: # unset previously selected week/show
+ self.weeks_list.getListItem(self.clicked_week).setProperty('clicked', 'false')
+
+ self.weeks_list.getSelectedItem().setProperty('clicked', 'true')
+ self.clicked_week = self.weeks_list.getSelectedPosition()
+ elif level == 'game/episode':
+ if self.clicked_game > -1: # unset previously selected game/episode
+ self.games_list.getListItem(self.clicked_game).setProperty('clicked', 'false')
+
+ self.games_list.getSelectedItem().setProperty('clicked', 'true')
+ self.clicked_game = self.games_list.getSelectedPosition()
+
+ def ask_bitrate(self, bitrates):
+ """Presents a dialog for user to select from a list of bitrates.
+ Returns the value of the selected bitrate.
+ """
+ options = []
+ for bitrate in bitrates:
+ options.append(bitrate + ' Kbps')
+ dialog = xbmcgui.Dialog()
+ xbmc.executebuiltin("Dialog.Close(busydialog)")
+ ret = dialog.select(language(30003), options)
+ if ret > -1:
+ return bitrates[ret]
+ else:
+ return None
+
+ def select_bitrate(self, manifest_bitrates=None):
+ """Returns a bitrate, while honoring the user's /preference/."""
+ bitrate_setting = int(addon.getSetting('preferred_bitrate'))
+ bitrate_values = ['4500', '3000', '2400', '1600', '1200', '800', '400']
+
+ highest = False
+ preferred_bitrate = None
+ if bitrate_setting == 0: # 0 === "highest"
+ highest = True
+ elif 0 < bitrate_setting and bitrate_setting < 8: # a specific bitrate. '8' === "ask"
+ preferred_bitrate = bitrate_values[bitrate_setting - 1]
+
+ if manifest_bitrates:
+ manifest_bitrates.sort(key=int, reverse=True)
+ if highest:
+ return manifest_bitrates[0]
+ elif preferred_bitrate and preferred_bitrate in manifest_bitrates:
+ return preferred_bitrate
+ else: # ask user
+ return self.ask_bitrate(manifest_bitrates)
+ else:
+ if highest:
+ return bitrate_values[0]
+ elif preferred_bitrate:
+ return preferred_bitrate
+ else: # ask user
+ return self.ask_bitrate(bitrate_values)
+
+ def select_version(self, game_versions):
+ """Returns a game version, while honoring the user's /preference/.
+ Note: the full version is always available but not always the condensed.
+ """
+ preferred_version = int(addon.getSetting('preferred_game_version'))
+
+ # user wants to be asked to select version
+ if preferred_version == 2:
+ versions = [language(30014)]
+ if 'Condensed' in game_versions:
+ versions.append(language(30015))
+ if 'Coach' in game_versions:
+ versions.append(language(30032))
+ dialog = xbmcgui.Dialog()
+ xbmc.executebuiltin("Dialog.Close(busydialog)")
+ preferred_version = dialog.select(language(30016), versions)
+
+ if preferred_version == 1 and 'Condensed' in game_versions:
+ game_version = 'condensed'
+ elif preferred_version == 2 and 'Coach' in game_versions:
+ game_version = 'coach'
+ else:
+ game_version = 'archive'
+
+ if preferred_version > -1:
+ return game_version
+ else:
+ return None
+
+ def onFocus(self, controlId): # pylint: disable=invalid-name
+ # save currently focused list
+ if controlId in [210, 220, 230, 240]:
+ self.focusId = controlId
+
+ def onClick(self, controlId): # pylint: disable=invalid-name
+ try:
+ xbmc.executebuiltin("ActivateWindow(busydialog)")
+ if controlId in [110, 120, 130]:
+ self.games_list.reset()
+ self.weeks_list.reset()
+ self.season_list.reset()
+ self.live_list.reset()
+ self.games_items = []
+ self.weeks_items = []
+ self.live_items = []
+ self.clicked_game = -1
+ self.clicked_week = -1
+ self.clicked_season = -1
+
+ if controlId in [110, 120]:
+ self.main_selection = 'GamePass'
+ self.window.setProperty('NW_clicked', 'false')
+ self.window.setProperty('GP_clicked', 'true')
+
+ # display games of current week for usability purposes
+ cur_s_w = gp.get_current_season_and_week()
+ self.selected_season = cur_s_w.keys()[0]
+ self.selected_week = cur_s_w.values()[0]
+ self.display_seasons()
+
+ try:
+ self.display_seasons_weeks()
+ self.display_weeks_games()
+ except:
+ addon_log('Error while reading seasons weeks and games')
+ elif controlId == 130:
+ self.main_selection = 'NFL Network'
+ self.window.setProperty('NW_clicked', 'true')
+ self.window.setProperty('GP_clicked', 'false')
+
+ listitem = xbmcgui.ListItem('NFL Network - Live', 'NFL Network - Live')
+ self.live_items.append(listitem)
+
+ if gp.redzone_on_air():
+ listitem = xbmcgui.ListItem('NFL RedZone - Live', 'NFL RedZone - Live')
+ self.live_items.append(listitem)
+
+ self.live_list.addItems(self.live_items)
+ self.display_nfln_seasons()
+
+ xbmc.executebuiltin("Dialog.Close(busydialog)")
+ return
+
+ if self.main_selection == 'GamePass':
+ if controlId == 210: # season is clicked
+ self.init('season')
+ self.selected_season = self.season_list.getSelectedItem().getLabel()
+
+ self.display_seasons_weeks()
+ elif controlId == 220: # week is clicked
+ self.init('week/show')
+ self.selected_week = self.weeks_list.getSelectedItem().getProperty('week_code')
+
+ self.display_weeks_games()
+ elif controlId == 230: # game is clicked
+ selectedGame = self.games_list.getSelectedItem()
+ if selectedGame.getProperty('isPlayable') == 'true':
+ self.init('game/episode')
+ game_id = selectedGame.getProperty('game_id')
+ game_versions = selectedGame.getProperty('game_versions')
+
+ if 'Live' in game_versions:
+ if 'Final' in selectedGame.getProperty('game_info'):
+ game_version = self.select_version(game_versions)
+ if game_version == 'archive':
+ game_version = 'dvr'
+ else:
+ game_version = 'live'
+ else:
+ # Check for coaches film availability
+ if gp.check_for_coachestape(game_id, self.selected_season):
+ game_versions = game_versions + ' Coach'
+
+ game_version = self.select_version(game_versions)
+ if game_version:
+ if game_version == 'coach':
+ xbmc.executebuiltin("ActivateWindow(busydialog)")
+ coachesItems = []
+ game_date = selectedGame.getProperty('game_date').replace('-', '/')
+ self.playBackStop = False
+
+ play_stream = gp.get_coaches_url(game_id, game_date, 'dummy')
+ plays = gp.get_coaches_playIDs(game_id, self.selected_season)
+ for playID in sorted(plays, key=int):
+ cf_url = str(play_stream).replace('dummy', playID)
+ item = xbmcgui.ListItem(plays[playID])
+ item.setProperty('url', cf_url)
+ coachesItems.append(item)
+
+ self.list_refill = True
+ xbmc.executebuiltin("Dialog.Close(busydialog)")
+ coachGui = CoachesFilmGUI('script-gamepass-coach.xml', ADDON_PATH, plays=coachesItems)
+ coachGui.doModal()
+ del coachGui
+ else:
+ game_streams = gp.get_publishpoint_streams(game_id, 'game', game_version)
+ bitrate = self.select_bitrate(game_streams.keys())
+ if bitrate:
+ game_url = game_streams[bitrate]
+ self.play_url(game_url)
+
+ elif self.main_selection == 'NFL Network':
+ if controlId == 210: # season is clicked
+ self.init('season')
+ self.selected_season = self.season_list.getSelectedItem().getLabel()
+
+ self.display_nfl_network_archive()
+ elif controlId == 220: # show is clicked
+ self.init('week/show')
+ show_name = self.weeks_list.getSelectedItem().getLabel()
+
+ self.display_shows_episodes(show_name, self.selected_season)
+ elif controlId == 230: # episode is clicked
+ self.init('game/episode')
+ video_id = self.games_list.getSelectedItem().getProperty('id')
+ video_streams = gp.get_publishpoint_streams(video_id, 'video')
+ if video_streams:
+ addon_log('Video-Streams: %s' % video_streams)
+ bitrate = self.select_bitrate(video_streams.keys())
+ if bitrate:
+ video_url = video_streams[bitrate]
+ self.play_url(video_url)
+ else:
+ dialog = xbmcgui.Dialog()
+ dialog.ok(language(30043), language(30045))
+ elif controlId == 240: # Live content (though not games)
+ show_name = self.live_list.getSelectedItem().getLabel()
+ if show_name == 'NFL RedZone - Live':
+ rz_live_streams = gp.get_publishpoint_streams('redzone')
+ if rz_live_streams:
+ bitrate = self.select_bitrate(rz_live_streams.keys())
+ if bitrate:
+ rz_live_url = rz_live_streams[bitrate]
+ self.play_url(rz_live_url)
+ else:
+ dialog = xbmcgui.Dialog()
+ dialog.ok(language(30043), language(30045))
+ elif show_name == 'NFL Network - Live':
+ nw_live_streams = gp.get_publishpoint_streams('nfl_network')
+ if nw_live_streams:
+ bitrate = self.select_bitrate(nw_live_streams.keys())
+ if bitrate:
+ nw_live_url = nw_live_streams[bitrate]
+ self.play_url(nw_live_url)
+ else:
+ dialog = xbmcgui.Dialog()
+ dialog.ok(language(30043), language(30045))
+ xbmc.executebuiltin("Dialog.Close(busydialog)")
+ except Exception: # catch anything that might fail
+ xbmc.executebuiltin("Dialog.Close(busydialog)")
+ addon_log(format_exc())
+
+ dialog = xbmcgui.Dialog()
+ if self.main_selection == 'NFL Network' and controlId == 230: # episode
+ # inform that not all shows will work
+ dialog.ok(language(30043), language(30044))
+ else:
+ # generic oops
+ dialog.ok(language(30021), language(30024))
+
+
+class CoachesFilmGUI(xbmcgui.WindowXML):
+ def __init__(self, xmlFilename, scriptPath, plays, defaultSkin="Default", defaultRes="720p"): # pylint: disable=invalid-name
+ self.playsList = None
+ self.playsItems = plays
+
+ xbmcgui.WindowXML.__init__(self, xmlFilename, scriptPath, defaultSkin, defaultRes)
+ self.action_previous_menu = (9, 10, 92, 216, 247, 257, 275, 61467, 61448)
+
+ def onInit(self): # pylint: disable=invalid-name
+ self.window = xbmcgui.Window(xbmcgui.getCurrentWindowId())
+ if addon.getSetting('coach_lite') == 'true':
+ self.window.setProperty('coach_lite', 'true')
+
+ self.playsList = self.window.getControl(110)
+ self.window.getControl(99).setLabel(language(30032))
+ self.playsList.addItems(self.playsItems)
+ self.setFocus(self.playsList)
+ url = self.playsList.getListItem(0).getProperty('url')
+ xbmc.executebuiltin("Dialog.Close(busydialog)")
+ xbmc.executebuiltin('PlayMedia(%s,False,1)' % url)
+
+ def onClick(self, controlId): # pylint: disable=invalid-name
+ if controlId == 110:
+ url = self.playsList.getSelectedItem().getProperty('url')
+ xbmc.executebuiltin('PlayMedia(%s,False,1)' % url)
+
+if __name__ == "__main__":
+ addon_log('script starting')
+ xbmc.executebuiltin("Dialog.Close(busydialog)")
+
+ try:
+ gp.login(username, password)
+ except gp.LoginFailure as error:
+ dialog = xbmcgui.Dialog()
+ if error.value == 'Game Pass Domestic Blackout':
+ addon_log('Game Pass Domestic is in blackout.')
+ dialog.ok(language(30021),
+ language(30022))
+ else:
+ addon_log('login failed')
+ dialog.ok(language(30021),
+ language(30023))
+ sys.exit(0)
+ except:
+ addon_log(format_exc())
+ dialog = xbmcgui.Dialog()
+ dialog.ok('Epic Failure',
+ language(30024))
+ sys.exit(0)
+
+ gui = GamepassGUI('script-gamepass.xml', ADDON_PATH)
+ gui.doModal()
+ del gui
+
+addon_log('script finished')