Esempio n. 1
0
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))