Esempio n. 1
0
def update_api_url():
    settingsJSON = load_file(file='settings.json', isJSON=True)

    try:
        settings.set(key='_api_url', value=settingsJSON['api_url'])
    except:
        settings.set(key='_api_url', value=CONST_DEFAULT_API)
Esempio n. 2
0
def update_user_agent():
    settingsJSON = load_file(file='settings.json', isJSON=True)

    try:
        settings.set(key='_user_agent', value=settingsJSON['user_agent'])
    except:
        settings.set(key='_user_agent', value=DEFAULT_USER_AGENT)
Esempio n. 3
0
def update_img_size():
    settingsJSON = load_file(file='settings.json', isJSON=True)

    try:
        settings.set(key='_img_size', value=settingsJSON['img_size'])
    except:
        settings.set(key='_img_size', value=CONST_DEFAULT_IMG_SIZE)
Esempio n. 4
0
def search(query=None, **kwargs):
    items = []

    if not query:
        query = gui.input(message=_.SEARCH, default='').strip()

        if not query:
            return

        for x in reversed(list(range(2, 10))):
            settings.set(key='_search' + unicode(x),
                         value=settings.get(key='_search' + unicode(x - 1)))

        settings.set(key='_search1', value=query)

    folder = plugin.Folder(title=_(_.SEARCH_FOR, query=query))

    data = load_file(file='list_replay.json', isJSON=True)
    processed = process_replaytv_search(data=data, start=0, search=query)
    items += processed['items']

    items[:] = sorted(items, key=_sort_replay_items, reverse=True)
    items = items[:25]

    folder.add_items(items)

    return folder
Esempio n. 5
0
def login(**kwargs):
    if len(settings.get(key='_devicekey')) == 0:
        settings.set(key='_devicekey',
                     value=''.join(
                         random.choice(string.ascii_uppercase +
                                       string.ascii_lowercase + string.digits)
                         for _ in range(64)))

    creds = get_credentials()
    username = gui.numeric(message=_.ASK_USERNAME,
                           default=creds['username']).strip()

    if not len(username) > 0:
        gui.ok(message=_.EMPTY_USER, heading=_.LOGIN_ERROR_TITLE)
        return

    password = gui.numeric(message=_.ASK_PASSWORD).strip()

    if not len(password) > 0:
        gui.ok(message=_.EMPTY_PASS, heading=_.LOGIN_ERROR_TITLE)
        return

    api.login(username=username, password=password, channels=True)
    plugin.logged_in = api.logged_in

    gui.refresh()
Esempio n. 6
0
def _reset(**kwargs):
    if not gui.yes_no(_.PLUGIN_RESET_YES_NO):
        return

    _close()

    try:
        xbmc.executeJSONRPC(
            '{{"jsonrpc":"2.0","id":1,"method":"Addons.SetAddonEnabled","params":{{"addonid":"{}","enabled":false}}}}'
            .format(ADDON_ID))
        proxyport = settings.getInt(key='_proxyserver_port')

        shutil.rmtree(ADDON_PROFILE)

        settings.setInt(key='_proxyserver_port', value=proxyport)

        system, arch = get_system_arch()
        settings.set(key="_system", value=system)
        settings.set(key="_arch", value=arch)

        download_files()
        update_settings()
        change_icon()

    except:
        pass

    xbmc.executeJSONRPC(
        '{{"jsonrpc":"2.0","id":1,"method":"Addons.SetAddonEnabled","params":{{"addonid":"{}","enabled":true}}}}'
        .format(ADDON_ID))

    gui.notification(_.PLUGIN_RESET_OK)
    signals.emit(signals.AFTER_RESET)
    gui.refresh()
Esempio n. 7
0
def startup():
    system, arch = get_system_arch()
    settings.set(key="_system", value=system)
    settings.set(key="_arch", value=arch)

    settings.setInt(key='_proxyserver_port', value=find_free_port())

    hourly()
    daily()
    change_icon()

    if settings.getBool(key='enable_simple_iptv') == True:
        try:
            IPTV_SIMPLE = xbmcaddon.Addon(id="pvr.iptvsimple")

            if IPTV_SIMPLE.getSetting("epgPath") == (
                    ADDON_PROFILE +
                    "epg.xml") and IPTV_SIMPLE.getSetting("m3uPath") == (
                        ADDON_PROFILE + "playlist.m3u8"):
                user_agent = settings.get(key='_user_agent')

                if IPTV_SIMPLE.getSetting("userAgent") != user_agent:
                    IPTV_SIMPLE.setSetting("userAgent", user_agent)

                    xbmc.executeJSONRPC(
                        '{{"jsonrpc":"2.0","id":1,"method":"Addons.SetAddonEnabled","params":{{"addonid":"{}","enabled":false}}}}'
                        .format(IPTV_SIMPLE_ADDON_ID))
                    xbmc.sleep(2000)
                    xbmc.executeJSONRPC(
                        '{{"jsonrpc":"2.0","id":1,"method":"Addons.SetAddonEnabled","params":{{"addonid":"{}","enabled":true}}}}'
                        .format(IPTV_SIMPLE_ADDON_ID))
        except:
            pass
Esempio n. 8
0
    def get_play_token(self, locator, force=False):
        if settings.getInt(key='_drm_token_age') < int(time.time() - 50) and (
                settings.getInt(key='_tokenrun') == 0 or
                settings.getInt(key='_tokenruntime') < int(time.time() - 30)):
            force = True

        if locator != settings.get(key='_drm_locator') or settings.getInt(
                key='_drm_token_age') < int(time.time() - 90) or force == True:
            settings.setInt(key='_tokenrun', value=1)
            settings.setInt(key='_tokenruntime', value=time.time())

            data = self.download(url=settings.get(key='_token_url'),
                                 type="post",
                                 code=[200],
                                 data={"contentLocator": locator},
                                 json_data=True,
                                 data_return=True,
                                 return_json=True,
                                 retry=True,
                                 check_data=False)

            if not data or not check_key(data, 'token'):
                settings.setInt(key="_tokenrun", value=0)
                return None

            settings.set(key='_drm_token', value=data['token'])
            settings.setInt(key='_drm_token_age', value=time.time())
            settings.set(key='_drm_locator', value=locator)
            settings.setInt(key="_tokenrun", value=0)

            return data['token']

        return settings.get(key='_drm_token')
