Пример #1
0
def get_game_rec(game_data, team_to_play):
    """
    """
    game_rec = None
    for game_pk in game_data:
        if team_to_play in (game_data[game_pk]['away_abbrev'],
                            game_data[game_pk]['home_abbrev']):
            game_rec = game_data[game_pk]
            break
    if game_rec is None:
        util.die("No game found for team {}".format(team_to_play))
    return game_rec
Пример #2
0
def login():
    """
    taken from plugin.video.mlbtv
    """
    url = 'https://secure.mlb.com/pubajaxws/services/IdentityPointService'
    headers = {
        "SOAPAction":
        "http://services.bamnetworks.com/registration/identityPoint/identify",
        "Content-type": "text/xml; charset=utf-8",
        "User-Agent":
        "Dalvik/2.1.0 (Linux; U; Android 6.0.1; Hub Build/MHC19J)",
        "Connection": "Keep-Alive"
    }

    payload = "<?xml version='1.0' encoding='UTF-8'?"
    payload += '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
    payload += '<SOAP-ENV:Body><tns:identityPoint_identify_request xmlns:tns="http://services.bamnetworks.com/registration/types/1.4">'
    payload += '<tns:identification type="email-password"><tns:id xsi:nil="true"/>'
    payload += '<tns:fingerprint xsi:nil="true"/>'
    payload += '<tns:email>'
    payload += '<tns:id xsi:nil="true"/>'
    payload += '<tns:address>{}</tns:address>'.format(
        config.CONFIG.parser['username'])
    payload += '</tns:email>'
    payload += '<tns:password>{}</tns:password>'.format(
        config.CONFIG.parser['password'])
    payload += '<tns:mobilePhone xsi:nil="true"/>'
    payload += '<tns:profileProperty xsi:nil="true"/>'
    payload += '</tns:identification>'
    payload += '</tns:identityPoint_identify_request>'
    payload += '</SOAP-ENV:Body>'
    payload += '</SOAP-ENV:Envelope>'

    util.log_http(url, 'post', headers, sys._getframe().f_code.co_name)
    req = requests.post(url,
                        headers=headers,
                        data=payload,
                        verify=config.VERIFY_SSL)
    """
    Bad username => <status><code>-1000</code><message> [Invalid credentials for identification] [com.bamnetworks.registration.types.exception.IdentificationException: Account doesn't exits]</message><exceptionClass>com.bamnetworks.registration.types.exception.IdentificationException</exceptionClass><detail type="identityPoint" field="exists" message="false" messageKey="identityPoint.exists" /><detail type="identityPoint" field="email-password" message="identification error on identity point of type email-password" messageKey="identityPoint.email-password" /></status>
    Bad password => <status><code>-1000</code><message> [Invalid credentials for identification] [com.bamnetworks.registration.types.exception.IdentificationException: Invalid Password]</message><exceptionClass>com.bamnetworks.registration.types.exception.IdentificationException</exceptionClass><detail type="identityPoint" field="exists" message="true" messageKey="identityPoint.exists" /><detail type="identityPoint" field="email-password" message="identification error on identity point of type email-password" messageKey="identityPoint.email-password" /></status>
    Good => <status><code>1</code><message>OK</message></status>
    """
    if find_text_in_str(req.text, '<code>', '</code>') != '1':
        LOG.debug('Login Error: r.text: %s', req.text)
        msg = find_text_in_str(
            req.text,
            'com.bamnetworks.registration.types.exception.IdentificationException: ',
            ']</message>')
        util.die('Login Error: {}'.format(msg))

    LOG.debug('Login successful')
    save_cookies(req.cookies)
Пример #3
0
def play_stream(game_rec,
                team_to_play,
                feedtype,
                date_str,
                fetch,
                login_func,
                from_start,
                offset=None,
                duration=None,
                is_multi_highlight=False):
    if feedtype is not None and feedtype in config.HIGHLIGHT_FEEDTYPES:
        # handle condensed/recap
        playback_url = find_highlight_url_for_team(game_rec, feedtype)
        if playback_url is None:
            util.die("No playback url for feed '{}'".format(feedtype))
        play_highlight(playback_url,
                       get_fetch_filename(date_str, game_rec, feedtype, fetch),
                       is_multi_highlight)
    else:
        # handle full game (live or archive)
        # this is the only feature requiring an authenticated session
        auth_cookie = auth.get_auth_cookie()
        if auth_cookie is None:
            login_func()
            # auth.login(config.CONFIG.parser['username'],
            #            config.CONFIG.parser['password'],
            #            config.CONFIG.parser.getboolean('use_rogers', False))
        LOG.debug('Authorization cookie: {}'.format(auth.get_auth_cookie()))

        media_playback_id, event_id = select_feed_for_team(
            game_rec, team_to_play, feedtype)
        if media_playback_id is not None:
            stream_url, media_auth = fetch_stream(game_rec['game_pk'],
                                                  media_playback_id, event_id)
            if stream_url is not None:
                if config.SAVE_PLAYLIST_FILE:
                    save_playlist_to_file(stream_url, media_auth)
                streamlink(
                    stream_url, media_auth,
                    get_fetch_filename(date_str, game_rec, feedtype, fetch),
                    from_start, offset, duration)
            else:
                LOG.error("No stream URL found")
        else:
            LOG.info("No game stream found for %s", team_to_play)
    return 0
