def iptv_sc_download(channelName, startdatetime): addon = xbmcaddon.Addon() if addon.getSetting('download_streams') == 'true': from o2tv.downloader import add_to_queue epgId = -1 from_ts = int(time.mktime(time.strptime(startdatetime, '%d.%m.%Y %H:%M'))) channels = Channels() channels_list = channels.get_channels_list('name', visible_filter=False) channelName = decode(channelName) event = get_epgId_iptvsc(channelName, channels_list[channelName]['channelKey'], from_ts) epgId = event['epgId'] if epgId > 0: event = get_epg_details([epgId], update_from_api=1) if event['startTime'] > int(time.mktime( datetime.now().timetuple())) or event['endTime'] > int( time.mktime(datetime.now().timetuple())): xbmcgui.Dialog().notification( 'Sledování O2TV', 'Lze stáhnout jen už odvysílaný pořad!', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() if event['availableTo'] < int(time.mktime(datetime.now().timetuple())): xbmcgui.Dialog().notification('Sledování O2TV', 'Pořad u O2 už není k dispozici!', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() add_to_queue(epgId, None) else: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Pořad u O2 nenalezen! Používáte EPG z doplňku Sledování O2TV?', xbmcgui.NOTIFICATION_ERROR, 10000) 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 play_catchup(channelKey, start_ts): channels = Channels() channels_list = channels.get_channels_list(visible_filter=False) event = get_epgId_iptvsc(channels_list[channelKey]['name'], channelKey, start_ts) if event['epgId'] == -1 or event['end'] > int( time.mktime(datetime.now().timetuple())) - 10: if event['epgId'] == -1: play_video(type='live_iptv', channelKey=channelKey, start=None, end=None, epgId=event['epgId'], title=None) else: play_video(type='live_iptv', channelKey=channelKey, start=event['start'], end=None, epgId=event['epgId'], title=None) else: play_video(type='archiv', channelKey=channelKey, start=event['start'], end=event['end'], epgId=event['epgId'], title=None)
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 iptv_sc_rec(channelName, startdatetime): epgId = -1 channels = Channels() channels_list = channels.get_channels_list('name', visible_filter=False) channelName = decode(channelName) from_ts = int(time.mktime(time.strptime(startdatetime, '%d.%m.%Y %H:%M'))) event = get_epgId_iptvsc(channelName, channels_list[channelName]['channelKey'], from_ts) epgId = event['epgId'] if epgId > 0: add_recording(channels_list[channelName]['channelKey'], epgId) else: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Pořad u O2 nenalezen! Používáte EPG z doplňku Sledování O2TV?', xbmcgui.NOTIFICATION_ERROR, 10000) sys.exit()
def list_planning_recordings(label): xbmcplugin.setPluginCategory(_handle, label) channels = Channels() channels_list = channels.get_channels_list('number') for number in sorted(channels_list.keys()): list_item = xbmcgui.ListItem(label=channels_list[number]['name']) if len(channels_list[number]['logo']) > 0: list_item.setArt({ 'thumb': channels_list[number]['logo'], 'icon': channels_list[number]['logo'] }) url = get_url(action='list_rec_days', channelKey=encode(channels_list[number]['channelKey']), label=label + ' / ' + encode(channels_list[number]['name'])) xbmcplugin.addDirectoryItem(_handle, url, list_item, True) xbmcplugin.endOfDirectory(_handle)
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 get_epg_ts(channelKey, from_ts, to_ts, min_limit): events_data = {} channels = Channels() channels_list = channels.get_channels_list() channelName = channels_list[channelKey]['name'] open_db() row = None cnt = 0 for row in db.execute( 'SELECT count(1) FROM epg WHERE startTime >= ? AND startTime <=? AND channel = ? AND availableTo > ?', [ from_ts, to_ts, channelName, int(time.mktime(datetime.now().timetuple())) ]): cnt = row[0] if cnt < min_limit: channelKeys = [channelKey] load_epg_ts(channelKeys, from_ts, to_ts) open_db() for row in db.execute( 'SELECT epgId, startTime, endTime, title FROM epg WHERE startTime >= ? AND startTime <=? AND channel = ? AND availableTo > ?', [ from_ts, to_ts, channelName, int(time.mktime(datetime.now().timetuple())) ]): epgId = int(row[0]) startTime = int(row[1]) endTime = int(row[2]) title = row[3] start = datetime.fromtimestamp(startTime) end = datetime.fromtimestamp(endTime) events_data.update({ startTime: { 'epgId': epgId, 'startts': startTime, 'endts': endTime, 'start': start, 'end': end, 'title': title } }) close_db() return events_data
def future_program(channelKey, day, label): label = label.replace('Nahrávky / Plánování /', '') xbmcplugin.setPluginCategory(_handle, label) channels = Channels() channels_list = channels.get_channels_list() channelKey = decode(channelKey) if int(day) == 0: from_datetime = datetime.now() to_datetime = datetime.combine(date.today(), datetime.max.time()) else: from_datetime = datetime.combine( date.today(), datetime.min.time()) + timedelta(days=int(day)) to_datetime = datetime.combine(from_datetime, datetime.max.time()) from_ts = int(time.mktime(from_datetime.timetuple())) to_ts = int(time.mktime(to_datetime.timetuple())) events = get_epg_ts(channelKey, from_ts, to_ts, 5) for key in sorted(events.keys()): epgId = events[key]['epgId'] start = events[key]['start'] end = events[key]['end'] list_item = xbmcgui.ListItem( label=decode(utils.day_translation_short[start.strftime('%w')]) + ' ' + start.strftime('%d.%m %H:%M') + ' - ' + end.strftime('%H:%M') + ' | ' + events[key]['title']) list_item = get_listitem_epg_details(list_item, str(epgId), channels_list[channelKey]['logo']) list_item.setInfo('video', { 'mediatype': 'movie', 'title': events[key]['title'] }) list_item.setProperty('IsPlayable', 'false') list_item.addContextMenuItems([( 'Přidat nahrávku', 'RunPlugin(plugin://' + plugin_id + '?action=add_recording&channelKey=' + channelKey + '&epgId=' + str(epgId) + ')', )]) url = get_url(action='add_recording', channelKey=encode(channelKey), epgId=epgId) xbmcplugin.addDirectoryItem(_handle, url, list_item, False) xbmcplugin.endOfDirectory(_handle)
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 get_epg_live(min_limit): events_data = {} current_ts = int(time.mktime(datetime.now().timetuple())) open_db() row = None cnt = 0 for row in db.execute( 'SELECT count(1) FROM epg WHERE startTime <= ? AND endTime >=?', [current_ts, current_ts]): cnt = row[0] if cnt + 3 < min_limit: channels = Channels() channels_list = channels.get_channels_list() load_epg_ts(channels_list.keys(), current_ts - 60 * 60 * 3, current_ts + 60 * 60 * 3) open_db() for row in db.execute( 'SELECT channel, epgId, startTime, endTime, title FROM epg WHERE startTime <= ? AND endTime >=?', [current_ts, current_ts]): channel = row[0] epgId = int(row[1]) startTime = int(row[2]) endTime = int(row[3]) title = row[4] start = datetime.fromtimestamp(startTime) end = datetime.fromtimestamp(endTime) events_data.update({ channel: { 'epgId': epgId, 'start': start, 'end': end, 'title': title } }) close_db() return events_data
def router(paramstring): params = dict(parse_qsl(paramstring)) check_settings() session = Session() if params: print(params) if params['action'] == 'list_live': list_live(params['page'], params['label']) elif params['action'] == 'play_live': play_video(type='live', channelKey=params['channelKey'], start=None, end=None, epgId=None, title=params['title']) elif params['action'] == 'list_archiv': list_archiv(params['label']) elif params['action'] == 'list_arch_days': list_arch_days(params['channelKey'], params['label']) elif params['action'] == 'list_program': list_program(params['channelKey'], params['day_min'], params['label']) elif params['action'] == 'play_archiv': play_video(type='archiv', channelKey=params['channelKey'], start=params['start'], end=params['end'], epgId=params['epgId'], title=None) elif params['action'] == 'list_categories': list_categories(params['label']) elif params['action'] == 'list_subcategories': list_subcategories(params['category'], params['label']) elif params['action'] == 'list_category': if 'page' not in params: params['page'] = None list_category(params['category'], params['dataSource'], params['filtr'], params['page'], params['label']) elif params['action'] == 'list_series': list_series(params['epgId'], params['season'], params['label']) elif params['action'] == 'list_related': list_related(params['epgId'], params['label']) elif params['action'] == 'list_same': list_same(params['epgId'], params['label']) elif params['action'] == 'list_planning_recordings': list_planning_recordings(params['label']) elif params['action'] == 'list_rec_days': list_rec_days(params['channelKey'], params['label']) elif params['action'] == 'future_program': future_program(params['channelKey'], params['day'], params['label']) elif params['action'] == 'list_recordings': list_recordings(params['label']) elif params['action'] == 'list_future_recordings': list_future_recordings(params['label']) elif params['action'] == 'delete_recording': delete_recording(params['channelKey'], params['pvrProgramId']) elif params['action'] == 'add_recording': add_recording(params['channelKey'], params['epgId']) elif params['action'] == 'play_recording': play_video(type='recording', channelKey=params['channelKey'], start=None, end=None, epgId=params['pvrProgramId'], title=params['title']) elif params['action'] == 'list_search': list_search(params['label']) elif params['action'] == 'program_search': program_search(params['query'], params['label']) elif params['action'] == 'delete_search': delete_search(params['query']) elif params['action'] == 'list_settings': list_settings(params['label']) elif params['action'] == 'list_devices': list_devices(params['label']) elif params['action'] == 'unpair_device': unpair_device(params['deviceId'], params['deviceName'], params['serviceid']) elif params['action'] == 'list_services': list_services(params['label']) elif params['action'] == 'enable_service': enable_service(params['serviceid']) elif params['action'] == 'disable_service': disable_service(params['serviceid']) elif params['action'] == 'move_service': move_service(params['serviceid']) elif params['action'] == 'list_channels_list': list_channels_list(params['label']) elif params['action'] == 'get_o2_channels_lists': get_o2_channels_lists(params['label']) elif params['action'] == 'load_o2_channels_list': load_o2_channels_list(params['serviceid'], params['list']) elif params['action'] == 'reset_channels_list': channels = Channels() channels.reset_channels() elif params['action'] == 'list_channels_list_backups': list_channels_list_backups(params['label']) elif params['action'] == 'restore_channels': channels = Channels() channels.restore_channels(params['backup']) elif params['action'] == 'list_channels_edit': list_channels_edit(params['label']) elif params['action'] == 'edit_channel': edit_channel(params['channelKey']) elif params['action'] == 'delete_channel': delete_channel(params['channelKey']) elif params['action'] == 'change_channels_numbers': change_channels_numbers(params['from_number'], params['direction']) elif params['action'] == 'list_channels_groups': list_channels_groups(params['label']) elif params['action'] == 'add_channel_group': add_channel_group(params['label']) elif params['action'] == 'delete_channel_group': delete_channel_group(params['group']) elif params['action'] == 'select_channel_group': select_channel_group(params['group']) elif params['action'] == 'edit_channel_group': edit_channel_group(params['group'], params['label']) elif params['action'] == 'edit_channel_group_list_channels': edit_channel_group_list_channels(params['group'], params['label']) elif params['action'] == 'edit_channel_group_add_channel': edit_channel_group_add_channel(params['group'], params['channel']) elif params['action'] == 'edit_channel_group_add_all_channels': edit_channel_group_add_all_channels(params['group']) elif params['action'] == 'edit_channel_group_delete_channel': edit_channel_group_delete_channel(params['group'], params['channel']) elif params['action'] == 'addon_settings': xbmcaddon.Addon().openSettings() elif params['action'] == 'generate_playlist': if 'output_file' in params: generate_playlist(params['output_file']) xbmcplugin.addDirectoryItem(_handle, '1', xbmcgui.ListItem()) xbmcplugin.endOfDirectory(_handle, succeeded=True) else: generate_playlist() elif params['action'] == 'generate_epg': if 'output_file' in params: generate_epg(params['output_file']) xbmcplugin.addDirectoryItem(_handle, '1', xbmcgui.ListItem()) xbmcplugin.endOfDirectory(_handle, succeeded=True) else: generate_epg() elif params['action'] == 'get_stream_url': if 'catchup_start_ts' in params and 'catchup_end_ts' in params: play_catchup(channelKey=params['channelKey'], start_ts=params['catchup_start_ts']) else: if addon.getSetting('switch_channel_archiv') == 'true' and len( xbmc.getInfoLabel('ListItem.ChannelName')) > 0 and len( xbmc.getInfoLabel('ListItem.Date')) > 0: iptv_sc_play( xbmc.getInfoLabel('ListItem.ChannelName'), parsedatetime(xbmc.getInfoLabel('ListItem.Date'), xbmc.getInfoLabel('ListItem.StartDate')), 0) else: play_video(type='live_iptv', channelKey=params['channelKey'], start=None, end=None, epgId=None, title=None) elif params['action'] == 'iptv_sc_play': iptv_sc_play(params['channel'], params['startdatetime'], 1) elif params['action'] == 'iptv_sc_rec': iptv_sc_rec(params['channel'], params['startdatetime']) elif params['action'] == 'iptv_sc_download': iptv_sc_download(params['channel'], params['startdatetime']) elif params['action'] == 'reset_session': session = Session() session.remove_session() elif params['action'] == 'add_to_queue': if 'pvrProgramId' in params: pvrProgramId = params['pvrProgramId'] else: pvrProgramId = None add_to_queue(epgId=params['epgId'], pvrProgramId=pvrProgramId) elif params['action'] == 'remove_from_queue': remove_from_queue(epgId=params['epgId']) elif params['action'] == 'list_downloads': list_downloads(params['label']) else: raise ValueError('Neznámý parametr: {0}!'.format(paramstring)) else: list_menu()
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_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 list_program(channelKey, day_min, label): label = label.replace('Archiv /', '') xbmcplugin.setPluginCategory(_handle, label) addon = xbmcaddon.Addon() channelKey = decode(channelKey) channels = Channels() channels_list = channels.get_channels_list() if int(day_min) == 0: from_datetime = datetime.combine(date.today(), datetime.min.time()) to_datetime = datetime.now() else: from_datetime = datetime.combine( date.today(), datetime.min.time()) - timedelta(days=int(day_min)) to_datetime = datetime.combine(from_datetime, datetime.max.time()) from_ts = int(time.mktime(from_datetime.timetuple())) to_ts = int(time.mktime(to_datetime.timetuple())) events = {} events = get_epg_ts(channelKey, from_ts, to_ts, 8) if addon.getSetting('archive_reverse_sort') == "true": archive_reverse = True else: archive_reverse = False for key in sorted(events.keys(), reverse=archive_reverse): if int(events[key]['endts']) > int( time.mktime(datetime.now().timetuple())) - 60 * 60 * 24 * 7: list_item = xbmcgui.ListItem( label=decode(utils.day_translation_short[ events[key]['start'].strftime('%w')]) + ' ' + events[key]['start'].strftime('%d.%m %H:%M') + ' - ' + events[key]['end'].strftime('%H:%M') + ' | ' + events[key]['title']) list_item.setInfo('video', { 'mediatype': 'movie', 'title': events[key]['title'] }) list_item = get_listitem_epg_details( list_item, str(events[key]['epgId']), channels_list[channelKey]['logo']) list_item.setProperty('IsPlayable', 'true') list_item.setContentLookup(False) menus = [ ('Přidat nahrávku', 'RunPlugin(plugin://' + plugin_id + '?action=add_recording&channelKey=' + channelKey + '&epgId=' + str(events[key]['epgId']) + ')'), ('Související pořady', 'Container.Update(plugin://' + plugin_id + '?action=list_related&epgId=' + str(events[key]['epgId']) + '&label=Související / ' + encode(events[key]['title']) + ')'), ('Vysílání pořadu', 'Container.Update(plugin://' + plugin_id + '?action=list_same&epgId=' + str(events[key]['epgId']) + '&label=' + encode(events[key]['title']) + ')') ] if addon.getSetting('download_streams') == 'true': menus.append(('Stáhnout', 'RunPlugin(plugin://' + plugin_id + '?action=add_to_queue&epgId=' + str(events[key]['epgId']) + ')')) list_item.addContextMenuItems(menus) url = get_url(action='play_archiv', channelKey=encode(channelKey), start=events[key]['startts'], end=events[key]['endts'], epgId=events[key]['epgId']) 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 iptv_sc_play(channelName, startdatetime, epg): epgId = -1 addon = xbmcaddon.Addon() channelName = decode(channelName) if len(startdatetime) > 0: from_ts = int( time.mktime(time.strptime(startdatetime, '%d.%m.%Y %H:%M'))) else: from_ts = int(time.mktime(datetime.now().timetuple())) channels = Channels() channels_list = channels.get_channels_list('name', visible_filter=False) if channelName not in channels_list: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Kanál přehrávaný z IPTV SC nebyl nalezený!', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() channelKey = channels_list[channelName]['channelKey'] if from_ts > int(time.mktime(datetime.now().timetuple())): xbmcgui.Dialog().notification('Sledování O2TV', 'Nelze přehrát budoucí pořad!', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() else: event = get_epgId_iptvsc(channelName, channelKey, from_ts) epgId = event['epgId'] if epgId > 0: startts = event['start'] start = datetime.fromtimestamp(event['start']) endts = event['end'] end = datetime.fromtimestamp(event['end']) epgId = event['epgId'] title = decode( utils.day_translation_short[start.strftime('%w')] ) + ' ' + start.strftime('%d.%m %H:%M') + ' - ' + end.strftime( '%H:%M') + ' | ' + event['title'] if int(epgId) > 0: if int(endts) < int(time.mktime(datetime.now().timetuple())): play_video(type='archiv_iptv', channelKey=encode(channelKey), start=startts, end=endts, epgId=epgId, title=title) else: if epg == 1: play_video(type='live_iptv_epg', channelKey=encode(channelKey), start=None, end=None, epgId=None, title=None) else: play_video(type='live_iptv', channelKey=encode(channelKey), start=None, end=None, epgId=None, title=None) else: if len(startdatetime) == 0: play_video(type='live_iptv', channelKey=encode(channelKey), start=None, end=None, epgId=None, title=None) else: xbmcgui.Dialog().notification( 'Sledování O2TV', 'Pořad u O2 nenalezen! Používáte EPG z doplňku Sledování O2TV?', xbmcgui.NOTIFICATION_ERROR, 10000) sys.exit()
def generate_playlist(output_file=''): addon = xbmcaddon.Addon() if addon.getSetting('output_dir') is None or len( addon.getSetting('output_dir')) == 0: xbmcgui.Dialog().notification('Sledování O2TV', 'Nastav adresář pro playlist!', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() channels = Channels() channels_list = channels.get_channels_list('number') if len(output_file) > 0: filename = output_file else: filename = addon.getSetting('output_dir') + 'playlist.m3u' if save_file_test(epg=0) == 0: xbmcgui.Dialog().notification('Sledování O2TV', 'Chyba při uložení playlistu', xbmcgui.NOTIFICATION_ERROR, 5000) return try: file = xbmcvfs.File(filename, 'w') if file == None: xbmcgui.Dialog().notification('Sledování O2TV', 'Chyba při uložení playlistu', xbmcgui.NOTIFICATION_ERROR, 5000) else: file.write(bytearray(('#EXTM3U\n').encode('utf-8'))) for number in sorted(channels_list.keys()): logo = channels_list[number]['logo'] if addon.getSetting('add_channel_numbers') == 'true': if addon.getSetting('catchup_mode') == 'default': line = '#EXTINF:-1 catchup="default" catchup-days="7" catchup-source="plugin://plugin.video.archivo2tv/?action=get_stream_url&channelKey=' + quote( encode(channels_list[number]['channelKey']) ) + '&catchup_start_ts={utc}&catchup_end_ts={utcend}" tvg-chno="' + str( number ) + '" tvg-id="' + channels_list[number][ 'name'] + '" tvh-epg="0" tvg-logo="' + logo + '",' + channels_list[ number]['name'] else: line = '#EXTINF:-1 catchup="append" catchup-days="7" catchup-source="&catchup_start_ts={utc}&catchup_end_ts={utcend}" tvg-chno="' + str( number ) + '" tvg-id="' + channels_list[number][ 'name'] + '" tvh-epg="0" tvg-logo="' + logo + '",' + channels_list[ number]['name'] else: if addon.getSetting('catchup_mode') == 'default': line = '#EXTINF:-1 catchup="default" catchup-days="7" catchup-source="plugin://plugin.video.archivo2tv/?action=get_stream_url&channelKey=' + quote( encode(channels_list[number]['channelKey']) ) + '&catchup_start_ts={utc}&catchup_end_ts={utcend}" tvg-id="' + channels_list[ number][ 'name'] + '" tvh-epg="0" tvg-logo="' + logo + '",' + channels_list[ number]['name'] else: line = '#EXTINF:-1 catchup="append" catchup-days="7" catchup-source="&catchup_start_ts={utc}&catchup_end_ts={utcend}" tvg-id="' + channels_list[ number][ 'name'] + '" tvh-epg="0" tvg-logo="' + logo + '",' + channels_list[ number]['name'] file.write(bytearray((line + '\n').encode('utf-8'))) line = 'plugin://' + plugin_id + '/?action=get_stream_url&channelKey=' + quote( encode(channels_list[number]['channelKey'])) if addon.getSetting('iptvsc_timeshift') == 'true': file.write( bytearray( ('#KODIPROP:inputstream=inputstream.ffmpegdirect\n' ).encode('utf-8'))) file.write( bytearray(( '#KODIPROP:inputstream.ffmpegdirect.stream_mode=timeshift\n' ).encode('utf-8'))) file.write( bytearray(( '#KODIPROP:inputstream.ffmpegdirect.is_realtime_stream=true\n' ).encode('utf-8'))) file.write( bytearray(('#KODIPROP:mimetype=video/mp2t\n' ).encode('utf-8'))) file.write(bytearray((line + '\n').encode('utf-8'))) file.close() xbmcgui.Dialog().notification('Sledování O2TV', 'Playlist byl uložený', xbmcgui.NOTIFICATION_INFO, 5000) except Exception: file.close() xbmcgui.Dialog().notification('Sledování O2TV', 'Chyba při uložení playlistu', xbmcgui.NOTIFICATION_ERROR, 5000)
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 load_epg_all(): addon = xbmcaddon.Addon() channels = Channels() channels_list = channels.get_channels_list('number') channelKeys = [] for number in sorted(channels_list.keys()): channelKeys.append(channels_list[number]['channelKey']) min_ts = 0 if addon.getSetting('info_enabled') == 'true': xbmcgui.Dialog().notification('Sledování O2TV', 'Začalo stahování dat EPG', xbmcgui.NOTIFICATION_INFO, 5000) cached_epg = 0 if addon.getSetting('cached_epg') == 'true': cached_epg = load_cached_epg() if cached_epg == 0: if addon.getSetting('info_enabled') == 'true' and addon.getSetting( 'cached_epg') == 'true': xbmcgui.Dialog().notification( 'Sledování O2TV', 'Došlo k chybě s EPG keší, stahuji z O2', xbmcgui.NOTIFICATION_INFO, 5000) for day in range(-8, 8, 1): from_datetime = datetime.combine( date.today(), datetime.min.time()) - timedelta(days=-1 * int(day)) from_ts = int(time.mktime(from_datetime.timetuple())) to_ts = from_ts + (24 * 60 * 60) - 1 if to_ts > min_ts: if from_ts < min_ts: from_ts = min_ts load_epg_ts(channelKeys, from_ts, to_ts) if addon.getSetting('info_enabled') == 'true': xbmcgui.Dialog().notification( 'Sledování O2TV', 'Začalo stahování detailních dat EPG', xbmcgui.NOTIFICATION_INFO, 5000) load_epg_details() if addon.getSetting('info_enabled') == 'true': xbmcgui.Dialog().notification('Sledování O2TV', 'Stahování dat EPG dokončeno', xbmcgui.NOTIFICATION_INFO, 5000) err = 0 try: rec_epgIds = get_recordings_epgIds() for epgId in rec_epgIds: if epgId == 'err': err = 1 if err == 0: in_epgId = '' if len(rec_epgIds) > 0: in_epgId = 'epgId not in (' + ','.join(rec_epgIds) + ') and ' now_ts = int(time.mktime(datetime.now().timetuple())) open_db() db.execute('DELETE FROM epg WHERE ' + in_epgId + 'availableTo < ?', [now_ts]) db.execute( 'DELETE FROM epg_details WHERE epgId NOT IN (SELECT epgId FROM epg)' ) db.commit() db.execute('VACUUM') close_db() except URLError: pass
def load_epg_db(output_file=''): addon = xbmcaddon.Addon() events_data = {} events_detailed_data = {} events_data, events_detailed_data = get_epg_all() channels = Channels() if addon.getSetting('epg_for_all_channels') == 'true': channels_list = channels.get_channels_list('number', available_filter=False, visible_filter=False) else: channels_list = channels.get_channels_list('number', visible_filter=True) if len(channels_list) > 0: if save_file_test(epg=1) == 0: xbmcgui.Dialog().notification('Sledování O2TV', 'Chyba při uložení EPG', xbmcgui.NOTIFICATION_ERROR, 5000) return if len(addon.getSetting('output_epg_dir')) > 0: output_dir = addon.getSetting('output_epg_dir') else: output_dir = addon.getSetting('output_dir') try: if len(output_file) > 0: file = xbmcvfs.File(output_file, 'w') else: file = xbmcvfs.File(output_dir + 'o2_epg.xml', 'w') if file == None: xbmcgui.Dialog().notification('Sledování O2TV', 'Chyba při uložení EPG', xbmcgui.NOTIFICATION_ERROR, 5000) else: file.write( bytearray(('<?xml version="1.0" encoding="UTF-8"?>\n' ).encode('utf-8'))) file.write( bytearray(('<tv generator-info-name="EPG grabber">\n' ).encode('utf-8'))) content = '' for number in sorted(channels_list.keys()): channel = channels_list[number]['name'] content = content + ' <channel id="' + channel.replace( '&', '&').replace('<', '<').replace( '>', '>') + '">\n' content = content + ' <display-name lang="cs">' + channel.replace( '&', '&').replace('<', '<').replace( '>', '>') + '</display-name>\n' content = content + ' <icon src="' + channels_list[ number]['logo'] + '" />\n' content = content + ' </channel>\n' file.write(bytearray((content).encode('utf-8'))) for number in sorted(channels_list.keys()): channel = channels_list[number]['name'] cnt = 0 content = '' if channel in events_data: for event in sorted(events_data[channel].keys()): starttime = datetime.fromtimestamp( events_data[channel][event] ['startTime']).strftime('%Y%m%d%H%M%S') endtime = datetime.fromtimestamp( events_data[channel][event] ['endTime']).strftime('%Y%m%d%H%M%S') content = content + ' <programme start="' + starttime + ' +0' + str( tz_offset ) + '00" stop="' + endtime + ' +0' + str( tz_offset) + '00" channel="' + events_data[ channel][event]['channel'] + '">\n' content = content + ' <title lang="cs">' + events_data[ channel][event]['title'].replace( '&', '&').replace('<', '<').replace( '>', '>') + '</title>\n' if events_data[channel][event][ 'epgId'] in events_detailed_data: if events_detailed_data[ events_data[channel][event] ['epgId']]['original'] != None and len( events_detailed_data[ events_data[channel][event] ['epgId']]['original']) > 0: content = content + ' <title>' + events_detailed_data[ events_data[channel][event] ['epgId']]['original'].replace( '&', '&').replace( '<', '<').replace( '<', '>') + '</title>\n' content = content + ' <desc lang="cs">' + events_detailed_data[ events_data[channel] [event]['epgId']]['desc'].replace( '&', '&').replace('<', '<').replace( '<', '>') + '</desc>\n' if events_detailed_data[ events_data[channel][event] ['epgId']]['episodeName'] != None and len( events_detailed_data[ events_data[channel][event] ['epgId']]['episodeName']) > 0: content = content + ' <sub-title lang="cs">' + events_detailed_data[ events_data[channel][event] ['epgId']]['episodeName'].replace( '&', '&').replace( '<', '<').replace( '<', '>') + '</sub-title>\n' if events_detailed_data[ events_data[channel][event] ['epgId']]['episodeNumber'] != None and events_detailed_data[ events_data[channel][event]['epgId']][ 'seasonNumber'] != None and events_detailed_data[ events_data[channel][event] ['epgId']][ 'episodeNumber'] > 0 and events_detailed_data[ events_data[channel] [event]['epgId']][ 'seasonNumber'] > 0: if events_detailed_data[ events_data[channel][event] ['epgId']][ 'episodesInSeason'] != None and events_detailed_data[ events_data[channel][event] ['epgId']][ 'episodesInSeason'] > 0: content = content + ' <episode-num system="xmltv_ns">' + str( events_detailed_data[ events_data[channel][event] ['epgId']]['seasonNumber'] - 1 ) + '.' + str( events_detailed_data[ events_data[channel][event] ['epgId']]['episodeNumber'] - 1 ) + '/' + str( events_detailed_data[ events_data[channel][event] ['epgId']]['episodesInSeason'] ) + '.0/0"</episode-num>\n' else: content = content + ' <episode-num system="xmltv_ns">' + str( events_detailed_data[ events_data[channel][event] ['epgId']]['seasonNumber'] - 1 ) + '.' + str( events_detailed_data[ events_data[channel][event] ['epgId']]['episodeNumber'] - 1) + '.0/0"</episode-num>\n' content = content + ' <icon src="' + events_detailed_data[ events_data[channel][event] ['epgId']]['icon'] + '"/>\n' content = content + ' <credits>\n' for cast in events_detailed_data[events_data[ channel][event]['epgId']]['cast']: content = content + ' <actor>' + cast.replace( '&', '&').replace('<', '<').replace( '>', '>') + '</actor>\n' for director in events_detailed_data[ events_data[channel][event] ['epgId']]['directors']: content = content + ' <director>' + director.replace( '&', '&').replace('<', '<').replace( '>', '>') + '</director>\n' content = content + ' </credits>\n' for category in events_detailed_data[ events_data[channel][event] ['epgId']]['genres']: content = content + ' <category>' + category.replace( '&', '&').replace('<', '<').replace( '>', '>') + '</category>\n' if len( str(events_detailed_data[events_data[ channel][event]['epgId']]['year']) ) > 0 and int(events_detailed_data[events_data[ channel][event]['epgId']]['year']) > 0: content = content + ' <date>' + str( events_detailed_data[ events_data[channel][event] ['epgId']]['year']) + '</date>\n' if len(events_detailed_data[ events_data[channel][event]['epgId']] ['country']) > 0: content = content + ' <country>' + events_detailed_data[ events_data[channel][event] ['epgId']]['country'].replace( '&', '&').replace( '<', '<').replace( '>', '>') + '</country>\n' for rating_name, rating in events_detailed_data[ events_data[channel][event] ['epgId']]['ratings'].items(): content = content + ' <rating system="' + rating_name.replace( '&', '&' ).replace('<', '<').replace( '>', '>') + '"><value>' + str( rating) + '/10</value></rating>\n' else: content = content + ' <desc lang="cs"></desc>\n' content = content + ' </programme>\n' cnt = cnt + 1 if cnt > 20: file.write(bytearray( (content).encode('utf-8'))) content = '' cnt = 0 file.write(bytearray((content).encode('utf-8'))) file.write(bytearray(('</tv>\n').encode('utf-8'))) file.close() if addon.getSetting('info_enabled') == 'true': xbmcgui.Dialog().notification('Sledování O2TV', 'EPG bylo uložené', xbmcgui.NOTIFICATION_INFO, 5000) except Exception: file.close() xbmcgui.Dialog().notification( 'Sledování O2TV', 'Nemohu zapsat do ' + output_dir + 'o2_epg.xml' + '!', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit() else: xbmcgui.Dialog().notification('Sledování O2TV', 'Nevrácena žádná data!', xbmcgui.NOTIFICATION_ERROR, 5000) sys.exit()
def list_live(page, label): addon = xbmcaddon.Addon() xbmcplugin.setPluginCategory(_handle, label) channels = Channels() channels_list = channels.get_channels_list('number') num = 0 pagesize = int(addon.getSetting('live_pagesize')) channels_details = get_epg_live(len(channels_list.keys())) color = get_color(addon.getSetting('label_color_live')) startitem = (int(page) - 1) * pagesize i = 0 for num in sorted(channels_list.keys()): if i >= startitem and i < startitem + pagesize: channelName = channels_list[num]['name'] channelKey = channels_list[num]['channelKey'] if channelName in channels_details: title = channels_details[channelName]['title'] start = channels_details[channelName]['start'] end = channels_details[channelName]['end'] live = '[COLOR ' + str( color) + '] | ' + title + ' | ' + start.strftime( '%H:%M') + ' - ' + end.strftime('%H:%M') + '[/COLOR]' live_noncolor = ' | ' + title + ' | ' + start.strftime( '%H:%M') + ' - ' + end.strftime('%H:%M') list_item = xbmcgui.ListItem(label=encode(channelName) + encode(live)) list_item.setInfo( 'video', { 'mediatype': 'movie', 'title': encode(channelName) + ' | ' + encode(title) }) list_item = get_listitem_epg_details( list_item, str(channels_details[channelName]['epgId']), channels_list[num]['logo']) else: live = '' live_noncolor = '' list_item = xbmcgui.ListItem(label=encode(channelName) + encode(live)) list_item.setInfo( 'video', { 'mediatype': 'movie', 'title': encode(channelName) + encode(live) }) list_item.setContentLookup(False) list_item.setProperty('IsPlayable', 'true') if channelName in channels_details: list_item.addContextMenuItems([ ('Související pořady', 'Container.Update(plugin://' + plugin_id + '?action=list_related&epgId=' + str(channels_details[channelName]['epgId']) + '&label=Související / ' + encode(channels_details[channelName]['title']) + ')'), ('Vysílání pořadu', 'Container.Update(plugin://' + plugin_id + '?action=list_same&epgId=' + str(channels_details[channelName]['epgId']) + '&label=' + encode(channels_details[channelName]['title']) + ')') ]) url = get_url(action='play_live', channelKey=encode(channelKey), title=encode(channelName) + encode(live_noncolor)) xbmcplugin.addDirectoryItem(_handle, url, list_item, False) i = i + 1 if int(page) * pagesize <= i: list_item = xbmcgui.ListItem(label='další strana') url = get_url(action='list_live', page=int(page) + 1, label='další strana') list_item.setProperty('IsPlayable', 'false') xbmcplugin.addDirectoryItem(_handle, url, list_item, True) xbmcplugin.endOfDirectory(_handle, cacheToDisc=False)