Esempio n. 9
0
def download_epg():
    settings.setInt(key='_epgrun', value=1)
    settings.setInt(key='_epgruntime', value=time.time())

    if settings.getBool(key="minimalChannels"):
        url = CONST_MINIMALEPG
    else:
        url = CONST_EPG

    if ADDON_ID == "plugin.video.ziggo" and settings.getBool(key='_base_v3') == True:
        url = url.replace('epg.xml.', 'epg.xml.v3.')

    resp = requests.get(url=url)

    settings.set(key='_epg_md5', value=hashlib.md5(resp.content).hexdigest())

    zipfile = ZipFile(BytesIO(resp.content))
    zipfile.extractall(ADDON_PROFILE)
    zipfile.close()

    for file in glob.glob(ADDON_PROFILE + "*_replay.xml"):
        if is_file_older_than_x_days(file=file, days=7):
            os.remove(file)

    for file in glob.glob(ADDON_PROFILE + "*_replay.json"):
        if is_file_older_than_x_days(file=file, days=7):
            os.remove(file)

    settings.setInt("_epgrun", 0)
Esempio n. 10
0
def download_vod():
    url = CONST_VOD

    if ADDON_ID == "plugin.video.ziggo" and settings.getBool(key='_base_v3') == True:
        url = url.replace('vod.', 'vod.v3.')

    resp = requests.get(url=url)
    write_file(file='vod.json', data=resp.text, isJSON=False)

    settings.set(key='_vod_md5', value=hashlib.md5(resp.content).hexdigest())
Esempio n. 11
0
def search(query=None, **kwargs):
    items = []

    if not query:
        query = gui.input(message=_.SEARCH, default='').strip()

        if not query:
            return

        for x in reversed(list(range(2, 10))):
            settings.set(key='_search' + unicode(x),
                         value=settings.get(key='_search' + unicode(x - 1)))

        settings.set(key='_search1', value=query)

    folder = plugin.Folder(title=_(_.SEARCH_FOR, query=query))

    data = load_file(file='list_replay.json', isJSON=True)
    processed = process_replaytv_search(data=data, start=0, search=query)
    items += processed['items']

    if settings.getBool('showMoviesSeries') == True:
        processed = process_vod_content(data=load_file(file='vod.json',
                                                       isJSON=True)['series'],
                                        start=0,
                                        search=query,
                                        type=_.SERIES)
        items += processed['items']
        processed = process_vod_content(data=load_file(file='vod.json',
                                                       isJSON=True)['movies'],
                                        start=0,
                                        search=query,
                                        type=_.MOVIES)
        items += processed['items']
        processed = process_vod_content(data=load_file(
            file='vod.json', isJSON=True)['kidsseries'],
                                        start=0,
                                        search=query,
                                        type=_.KIDS_SERIES)
        items += processed['items']
        processed = process_vod_content(data=load_file(
            file='vod.json', isJSON=True)['kidsmovies'],
                                        start=0,
                                        search=query,
                                        type=_.KIDS_MOVIES)
        items += processed['items']

    items[:] = sorted(items, key=_sort_replay_items, reverse=True)
    items = items[:25]

    folder.add_items(items)

    return folder
Esempio n. 12
0
def download_images():
    resp = requests.get(url=CONST_IMAGES)

    settings.set(key='_images_md5', value=hashlib.md5(resp.content).hexdigest())

    zipfile = ZipFile(BytesIO(resp.content))
    zipfile.extractall(ADDON_PROFILE)
    zipfile.close()

    for file in glob.glob(ADDON_PROFILE + "images" + os.sep + "*.png"):
        if is_file_older_than_x_days(file=file, days=7):
            os.remove(file)
Esempio n. 13
0
def online_search(query=None, **kwargs):
    if not query:
        query = gui.input(message=_.SEARCH, default='').strip()

        if not query:
            return

        for x in reversed(list(range(2, 10))):
            settings.set(key='_search' + unicode(x), value=settings.get(key='_search' + unicode(x - 1)))
            settings.set(key='_search_type' + unicode(x), value=settings.get(key='_search_type' + unicode(x - 1)))

        settings.set(key='_search1', value=query)
        settings.set(key='_search_type1', value=' (Online)')

    folder = plugin.Folder(title=_(_.SEARCH_FOR, query=query))

    data = api.online_search(search=query, vod=settings.getBool('showMoviesSeries'))

    if data:
        processed = process_online_search(data=data)

        if processed:
            folder.add_items(processed)

    return folder
Esempio n. 14
0
def download_settings():
    resp = requests.get(url=CONST_SETTINGS)
    write_file(file='settings.json', data=resp.text, isJSON=False)

    if settings.getBool(key='enable_radio') == True:
        resp = requests.get(url=CONST_RADIO)
        write_file(file='radio.m3u8', data=resp.text, isJSON=False)
        combine_playlist()

    settingsJSON = load_file(file='settings.json', isJSON=True)

    try:
        settings.set(key='_user_agent', value=settingsJSON['user_agent'])
    except:
        settings.set(key='_user_agent', value=DEFAULT_USER_AGENT)
Esempio n. 15
0
def update_os_browser():
    user_agent = settings.get(key='_user_agent')
    settings.set(key='_browser_name',
                 value=uaparser.detect(user_agent)['browser']['name'])
    settings.set(key='_browser_version',
                 value=uaparser.detect(user_agent)['browser']['version'])
    settings.set(key='_os_name',
                 value=uaparser.detect(user_agent)['os']['name'])
    settings.set(key='_os_version',
                 value=uaparser.detect(user_agent)['os']['version'])
Esempio n. 16
0
def set_credentials(username, password):
    encoded = Credentials().encode_credentials(username, password)

    try:
        settings.set(key='_username', value=encoded['username'].decode('utf-8'))
    except:
        settings.set(key='_username', value=encoded['username'])

    try:
        settings.set(key='_pswd', value=encoded['password'].decode('utf-8'))
    except:
        settings.set(key='_pswd', value=encoded['password'])