Пример #4
0
def play_stream(game_rec,
                team_to_play,
                feedtype,
                date_str,
                fetch,
                from_start,
                inning_ident,
                is_multi_highlight=False):
    if game_rec['doubleHeader'] != 'N':
        LOG.info('Selected game number %s of doubleheader',
                 game_rec['gameNumber'])
    if feedtype is not None and feedtype in config.HIGHLIGHT_FEEDTYPES:
        # handle condensed/recap
        playback_url = find_highlight_url_for_team(game_rec, feedtype)
        if playback_url is None:
            util.die("No playback url for feed '{}'".format(feedtype))
        play_highlight(playback_url,
                       get_fetch_filename(date_str, game_rec, feedtype, fetch),
                       is_multi_highlight)
    else:
        # handle full game (live or archive)
        # this is the only feature requiring an authenticated session
        import mlbam.session as session
        mlb_session = session.MLBSession()

        media_playback_id, media_state = select_feed_for_team(
            game_rec, team_to_play, feedtype)
        if media_playback_id is not None:
            stream_url = mlb_session.lookup_stream_url(game_rec['game_pk'],
                                                       media_playback_id)
            if stream_url is not None:
                offset = None
                if config.SAVE_PLAYLIST_FILE:
                    mlb_session.save_playlist_to_file(stream_url)
                if inning_ident:
                    offset = _calculate_inning_offset(inning_ident,
                                                      media_state, game_rec)
                streamlink(
                    stream_url, mlb_session,
                    get_fetch_filename(date_str, game_rec, feedtype, fetch),
                    from_start, offset)
            else:
                LOG.error("No stream URL found")
        else:
            LOG.info("No game stream found for %s", team_to_play)
    return 0
Пример #5
0
def get_game_rec(game_data, team_to_play, game_number_str):
    """ game_number_str: is an string 1 or 2 indicating game number for doubleheader
    """
    game_rec = None
    for game_pk in game_data:
        if team_to_play in (game_data[game_pk]['away']['abbrev'],
                            game_data[game_pk]['home']['abbrev']):
            if game_data[game_pk][
                    'doubleHeader'] != 'N' and game_number_str != game_data[
                        game_pk]['gameNumber']:
                # game is doubleheader but not our game_number
                continue
            game_rec = game_data[game_pk]
            break
    if game_rec is None:
        if int(game_number_str) > 1:
            util.die(
                "No second game available for team {}".format(team_to_play))
        util.die("No game found for team {}".format(team_to_play))
    return game_rec
Пример #6
0
def get_session_key(game_pk, event_id, content_id, auth_cookie):
    """ game_pk: game_pk
        event_id: eventId
        content_id: mediaPlaybackId
    """

    raise Exception("Not implemented")

    session_key_file = os.path.join(config.CONFIG.dir, 'sessionkey')
    if os.path.exists(session_key_file):
        if datetime.today() - datetime.fromtimestamp(
                os.path.getmtime(session_key_file)) < timedelta(days=1):
            with open(session_key_file, 'r') as f:
                for line in f:
                    session_key = line.strip()
                    LOG.debug(
                        'Using cached session key: {}'.format(session_key))
                    return session_key
    LOG.debug("Requesting session key")
    epoch_time_now = str(int(round(time.time() * 1000)))
    url = 'https://mf.svc.nhl.com/ws/media/mf/v2.4/stream?eventId={}&format=json&platform={}&subject=NHLTV&_={}'
    url = url.format(event_id, config.CONFIG.platform, epoch_time_now)
    headers = {
        "Accept":
        "application/json",
        "Accept-Encoding":
        "identity",
        "Accept-Language":
        "en-US,en;q=0.8",
        "Connection":
        "keep-alive",
        "Authorization":
        auth_cookie,
        "User-Agent":
        config.CONFIG.ua_pc,
        "Origin":
        "https://www.nhl.com",
        "Referer":
        "https://www.nhl.com/tv/{}/{}/{}".format(game_pk, event_id, content_id)
    }
    util.log_http(url, 'get', headers, sys._getframe().f_code.co_name)
    r = requests.get(url,
                     headers=headers,
                     cookies=load_cookies(),
                     verify=config.VERIFY_SSL)
    json_source = r.json()
    LOG.debug('Session key json: {}'.format(json_source))

    if json_source['status_code'] == 1:
        if json_source['user_verified_event'][0]['user_verified_content'][0][
                'user_verified_media_item'][0]['blackout_status'][
                    'status'] == 'BlackedOutStatus':
            session_key = 'blackout'
            LOG.debug('Event blacked out: {}'.format(
                json_source['user_verified_event'][0]['user_verified_content']
                [0]['user_verified_media_item'][0]))
        else:
            session_key = str(json_source['session_key'])
    else:
        msg = json_source['status_message']
        util.die('Could not get session key: {}'.format(msg))

    LOG.debug('Retrieved session key: {}'.format(session_key))
    update_session_key(session_key)
    return session_key
