def load_o2_channels_list(serviceid, list): session = Session() channels = Channels() data = call_o2_api( url= 'https://app.o2tv.cz/sws/subscription/settings/get-user-pref.json?name=nangu.channelListUserChannelNumbers', data=None, header=get_header(session.services[serviceid])) if 'err' in data: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s načtením seznamu kanálů', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() if 'listUserChannelNumbers' in data and len( data['listUserChannelNumbers']) > 0: for list_name in data['listUserChannelNumbers']: if list == encode(list_name): channels_list = channels.get_channels_list( visible_filter=False) for channel in channels_list: if channel in data['listUserChannelNumbers'][decode(list)]: channels.set_visibility(channel, True) else: channels.set_visibility(channel, False) xbmcgui.Dialog().notification('Sledování O2TV', 'Seznam kanálů byl načtený', xbmcgui.NOTIFICATION_INFO, 5000) else: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s načtením seznamu kanálů', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit()
def list_related(epgId, label): xbmcplugin.setPluginCategory(_handle, label) addon = xbmcaddon.Addon(id=plugin_id) channels = Channels() channels_list = channels.get_channels_list() data = call_o2_api(url='https://api.o2tv.cz/unity/api/v1/programs/' + str(epgId) + '/related/?encodedChannels=' + channels.get_encoded_channels() + '&isFuture=false', data=None, header=get_header_unity()) if 'err' in data: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s načtením kategorie', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() if 'result' in data and len(data['result']) > 0: for event in data['result']: if event['channelKey'] in channels_list: startts = event['start'] / 1000 start = datetime.fromtimestamp(event['start'] / 1000) endts = event['end'] / 1000 end = datetime.fromtimestamp(event['end'] / 1000) epgId = event['epgId'] list_item = xbmcgui.ListItem( label=event['name'] + ' (' + channels_list[event['channelKey']]['name'] + ' | ' + decode(utils.day_translation_short[start.strftime('%w')]) + ' ' + start.strftime('%d.%m %H:%M') + ' - ' + end.strftime('%H:%M') + ')') list_item.setInfo( 'video', { 'mediatype': 'movie', 'title': event['name'] + ' (' + channels_list[event['channelKey']]['name'] + ')' }) list_item = get_listitem_epg_details( list_item, str(event['epgId']), channels_list[event['channelKey']]['logo']) list_item.setProperty('IsPlayable', 'true') list_item.setContentLookup(False) if addon.getSetting('download_streams') == 'true': list_item.addContextMenuItems([ ('Stáhnout', 'RunPlugin(plugin://' + plugin_id + '?action=add_to_queue&epgId=' + str(epgId) + ')') ]) url = get_url(action='play_archiv', channelKey=encode(event['channelKey']), start=startts, end=endts, epgId=epgId) xbmcplugin.addDirectoryItem(_handle, url, list_item, False) xbmcplugin.endOfDirectory(_handle) else: xbmcgui.Dialog().notification('Sledování O2TV', 'Žádné pořady nenalezeny', xbmcgui.NOTIFICATION_INFO, 4000)
def get_auth_password(self): addon = xbmcaddon.Addon() self.services = {} post = { 'grant_type': 'password', 'client_id': 'tef-web-portal-etnetera', 'client_secret': '2b16ac9984cd60dd0154f779ef200679', 'platform_id': '231a7d6678d00c65f6f3b2aaa699a0d0', 'language': 'cs', 'username': addon.getSetting('username'), 'password': addon.getSetting('password') } data = call_o2_api(url='https://oauth.o2tv.cz/oauth/token', data=post, header=get_header()) if 'err' in data: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém při přihlášení', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() if 'access_token' in data and len(data['access_token']) > 0: access_token = data['access_token'] refresh_token = data['refresh_token'] expires_in = 0 self.get_subscription(access_token, refresh_token, expires_in, 'password_authentication', 'password_authentication') else: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s příhlášením - token', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit()
def unpair_device(deviceId, deviceName, serviceid): session = Session() if deviceId == 'None': deviceId = '' response = xbmcgui.Dialog().yesno('Smazání zařízení', 'Opravdu smazat spárované zařízení ' + deviceName + ' (' + deviceId + ')' + '?', nolabel='Ne', yeslabel='Ano') if response: post = {'deviceId': deviceId} data = call_o2_api( url= 'https://app.o2tv.cz/sws/subscription/settings/remove-device.json', data=post, header=get_header(session.services[serviceid])) if data != None and 'err' in data: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Problém při smazání spárovaného zařízení', xbmcgui.NOTIFICATION_ERROR, 4000) sys.exit() xbmcgui.Dialog().notification( 'Sledování O2TV', 'Může trvat i cca. hodinu, než se změna projeví', xbmcgui.NOTIFICATION_INFO, 4000) xbmc.executebuiltin('Container.Refresh')
def list_series(epgId, season, label): xbmcplugin.setPluginCategory(_handle, label) params = '' channels = Channels() channels_list = channels.get_channels_list() if int(season) > 0: params = params + '&seasonNumber=' + str(season) data = call_o2_api( url='https://api.o2tv.cz/unity/api/v1/programs/' + str(epgId) + '/episodes/?containsAllGenres=false&encodedChannels=' + channels.get_encoded_channels() + '&isFuture=false' + params, data=None, header=get_header_unity()) if 'err' in data: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s načtením kategorie', xbmcgui.NOTIFICATION_ERROR, 4000) sys.exit() if 'result' in data and len(data['result']) > 0: for event in data['result']: if event['channelKey'] in channels_list: startts = event['start'] / 1000 start = datetime.fromtimestamp(event['start'] / 1000) endts = event['end'] / 1000 end = datetime.fromtimestamp(event['end'] / 1000) epgId = event['epgId'] list_item = xbmcgui.ListItem( label=event['name'] + ' (' + channels_list[event['channelKey']]['name'] + ' | ' + decode(utils.day_translation_short[start.strftime('%w')]) + ' ' + start.strftime('%d.%m %H:%M') + ' - ' + end.strftime('%H:%M') + ')') list_item.setInfo( 'video', { 'mediatype': 'movie', 'title': event['name'] + ' (' + channels_list[event['channelKey']]['name'] + ')' }) list_item = get_listitem_epg_details( list_item, str(event['epgId']), channels_list[event['channelKey']]['logo']) list_item.setProperty('IsPlayable', 'true') list_item.setContentLookup(False) url = get_url(action='play_archiv', channelKey=encode(event['channelKey']), start=startts, end=endts, epgId=epgId) xbmcplugin.addDirectoryItem(_handle, url, list_item, False) xbmcplugin.endOfDirectory(_handle)
def get_recordings_epgIds(): epgIds = [] session = Session() for serviceid in session.get_services(): data = call_o2_api(url='https://api.o2tv.cz/unity/api/v1/recordings/', data=None, header=get_header_unity( session.services[serviceid])) if 'err' in data: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Problém s načtením nahrávek, zkuste to znovu', xbmcgui.NOTIFICATION_ERROR, 5000) if 'result' in data and len(data['result']) > 0: for program in data['result']: epgIds.append(str(program['program']['epgId'])) return epgIds
def add_recording(channelKey, epgId): channelKey = decode(channelKey) channels = Channels() channels_list = channels.get_channels_list() session = Session() service = session.get_service(channels_list[channelKey]['serviceid']) post = {'epgId': int(epgId)} data = call_o2_api( url='https://app.o2tv.cz/sws/subscription/vod/pvr-add-program.json', data=post, header=get_header(service)) if 'err' in data: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s přidáním nahrávky', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() xbmcgui.Dialog().notification('Sledování O2TV', 'Nahrávka přidána', xbmcgui.NOTIFICATION_INFO, 5000)
def delete_recording(channelKey, pvrProgramId): channelKey = decode(channelKey) channels = Channels() channels_list = channels.get_channels_list(visible_filter=False) session = Session() service = session.get_service(channels_list[channelKey]['serviceid']) post = {'pvrProgramId': int(pvrProgramId)} data = call_o2_api( url='https://app.o2tv.cz/sws/subscription/vod/pvr-remove-program.json', data=post, header=get_header(service)) if data != None and 'err' in data: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s odstraněním nahrávky', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() else: xbmcgui.Dialog().notification('Sledování O2TV', 'Nahrávka odstraněna', xbmcgui.NOTIFICATION_INFO, 5000) xbmc.executebuiltin('Container.Refresh')
def refresh_token(self, access_token, refresh_token): post = { 'grant_type': 'refresh_token', 'client_id': 'tef-web-portal-etnetera', 'client_secret': '2b16ac9984cd60dd0154f779ef200679', 'platform_id': '231a7d6678d00c65f6f3b2aaa699a0d0', 'language': 'cs', 'refresh_token': str(refresh_token) } data = call_o2_api(url='https://oauth.o2tv.cz/oauth/token', data=post, header=get_header()) if 'err' in data: return None, None, -1 if 'access_token' in data and len(data['access_token']) > 0: access_token = data['access_token'] refresh_token = data['refresh_token'] expires_in = int(time.time()) + int(data['expires_in']) return access_token, refresh_token, expires_in else: return None, None, -1
def get_o2_channels_lists(label): xbmcplugin.setPluginCategory(_handle, label) session = Session() for serviceid in session.get_services(): data = call_o2_api( url= 'https://app.o2tv.cz/sws/subscription/settings/get-user-pref.json?name=nangu.channelListUserChannelNumbers', data=None, header=get_header(session.services[serviceid])) if 'err' in data: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s načtením seznamu kanálů', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() if 'listUserChannelNumbers' in data and len( data['listUserChannelNumbers']) > 0: for list in data['listUserChannelNumbers']: list_item = xbmcgui.ListItem(label=list.replace('user::', '')) url = get_url(action='load_o2_channels_list', serviceid=serviceid, list=encode(list)) xbmcplugin.addDirectoryItem(_handle, url, list_item, True) xbmcplugin.endOfDirectory(_handle)
def list_devices(label): xbmcplugin.setPluginCategory(_handle, label) session = Session() for serviceid in session.get_services(): data = call_o2_api(url='https://api.o2tv.cz/unity/api/v1/devices/', data=None, header=get_header_unity( session.services[serviceid])) if 'err' in data: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Problém při zjištování spárovaných zařízení', xbmcgui.NOTIFICATION_ERROR, 4000) sys.exit() if 'pairedDeviceAddLimit' in data and 'sessionLimit' in data and 'result' in data: list_item = xbmcgui.ListItem( label='Limit souběžných přehrávání: ' + str(int(data['sessionLimit']))) xbmcplugin.addDirectoryItem(_handle, None, list_item, False) else: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Problém při zjištování spárovaných zařízení', xbmcgui.NOTIFICATION_ERROR, 4000) sys.exit() data = call_o2_api( url= 'https://app.o2tv.cz/sws/subscription/settings/subscription-configuration.json', data=None, header=get_header(session.services[serviceid])) if 'err' in data: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Problém při zjištování spárovaných zařízení', xbmcgui.NOTIFICATION_ERROR, 4000) sys.exit() if 'pairedDevicesLimit' in data and 'pairedDevices' in data: list_item = xbmcgui.ListItem(label='Spárovaných zařízení: ' + str(len(data['pairedDevices'])) + '/' + str(int(data['pairedDevicesLimit']))) xbmcplugin.addDirectoryItem(_handle, None, list_item, False) if len(data['pairedDevices']) > 0: devices = sorted(data['pairedDevices'], key=lambda k: k['lastLoginTimestamp']) for device in devices: list_item = xbmcgui.ListItem( label=device['deviceName'] + ' (' + str(device['deviceId']) + ') - ' + datetime.fromtimestamp(device['lastLoginTimestamp'] / 1000).strftime('%d.%m.%Y') + ' z ' + device['lastLoginIpAddress']) list_item.addContextMenuItems([( 'Smazat zařízení', 'RunPlugin(plugin://' + plugin_id + '?action=unpair_device&deviceId=' + quote(encode(str(device['deviceId']))) + '&deviceName=' + quote(encode(device['deviceName'])) + '&serviceid=' + serviceid + ')', )]) xbmcplugin.addDirectoryItem(_handle, None, list_item, False) else: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Problém při zjištování spárovaných zařízení', xbmcgui.NOTIFICATION_ERROR, 4000) sys.exit() xbmcplugin.endOfDirectory(_handle, cacheToDisc=False)
def list_future_recordings(label): xbmcplugin.setPluginCategory(_handle, label) channels = Channels() channels_list = channels.get_channels_list() session = Session() recordings = {} for serviceid in session.get_services(): data = call_o2_api(url='https://api.o2tv.cz/unity/api/v1/recordings/', data=None, header=get_header_unity( session.services[serviceid])) if 'err' in data: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s načtením nahrávek', xbmcgui.NOTIFICATION_ERROR, 5000) if 'result' in data and len(data['result']) > 0: for program in data['result']: if program['state'] != 'DONE' and program['program'][ 'channelKey'] in channels_list: recordings.update({ program['program']['start'] + random.randint(0, 100): { 'pvrProgramId': program['pvrProgramId'], 'name': program['program']['name'], 'channelKey': program['program']['channelKey'], 'start': decode(utils.day_translation_short[ datetime.fromtimestamp( program['program']['start'] / 1000).strftime('%w')]) + ' ' + datetime.fromtimestamp( program['program']['start'] / 1000).strftime('%d.%m %H:%M'), 'end': datetime.fromtimestamp(program['program']['end'] / 1000).strftime('%H:%M'), 'epgId': program['program']['epgId'] } }) if len(recordings) > 0: for recording in sorted(recordings.keys(), reverse=True): list_item = xbmcgui.ListItem( label=recordings[recording]['name'] + ' (' + recordings[recording]['channelKey'] + ' | ' + recordings[recording]['start'] + ' - ' + recordings[recording]['end'] + ')') list_item.setInfo( 'video', { 'mediatype': 'movie', 'title': recordings[recording]['name'] + ' (' + recordings[recording]['channelKey'] + ')' }) list_item.setProperty('IsPlayable', 'true') list_item = get_listitem_epg_details( list_item, recordings[recording]['epgId'], channels_list[recordings[recording]['channelKey']]['logo']) list_item.addContextMenuItems([( 'Smazat nahrávku', 'RunPlugin(plugin://' + plugin_id + '?action=delete_recording&channelKey=' + recordings[recording]['channelKey'] + '&pvrProgramId=' + str(recordings[recording]['pvrProgramId']) + ')', )]) url = get_url(action='list_future_recordings') xbmcplugin.addDirectoryItem(_handle, url, list_item, True) xbmcplugin.endOfDirectory(_handle, cacheToDisc=False) else: xbmcgui.Dialog().notification('Sledování O2TV', 'Nenalezena žádná nahrávka', xbmcgui.NOTIFICATION_INFO, 5000) sys.exit()
def list_recordings(label): xbmcplugin.setPluginCategory(_handle, label) addon = xbmcaddon.Addon() channels = Channels() channels_list = channels.get_channels_list(visible_filter=False) session = Session() recordings = {} list_item = xbmcgui.ListItem(label='Plánování nahrávek') url = get_url(action='list_planning_recordings', label=label + ' / ' + 'Plánování') xbmcplugin.addDirectoryItem(_handle, url, list_item, True) list_item = xbmcgui.ListItem(label='Naplánované nahrávky') url = get_url(action='list_future_recordings', label=label + ' / ' + 'Naplánované nahrávky') xbmcplugin.addDirectoryItem(_handle, url, list_item, True) for serviceid in session.get_services(): data = call_o2_api(url='https://api.o2tv.cz/unity/api/v1/recordings/', data=None, header=get_header_unity( session.services[serviceid])) if 'err' in data: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Problém s načtením nahrávek, zkuste to znovu', xbmcgui.NOTIFICATION_ERROR, 6000) if 'result' in data and len(data['result']) > 0: for program in data['result']: if program['state'] == 'DONE': recordings.update({ program['program']['start'] + random.randint(0, 100): { 'pvrProgramId': program['pvrProgramId'], 'name': program['program']['name'], 'channelKey': program['program']['channelKey'], 'start': decode(utils.day_translation_short[ datetime.fromtimestamp( program['program']['start'] / 1000).strftime('%w')]) + ' ' + datetime.fromtimestamp( program['program']['start'] / 1000).strftime('%d.%m %H:%M'), 'end': datetime.fromtimestamp(program['program']['end'] / 1000).strftime('%H:%M'), 'epgId': program['program']['epgId'] } }) for recording in sorted(recordings.keys(), reverse=True): if recordings[recording]['channelKey'] in channels_list: list_item = xbmcgui.ListItem( label=recordings[recording]['name'] + ' (' + recordings[recording]['channelKey'] + ' | ' + recordings[recording]['start'] + ' - ' + recordings[recording]['end'] + ')') list_item.setProperty('IsPlayable', 'true') list_item.setInfo( 'video', { 'mediatype': 'movie', 'title': recordings[recording]['name'] + ' (' + recordings[recording]['channelKey'] + ')' }) list_item = get_listitem_epg_details( list_item, recordings[recording]['epgId'], channels_list[recordings[recording]['channelKey']]['logo']) list_item.setContentLookup(False) menus = [('Smazat nahrávku', 'RunPlugin(plugin://' + plugin_id + '?action=delete_recording&channelKey=' + recordings[recording]['channelKey'] + '&pvrProgramId=' + str(recordings[recording]['pvrProgramId']) + ')')] if addon.getSetting('download_streams') == 'true': menus.append( ('Stáhnout', 'RunPlugin(plugin://' + plugin_id + '?action=add_to_queue&epgId=' + str(recordings[recording]['epgId']) + '&pvrProgramId=' + str(recordings[recording]['pvrProgramId']) + ')')) list_item.addContextMenuItems(menus) url = get_url(action='play_recording', channelKey=encode( recordings[recording]['channelKey']), pvrProgramId=recordings[recording]['pvrProgramId'], title=encode(recordings[recording]['name'])) xbmcplugin.addDirectoryItem(_handle, url, list_item, False) xbmcplugin.endOfDirectory(_handle, cacheToDisc=False)
def get_epg_details(epgIds, update_from_api=0): global db open_db() for epgId in epgIds: row = None epg = 0 startTime = -1 endTime = -1 channel = 'N/A' title = 'N/A' availableTo = -1 for row in db.execute( 'SELECT startTime, endTime, channel, title, availableTo FROM epg WHERE epgId = ?', [epgId]): startTime = int(row[0]) endTime = int(row[1]) channel = row[2] title = row[3] availableTo = int(row[4]) epg = 1 row = None for row in db.execute('SELECT * FROM epg_details WHERE epgId = ?', [epgId]): epgId = row[0] cover = row[1] description = row[2] ratings = json.loads(row[3]) cast = json.loads(row[4]) directors = json.loads(row[5]) year = row[6] country = row[7] original = row[8] genres = json.loads(row[9]) imdb = row[10] episodeNumber = row[11] episodeName = row[12] seasonNumber = row[13] episodesInSeason = row[14] seasonName = row[15] seriesName = row[16] contentType = row[17] if not row: cover = '' description = '' ratings = {} cast = [] directors = [] year = '' country = '' original = '' imdb = '' genres = [] episodeNumber = -1 episodeName = '' seasonNumber = -1 episodesInSeason = -1 seasonName = '' seriesName = '' contentType = '' if update_from_api == 1: data = call_o2_api( url='https://api.o2tv.cz/unity/api/v1/programs/' + str(epgId) + '/', data=None, header=get_header_unity()) if not 'err' in data: if epg == 0: channels = Channels() channels_list = channels.get_channels_list() channel = channels_list[data['channelKey']] startTime = int(data['start']) / 1000 endTime = int(data['end']) / 1000 title = data['name'] availableTo = data['availableTo'] db.execute('INSERT INTO epg VALUES(?, ?, ?, ?, ?, ?)', (epgId, startTime, endTime, channel, title, availableTo)) db.commit if 'images' in data and len( data['images'] ) > 0 and 'cover' in data['images'][0]: cover = data['images'][0]['cover'] elif 'picture' in data and len(data['picture']) > 0: cover = data['picture'] if 'longDescription' in data and len( data['longDescription']) > 0: description = data['longDescription'] elif 'shortDescription' in data and len( data['shortDescription']) > 0: description = data['shortDescription'] if 'ratings' in data and len(data['ratings']) > 0: for rating, rating_value in data['ratings'].items(): ratings.update({rating: int(rating_value)}) if 'castAndCrew' in data and len( data['castAndCrew'] ) > 0 and 'cast' in data['castAndCrew'] and len( data['castAndCrew']['cast']) > 0: for person in data['castAndCrew']['cast']: cast.append(person['name']) if 'castAndCrew' in data and len( data['castAndCrew'] ) > 0 and 'directors' in data['castAndCrew'] and len( data['castAndCrew']['directors']) > 0: for person in data['castAndCrew']['directors']: directors.append(person['name']) if 'origin' in data and len(data['origin']) > 0: if 'year' in data['origin'] and len( str(data['origin']['year'])) > 0: year = data['origin']['year'] if 'country' in data['origin'] and len( data['origin']['country']) > 0: country = data['origin']['country']['name'] if 'origName' in data and len(data['origName']) > 0: original = data['origName'] if 'ext' in data and len( data['ext']) > 0 and 'imdbId' in data[ 'ext'] and len(data['ext']['imdbId']) > 0: imdb = data['ext']['imdbId'] if 'genreInfo' in data and len( data['genreInfo'] ) > 0 and 'genres' in data['genreInfo'] and len( data['genreInfo']['genres']) > 0: for genre in data['genreInfo']['genres']: genres.append(genre['name']) if 'seriesInfo' in data: if 'episodeNumber' in data['seriesInfo'] and len( str(data['seriesInfo']['episodeNumber']) ) > 0 and int(data['seriesInfo']['episodeNumber']) > 0: episodeNumber = int( data['seriesInfo']['episodeNumber']) if 'episodeName' in data['seriesInfo'] and len( data['seriesInfo']['episodeName']) > 0: episodeName = data['seriesInfo']['episodeName'] if 'seasonNumber' in data['seriesInfo'] and len( str(data['seriesInfo']['seasonNumber']) ) > 0 and int(data['seriesInfo']['seasonNumber']) > 0: seasonNumber = int( data['seriesInfo']['seasonNumber']) if 'episodesInSeason' in data['seriesInfo'] and len( str(data['seriesInfo']['episodesInSeason']) ) > 0 and int( data['seriesInfo']['episodesInSeason']) > 0: episodesInSeason = int( data['seriesInfo']['episodesInSeason']) if 'seasonName' in data['seriesInfo'] and len( data['seriesInfo']['seasonName']) > 0: seasonName = data['seriesInfo']['seasonName'] if 'seriesName' in data['seriesInfo'] and len( data['seriesInfo']['seriesName']) > 0: seriesName = data['seriesInfo']['seriesName'] if 'contentType' in data and len(data['contentType']) > 0: contentType = data['contentType'] db.execute( 'INSERT INTO epg_details VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', (epgId, cover, description, json.dumps(ratings), json.dumps(cast), json.dumps(directors), year, country, original, json.dumps(genres), imdb, episodeNumber, episodeName, seasonNumber, episodesInSeason, seasonName, seriesName, contentType)) db.commit() close_db() event = { 'epgId': epgId, 'startTime': startTime, 'endTime': endTime, 'channel': channel, 'title': title, 'availableTo': availableTo, 'cover': cover, 'description': description, 'ratings': ratings, 'cast': cast, 'directors': directors, 'year': year, 'country': country, 'original': original, 'genres': genres, 'imdb': imdb, 'episodeNumber': episodeNumber, 'episodeName': episodeName, 'seasonNumber': seasonNumber, 'episodesInSeason': episodesInSeason, 'seasonName': seasonName, 'seriesName': seriesName } return event
def play_video(type, channelKey, start, end, epgId, title): addon = xbmcaddon.Addon() session = Session() channelKey = decode(channelKey) channels = Channels() channels_list = channels.get_channels_list(visible_filter=False) header_unity = get_header_unity( session.get_service(channels_list[channelKey]['serviceid'])) header = get_header( session.get_service(channels_list[channelKey]['serviceid'])) if 'serviceid' not in channels_list[channelKey] or len( channels_list[channelKey]['serviceid']) == 0: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Pravděpodobně neaktivní kanál. Zkuste reset kanálů.', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() subscription = session.get_service( channels_list[channelKey]['serviceid'])['subscription'] if addon.getSetting('select_resolution') == 'true' and addon.getSetting( 'stream_type') == 'HLS' and addon.getSetting('only_sd') != 'true': resolution = xbmcgui.Dialog().select('Rozlišení', ['HD', 'SD'], preselect=0) else: resolution = -1 if addon.getSetting('stream_type') == 'MPEG-DASH': stream_type = 'DASH' else: stream_type = 'HLS' force_mpeg_dash = 0 if addon.getSetting('stream_type') == 'HLS' and xbmc.getCondVisibility( 'System.HasAddon(inputstream.adaptive)') and ( type == 'live_iptv' or type == 'live_iptv_epg' ) and addon.getSetting('force_mpeg_dash') == 'true': stream_type = 'DASH' force_mpeg_dash = 1 if type == 'live' or type == 'live_iptv' or type == 'live_iptv_epg': startts = 0 channels_details = get_epg_live(len(channels_list.keys())) if channels_list[channelKey]['name'] in channels_details: without_details = 0 else: without_details = 1 if channelKey in channels_list and without_details == 0: data = channels_details[channels_list[channelKey]['name']] start = data['start'] startts = int(time.mktime(start.timetuple())) end = data['end'] epgId = str(data['epgId']) if addon.getSetting('stream_type') == 'MPEG-DASH-web': if type == 'archiv' or type == 'archiv_iptv': data = call_o2_api( url='https://api.o2tv.cz/unity/api/v1/programs/' + str(epgId) + '/playlist/', data=None, header=header_unity) if type == 'live' or type == 'live_iptv' or type == 'live_iptv_epg': data = call_o2_api( url= 'https://api.o2tv.cz/unity/api/v1/channels/playlist/?channelKey=' + quote(channelKey), data=None, header=header_unity) if type == 'recording': data = call_o2_api( url='https://api.o2tv.cz/unity/api/v1/recordings/' + str(epgId) + '/playlist/', data=None, header=header_unity) if 'err' in data: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s přehráním streamu', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() if 'playlist' in data and len( data['playlist']) > 0 and 'streamUrls' in data['playlist'][ 0] and 'main' in data['playlist'][0]['streamUrls'] and len( data['playlist'][0]['streamUrls']['main']) > 0: if 'timeshift' in data['playlist'][0]['streamUrls']: url = data['playlist'][0]['streamUrls']['timeshift'] else: url = data['playlist'][0]['streamUrls']['main'] request = Request(url=url, data=None, headers=header) response = urlopen(request) url = response.geturl() else: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s přehráním streamu', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() else: if type == 'archiv' or type == 'archiv_iptv': start = int(float(start) * 1000) end = int(float(end) * 1000) post = { 'serviceType': 'TIMESHIFT_TV', 'deviceType': addon.getSetting('devicetype'), 'streamingProtocol': stream_type, 'subscriptionCode': subscription, 'channelKey': encode(channelKey), 'fromTimestamp': str(start), 'toTimestamp': str(end + (int(addon.getSetting('offset')) * 60 * 1000)), 'id': epgId, 'encryptionType': 'NONE' } if type == 'live' or type == 'live_iptv' or type == 'live_iptv_epg': if (addon.getSetting('stream_type') == 'MPEG-DASH' or force_mpeg_dash == 1 ) and startts > 0 and addon.getSetting('startover') == 'true': startts = int(float(startts) * 1000 - 300000) post = { 'serviceType': 'STARTOVER_TV', 'deviceType': addon.getSetting('devicetype'), 'streamingProtocol': stream_type, 'subscriptionCode': subscription, 'channelKey': encode(channelKey), 'fromTimestamp': startts, 'encryptionType': 'NONE' } else: post = { 'serviceType': 'LIVE_TV', 'deviceType': addon.getSetting('devicetype'), 'streamingProtocol': stream_type, 'subscriptionCode': subscription, 'channelKey': encode(channelKey), 'encryptionType': 'NONE' } if type == 'recording': post = { 'serviceType': 'NPVR', 'deviceType': addon.getSetting('devicetype'), 'streamingProtocol': stream_type, 'subscriptionCode': subscription, 'contentId': epgId, 'encryptionType': 'NONE' } if addon.getSetting( 'stream_type') != 'MPEG-DASH' and force_mpeg_dash == 0 and ( addon.getSetting('only_sd') == 'true' or resolution == 1): post.update({'resolution': 'SD'}) data = call_o2_api( url='https://app.o2tv.cz/sws/server/streaming/uris.json', data=post, header=header) if 'err' in data: if data['err'] == 'Not Found': post = { 'serviceType': 'LIVE_TV', 'deviceType': addon.getSetting('devicetype'), 'streamingProtocol': stream_type, 'subscriptionCode': subscription, 'channelKey': encode(channelKey), 'encryptionType': 'NONE' } data = call_o2_api( url='https://app.o2tv.cz/sws/server/streaming/uris.json', data=post, header=header) if 'err' in data: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Problém s přehráním streamu', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() else: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s přehráním streamu', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() url = '' if 'uris' in data and len( data['uris']) > 0 and 'uri' in data['uris'][0] and len( data['uris'][0]['uri']) > 0: for uris in data['uris']: print(uris) if addon.getSetting( 'only_sd' ) != 'true' and resolution != 1 and uris['resolution'] == 'HD': url = uris['uri'] if (addon.getSetting('only_sd') == 'true' or resolution == 1) and uris['resolution'] == 'SD': url = uris['uri'] if url == '': url = data['uris'][0]['uri'] if addon.getSetting( 'stream_type') == 'MPEG-DASH' or force_mpeg_dash == 1: request = Request(url=url, data=None, headers=header) response = urlopen(request) url = response.geturl().replace('http:', 'https:').replace( ':80/', ':443/') else: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s přehráním streamu', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() if type == 'live_iptv' or type == 'live_iptv_epg': list_item = xbmcgui.ListItem(path=url) list_item = get_listitem_epg_details(list_item, str(epgId), '', update_from_api=1) elif type == 'archiv_iptv': list_item = xbmcgui.ListItem(title) list_item = get_listitem_epg_details(list_item, str(epgId), '', update_from_api=1) else: list_item = xbmcgui.ListItem(path=url) if addon.getSetting('stream_type') == 'MPEG-DASH' or addon.getSetting( 'stream_type') == 'MPEG-DASH-web' or force_mpeg_dash == 1: list_item.setProperty('inputstreamaddon', 'inputstream.adaptive') list_item.setProperty('inputstream', 'inputstream.adaptive') list_item.setProperty('inputstream.adaptive.manifest_type', 'mpd') list_item.setMimeType('application/dash+xml') if type == 'archiv_iptv' or (type == 'live_iptv' and (addon.getSetting('stream_type') != 'HLS' or force_mpeg_dash == 1) and addon.getSetting('startover') == 'true') or type == 'live_iptv_epg': playlist = xbmc.PlayList(1) playlist.clear() if epgId is not None: event = get_epg_details([str(epgId)], update_from_api=1) list_item.setInfo('video', {'title': event['title']}) else: list_item.setInfo('video', {'title': channels_list[channelKey]['name']}) xbmc.PlayList(1).add(url, list_item) xbmc.Player().play(playlist) else: list_item.setContentLookup(False) xbmcplugin.setResolvedUrl(_handle, True, list_item)
def list_category(category, dataSource, filtr, page, label): xbmcplugin.setPluginCategory(_handle, label) addon = xbmcaddon.Addon() page_limit = int(addon.getSetting('category_pagesize')) filtr = json.loads(filtr) params = '' genres = [] nongenres = [] for genre in filtr['genres']: if len(genre) > 0: params = params + '&genres=' + quote_plus(encode(genre)) genres.append(genre) for nongenre in filtr['notGenres']: if len(nongenre) > 0: params = params + '¬Genres=' + quote_plus(encode(nongenre)) nongenres.append(nongenre) contentType = filtr['contentType'] channels = Channels() channels_list = channels.get_channels_list() events = {} data = call_o2_api( url='https://api.o2tv.cz' + dataSource + '?containsAllGenres=' + str(filtr['containsAllGenres']).lower() + '&contentType=' + contentType + params + '&encodedChannels=' + channels.get_encoded_channels() + '&sort=-o2rating&grouped=true&isFuture=false&limit=500&offset=0', data=None, header=get_header_unity()) if 'err' in data: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s načtením kategorie', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() if 'result' in data and len(data['result']) > 0: num = 0 cnt = 0 characters = [] for event in data['result']: cnt = cnt + 1 if addon.getSetting('categories_sorting') == 'ratingu': events.update({num: event}) num = num + 1 else: events.update({remove_diacritics(event['name']): event}) if remove_diacritics( event['name'][:1].upper()) not in characters: characters.append( remove_diacritics(event['name'][:1].upper())) if addon.getSetting( 'categories_sorting' ) == 'názvu' and page is None and page_limit > 0 and len( events) > page_limit: characters.sort() for character in characters: list_item = xbmcgui.ListItem(label=character) url = get_url(action='list_category', category=contentType, dataSource=dataSource, filtr=json.dumps(filtr), page=encode(character), label=label + ' / ' + encode(character.decode('utf-8'))) xbmcplugin.addDirectoryItem(_handle, url, list_item, True) else: if addon.getSetting( 'categories_sorting') == 'ratingu' and page_limit > 0: if page is None: page = 1 startitem = (int(page) - 1) * page_limit cnt = 0 for key in sorted(events.keys()): if page is None or page_limit == 0 or ( page is not None and addon.getSetting('categories_sorting') == 'názvu' and remove_diacritics(events[key]['name'][:1].upper()) == page.encode('utf-8') ) or (page is not None and addon.getSetting('categories_sorting') == 'ratingu' and cnt >= startitem and cnt < startitem + page_limit): event = events[key] startts = event['start'] / 1000 start = datetime.fromtimestamp(event['start'] / 1000) endts = event['end'] / 1000 end = datetime.fromtimestamp(event['end'] / 1000) epgId = event['epgId'] isSeries = 0 if event['channelKey'] in channels_list: if 'seriesInfo' in event and 'seriesName' in event[ 'seriesInfo'] and len( event['seriesInfo']['seriesName']) > 0: isSeries = 1 event['name'] = event['seriesInfo']['seriesName'] if 'seasonNumber' in event['seriesInfo']: event['name'] = event[ 'name'] # + ' ['+ str(event['seriesInfo']['seasonNumber']) + ']' list_item = xbmcgui.ListItem( label=event['name'] + ' (' + channels_list[event['channelKey']]['name'] + ')') else: list_item = xbmcgui.ListItem( label=event['name'] + ' (' + channels_list[event['channelKey']]['name'] + ' | ' + decode(utils.day_translation_short[ start.strftime('%w')]) + ' ' + start.strftime('%d.%m %H:%M') + ' - ' + end.strftime('%H:%M') + ')') cast = [] directors = [] genres = [] list_item.setInfo( 'video', { 'mediatype': 'movie', 'title': event['name'] + ' (' + channels_list[event['channelKey']]['name'] + ')' }) if 'images' in event and len(event['images']) > 0: list_item.setArt({ 'poster': 'https://img1.o2tv.cz/' + event['images'][0]['cover'], 'thumb': 'https://img1.o2tv.cz/' + event['images'][0]['cover'], 'icon': 'https://img1.o2tv.cz/' + event['images'][0]['cover'] }) if 'longDescription' in event and len( event['longDescription']) > 0: list_item.setInfo( 'video', {'plot': event['longDescription']}) if 'ratings' in event and len(event['ratings']) > 0: for rating, rating_value in event['ratings'].items( ): list_item.setRating(rating, int(rating_value) / 10) if 'castAndCrew' in event and len( event['castAndCrew'] ) > 0 and 'cast' in event['castAndCrew'] and len( event['castAndCrew']['cast']) > 0: for person in event['castAndCrew']['cast']: cast.append(encode(person['name'])) list_item.setInfo('video', {'cast': cast}) if 'castAndCrew' in event and len( event['castAndCrew'] ) > 0 and 'directors' in event['castAndCrew'] and len( event['castAndCrew']['directors']) > 0: for person in event['castAndCrew']['directors']: directors.append(encode(person['name'])) list_item.setInfo('video', {'director': directors}) if 'origin' in event and len(event['origin']) > 0: if 'year' in event['origin'] and len( str(event['origin']['year'])) > 0: list_item.setInfo( 'video', {'year': event['origin']['year']}) if 'country' in event['origin'] and len( event['origin']['country']) > 0: list_item.setInfo('video', { 'country': event['origin']['country']['name'] }) if 'origName' in event and len(event['origName']) > 0: list_item.setInfo( 'video', {'originaltitle': event['origName']}) if 'ext' in event and len( event['ext']) > 0 and 'imdbId' in event[ 'ext'] and len(event['ext']['imdbId']) > 0: list_item.setInfo( 'video', {'imdbnumber': event['ext']['imdbId']}) if 'genreInfo' in event and len( event['genreInfo'] ) > 0 and 'genres' in event['genreInfo'] and len( event['genreInfo']['genres']) > 0: for genre in event['genreInfo']['genres']: genres.append(encode(genre['name'])) list_item.setInfo('video', {'genre': genres}) menus = [ ('Související pořady', 'Container.Update(plugin://' + plugin_id + '?action=list_related&epgId=' + str(epgId) + '&label=Související / ' + encode(event['name']) + ')'), ('Vysílání pořadu', 'Container.Update(plugin://' + plugin_id + '?action=list_same&epgId=' + str(epgId) + '&label=' + encode(event['name']) + ')'), ('Přidat nahrávku', 'RunPlugin(plugin://' + plugin_id + '?action=add_recording&channelKey=' + event['channelKey'] + '&epgId=' + str(epgId) + ')') ] if addon.getSetting('download_streams') == 'true': menus.append( ('Stáhnout', 'RunPlugin(plugin://' + plugin_id + '?action=add_to_queue&epgId=' + str(epgId) + ')')) list_item.addContextMenuItems(menus) if isSeries == 0: list_item.setProperty('IsPlayable', 'true') list_item.setContentLookup(False) url = get_url(action='play_archiv', channelKey=encode( event['channelKey']), start=startts, end=endts, epgId=epgId) xbmcplugin.addDirectoryItem( _handle, url, list_item, False) else: if 'seasonNumber' in event['seriesInfo'] and int( event['seriesInfo']['seasonNumber']) > 0: season = int( event['seriesInfo']['seasonNumber']) else: season = -1 list_item.setProperty('IsPlayable', 'false') url = get_url(action='list_series', epgId=epgId, season=season, label=encode(event['name'])) xbmcplugin.addDirectoryItem( _handle, url, list_item, True) cnt = cnt + 1 if page is not None and addon.getSetting( 'categories_sorting' ) == 'ratingu' and int(page) * page_limit <= cnt: list_item = xbmcgui.ListItem(label='další strana') url = get_url(action='list_category', category=contentType, dataSource=dataSource, filtr=json.dumps(filtr), page=int(page) + 1, label=label) list_item.setProperty('IsPlayable', 'false') xbmcplugin.addDirectoryItem(_handle, url, list_item, True) xbmcplugin.endOfDirectory(_handle)
def get_event(epgId, pvrProgramId, title): addon = xbmcaddon.Addon() err = 0 url = '' post = {} channelKey = '' stream_type = 'HLS' current_ts = int(time.mktime(datetime.now().timetuple())) event = get_epg_details([epgId], update_from_api=1) channels = Channels() channels_list = channels.get_channels_list('name', visible_filter=False) if event != None and (current_ts < event['availableTo'] or pvrProgramId is not None): if event['startTime'] < current_ts: if event['endTime'] < current_ts: if pvrProgramId == None: channelKey = channels_list[event['channel']]['channelKey'] session = Session() channels_list = channels.get_channels_list( visible_filter=False) header = get_header( session.get_service( channels_list[channelKey]['serviceid'])) subscription = session.get_service( channels_list[channelKey]['serviceid'])['subscription'] post = { 'serviceType': 'TIMESHIFT_TV', 'deviceType': addon.getSetting('devicetype'), 'streamingProtocol': stream_type, 'subscriptionCode': subscription, 'channelKey': encode(channelKey), 'fromTimestamp': str(event['startTime'] * 1000), 'toTimestamp': str(event['endTime'] * 1000 + (int(addon.getSetting('offset')) * 60 * 1000)), 'id': epgId, 'encryptionType': 'NONE' } else: session = Session() for serviceid in session.get_services(): data = call_o2_api( url='https://api.o2tv.cz/unity/api/v1/recordings/', data=None, header=get_header_unity( session.services[serviceid])) if 'err' in data: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Problém s načtením nahrávek, zkuste to znovu', xbmcgui.NOTIFICATION_ERROR, 6000) if 'result' in data and len(data['result']) > 0: for program in data['result']: if program['pvrProgramId'] == pvrProgramId: channelKey = program['program'][ 'channelKey'] if len(channelKey) > 0: channels_list = channels.get_channels_list( visible_filter=False) header = get_header( session.get_service( channels_list[channelKey]['serviceid'])) subscription = session.get_service( channels_list[channelKey] ['serviceid'])['subscription'] post = { 'serviceType': 'NPVR', 'deviceType': addon.getSetting('devicetype'), 'streamingProtocol': stream_type, 'subscriptionCode': subscription, 'contentId': pvrProgramId, 'encryptionType': 'NONE' } else: xbmc.log('live') err = 1 else: xbmc.log('future') err = 1 else: xbmc.log('neni') err = 1 if err == 1: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s stažením ' + encode(title), xbmcgui.NOTIFICATION_ERROR, 5000) current_ts = int(time.mktime(datetime.now().timetuple())) db.execute( 'UPDATE queue SET status = -1, downloadts = ? WHERE epgId = ?', [str(current_ts), str(epgId)]) db.commit() return {}, '' else: if addon.getSetting('only_sd') == 'true': post.update({'resolution': 'SD'}) data = call_o2_api( url='https://app.o2tv.cz/sws/server/streaming/uris.json', data=post, header=header) if 'err' in data: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s stažením streamu', xbmcgui.NOTIFICATION_ERROR, 5000) url = '' if 'uris' in data and len( data['uris']) > 0 and 'uri' in data['uris'][0] and len( data['uris'][0]['uri']) > 0: for uris in data['uris']: if addon.getSetting( 'only_sd') != 'true' and uris['resolution'] == 'HD': url = uris['uri'] if addon.getSetting( 'only_sd') == 'true' and uris['resolution'] == 'SD': url = uris['uri'] if url == '': url = data['uris'][0]['uri'] else: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s stažením streamu', xbmcgui.NOTIFICATION_ERROR, 5000) return event, url
def get_auth_web(self): addon = xbmcaddon.Addon() post = { 'username': addon.getSetting('username'), 'password': addon.getSetting('password') } req = Request('https://api.o2tv.cz/unity/api/v1/services/') req.add_header('Content-Type', 'application/json') resp = urlopen(req, json.dumps(post)) data = json.loads(resp.read()) if 'err' in data: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém při přihlášení', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() if 'services' in data and 'remote_access_token' in data and len( data['remote_access_token']) > 0 and len(data['services']) > 0: remote_access_token = data['remote_access_token'] for service in data['services']: service_id = service['service_id'] post = {'remoteAccessToken': remote_access_token} req = Request( 'https://api.o2tv.cz/unity/api/v1/services/selection/' + service_id + '/') req.add_header('Content-Type', 'application/json') resp = urlopen(req, json.dumps(post)) data = json.loads(resp.read()) if 'err' in data: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Problém při přihlášení - služby', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() if 'accessToken' in data and len(data['accessToken']) > 0: access_token = data['accessToken'] header_unity = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0', 'Content-Type': 'application/json', 'x-o2tv-access-token': str(access_token), 'x-o2tv-device-id': addon.getSetting('deviceid'), 'x-o2tv-device-name': addon.getSetting('devicename') } data = call_o2_api( url='https://api.o2tv.cz/unity/api/v1/user/profile/', data=None, header=header_unity) if 'err' in data: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Problém při přihlášení - profil', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() isp = 1 subscription = data['code'] sdata = data['sdata'] locality = data['locality'] offers = data['subscription']['offers'] tariff = data['tariff'] encodedChannels = data['encodedChannels'] channels = data['ottChannels']['live'] self.valid_to = int(time.time()) + 60 * 60 * 24 * 7 self.services.update({ service_id: { 'access_token': access_token, 'subscription': subscription, 'isp': isp, 'locality': locality, 'offers': offers, 'tariff': tariff, 'sdata': sdata, 'encodedChannels': encodedChannels, 'channels': channels } }) else: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Problém při příhlášení - služby', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() else: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém při přihlášení', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit()
def get_subscription(self, access_token, refresh_token, expires_in, service_id, service_description): addon = xbmcaddon.Addon() header = get_header() header.update({ 'X-NanguTv-Access-Token': str(access_token), 'X-NanguTv-Device-Id': addon.getSetting('deviceid') }) data = call_o2_api( url= 'https://app.o2tv.cz/sws/subscription/settings/subscription-configuration.json', data=None, header=header) if 'err' in data: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Problém při přihlášení - subskripce', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() if 'isp' in data and len( data['isp']) > 0 and 'locality' in data and len( data['locality']) > 0 and 'billingParams' in data and len( data['billingParams'] ) > 0 and 'offers' in data['billingParams'] and len( data['billingParams']['offers'] ) > 0 and 'tariff' in data['billingParams'] and len( data['billingParams']['tariff']) > 0: subscription = data['subscription'] isp = data['isp'] locality = data['locality'] offers = data['billingParams']['offers'] tariff = data['billingParams']['tariff'] header_unity = get_header_unity() header_unity.update({ 'x-o2tv-access-token': str(access_token), 'x-o2tv-device-id': addon.getSetting('deviceid'), 'x-o2tv-device-name': addon.getSetting('devicename') }) data = call_o2_api( url='https://api.o2tv.cz/unity/api/v1/user/profile/', data=None, header=header_unity) if 'err' in data: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Problém při přihlášení - profil', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() sdata = data['sdata'] encodedChannels = data['encodedChannels'] channels = data['ottChannels']['live'] self.valid_to = int(time.time()) + 60 * 60 * 24 * 7 self.services.update({ service_id: { 'description': service_description, 'access_token': access_token, 'refresh_token': refresh_token, 'expires_in': expires_in, 'subscription': subscription, 'isp': isp, 'locality': locality, 'offers': offers, 'tariff': tariff, 'sdata': sdata, 'encodedChannels': encodedChannels, 'channels': channels } }) else: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Problém s příhlášením - subskribce', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit()
def get_auth_token(self): addon = xbmcaddon.Addon() self.services = {} post = { 'username': addon.getSetting('username'), 'password': addon.getSetting('password') } data = call_o2_api( url='https://ottmediator.o2tv.cz/ottmediator-war/login', data=post, header=get_header()) if 'err' in data: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém při přihlášení', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() if 'services' in data and 'remote_access_token' in data and len( data['remote_access_token']) > 0 and len(data['services']) > 0: remote_access_token = data['remote_access_token'] for service in data['services']: service_id = service['service_id'] service_desc = service['description'] post = { 'service_id': service_id, 'remote_access_token': remote_access_token } data = call_o2_api( url= 'https://ottmediator.o2tv.cz/ottmediator-war/loginChoiceService', data=post, header=get_header()) if 'err' in data: pass # xbmcgui.Dialog().notification('Sledování O2TV','Problém při přihlášení', xbmcgui.NOTIFICATION_ERROR, 5000) else: post = { 'grant_type': 'remote_access_token', 'client_id': 'tef-web-portal-etnetera', 'client_secret': '2b16ac9984cd60dd0154f779ef200679', 'platform_id': '231a7d6678d00c65f6f3b2aaa699a0d0', 'language': 'cs', 'remote_access_token': str(remote_access_token), 'authority': 'tef-sso', 'isp_id': '1' } data = call_o2_api(url='https://oauth.o2tv.cz/oauth/token', data=post, header=get_header()) if 'err' in data: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Problém při přihlášení - token', xbmcgui.NOTIFICATION_ERROR, 5000) else: if 'access_token' in data and len( data['access_token']) > 0: access_token = data['access_token'] refresh_token = data['refresh_token'] expires_in = 0 self.get_subscription(access_token, refresh_token, expires_in, service_id, service_desc) else: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Problém s příhlášením - token', xbmcgui.NOTIFICATION_ERROR, 5000) else: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s příhlášením', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() if len(self.services) < 1: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s příhlášením - služby', xbmcgui.NOTIFICATION_ERROR, 5000)
def load_categories(): addon = xbmcaddon.Addon() addon_userdata_dir = translatePath(addon.getAddonInfo('profile')) filename = addon_userdata_dir + 'categories.txt' not_found = 0 try: with codecs.open(filename, 'r', encoding='utf-8') as file: for line in file: data = json.loads(line[:-1]) except IOError: not_found = 1 if not_found == 1 or (data and 'valid_to' in data and data['valid_to'] < int(time.time())): slugs = [] invalid_slugs = [] categories = {} subcategories = {} data = call_o2_api( url='https://api.o2tv.cz/unity/api/v1/lists/?name=catalogue', data=None, header=get_header_unity()) if 'err' in data: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s načtením kategorií', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() if 'result' in data and len(data['result']) > 0: for category in data['result']: if 'slug' in category and len(category['slug']) > 0: slugs.append(category['slug']) for slug in slugs: data = call_o2_api( url='https://api.o2tv.cz/unity/api/v1/lists/slug/?slug=' + slug, data=None, header=get_header_unity()) if 'err' in data: invalid_slugs.append(slug) else: if 'name' in data and len(data['name']) > 0: categories.update({ slug: { 'name': data['name'], 'type': data['type'], 'filter': data['filter'], 'dataSource': data['dataSource'] } }) for slug in invalid_slugs: slugs.remove(slug) for slug in slugs: if categories[slug]['type'] == 'list': data = call_o2_api( url='https://api.o2tv.cz/unity/api/v1/lists/?name=' + encode(categories[slug]['filter']['name']), data=None, header=get_header_unity()) if 'err' in data: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Problém s načtením kategorií', xbmcgui.NOTIFICATION_ERROR, 4000) sys.exit() if 'result' in data and len(data['result']) > 0: cnt = 0 subcategory = {} for category in data['result']: subcategory.update({ cnt: { 'name': category['name'], 'type': category['type'], 'filter': category['filter'], 'dataSource': category['dataSource'] } }) cnt = cnt + 1 subcategories.update( {categories[slug]['filter']['name']: subcategory}) try: with codecs.open(filename, 'w', encoding='utf-8') as file: data = json.dumps({ 'categories': categories, 'subcategories': subcategories, 'slugs': slugs, 'valid_to': int(time.time()) + 60 * 60 * 24 }) file.write('%s\n' % data) except IOError: xbmc.log('Chyba uložení kategorií') else: categories = data['categories'] subcategories = data['subcategories'] slugs = data['slugs'] return categories, subcategories, slugs
def load_epg_details(): global db events_detailed_data = {} try: url = 'https://api.o2tv.cz/unity/api/v1/epg/' data = call_o2_api(url=url, data=None, header=get_header_unity()) if 'err' in data: xbmc.log('Chyba API O2 při načítání detailních dat pro EPG!') sys.exit() if 'result' in data and len( data['result']) > 0 and 'count' in data and data['count'] > 0: offset = 0 step = 50 cnt = data['count'] for offset in range(0, cnt + step, step): url = 'https://api.o2tv.cz/unity/api/v1/epg/?offset=' + str( offset) data = call_o2_api(url=url, data=None, header=get_header_unity()) if 'err' in data: xbmc.log( 'Chyba API O2 při načítání detailních dat pro EPG!') sys.exit() if 'result' in data and len(data['result']) > 0: for event in data['result']: cover = '' description = '' ratings = {} cast = [] directors = [] year = '' country = '' original = '' imdb = '' genres = [] episodeNumber = -1 episodeName = '' seasonNumber = -1 episodesInSeason = -1 seasonName = '' seriesName = '' contentType = '' if 'images' in event and len( event['images'] ) > 0 and 'cover' in event['images'][0]: cover = event['images'][0]['cover'] elif 'picture' in event and len(event['picture']) > 0: cover = event['picture'] if 'longDescription' in event and len( event['longDescription']) > 0: description = event['longDescription'] elif 'shortDescription' in event and len( event['shortDescription']) > 0: description = event['shortDescription'] if 'ratings' in event and len(event['ratings']) > 0: for rating, rating_value in event['ratings'].items( ): ratings.update({rating: int(rating_value)}) if 'castAndCrew' in event and len( event['castAndCrew'] ) > 0 and 'cast' in event['castAndCrew'] and len( event['castAndCrew']['cast']) > 0: for person in event['castAndCrew']['cast']: cast.append(encode(person['name'])) if 'castAndCrew' in event and len( event['castAndCrew'] ) > 0 and 'directors' in event['castAndCrew'] and len( event['castAndCrew']['directors']) > 0: for person in event['castAndCrew']['directors']: directors.append(encode(person['name'])) if 'origin' in event and len(event['origin']) > 0: if 'year' in event['origin'] and len( str(event['origin']['year'])) > 0: year = event['origin']['year'] if 'country' in event['origin'] and len( event['origin']['country']) > 0: country = event['origin']['country']['name'] if 'origName' in event and len(event['origName']) > 0: original = event['origName'] if 'ext' in event and len( event['ext']) > 0 and 'imdbId' in event[ 'ext'] and len(event['ext']['imdbId']) > 0: imdb = event['ext']['imdbId'] if 'genreInfo' in event and len( event['genreInfo'] ) > 0 and 'genres' in event['genreInfo'] and len( event['genreInfo']['genres']) > 0: for genre in event['genreInfo']['genres']: genres.append(encode(genre['name'])) if 'seriesInfo' in event: if 'episodeNumber' in event['seriesInfo'] and len( str(event['seriesInfo']['episodeNumber']) ) > 0 and int( event['seriesInfo']['episodeNumber']) > 0: episodeNumber = int( event['seriesInfo']['episodeNumber']) if 'episodeName' in event['seriesInfo'] and len( event['seriesInfo']['episodeName']) > 0: episodeName = event['seriesInfo'][ 'episodeName'] if 'seasonNumber' in event['seriesInfo'] and len( str(event['seriesInfo']['seasonNumber']) ) > 0 and int( event['seriesInfo']['seasonNumber']) > 0: seasonNumber = int( event['seriesInfo']['seasonNumber']) if 'episodesInSeason' in event[ 'seriesInfo'] and len( str(event['seriesInfo'] ['episodesInSeason'])) > 0 and int( event['seriesInfo'] ['episodesInSeason']) > 0: episodesInSeason = int( event['seriesInfo']['episodesInSeason']) if 'seasonName' in event['seriesInfo'] and len( event['seriesInfo']['seasonName']) > 0: seasonName = event['seriesInfo']['seasonName'] if 'seriesName' in event['seriesInfo'] and len( event['seriesInfo']['seriesName']) > 0: seriesName = event['seriesInfo']['seriesName'] if 'contentType' in event and len( event['contentType']) > 0: contentType = event['contentType'] events_detailed_data.update({ event['epgId']: { 'cover': cover, 'description': description, 'ratings': ratings, 'cast': cast, 'directors': directors, 'year': year, 'country': country, 'original': original, 'genres': genres, 'imdb': imdb, 'episodeNumber': episodeNumber, 'episodeName': episodeName, 'seasonNumber': seasonNumber, 'episodesInSeason': episodesInSeason, 'seasonName': seasonName, 'seriesName': seriesName, 'contentType': contentType } }) cnt = 0 open_db() for epgId in events_detailed_data.keys(): row = None for row in db.execute('SELECT * FROM epg WHERE epgId = ?', [epgId]): event = row if row: row = None for row in db.execute( 'SELECT * FROM epg_details WHERE epgId = ?', [epgId]): event = row if not row: cnt = cnt + 1 db.execute( 'INSERT INTO epg_details VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', (epgId, events_detailed_data[epgId]['cover'], events_detailed_data[epgId]['description'], json.dumps(events_detailed_data[epgId]['ratings']), json.dumps(events_detailed_data[epgId]['cast']), json.dumps(events_detailed_data[epgId]['directors']), events_detailed_data[epgId]['year'], events_detailed_data[epgId]['country'], events_detailed_data[epgId]['original'], json.dumps(events_detailed_data[epgId]['genres']), events_detailed_data[epgId]['imdb'], events_detailed_data[epgId]['episodeNumber'], events_detailed_data[epgId]['episodeName'], events_detailed_data[epgId]['seasonNumber'], events_detailed_data[epgId]['episodesInSeason'], events_detailed_data[epgId]['seasonName'], events_detailed_data[epgId]['seriesName'], events_detailed_data[epgId]['contentType'])) db.commit() close_db() xbmc.log('INSERTED epg_details: ' + str(cnt)) except URLError: xbmcgui.Dialog().notification('Sledování O2TV', 'Chyba API O2 při načítání EPG!', xbmcgui.NOTIFICATION_WARNING, 5000) xbmc.log('Error getting EPG data') pass
def get_o2_channels(self): addon = xbmcaddon.Addon() channels = {} data = call_o2_api(url='https://api.o2tv.cz/unity/api/v1/channels/', data=None, header=get_header_unity()) if 'err' in data: xbmcgui.Dialog().notification('O2TV', 'Problém při načtení kanálů z O2', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() if 'result' in data and len(data['result']) > 0: for channel in data['result']: channels.update({ channel['channel']['channelKey']: { 'name': channel['channel']['name'], 'number': int(channel['channel']['weight']), 'logo': 'https://assets.o2tv.cz' + channel['channel']['images']['color']['url'], 'key': channel['channel']['keyForCache'], 'available': False, 'serviceid': '' } }) session = Session() for serviceid in session.get_services(): for offer in session.services[serviceid]['offers']: post = { 'locality': session.services[serviceid]['locality'], 'tariff': session.services[serviceid]['tariff'], 'isp': session.services[serviceid]['isp'], 'language': 'ces', 'deviceType': addon.getSetting('devicetype'), 'liveTvStreamingProtocol': 'HLS', 'offer': offer } data = call_o2_api( url='https://app.o2tv.cz/sws/server/tv/channels.json', data=post, header=get_header(session.services[serviceid])) if 'err' in data: xbmcgui.Dialog().notification('Sledování O2TV', 'Problém s načtením kanálů', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() if 'channels' in data and len(data['channels']) > 0: for channel in data['channels']: if data['channels'][channel][ 'channelType'] == 'TV' and data['channels'][ channel]['channelKey'] not in channels: channels.update({ data['channels'][channel]['channelKey']: { 'name': data['channels'][channel]['channelName'], 'number': int(data['channels'][channel] ['channelNumber']), 'key': '', 'logo': '' } }) if data['channels'][channel]['channelKey'] in channels: channels[data['channels'][channel] ['channelKey']].update( {'available': True}) if 'serviceid' not in channels[data['channels'][ channel]['channelKey']] or len( channels[data['channels'][channel][ 'channelKey']]['serviceid']) == 0: channels[data['channels'][channel] ['channelKey']].update( {'serviceid': serviceid}) return channels
def load_epg_ts(channelKeys, from_ts, to_ts): global db open_db(check=1) close_db() events_data = {} params = '' for channelKey in channelKeys: params = params + ('&channelKey=' + quote(encode(channelKey))) try: url = 'https://api.o2tv.cz/unity/api/v1/epg/depr/?forceLimit=true&limit=500' + params + '&from=' + str( from_ts * 1000) + '&to=' + str(to_ts * 1000) print(url) data = call_o2_api(url=url, data=None, header=get_header_unity()) if 'err' in data: xbmcgui.Dialog().notification('Sledování O2TV', 'Chyba API O2 při načítání EPG!', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() if 'epg' in data and len( data['epg']) > 0 and 'items' in data['epg'] and len( data['epg']['items']) > 0: for channel in data['epg']['items']: for event in channel['programs']: events_data.update({ event['epgId']: { 'startTime': int(event['start'] / 1000), 'endTime': int(event['end'] / 1000), 'channel': channel['channel']['name'], 'title': event['name'], 'availableTo': int(event['availableTo'] / 1000) } }) cnt = 0 open_db() for epgId in events_data.keys(): row = None for row in db.execute('SELECT * FROM epg WHERE epgId = ?', [epgId]): event = row startTime = int(row[1]) endTime = int(row[2]) channel = row[3] title = row[4] availableTo = int(row[5]) if startTime != events_data[epgId][ 'startTime'] or endTime != events_data[epgId][ 'endTime'] or channel != events_data[epgId][ 'channel'] or title != events_data[epgId][ 'title'] or availableTo != events_data[ epgId]['availableTo']: db.execute( 'UPDATE epg SET startTime = ?, endTime = ?, channel = ?, title = ?, availableTo = ? WHERE epgId = ?', (events_data[epgId]['startTime'], events_data[epgId]['endTime'], events_data[epgId]['channel'], events_data[epgId]['title'], events_data[epgId]['availableTo'], epgId)) if not row: cnt = cnt + 1 db.execute('INSERT INTO epg VALUES(?, ?, ?, ?, ?, ?)', (epgId, events_data[epgId]['startTime'], events_data[epgId]['endTime'], events_data[epgId]['channel'], events_data[epgId]['title'], events_data[epgId]['availableTo'])) db.commit() close_db() xbmc.log('INSERTED epg: ' + str(cnt)) except URLError: xbmc.log('Error getting EPG data') xbmcgui.Dialog().notification('Sledování O2TV', 'Chyba API O2 při načítání EPG!', xbmcgui.NOTIFICATION_WARNING, 5000) pass