Esempio n. 17
0
    def login(self, username, password, channels=False):
        settings.remove(key='_access_token')
        user_agent = settings.get(key='_user_agent')

        HEADERS = {
            'User-Agent': user_agent,
            'X-Client-Id': settings.get(key='_client_id') + "||" + user_agent,
            'X-OESP-Token': '',
            'X-OESP-Username': username,
        }

        self._session = Session(headers=HEADERS)
        data = self.download(url=settings.get(key='_session_url'),
                             type="post",
                             code=[200],
                             data={
                                 "username": username,
                                 "password": password
                             },
                             json_data=True,
                             data_return=True,
                             return_json=True,
                             retry=True,
                             check_data=False)

        if not data or not check_key(data, 'oespToken'):
            gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE)
            return

        settings.set(key='_access_token', value=data['oespToken'])
        self._session.headers.update({'X-OESP-Token': data['oespToken']})

        if channels == True or settings.getInt(
                key='_channels_age') < int(time.time() - 86400):
            self.get_channels_for_user(location=data['locationId'])

        if settings.getBool(key='save_password', default=False):
            set_credentials(username=username, password=password)
        else:
            set_credentials(username=username, password='')

        self.logged_in = True
Esempio n. 18
0
def startup():
    settings.setBool(key='_test_running', value=False)
    system, arch = get_system_arch()
    settings.set(key="_system", value=system)
    settings.set(key="_arch", value=arch)

    settings.setInt(key='_proxyserver_port', value=find_free_port())

    channels = False

    if settings.getInt(key='_channels_age') < int(time.time() - 86400):
        channels = True

    api.new_session(force=False, retry=False, channels=channels)
    api.update_prefs()

    hourly(type=0)
    daily()
    change_icon()
    hourly(type=2)
Esempio n. 19
0
def update_settings():
    settingsJSON = load_file(file='settings.json', isJSON=True)

    try:
        base = settingsJSON['settings']['urls']['base']

        if settings.getBool(key='_base_v3'):
            basethree = settingsJSON['settings']['urls']['alternativeAjaxBase']
        else:
            basethree = base

        complete_base_url = '{base_url}/{country_code}/{language_code}'.format(base_url=basethree, country_code=settingsJSON['settings']['countryCode'], language_code=settingsJSON['settings']['languageCode'])

        settings.set(key='_base_url', value=complete_base_url + '/web')
        settings.set(key='_search_url', value=settingsJSON['settings']['routes']['search'].replace(base, basethree))
        settings.set(key='_session_url', value=settingsJSON['settings']['routes']['session'].replace(base, basethree))
        #settings.set(key='_token_url', value=settingsJSON['settings']['routes']['refreshToken'].replace(base, basethree))
        settings.set(key='_channels_url', value=settingsJSON['settings']['routes']['channels'].replace(base, basethree))
        settings.set(key='_token_url',  value='{complete_base_url}/web/license/token'.format(complete_base_url=complete_base_url))
        settings.set(key='_widevine_url', value='{complete_base_url}/web/license/eme'.format(complete_base_url=complete_base_url))
        settings.set(key='_listings_url', value=settingsJSON['settings']['routes']['listings'].replace(base, basethree))
        settings.set(key='_mediaitems_url', value=settingsJSON['settings']['routes']['mediaitems'].replace(base, basethree))
        settings.set(key='_mediagroupsfeeds_url', value=settingsJSON['settings']['routes']['mediagroupsfeeds'].replace(base, basethree))
        settings.set(key='_watchlist_url', value=settingsJSON['settings']['routes']['watchlist'].replace(base, basethree))
    except:
        pass

    try:
        client_id = settingsJSON['client_id']
    except:
        client_id = CONST_DEFAULT_CLIENTID

    settings.set(key='_client_id', value=client_id)
Esempio n. 20
0
    def play_url(self, type, channel=None, id=None):
        playdata = {'path': '', 'license': '', 'token': ''}

        license = ''
        asset_id = ''
        militime = int(time.time() * 1000)

        if type == 'channel':
            play_url = '{api_url}/CONTENT/VIDEOURL/LIVE/{channel}/{id}/?deviceId={device_key}&profile=G02&time={time}'.format(api_url=settings.get(key='_api_url'), channel=channel, id=id, device_key=settings.get(key='_devicekey'), time=militime)
        else:
            if type == 'program':
                typestr = "PROGRAM"
            else:
                typestr = "VOD"

            program_url = '{api_url}/CONTENT/USERDATA/{type}/{id}'.format(api_url=settings.get(key='_api_url'), type=typestr, id=id)
            data = self.download(url=program_url, type='get', code=[200], data=None, json_data=False, data_return=True, return_json=True, retry=True, check_data=True)

            if not data or not check_key(data['resultObj'], 'containers'):
                return playdata

            for row in data['resultObj']['containers']:
                if check_key(row, 'entitlement') and check_key(row['entitlement'], 'assets'):
                    for asset in row['entitlement']['assets']:
                        if type == 'program':
                            if check_key(asset, 'videoType') and check_key(asset, 'programType') and asset['videoType'] == 'SD_DASH_PR' and asset['programType'] == 'CUTV':
                                asset_id = asset['assetId']
                                break
                        else:
                            if check_key(asset, 'videoType') and check_key(asset, 'assetType') and asset['videoType'] == 'SD_DASH_PR' and asset['assetType'] == 'MASTER':
                                if check_key(asset, 'rights') and asset['rights'] == 'buy':
                                    gui.ok(message=_.NO_STREAM_AUTH, heading=_.PLAY_ERROR)
                                    return playdata

                                asset_id = asset['assetId']
                                break

            if len(str(asset_id)) == 0:
                return playdata

            play_url = '{api_url}/CONTENT/VIDEOURL/{type}/{id}/{asset_id}/?deviceId={device_key}&profile=G02&time={time}'.format(api_url=settings.get(key='_api_url'), type=typestr, id=id, asset_id=asset_id, device_key=settings.get(key='_devicekey'), time=militime)

        data = self.download(url=play_url, type='get', code=[200], data=None, json_data=False, data_return=True, return_json=True, retry=True, check_data=True)

        if not data or not check_key(data['resultObj'], 'token') or not check_key(data['resultObj'], 'src') or not check_key(data['resultObj']['src'], 'sources') or not check_key(data['resultObj']['src']['sources'], 'src'):
            return playdata

        if check_key(data['resultObj']['src']['sources'], 'contentProtection') and check_key(data['resultObj']['src']['sources']['contentProtection'], 'widevine') and check_key(data['resultObj']['src']['sources']['contentProtection']['widevine'], 'licenseAcquisitionURL'):
            license = data['resultObj']['src']['sources']['contentProtection']['widevine']['licenseAcquisitionURL']

        path = data['resultObj']['src']['sources']['src']
        token = data['resultObj']['token']

        real_url = "{hostscheme}://{hostname}".format(hostscheme=urlparse(path).scheme, hostname=urlparse(path).hostname)
        proxy_url = "http://127.0.0.1:{proxy_port}".format(proxy_port=settings.get(key='_proxyserver_port'))

        settings.set(key='_stream_hostname', value=real_url)
        path = path.replace(real_url, proxy_url)

        playdata = {'path': path, 'license': license, 'token': token}

        return playdata