Пример #7
0
def play_stream(game_data, team_to_play, game_number_str, feedtype, date_str,
                fetch, wait_for_start):
    """ game_number_str: is an string 1 or 2 indicating game number for doubleheader
    """
    game_rec = None
    for game_pk in game_data:
        if team_to_play in (game_data[game_pk]['away']['abbrev'],
                            game_data[game_pk]['home']['abbrev']):
            if game_data[game_pk][
                    'doubleHeader'] != 'N' and game_number_str != game_data[
                        game_pk]['gameNumber']:
                # game is doubleheader but not our game_number
                continue
            game_rec = game_data[game_pk]
            break
    if game_rec is None:
        if int(game_number_str) > 1:
            util.die(
                "No second game available for team {}".format(team_to_play))
        util.die("No game found for team {}".format(team_to_play))

    if game_rec['doubleHeader'] != 'N':
        LOG.info('Selected game number %s of doubleheader',
                 game_rec['gameNumber'])
    if feedtype is not None and feedtype in config.HIGHLIGHT_FEEDTYPES:
        # handle condensed/recap
        playback_url = find_highlight_url_for_team(game_rec, feedtype)
        if playback_url is None:
            util.die("No playback url for feed '{}'".format(feedtype))
        play_highlight(playback_url,
                       get_fetch_filename(date_str, game_rec, feedtype, fetch))
    else:
        # handle full game (live or archive)
        # this is the only feature requiring an authenticated session
        import mlbam.session as session
        mlb_session = session.MLBSession()

        if wait_for_start and not _has_game_started(game_rec['mlbdate']):
            LOG.info('Waiting for game to start. Local start time is ' +
                     util.convert_time_to_local(game_rec['mlbdate']))
            print('Use Ctrl-c to quit .', end='', flush=True)
            count = 0
            while not _has_game_started(game_rec['mlbdate']):
                time.sleep(10)
                count += 1
                if count % 6 == 0:
                    print('.', end='', flush=True)

        media_playback_id, event_id = select_feed_for_team(
            game_rec, team_to_play, feedtype)
        if media_playback_id is not None:
            stream_url = mlb_session.lookup_stream_url(game_rec['game_pk'],
                                                       media_playback_id)
            if stream_url is not None:
                if config.DEBUG:
                    mlb_session.save_playlist_to_file(stream_url)
                streamlink(
                    stream_url, mlb_session,
                    get_fetch_filename(date_str, game_rec, feedtype, fetch))
            else:
                LOG.error("No stream URL")
        else:
            LOG.info("No game found for {}".format(team_to_play))
    return 0
