def build_live_tv_menu(params): # First we parse the xmltv guide channels_xmltv = {} pgrms_xmltv = {} # current_time = int(time.strftime('%Y%m%d%H%M%S')) current_time = int(datetime.datetime.utcnow().strftime('%Y%m%d%H%M%S')) if os.path.exists(XMLTV_FILEPATH): tree = ET.parse(XMLTV_FILEPATH) root = tree.getroot() for channel in root.findall('channel'): channels_xmltv[channel.get('id')] = channel for pgrm in root.findall('programme'): pgrm_channel = pgrm.get('channel') if pgrm_channel in pgrms_xmltv: continue pgrm_start_s = pgrm.get('start') pgrm_start = int(pgrm_start_s.split()[0]) pgrm_stop_s = pgrm.get('stop') pgrm_stop = int(pgrm_stop_s.split()[0]) if current_time >= pgrm_start and \ current_time <= pgrm_stop: pgrms_xmltv[pgrm_channel] = pgrm # We sort not hidden channels menu = [] folder_path = eval(params.item_path) for channel in eval(params.item_skeleton): channel_name = channel[0] # If channel isn't disable if common.PLUGIN.get_setting(channel_name): # Get order value in settings file channel_order = common.PLUGIN.get_setting(channel_name + '.order') channel_path = list(folder_path) channel_path.append(skeleton.CHANNELS[channel_name]) item = (channel_order, channel_name, channel_path) menu.append(item) menu = sorted(menu, key=lambda x: x[0]) listing = [] for index, (channel_order, channel_name, channel_path) in enumerate(menu): params['module_path'] = str(channel_path) params['module_name'] = channel_name params['channel_label'] = skeleton.LABELS[channel_name] # Legacy fix (il faudrait remplacer channel_name par # module_name dans tous les .py des chaines) params['channel_name'] = params.module_name item = {} # Build context menu (Move up, move down, ...) context_menu = [] item_down = ( common.GETTEXT('Move down'), 'XBMC.RunPlugin(' + common.PLUGIN.get_url(action='move', direction='down', item_id_order=channel_name + '.order', displayed_items=menu) + ')') item_up = (common.GETTEXT('Move up'), 'XBMC.RunPlugin(' + common.PLUGIN.get_url(action='move', direction='up', item_id_order=channel_name + '.order', displayed_items=menu) + ')') if index == 0: context_menu.append(item_down) elif index == len(menu) - 1: context_menu.append(item_up) else: context_menu.append(item_up) context_menu.append(item_down) hide = (common.GETTEXT('Hide'), 'XBMC.RunPlugin(' + common.PLUGIN.get_url(action='hide', item_id=channel_name) + ')') context_menu.append(hide) context_menu.append(utils.vpn_context_menu_item()) image = None plot = None aspect = None year = None rating = None duration = None cast = [] director = None writer = None plotoutline = None episode = None season = None icon = None # Is this channel exists in XMLTV grab infos channel_xmltv_id = XMLTV_CHANNEL_ID[params.module_name] if 'api.telerama.fr' in channel_xmltv_id and \ channel_xmltv_id in pgrms_xmltv: title_channel = channels_xmltv[channel_xmltv_id].find( 'display-name').text icon = channels_xmltv[channel_xmltv_id].find('icon').get('src') pgrm = pgrms_xmltv[channel_xmltv_id] pgrm_name = pgrm.find('title').text title = title_channel + " - [I]" + pgrm_name + "[/I]" plot_object = pgrm.find('desc') if plot_object is not None: plot = plot_object.text sub_title_object = pgrm.find('sub-title') if sub_title_object is not None: if plot is None: plot = sub_title_object.text else: plot = sub_title_object.text + "[CR]" + plot if plot is not None: plot = plot.replace('<P>', '[CR]') plot = plot.replace('</P>;', '[CR]') plot = plot.replace('</I>;', '[/I]') plot = plot.replace('<I>', '[I]') image_object = pgrm.find('icon') if image_object is not None: image = image_object.get('src') aspect_object = pgrm.find('video').find('aspect') if aspect_object is not None: num = float(aspect_object.text.split(':')[0]) den = float(aspect_object.text.split(':')[1]) aspect = num / den year_object = pgrm.find('date') if year_object is not None: year = int(year_object.text) rating_object = pgrm.find('star-rating') if rating_object is not None: rating_object = rating_object.find('value') if rating_object is not None: rating = float(rating_object.text.split('/')[0]) * 2.0 length_object = pgrm.find('length') if length_object is not None: if length_object.get('units') == 'minutes': duration = int(length_object.text) * 60 elif length_object.get('units') == 'hours': duration = int(length_object.text) * 3600 credits_object = pgrm.find('credits') if credits_object is not None: for credit in credits_object.findall('actor'): cast.append(credit.text) for credit in credits_object.findall('writer'): if writer is not None: writer = writer + ' - ' + credit.text else: writer = credit.text for credit in credits_object.findall('presenter'): cast.append(credit.text) for credit in credits_object.findall('director'): if director is not None: director = director + ' - ' + credit.text else: director = credit.text for credit in credits_object.findall('composer'): cast.append(credit.text) episode_num_object = pgrm.find('episode-num') if episode_num_object is not None: season_s = episode_num_object.text.split('.')[0] if season_s != '': season = int(season_s) + 1 episode_s = episode_num_object.text.split('.')[1] if episode_s != '': episode = int(episode_s) + 1 # Else, just get the title form skeleton.py else: try: title = common.GETTEXT(skeleton.LABELS[params.module_name]) except Exception: title = skeleton.LABELS[params.module_name] info = { 'video': { 'title': title, 'plot': plot, # 'aired': aired, # 'date': date, 'duration': duration, 'year': year, 'rating': rating, 'cast': cast, 'director': director, 'writer': writer, 'plotoutline': plotoutline, 'episode': episode, 'season': season } } stream_info = {'video': {'aspect': aspect}} # If the channel has multiples streams like France TV Sport is_playable = True if XMLTV_CHANNEL_ID[params.module_name] == 'multiple_streams': is_playable = False if icon is None or \ icon == 'http://television.telerama.fr/': item_path_media = list(channel_path) item_path_media.pop() item_path_media.append(channel_name) media_item_path = common.sp.xbmc.translatePath( common.sp.os.path.join(common.MEDIA_PATH, *(item_path_media))) media_item_path = media_item_path.decode("utf-8").encode( common.FILESYSTEM_CODING) icon = media_item_path + '.png' listing.append({ 'label': title, 'fanart': image, 'thumb': icon, 'url': common.PLUGIN.get_url(module_path=params.module_path, module_name=params.module_name, action='start_live_tv_stream'), 'is_playable': is_playable, 'context_menu': context_menu, 'info': info, 'stream_info': stream_info, }) return common.PLUGIN.create_listing( listing, sort_methods=(common.sp.xbmcplugin.SORT_METHOD_UNSORTED, common.sp.xbmcplugin.SORT_METHOD_LABEL), category=common.get_window_title(params), content='tvshows')
def root(params): """ Build the addon main menu with all not hidden categories """ # First, we sort main menu by order categories = [] for category_id, title in skeleton.CATEGORIES.iteritems(): # If category isn't disable if common.PLUGIN.get_setting(category_id): category_order = common.PLUGIN.get_setting(category_id + '.order') category = (category_order, category_id, title) categories.append(category) categories = sorted(categories, key=lambda x: x[0]) listing = [] last_category_id = '' for index, (order, category_id, title) in enumerate(categories): if common.PLUGIN.get_setting(category_id): last_category_id = category_id last_window_title = _(title) # Build context menu (Move up, move down, ...) context_menu = [] item_down = ( _('Move down'), 'XBMC.RunPlugin(' + common.PLUGIN.get_url(action='move', direction='down', item_id_order=category_id + '.order', displayed_items=categories) + ')') item_up = ( _('Move up'), 'XBMC.RunPlugin(' + common.PLUGIN.get_url(action='move', direction='up', item_id_order=category_id + '.order', displayed_items=categories) + ')') if index == 0: context_menu.append(item_down) elif index == len(categories) - 1: context_menu.append(item_up) else: context_menu.append(item_up) context_menu.append(item_down) hide = (_('Hide'), 'XBMC.RunPlugin(' + common.PLUGIN.get_url(action='hide', item_id=category_id) + ')') context_menu.append(hide) context_menu.append(utils.vpn_context_menu_item()) media_category_path = common.sp.xbmc.translatePath( common.sp.os.path.join(MEDIA_PATH, 'categories', category_id[-2:])) media_category_path = media_category_path.decode("utf-8").encode( common.FILESYSTEM_CODING) icon = media_category_path + '.png' fanart = media_category_path + '_fanart.jpg' listing.append({ 'icon': icon, 'fanart': fanart, 'label': _(title), 'url': common.PLUGIN.get_url(action='list_channels', category_id=category_id, window_title=_(title)), 'context_menu': context_menu }) # If only one category is present, directly open this category if len(listing) == 1: params['category_id'] = last_category_id params['window_title'] = last_window_title return list_channels(params) return common.PLUGIN.create_listing( listing, sort_methods=(common.sp.xbmcplugin.SORT_METHOD_UNSORTED, ), category=common.get_window_title())
def generic_menu(params): """ Build a generic addon menu with all not hidden items """ current_skeleton = skeleton.SKELETON[('root', 'generic_menu')] current_path = ['root'] if 'item_skeleton' in params: current_skeleton = eval(params.item_skeleton) current_path = eval(params.item_path) # First we sort the current menu menu = [] for value in current_skeleton: item_id = value[0] item_next = value[1] # If menu item isn't disable if common.PLUGIN.get_setting(item_id): # Get order value in settings file item_order = common.PLUGIN.get_setting(item_id + '.order') # Get english item title in LABELS dict in skeleton file # and check if this title has any translated version in strings.po item_title = '' try: item_title = common.GETTEXT(skeleton.LABELS[item_id]) except Exception: item_title = skeleton.LABELS[item_id] # Build step by step the module pathfile item_path = list(current_path) if item_id in skeleton.FOLDERS: item_path.append(skeleton.FOLDERS[item_id]) else: item_path.append(item_id) item_skeleton = {} try: item_skeleton = current_skeleton[value] except TypeError: item_skeleton = {} item = (item_order, item_id, item_title, item_path, item_next, item_skeleton) menu.append(item) menu = sorted(menu, key=lambda x: x[0]) # If only one item is present, directly open this item only_one_item = False if len(menu) == 1: only_one_item = True item = menu[0] item_id = item[1] item_title = item[2] item_path = item[3] item_next = item[4] item_skeleton = item[5] params['item_id'] = item_id params['item_path'] = str(item_path) params['item_skeleton'] = str(item_skeleton) params['window_title'] = item_title if item_next == 'generic_menu': return generic_menu(params) elif item_next == 'replay_entry': return replay_entry(params) elif item_next == 'build_live_tv_menu': return build_live_tv_menu(params) else: only_one_item = False if not only_one_item: listing = [] for index, (item_order, item_id, item_title, item_path, item_next, item_skeleton) in enumerate(menu): # Build context menu (Move up, move down, ...) context_menu = [] item_down = ( common.GETTEXT('Move down'), 'XBMC.RunPlugin(' + common.PLUGIN.get_url(action='move', direction='down', item_id_order=item_id + '.order', displayed_items=menu) + ')') item_up = (common.GETTEXT('Move up'), 'XBMC.RunPlugin(' + common.PLUGIN.get_url(action='move', direction='up', item_id_order=item_id + '.order', displayed_items=menu) + ')') if index == 0: context_menu.append(item_down) elif index == len(menu) - 1: context_menu.append(item_up) else: context_menu.append(item_up) context_menu.append(item_down) hide = (common.GETTEXT('Hide'), 'XBMC.RunPlugin(' + common.PLUGIN.get_url(action='hide', item_id=item_id) + ')') context_menu.append(hide) context_menu.append(utils.vpn_context_menu_item()) item_path_media = list(current_path) item_path_media.append(item_id) media_item_path = common.sp.xbmc.translatePath( common.sp.os.path.join(common.MEDIA_PATH, *(item_path_media))) media_item_path = media_item_path.decode("utf-8").encode( common.FILESYSTEM_CODING) icon = media_item_path + '.png' fanart = media_item_path + '_fanart.jpg' listing.append({ 'icon': icon, 'fanart': fanart, 'label': item_title, 'url': common.PLUGIN.get_url(action=item_next, item_id=item_id, item_path=str(item_path), item_skeleton=str(item_skeleton), window_title=item_title), 'context_menu': context_menu }) return common.PLUGIN.create_listing( listing, sort_methods=(common.sp.xbmcplugin.SORT_METHOD_UNSORTED, ), category=common.get_window_title(params))
def list_channels(params): """ Build the channels list of the desired category """ # First, we sort channels by order channels_dict = skeleton.CHANNELS[params.category_id] channels = [] for channel_id, title in channels_dict.iteritems(): # If channel isn't disable if common.PLUGIN.get_setting(channel_id): channel_order = common.PLUGIN.get_setting(channel_id + '.order') channel = (channel_order, channel_id, title) channels.append(channel) channels = sorted(channels, key=lambda x: x[0]) # Secondly, we build channels list in Kodi listing = [] for index, (order, channel_id, title) in enumerate(channels): # channel_id = channels.fr.6play.w9 [ channel_type, # channels channel_category, # fr channel_file, # 6play channel_name # w9 ] = channel_id.split('.') # channel_module = channels.fr.6play channel_module = '.'.join( (channel_type, channel_category, channel_file)) media_channel_path = common.sp.xbmc.translatePath( common.sp.os.path.join(MEDIA_PATH, channel_type, channel_category, channel_name)) media_channel_path = media_channel_path.decode("utf-8").encode( common.FILESYSTEM_CODING) # Build context menu (Move up, move down, ...) context_menu = [] item_down = (_('Move down'), 'XBMC.RunPlugin(' + common.PLUGIN.get_url(action='move', direction='down', item_id_order=channel_id + '.order', displayed_items=channels) + ')') item_up = (_('Move up'), 'XBMC.RunPlugin(' + common.PLUGIN.get_url(action='move', direction='up', item_id_order=channel_id + '.order', displayed_items=channels) + ')') if index == 0: context_menu.append(item_down) elif index == len(channels) - 1: context_menu.append(item_up) else: context_menu.append(item_up) context_menu.append(item_down) hide = (_('Hide'), 'XBMC.RunPlugin(' + common.PLUGIN.get_url(action='hide', item_id=channel_id) + ')') context_menu.append(hide) context_menu.append(utils.vpn_context_menu_item()) icon = media_channel_path + '.png' fanart = media_channel_path + '_fanart.jpg' listing.append({ 'icon': icon, 'fanart': fanart, 'label': title, 'url': common.PLUGIN.get_url(action='channel_entry', next='root', channel_name=channel_name, channel_module=channel_module, channel_id=channel_id, channel_category=channel_category, window_title=title), 'context_menu': context_menu }) return common.PLUGIN.create_listing( listing, sort_methods=(common.sp.xbmcplugin.SORT_METHOD_UNSORTED, ), category=common.get_window_title())
def build_live_tv_menu(params): """ build_live_tv_menu asks each channel for current live TV information and display the concatenation of this to Kodi """ folder_path = eval(params.item_path) country = folder_path[-1] if country == "fr": return live_tv_fr.build_live_tv_menu(params) else: # First we sort channels menu = [] for channel in eval(params.item_skeleton): channel_name = channel[0] # If channel isn't disable if common.PLUGIN.get_setting(channel_name): # Get order value in settings file channel_order = common.PLUGIN.get_setting(channel_name + '.order') channel_path = list(folder_path) channel_path.append(skeleton.CHANNELS[channel_name]) item = (channel_order, channel_name, channel_path) menu.append(item) menu = sorted(menu, key=lambda x: x[0]) listing = [] for index, (channel_order, channel_name, channel_path) in \ enumerate(menu): params['module_path'] = str(channel_path) params['module_name'] = channel_name params['channel_label'] = skeleton.LABELS[channel_name] channel = utils.get_module(params) # Legacy fix (il faudrait remplacer channel_name par # module_name dans tous les .py des chaines) params['channel_name'] = params.module_name item = {} # Build context menu (Move up, move down, ...) context_menu = [] item_down = ( common.GETTEXT('Move down'), 'XBMC.RunPlugin(' + common.PLUGIN.get_url(action='move', direction='down', item_id_order=channel_name + '.order', displayed_items=menu) + ')') item_up = ( common.GETTEXT('Move up'), 'XBMC.RunPlugin(' + common.PLUGIN.get_url(action='move', direction='up', item_id_order=channel_name + '.order', displayed_items=menu) + ')') if index == 0: context_menu.append(item_down) elif index == len(menu) - 1: context_menu.append(item_up) else: context_menu.append(item_up) context_menu.append(item_down) hide = (common.GETTEXT('Hide'), 'XBMC.RunPlugin(' + common.PLUGIN.get_url( action='hide', item_id=channel_name) + ')') context_menu.append(hide) context_menu.append(utils.vpn_context_menu_item()) try: item = channel.get_live_item(params) if item is not None: if type(item) is dict: item['context_menu'] = context_menu listing.append(item) elif type(item) is list: for subitem in item: subitem['context_menu'] = context_menu listing.append(subitem) except Exception: title = params['channel_label'] + ' broken' utils.send_notification('', title=title, time=2000) return common.PLUGIN.create_listing( listing, sort_methods=(common.sp.xbmcplugin.SORT_METHOD_UNSORTED, common.sp.xbmcplugin.SORT_METHOD_LABEL), category=common.get_window_title(params))