Esempio n. 21
0
    def play_url(self, type, channel=None, id=None):
        playdata = {'path': '', 'license': '', 'token': '', 'sessionid': ''}

        if not type or not len(type) > 0:
            return playdata

        if type == 'channel' and channel:
            channel_url = 'https://www.tv-anywhere.nl/api/guide/details/{channel}'.format(
                channel=channel)
            data = self.download(url=channel_url,
                                 type="get",
                                 code=[200],
                                 data=None,
                                 json_data=False,
                                 data_return=True,
                                 return_json=True,
                                 retry=True,
                                 check_data=True)

            if not data or not check_key(data, 'id'):
                return playdata

            id = data['id']

        if not id:
            return playdata

        self._session.headers.update(
            {'Authorization': 'Bearer ' + settings.get(key='_session_token')})

        session_post_data = {
            "DispatchTime": time.time(),
            "BusinessUnit": settings.get(key='_emp_businessunit'),
            "Customer": settings.get(key='_emp_customer'),
            "Payload": {
                'Timestamp': time.time(),
                'EventType': 'Playback.Aborted',
                'OffsetTime': time.time(),
            },
            "SessionId": settings.get(key='_play_session_id'),
            "ClockOffset": 0,
        }

        eventsink_send_url = '{emp_url}/eventsink/send'.format(
            emp_url=settings.get(key='_emp_url'))
        self.download(url=eventsink_send_url,
                      type="post",
                      code=None,
                      data=session_post_data,
                      json_data=True,
                      data_return=False,
                      return_json=False,
                      retry=False,
                      check_data=False)

        session_post_data = {
            "drm": "CENC",
            "format": "DASH",
            "type": "application/dash+xml",
        }

        play_url_path = '{emp_url}/v1/customer/{emp_customer}/businessunit/{emp_businessunit}/entitlement/channel/{channel}/program/{id}/play'.format(
            emp_url=settings.get(key='_emp_url'),
            emp_customer=settings.get(key='_emp_customer'),
            emp_businessunit=settings.get(key='_emp_businessunit'),
            channel=channel,
            id=id)
        data = self.download(url=play_url_path,
                             type="post",
                             code=[200],
                             data=session_post_data,
                             json_data=True,
                             data_return=True,
                             return_json=True,
                             retry=True,
                             check_data=True)

        if not data or check_key(data, 'message') or not check_key(
                data, 'cencConfig') or not check_key(
                    data, 'mediaLocator') or not check_key(
                        data, 'playSessionId'):
            return playdata

        license = data['cencConfig']['com.widevine.alpha']
        path = data['mediaLocator']
        sessionid = data['playSessionId']
        token = data['playToken']

        settings.set(key='_play_session_id', value=sessionid)

        session_post_data = {
            "BusinessUnit": settings.get(key='_emp_businessunit'),
            "Customer": settings.get(key='_emp_customer'),
            "SessionId": settings.get(key='_play_session_id'),
        }

        eventsink_init_url = '{emp_url}/eventsink/init'.format(
            emp_url=settings.get(key='_emp_url'))
        self.download(url=eventsink_init_url,
                      type="post",
                      code=None,
                      data=session_post_data,
                      json_data=True,
                      data_return=False,
                      return_json=False,
                      retry=False,
                      check_data=False)

        real_url = "{hostscheme}://{hostname}".format(
            hostscheme=urlparse(path).scheme, hostname=urlparse(path).hostname)
        proxy_url = "http://127.0.0.1:{proxy_port}".format(
            proxy_port=settings.get(key='_proxyserver_port'))

        settings.set(key='_stream_hostname', value=real_url)
        path = path.replace(real_url, proxy_url)

        playdata = {
            'path': path,
            'license': license,
            'token': token,
            'sessionid': sessionid
        }

        return playdata