Пример #8
0
def nhl_login():
    """Authenticates user to nhl site."""
    url = 'https://user.svc.nhl.com/oauth/token?grant_type=client_credentials'
    headers = {
        "Accept":
        "application/json",
        "Accept-Encoding":
        "identity",
        "Accept-Language":
        "en-US,en;q=0.8",
        "User-Agent":
        config.CONFIG.ua_pc,
        "Origin":
        "https://www.nhl.com",
        "Authorization":
        "Basic d2ViX25obC12MS4wLjA6MmQxZDg0NmVhM2IxOTRhMThlZjQwYWM5ZmJjZTk3ZTM=",
    }
    userid = config.CONFIG.parser['username']
    passwd = config.CONFIG.parser['password']
    use_rogers = config.CONFIG.parser.getboolean('use_rogers', False)
    util.log_http(url, 'post', headers, sys._getframe().f_code.co_name)
    r = requests.post(url,
                      headers=headers,
                      data='',
                      cookies=load_cookies(),
                      verify=config.VERIFY_SSL)
    if r.status_code >= 400:
        util.die("Authorization cookie couldn't be downloaded.")

    json_source = r.json()

    if get_auth_cookie() is not None:
        LOG.debug('login: already logged in (we have a valid cookie)')
        return

    auth_cookie = json_source['access_token']

    if use_rogers:
        LOG.info("Logging in via Rogers")
        url = 'https://activation-rogers.svc.nhl.com/ws/subscription/flow/rogers.login'
        login_data = '{"rogerCredentials":{"email":%s,"password":%s}}' % (
            userid, passwd)
        # referer = "https://www.nhl.com/login/rogers"
    else:
        LOG.info("Logging in via NHL")
        url = 'https://user.svc.nhl.com/v2/user/identity'
        login_data = '{"email":{"address":%s},"type":"email-password","password":{"value":%s}}' % (
            userid, passwd)

    headers = {
        "Accept": "*/*",
        "Accept-Encoding": "identity",
        "Accept-Language": "en-US,en;q=0.8",
        "Content-Type": "application/json",
        "Authorization": auth_cookie,
        "Connection": "keep-alive",
        "User-Agent": config.CONFIG.ua_pc
    }

    util.log_http(url, 'post', headers, sys._getframe().f_code.co_name)
    r = requests.post(url,
                      headers=headers,
                      data=login_data,
                      cookies=load_cookies(),
                      verify=config.VERIFY_SSL)
    if r.status_code >= 400:
        try:
            json_source = r.json()
            msg = json_source['message']
        except Exception as e:
            msg = "Please check that your username and password are correct"
        LOG.debug('Login Error: json_source: {}'.format(json_source))
        util.die('Login Error: {}'.format(msg))

    LOG.debug('Login successful')
    save_cookies(r.cookies)
Пример #9
0
def fetch_stream(game_pk, content_id, event_id):
    """ game_pk: game_pk
        event_id: eventId
        content_id: mediaPlaybackId
    """
    stream_url = None
    media_auth = None

    auth_cookie = auth.get_auth_cookie()
    if auth_cookie is None:
        LOG.error("fetch_stream: not logged in")
        return stream_url, media_auth

    session_key = auth.get_session_key(game_pk, event_id, content_id,
                                       auth_cookie)
    if session_key is None:
        return stream_url, media_auth
    elif session_key == 'blackout':
        msg = (
            'The game you are trying to access is not currently available due to local '
            'or national blackout restrictions.\n'
            ' Full game archives will be available 48 hours after completion of this game.'
        )
        LOG.info('Game Blacked Out: {}'.format(msg))
        return stream_url, media_auth

    url = config.CONFIG.mf_svc_url
    url += '?contentId=' + content_id
    url += '&playbackScenario=' + config.CONFIG.playback_scenario
    url += '&platform=' + config.CONFIG.platform
    url += '&sessionKey=' + urllib.parse.quote_plus(session_key)

    # Get user set CDN
    if config.CONFIG.parser['cdn'] == 'akamai':
        url += '&cdnName=MED2_AKAMAI_SECURE'
    elif config.CONFIG.parser['cdn'] == 'level3':
        url += '&cdnName=MED2_LEVEL3_SECURE'

    headers = {
        "Accept": "*/*",
        "Accept-Encoding": "identity",
        "Accept-Language": "en-US,en;q=0.8",
        "Connection": "keep-alive",
        "Authorization": auth_cookie,
        "User-Agent": config.CONFIG.svc_user_agent,
        "Proxy-Connection": "keep-alive"
    }

    util.log_http(url, 'get', headers, sys._getframe().f_code.co_name)
    r = requests.get(url,
                     headers=headers,
                     cookies=auth.load_cookies(),
                     verify=config.VERIFY_SSL)
    json_source = r.json()

    if json_source['status_code'] == 1:
        media_item = json_source['user_verified_event'][0][
            'user_verified_content'][0]['user_verified_media_item'][0]
        if media_item['blackout_status']['status'] == 'BlackedOutStatus':
            msg = (
                'The game you are trying to access is not currently available due to local '
                'or national blackout restrictions.\n'
                'Full game archives will be available 48 hours after completion of this game.'
            )
            util.die('Game Blacked Out: {}'.format(msg))
        elif media_item['auth_status'] == 'NotAuthorizedStatus':
            msg = 'You do not have an active subscription. To access this content please purchase a subscription.'
            util.die('Account Not Authorized: {}'.format(msg))
        else:
            stream_url = media_item['url']
            media_auth = '{}={}'.format(
                str(json_source['session_info']['sessionAttributes'][0]
                    ['attributeName']),
                str(json_source['session_info']['sessionAttributes'][0]
                    ['attributeValue']))
            session_key = json_source['session_key']
            auth.update_session_key(session_key)
    else:
        msg = json_source['status_message']
        util.die('Error Fetching Stream: {}', msg)

    LOG.debug('fetch_stream stream_url: ' + stream_url)
    LOG.debug('fetch_stream media_auth: ' + media_auth)
    return stream_url, media_auth