Esempio n. 22
0
    def play_url(self,
                 type,
                 channel=None,
                 id=None,
                 test=False,
                 from_beginning=False):
        if self._debug_mode:
            log.debug('Executing: api.play_url')
            log.debug(
                'Vars: type={type}, channel={channel}, id={id}, test={test}'.
                format(type=type, channel=channel, id=id, test=test))

        playdata = {'path': '', 'license': '', 'token': ''}

        license = ''
        asset_id = ''
        militime = int(time.time() * 1000)
        typestr = 'PROGRAM'
        info = []
        program_id = None

        if not test:
            while not self._abortRequested and not xbmc.Monitor(
            ).abortRequested() and settings.getBool(key='_test_running'):
                settings.setInt(key='_last_playing', value=time.time())

                if self._abortRequested or xbmc.Monitor().waitForAbort(1):
                    self._abortRequested = True
                    break

            if self._abortRequested or xbmc.Monitor().abortRequested():
                return playdata

        if type == 'channel':
            if not test:
                info_url = '{api_url}/TRAY/SEARCH/LIVE?maxResults=1&filter_airingTime=now&filter_channelIds={channel}&orderBy=airingStartTime&sortOrder=desc'.format(
                    api_url=self._api_url, channel=channel)
                data = self.download(url=info_url,
                                     type='get',
                                     code=[200],
                                     data=None,
                                     json_data=False,
                                     data_return=True,
                                     return_json=True,
                                     retry=True,
                                     check_data=True)

                if not data or not check_key(data['resultObj'], 'containers'):
                    if self._debug_mode:
                        log.debug('Failure to retrieve expected data')
                        log.debug('Execution Done: api.play_url')

                    return playdata

                for row in data['resultObj']['containers']:
                    program_id = row['id']

                info = data

            play_url = '{api_url}/CONTENT/VIDEOURL/LIVE/{channel}/{id}/?deviceId={device_key}&profile=G02&time={time}'.format(
                api_url=self._api_url,
                channel=channel,
                id=id,
                device_key=self._devicekey,
                time=militime)
        else:
            if type == 'program':
                typestr = "PROGRAM"
            else:
                typestr = "VOD"

            program_id = id

            program_url = '{api_url}/CONTENT/USERDATA/{type}/{id}'.format(
                api_url=self._api_url, type=typestr, id=id)
            data = self.download(url=program_url,
                                 type='get',
                                 code=[200],
                                 data=None,
                                 json_data=False,
                                 data_return=True,
                                 return_json=True,
                                 retry=True,
                                 check_data=True)

            if not data or not check_key(data['resultObj'], 'containers'):
                if self._debug_mode:
                    log.debug('Failure to retrieve expected data')
                    log.debug('Execution Done: api.play_url')

                return playdata

            for row in data['resultObj']['containers']:
                if check_key(row, 'entitlement') and check_key(
                        row['entitlement'], 'assets'):
                    for asset in row['entitlement']['assets']:
                        if type == 'program':
                            if check_key(asset, 'videoType') and check_key(
                                    asset, 'programType'
                            ) and asset['videoType'] == 'SD_DASH_PR' and asset[
                                    'programType'] == 'CUTV':
                                asset_id = asset['assetId']
                                break
                        else:
                            if check_key(asset, 'videoType') and check_key(
                                    asset, 'assetType'
                            ) and asset['videoType'] == 'SD_DASH_PR' and asset[
                                    'assetType'] == 'MASTER':
                                if check_key(
                                        asset,
                                        'rights') and asset['rights'] == 'buy':
                                    gui.ok(message=_.NO_STREAM_AUTH,
                                           heading=_.PLAY_ERROR)
                                    return playdata

                                asset_id = asset['assetId']
                                break

            if len(unicode(asset_id)) == 0:
                if self._debug_mode:
                    log.debug('Failure, empty asset_id')
                    log.debug('Execution Done: api.play_url')

                return playdata

            play_url = '{api_url}/CONTENT/VIDEOURL/{type}/{id}/{asset_id}/?deviceId={device_key}&profile=G02&time={time}'.format(
                api_url=self._api_url,
                type=typestr,
                id=id,
                asset_id=asset_id,
                device_key=self._devicekey,
                time=militime)

        if self._abortRequested or xbmc.Monitor().abortRequested():
            return playdata

        if program_id and not test:
            info_url = '{api_url}/CONTENT/DETAIL/{type}/{id}'.format(
                api_url=self._api_url, type=typestr, id=program_id)
            data = self.download(url=info_url,
                                 type='get',
                                 code=[200],
                                 data=None,
                                 json_data=False,
                                 data_return=True,
                                 return_json=True,
                                 retry=True,
                                 check_data=True)

            if not data or not check_key(data['resultObj'], 'containers'):
                if self._debug_mode:
                    log.debug('Failure to retrieve expected data')
                    log.debug('Execution Done: api.play_url')

                return playdata

            info = data

        if self._abortRequested or xbmc.Monitor().waitForAbort(1):
            return playdata

        data = self.download(url=play_url,
                             type='get',
                             code=[200],
                             data=None,
                             json_data=False,
                             data_return=True,
                             return_json=True,
                             retry=True,
                             check_data=True)

        if not data or not check_key(
                data['resultObj'], 'token') or not check_key(
                    data['resultObj'], 'src') or not check_key(
                        data['resultObj']['src'], 'sources') or not check_key(
                            data['resultObj']['src']['sources'], 'src'):
            if self._debug_mode:
                log.debug('Failure, empty token or source')
                log.debug('Execution Done: api.play_url')

            return playdata

        if check_key(
                data['resultObj']['src']['sources'],
                'contentProtection') and check_key(
                    data['resultObj']['src']['sources']['contentProtection'],
                    'widevine') and check_key(
                        data['resultObj']['src']['sources']
                        ['contentProtection']['widevine'],
                        'licenseAcquisitionURL'):
            license = data['resultObj']['src']['sources']['contentProtection'][
                'widevine']['licenseAcquisitionURL']

        path = data['resultObj']['src']['sources']['src']
        token = data['resultObj']['token']

        if not test:
            real_url = "{hostscheme}://{netloc}".format(
                hostscheme=urlparse(path).scheme, netloc=urlparse(path).netloc)
            proxy_url = "http://127.0.0.1:{proxy_port}".format(
                proxy_port=settings.getInt(key='_proxyserver_port'))

            if self._debug_mode:
                log.debug('Real url: {real_url}'.format(real_url=real_url))
                log.debug('Proxy url: {proxy_url}'.format(proxy_url=proxy_url))

            settings.set(key='_stream_hostname', value=real_url)
            path = path.replace(real_url, proxy_url)

            settings.setInt(key='_drm_token_age', value=time.time())
            settings.set(key='_renew_path', value=path)
            settings.set(key='_renew_token', value=token)

        playdata = {
            'path': path,
            'license': license,
            'token': token,
            'type': typestr,
            'info': info
        }

        if self._debug_mode:
            log.debug(
                'Returned Playdata: {playdata}'.format(playdata=playdata))
            log.debug('Execution Done: api.play_url')

        return playdata
Esempio n. 23
0
    def play_url(self, type, path=None, locator=None):
        playdata = {'path': '', 'license': '', 'token': '', 'locator': ''}

        if not type or not len(type) > 0:
            return playdata

        if type == 'vod':
            if not path or not len(path) > 0:
                return playdata

            mediaitems_url = '{mediaitems_url}/{path}'.format(
                mediaitems_url=settings.get(key='_mediaitems_url'), path=path)
            data = self.download(url=mediaitems_url,
                                 type="get",
                                 code=[200],
                                 data=None,
                                 json_data=False,
                                 data_return=True,
                                 return_json=True,
                                 retry=True,
                                 check_data=False)

            if not data or not check_key(data, 'videoStreams'):
                return playdata

            urldata = get_play_url(content=data['videoStreams'])

            if urldata and check_key(urldata, 'play_url') and check_key(
                    urldata, 'locator'):
                path = urldata['play_url']
                locator = urldata['locator']

        if not path or not locator or not len(path) > 0 or not len(
                locator) > 0:
            return playdata

        license = settings.get('_widevine_url')

        token = self.get_play_token(locator=locator, force=True)

        if not token or not len(token) > 0:
            gui.ok(message=_.NO_STREAM_AUTH, heading=_.PLAY_ERROR)
            return playdata

        token = 'WIDEVINETOKEN'

        token_regex = re.search(r"(?<=;vxttoken=)(.*?)(?=/)", path)

        if token_regex and token_regex.group(1) and len(
                token_regex.group(1)) > 0:
            path = path.replace(token_regex.group(1), token)
        else:
            if 'sdash/' in path:
                spliturl = path.split('sdash/', 1)

                if len(spliturl) == 2:
                    path = '{urlpart1}sdash;vxttoken={token}/{urlpart2}?device=Orion-Replay-DASH'.format(
                        urlpart1=spliturl[0],
                        token=token,
                        urlpart2=spliturl[1])
            else:
                spliturl = path.rsplit('/', 1)

                if len(spliturl) == 2:
                    path = '{urlpart1};vxttoken={token}/{urlpart2}'.format(
                        urlpart1=spliturl[0],
                        token=token,
                        urlpart2=spliturl[1])

        real_url = "{hostscheme}://{hostname}".format(
            hostscheme=urlparse(path).scheme, hostname=urlparse(path).hostname)
        proxy_url = "http://127.0.0.1:{proxy_port}".format(
            proxy_port=settings.get(key='_proxyserver_port'))

        settings.set(key='_stream_hostname', value=real_url)
        path = path.replace(real_url, proxy_url)

        playdata = {
            'path': path,
            'license': license,
            'token': token,
            'locator': locator
        }

        return playdata
Esempio n. 24
0
    def login(self, username, password, channels=False):
        settings.remove(key='_cookies')
        self._session = Session(cookies_key='_cookies')

        login_url = '{base_url}/inloggen'.format(base_url=CONST_BASE_URL)

        resp = self.download(url=login_url,
                             type="get",
                             code=None,
                             data=None,
                             json_data=False,
                             data_return=True,
                             return_json=False,
                             retry=False,
                             check_data=False)

        if resp.status_code != 200 and resp.status_code != 302:
            gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE)
            self.clear_session()
            return

        if self.check_data(resp=resp) == False:
            resp.encoding = 'utf-8'
            frmtoken = re.findall(
                r'name=\"form\[_token\]\"\s+value=\"([\S]*)\"', resp.text)

            session_post_data = {
                "form[password]": password,
                "form[email]": username,
                "form[login]": '',
                'form[_token]': frmtoken[0],
            }

            resp = self.download(url=login_url,
                                 type="post",
                                 code=None,
                                 data=session_post_data,
                                 json_data=False,
                                 data_return=True,
                                 return_json=False,
                                 retry=False,
                                 check_data=False)

            if (resp.status_code != 200
                    and resp.status_code != 302) or self.check_data(
                        resp=resp) == False:
                gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE)
                self.clear_session()
                return

        data = self.download(
            url='{base_url}/api/info'.format(base_url=CONST_BASE_URL),
            type="get",
            code=[200],
            data=None,
            json_data=False,
            data_return=True,
            return_json=True,
            retry=False,
            check_data=True)

        if not data or not check_key(data, 'sessionToken') or not check_key(
                data, 'emp'):
            gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE)
            self.clear_session()
            return

        settings.set(key='_session_token', value=data['sessionToken'])
        settings.set(key='_emp_url', value=data['emp']['url'])
        settings.set(key='_emp_customer', value=data['emp']['customer'])
        settings.set(key='_emp_businessunit',
                     value=data['emp']['businessunit'])

        if channels == True or settings.getInt(
                key='_channels_age') < int(time.time() - 86400):
            self.get_channels_for_user(channels=data['channels'])

        if settings.getBool(key='save_password', default=False):
            set_credentials(username=username, password=password)
        else:
            set_credentials(username=username, password='')

        self.logged_in = True
Esempio n. 25
0
    def login(self, username, password, channels=False, retry=True):
        if self._debug_mode:
            log.debug('Executing: api.login')
            log.debug('Vars: username={username}, password={password}, channels={channels}, retry={retry}'.format(username=username, password=password, channels=channels, retry=retry))

        oauth = ''

        settings.remove(key='_cookies')
        self._cookies = ''
        settings.remove(key='_session_token')
        self._session_token = ''
        self._session = Session(cookies_key='_cookies')
        self._session.headers = CONST_BASE_HEADERS
        auth_url = '{login_url}/authenticate?redirect_uri=https%3A%2F%2Flivetv.canaldigitaal.nl%2Fauth.aspx&state={state}&response_type=code&scope=TVE&client_id=StreamGroup'.format(login_url=CONST_LOGIN_URL, state=int(time.time()))

        if self._debug_mode:
            log.debug('Clear Setting _cookies')
            log.debug('Creating new Requests Session')
            log.debug('Request Session Headers')
            log.debug(self._session.headers)

        data = self.download(url=auth_url, type="get", code=[200], data=None, json_data=False, data_return=True, return_json=False, retry=retry, check_data=False, allow_redirects=False)

        if not data:
            if self._debug_mode:
                log.debug('Failure to retrieve expected data')
                log.debug('Execution Done: api.login')

            gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE)
            self.clear_session()
            return False

        self._session.headers = CONST_LOGIN_HEADERS
        self._session.headers.update({'Referer': auth_url})

        session_post_data = {
            "Password": password,
            "Username": username,
        }

        if self._debug_mode:
            log.debug('Request Session Headers')
            log.debug(self._session.headers)

        resp = self.download(url=CONST_LOGIN_URL, type="post", code=None, data=session_post_data, json_data=False, data_return=True, return_json=False, retry=retry, check_data=False, allow_redirects=False)

        if (resp.status_code != 302):
            if self._debug_mode:
                log.debug('Failure to retrieve expected data')
                log.debug('Execution Done: api.login')

            gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE)
            self.clear_session()
            return False

        params = parse_qs(urlparse(resp.headers['Location']).query)

        if check_key(params, 'code'):
            oauth = params['code'][0]

        if self._debug_mode:
            log.debug('Params: {params}'.format(params=params))
            log.debug('OAuth: {oauth}'.format(oauth=oauth))

        if len(oauth) == 0:
            if self._debug_mode:
                log.debug('Failure to retrieve expected data')
                log.debug('Execution Done: api.login')

            gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE)
            self.clear_session()
            return False

        challenge_url = "{base_url}/m7be2iphone/challenge.aspx".format(base_url=CONST_BASE_URL)
        browser_name = settings.get(key='_browser_name')

        session_post_data = {
            "autotype": "nl",
            "app": "cds",
            "prettyname": browser_name,
            "model": "web",
            "serial": self._devicekey,
            "oauthcode": oauth
        }

        self._session.headers = CONST_BASE_HEADERS
        self._session.headers.update({'Content-Type': 'application/json;charset=UTF-8'})

        if self._debug_mode:
            log.debug('Request Session Headers')
            log.debug(self._session.headers)

        data = self.download(url=challenge_url, type="post", code=[200], data=session_post_data, json_data=True, data_return=True, return_json=True, retry=retry, check_data=False, allow_redirects=False)

        if not data or not check_key(data, 'id') or not check_key(data, 'secret'):
            if check_key(data, 'error') and data['error'] == 'toomany':
                gui.ok(message=_.TOO_MANY_DEVICES, heading=_.LOGIN_ERROR_TITLE)
            else:
                gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE)

            if self._debug_mode:
                log.debug('Failure to retrieve expected data')
                log.debug('Execution Done: api.login')

            self.clear_session()
            return False

        login_url = "{base_url}/m7be2iphone/login.aspx".format(base_url=CONST_BASE_URL)

        self._session.headers = CONST_BASE_HEADERS
        self._session.headers.update({'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'})

        if self._debug_mode:
            log.debug('Request Session Headers')
            log.debug(self._session.headers)

        secret = '{id}\t{secr}'.format(id=data['id'], secr=data['secret'])

        session_post_data = {
            "secret": secret,
            "uid": self._devicekey,
            "app": "cds",
        }

        resp = self.download(url=login_url, type="post", code=None, data=session_post_data, json_data=False, data_return=True, return_json=False, retry=retry, check_data=False, allow_redirects=False)

        if (resp.status_code != 302):
            if self._debug_mode:
                log.debug('Failure to retrieve expected data')
                log.debug('Execution Done: api.login')

            gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE)
            self.clear_session()
            return False

        ssotoken_url = "{base_url}/m7be2iphone/capi.aspx?z=ssotoken".format(base_url=CONST_BASE_URL)

        self._session.headers = CONST_BASE_HEADERS

        if self._debug_mode:
            log.debug('Request Session Headers')
            log.debug(self._session.headers)

        data = self.download(url=ssotoken_url, type="get", code=[200], data=None, json_data=False, data_return=True, return_json=True, retry=retry, check_data=False, allow_redirects=False)

        if not data or not check_key(data, 'ssotoken'):
            if self._debug_mode:
                log.debug('Failure to retrieve expected data')
                log.debug('Execution Done: api.login')

            gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE)
            self.clear_session()
            return False

        session_url = "{api_url}/session".format(api_url=CONST_DEFAULT_API)

        session_post_data = {
            "sapiToken": data['ssotoken'],
            "deviceType": "PC",
            "deviceModel": browser_name,
            "osVersion": '{name} {version}'.format(name=settings.get(key='_os_name'), version=settings.get(key='_os_version')),
            "deviceSerial": self._devicekey,
            "appVersion": settings.get(key='_browser_version'),
            "brand": "cds"
        }

        self._session.headers = CONST_BASE_HEADERS
        self._session.headers.update({'Content-Type': 'application/json;charset=UTF-8'})

        if self._debug_mode:
            log.debug('Request Session Headers')
            log.debug(self._session.headers)

        data = self.download(url=session_url, type="post", code=[200], data=session_post_data, json_data=True, data_return=True, return_json=True, retry=retry, check_data=False, allow_redirects=False)

        if not data or not check_key(data, 'token'):
            if self._debug_mode:
                log.debug('Failure to retrieve expected data')
                log.debug('Execution Done: api.login')

            gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE)
            self.clear_session()
            return False

        self._session_token = data['token']
        settings.set(key='_session_token', value=self._session_token)
        self._session_age = time.time()
        settings.setInt(key='_session_age', value=self._session_age)

        if self._debug_mode:
            log.debug('Session Token: {session_token}'.format(session_token=self._session_token))
            log.debug('Settings _channels_age: {channels_age}'.format(channels_age=self._channels_age))
            log.debug('Time - 86400 seconds: {time}'.format(time=int(time.time() - 86400)))

        if channels or self._channels_age < int(time.time() - 86400):
            self.get_channels_for_user()

        self._username = username
        self._password = password

        if settings.getBool(key='save_password', default=False):
            set_credentials(username=username, password=password)
        else:
            set_credentials(username=username, password='')

        self.logged_in = True
        self._session.headers = CONST_BASE_HEADERS
        self._session.headers.update({'Authorization': 'Bearer ' + self._session_token})

        if self._debug_mode:
            log.debug('Request Session Headers')
            log.debug(self._session.headers)
            log.debug('Execution Done: api.login')

        return True
Esempio n. 26
0
def update_settings():
    settingsJSON = load_file(file='settings.json', isJSON=True)

    try:
        license_url = '{base_url}/{country_code}/{language_code}'.format(base_url=settingsJSON['settings']['urls']['base'], country_code=settingsJSON['settings']['countryCode'], language_code=settingsJSON['settings']['languageCode'])

        settings.set(key='_search_url', value=settingsJSON['settings']['routes']['search'])
        settings.set(key='_session_url', value=settingsJSON['settings']['routes']['session'])
        settings.set(key='_token_url', value=settingsJSON['settings']['routes']['refreshToken'])
        settings.set(key='_channels_url', value=settingsJSON['settings']['routes']['channels'])
        settings.set(key='_token_url',  value='{license_url}/web/license/token'.format(license_url=license_url))
        settings.set(key='_widevine_url', value='{license_url}/web/license/eme'.format(license_url=license_url))
        settings.set(key='_listings_url', value=settingsJSON['settings']['routes']['listings'])
        settings.set(key='_mediaitems_url', value=settingsJSON['settings']['routes']['mediaitems'])
        settings.set(key='_mediagroupsfeeds_url', value=settingsJSON['settings']['routes']['mediagroupsfeeds'])
        settings.set(key='_watchlist_url', value=settingsJSON['settings']['routes']['watchlist'])
    except:
        pass

    try:
        client_id = settingsJSON['client_id']
    except:
        client_id = CONST_DEFAULT_CLIENTID

    settings.set(key='_client_id', value=client_id)
Esempio n. 27
0
    def play_url(self, type, channel=None, id=None, test=False, from_beginning='False'):
        self._session.headers = CONST_BASE_HEADERS
        self._session.headers.update({'Authorization': 'Bearer ' + self._session_token})

        if self._debug_mode:
            log.debug('Executing: api.play_url')
            log.debug('Vars: type={type}, channel={channel}, id={id}, test={test}'.format(type=type, channel=channel, id=id, test=test))
            log.debug('Request Session Headers')
            log.debug(self._session.headers)

        playdata = {'path': '', 'license': None, 'info': None}

        if not type or not len(unicode(type)) > 0:
            if self._debug_mode:
                log.debug('Failure executing api.play_url, no type set')
                log.debug('Execution Done: api.play_url')

            return playdata

        if not test:
            while not self._abortRequested and not xbmc.Monitor().abortRequested() and settings.getBool(key='_test_running'):
                settings.setInt(key='_last_playing', value=time.time())

                if self._abortRequested or xbmc.Monitor().waitForAbort(1):
                    self._abortRequested = True
                    break

            if self._abortRequested or xbmc.Monitor().abortRequested():
                return playdata

        if type == 'channel':
            info_url = '{api_url}/assets/{channel}'.format(api_url=CONST_DEFAULT_API, channel=channel)
        else:
            info_url = '{api_url}/assets/{id}'.format(api_url=CONST_DEFAULT_API, id=id)

        play_url = info_url + '/play'

        if not test:
            data = self.download(url=info_url, type="get", code=[200], data=None, json_data=False, data_return=True, return_json=True, retry=True, check_data=True, allow_redirects=True)

            if not data or not check_key(data, 'id'):
                if self._debug_mode:
                    log.debug('Failure to retrieve expected data')
                    log.debug('Execution Done: api.play_url')

                return playdata

            session_post_data = {
                "player": {
                    "name":"Bitmovin",
                    "version":"8.22.0",
                    "capabilities": {
                        "mediaTypes": ["DASH","HLS","MSSS","Unspecified"],
                        "drmSystems": ["Widevine"],
                    },
                    "drmSystems": ["Widevine"],
                },
            }

            if type == 'channel' and check_key(data, 'params') and check_key(data['params'], 'now') and check_key(data['params']['now'], 'id'):
                play_url2 = '{api_url}/assets/{id}/play'.format(api_url=CONST_DEFAULT_API, id=data['params']['now']['id'])
                info = data['params']['now']

                data = self.download(url=play_url2, type="post", code=[200], data=session_post_data, json_data=True, data_return=True, return_json=True, retry=True, check_data=True, allow_redirects=True)

                if data and check_key(data, 'url'):
                    if not settings.getBool(key='ask_start_from_beginning') or not gui.yes_no(message=_.START_FROM_BEGINNING, heading=info['title']):
                        data = self.download(url=play_url, type="post", code=[200], data=session_post_data, json_data=True, data_return=True, return_json=True, retry=True, check_data=True, allow_redirects=True)
                else:
                    data = self.download(url=play_url, type="post", code=[200], data=session_post_data, json_data=True, data_return=True, return_json=True, retry=True, check_data=True, allow_redirects=True)
            else:
                info = data
                data = self.download(url=play_url, type="post", code=[200], data=session_post_data, json_data=True, data_return=True, return_json=True, retry=True, check_data=True, allow_redirects=True)
        else:
            if self._abortRequested or xbmc.Monitor().abortRequested():
                return playdata

            data = self.download(url=play_url, type="post", code=[200], data=session_post_data, json_data=True, data_return=True, return_json=True, retry=True, check_data=True, allow_redirects=True)

        if not data or not check_key(data, 'url'):
            if self._debug_mode:
                log.debug('Failure to retrieve expected data')
                log.debug('Execution Done: api.play_url')

            return playdata

        if check_key(data, 'drm') and check_key(data['drm'], 'licenseUrl'):
            license = data['drm']['licenseUrl']

        path = data['url']

        if not test:
            real_url = "{hostscheme}://{netloc}".format(hostscheme=urlparse(path).scheme, netloc=urlparse(path).netloc)
            proxy_url = "http://127.0.0.1:{proxy_port}".format(proxy_port=settings.getInt(key='_proxyserver_port'))

            if self._debug_mode:
                log.debug('Real url: {real_url}'.format(real_url=real_url))
                log.debug('Proxy url: {proxy_url}'.format(proxy_url=proxy_url))

            settings.set(key='_stream_hostname', value=real_url)
            path = path.replace(real_url, proxy_url)

        playdata = {'path': path, 'license': license, 'info': info}

        if self._debug_mode:
            log.debug('Returned Playdata: {playdata}'.format(playdata=playdata))
            log.debug('Execution Done: api.play_url')

        return playdata