def __init__(self, name):
        super(_PersistentBase, self).__init__()
        self._version_string = "__codequick_storage_version__"
        self._data_string = "__codequick_storage_data__"
        self._serializer_obj = object
        self._stream = None
        self._hash = None
        self._data = None

        # Filename is already a fullpath
        if os.path.sep in name:
            self._filepath = ensure_unicode(name)
            data_dir = os.path.dirname(self._filepath)
        else:
            # Filename must be relative, joining profile directory with filename
            self._filepath = os.path.join(profile_dir, ensure_unicode(name))
            data_dir = profile_dir

        # Ensure that filepath is bytes when platform type is linux/bsd
        if not sys.platform.startswith("win"):  # pragma: no branch
            self._filepath = self._filepath.encode("utf8")
            data_dir = data_dir.encode("utf8")

        # Create any missing data directory
        if not os.path.exists(data_dir):
            os.makedirs(data_dir)
Esempio n. 2
0
    def __init__(self, name):
        super(_PersistentBase, self).__init__()
        self._version_string = "__codequick_storage_version__"
        self._data_string = "__codequick_storage_data__"
        self._serializer_obj = object
        self._stream = None
        self._hash = None
        self._data = None

        # Filename is already a fullpath
        if os.path.sep in name:
            self._filepath = ensure_unicode(name)
            data_dir = os.path.dirname(self._filepath)
        else:
            # Filename must be relative, joining profile directory with filename
            self._filepath = os.path.join(profile_dir, ensure_unicode(name))
            data_dir = profile_dir

        # Ensure that filepath is bytes when platform type is linux/bsd
        if not sys.platform.startswith("win"):  # pragma: no branch
            self._filepath = self._filepath.encode("utf8")
            data_dir = data_dir.encode("utf8")

        # Create any missing data directory
        if not os.path.exists(data_dir):
            os.makedirs(data_dir)
def list_programs(plugin, item_id):
    """
    Build categories listing
    - Tous les programmes
    - Séries
    - Informations
    - ...
    """
    region = utils.ensure_unicode(Script.setting['la_1ere.region'])
    region = LIVE_LA1ERE_REGIONS[region]
    resp2 = urlquick.get(URL_EMISSIONS % region)
    root_soup = bs(resp2.text, 'html.parser')
    list_programs_datas = root_soup.find_all('div', class_='block-fr3-content')

    for program_datas in list_programs_datas:
        program_title = program_datas.find('a').get('title')
        program_image = program_datas.find('img').get('src')
        if 'http' in program_datas.find('a').get('href'):
            program_url = program_datas.find('a').get('href')
        else:
            program_url = URL_ROOT + program_datas.find('a').get('href')

        item = Listitem()
        item.label = program_title
        item.art['thumb'] = program_image
        item.set_callback(list_videos,
                          item_id=item_id,
                          program_url=program_url)
        yield item
Esempio n. 4
0
def list_programs(plugin, item_id, **kwargs):
    """
    Build categories listing
    - Tous les programmes
    - Séries
    - Informations
    - ...
    """
    region = utils.ensure_unicode(Script.setting['la_1ere.language'])
    region = LIVE_LA1ERE_REGIONS[region]
    resp = urlquick.get(URL_EMISSIONS % region)
    root = resp.parse()

    for program_datas in root.iterfind(".//div[@class='block-fr3-content']"):
        program_title = program_datas.find('.//a').get('title')
        program_image = program_datas.find('.//img').get('src')
        if 'http' in program_datas.find('.//a').get('href'):
            program_url = program_datas.find('.//a').get('href')
        else:
            program_url = URL_ROOT + program_datas.find('.//a').get('href')

        item = Listitem()
        item.label = program_title
        item.art['thumb'] = program_image
        item.set_callback(list_videos,
                          item_id=item_id,
                          program_url=program_url)
        item_post_treatment(item)
        yield item
Esempio n. 5
0
def get_live_url(plugin, item_id, video_id, item_dict):

    lives_html = urlquick.get(
        URL_LIVE, headers={'User-Agent': web_utils.get_random_ua}, max_age=-1)
    lives_soup = bs(lives_html.text, 'html.parser')
    lives_datas = lives_soup.find_all(
        'div', class_=re.compile("button"))
    live_id = ''
    for live_datas in lives_datas:
        if item_id == 'tvpinfo':
            if 'info' in live_datas.find('img').get('alt'):
                live_id = live_datas.get('data-video-id')
        elif item_id == 'tvppolonia':
            if 'Polonia' in live_datas.get('data-title'):
                live_id = live_datas.get('data-video-id')
        elif item_id == 'tvp3':
            if LIVE_TVP3_REGIONS[utils.ensure_unicode(
                    Script.setting['tvp3.region'])] in live_datas.find('img').get('alt'):
                live_id = live_datas.get('data-video-id')
    if live_id == '':
        # Add Notification
        return False
    lives_html = urlquick.get(
        URL_STREAM % live_id,
        headers={'User-Agent': web_utils.get_random_ua},
        max_age=-1)
    return re.compile(
        r'src:\'(.*?)\'').findall(lives_html.text)[0]
Esempio n. 6
0
    def _process_item(self, count, url):
        """
        Process the playlist item and add to kodi playlist.

        :param int count: The part number of the item
        :param str url: The resolved object
        """
        # Kodi original listitem object
        if isinstance(url, xbmcgui.ListItem):
            return url
        # Custom listitem object
        elif isinstance(url, Listitem):
            # noinspection PyProtectedMember
            return url._close()[1]
        else:
            # Not already a listitem object
            listitem = xbmcgui.ListItem()
            if isinstance(url, (list, tuple)):
                title, url = url
                title = ensure_unicode(title)
            else:
                title = self._title

            # Create listitem with new title
            listitem.setLabel(u"%s Part %i" % (title, count) if count > 1 else title)
            listitem.setInfo("video", {"title": title})
            listitem.setPath(url)
            return listitem
Esempio n. 7
0
    def hash_params(data):
        # Convert dict of params into a sorted list of key, value pairs
        sorted_dict = sorted(data.items())

        # Pickle the sorted dict so we can hash the contents
        content = pickle.dumps(sorted_dict, protocol=2)
        return ensure_unicode(sha1(content).hexdigest())
def list_programs(plugin, item_id):
    """
    Build categories listing
    - Tous les programmes
    - Séries
    - Informations
    - ...
    """
    region = utils.ensure_unicode(Script.setting['france3regions.language'])
    region = LIVE_FR3_REGIONS[region]
    resp = urlquick.get(URL_EMISSIONS % region)
    root = resp.parse()

    for program_datas in root.iterfind(
            ".//div[@class='little-column-style--content col-sm-6 col-md-4 mobile-toggler-replace']"
    ):
        program_title = program_datas.find('.//h2').text
        program_plot = program_datas.find(
            ".//div[@class='column-style--text hidden-xs']").text
        program_image = program_datas.find('.//img').get('data-srcset')
        program_url = program_datas.find('.//a').get('href')

        item = Listitem()
        item.label = program_title
        item.art['thumb'] = program_image
        item.info['plot'] = program_plot
        item.set_callback(list_videos,
                          item_id=item_id,
                          program_url=program_url)
        yield item
Esempio n. 9
0
def check_filename(name):
    # Filename is already a fullpath
    if os.path.sep in name:
        filepath = ensure_unicode(name)
        data_dir = os.path.dirname(filepath)
    else:
        # Filename must be relative, joining profile directory with filename
        filepath = os.path.join(profile_dir, ensure_unicode(name))
        data_dir = profile_dir

    # Create any missing data directory
    if not os.path.exists(data_dir):
        os.makedirs(data_dir)

    # The full file path
    return filepath
Esempio n. 10
0
def get_live_url(plugin, item_id, video_id, **kwargs):
    final_language = kwargs.get('language', Script.setting['tvp3.language'])

    resp = urlquick.get(URL_LIVE,
                        headers={'User-Agent': web_utils.get_random_ua()},
                        max_age=-1)
    root = resp.parse()

    live_id = ''
    for live_datas in root.findall(".//div"):
        if live_datas.get('data-stationname') is not None:
            if item_id == 'tvpinfo':
                if 'info' in live_datas.find('.//img').get('alt'):
                    live_id = live_datas.get('data-video-id')
            elif item_id == 'tvppolonia':
                if 'Polonia' in live_datas.get('data-title'):
                    live_id = live_datas.get('data-video-id')
            elif item_id == 'tvppolandin':
                if 'News and entertainment' in live_datas.get('data-title'):
                    live_id = live_datas.get('data-video-id')
            elif item_id == 'tvp3':
                if LIVE_TVP3_REGIONS[utils.ensure_unicode(
                        final_language)] in live_datas.find('.//img').get(
                            'alt'):
                    live_id = live_datas.get('data-video-id')
    if live_id == '':
        # Add Notification
        return False
    lives_html = urlquick.get(URL_STREAM % live_id,
                              headers={'User-Agent': web_utils.get_random_ua()},
                              max_age=-1)
    return re.compile(r'src:\'(.*?)\'').findall(lives_html.text)[0]
def list_programs(plugin, item_id):
    """
    Build categories listing
    - Tous les programmes
    - Séries
    - Informations
    - ...
    """
    region = utils.ensure_unicode(Script.setting['france3.region'])
    region = LIVE_FR3_REGIONS[region]
    resp2 = urlquick.get(URL_EMISSIONS % region)
    root_soup = bs(resp2.text, 'html.parser')
    list_programs_datas = root_soup.find_all(
        'div', class_=re.compile('little-column-style--content col-sm-6 col-md-4'))

    for program_datas in list_programs_datas:
        program_title = program_datas.find('h2').get_text()
        program_plot = program_datas.find('div', class_='column-style--text hidden-xs').get_text()
        program_image = program_datas.find('img').get('data-srcset')
        program_url = program_datas.find('a').get('href')

        item = Listitem()
        item.label = program_title
        item.art['thumb'] = program_image
        item.info['plot'] = program_plot
        item.set_callback(
            list_videos,
            item_id=item_id,
            program_url=program_url)
        yield item
Esempio n. 12
0
    def _playlist_item(self, count, url):
        """
        Process the playlist item and add to kodi playlist.

        :param int count: The part number of the item
        :param url: The resolved object
        :type url: str or unicode
        """
        # Kodi original listitem object
        if isinstance(url, xbmcgui.ListItem):
            listitem = url
        # Custom listitem object
        elif isinstance(url, Listitem):
            # noinspection PyProtectedMember
            listitem = url._close()[1]
        else:
            # Not already a listitem object
            listitem = xbmcgui.ListItem()
            if isinstance(url, (list, tuple)):
                title, url = url
                title = ensure_unicode(title)
            else:
                title = self._title

            # Create listitem with new title
            listitem.setLabel(u"%s Part %i" % (title, count))
            listitem.setPath(url)

        # Populate Playlis
        self.playlist.add(listitem.getPath(), listitem)
Esempio n. 13
0
    def __setitem__(self, key, value):
        """
        Set add-on setting.

        :param str key: ID of the setting.
        :param str value: Value of the setting.
        """
        # noinspection PyTypeChecker
        addon_data.setSetting(key, ensure_unicode(value))
Esempio n. 14
0
    def __setitem__(self, key, value):
        """
        Set add-on setting.

        :param str key: ID of the setting.
        :param str value: Value of the setting.
        """
        # noinspection PyTypeChecker
        addon_data.setSetting(key, ensure_unicode(value))
Esempio n. 15
0
    def label(self):
        """
        The listitem label property.

        :example:
            >>> item = Listitem()
            >>> item.label = "Video Title"
        """
        return ensure_unicode(self.listitem.getLabel())
Esempio n. 16
0
def get_live_url(plugin, item_id, video_id, item_dict):

    resp = urlquick.get(URL_LIVES_JSON,
                        headers={'User-Agent': web_utils.get_random_ua},
                        max_age=-1)
    json_parser = json.loads(resp.text)

    region = utils.ensure_unicode(Script.setting['france3.region'])
    id_sivideo = json_parser[LIVE_FR3_REGIONS[region]]["id_sivideo"]
    return resolver_proxy.get_francetv_live_stream(plugin,
                                                   id_sivideo.split('@')[0])
Esempio n. 17
0
def get_live_url(plugin, item_id, video_id, **kwargs):
    final_region = kwargs.get('language', Script.setting['la_1ere.language'])

    resp = urlquick.get(URL_LIVES_JSON,
                        headers={'User-Agent': web_utils.get_random_ua()},
                        max_age=-1)
    json_parser = json.loads(resp.text)

    region = utils.ensure_unicode(final_region)
    id_sivideo = json_parser[LIVE_LA1ERE_REGIONS[region]]["id_sivideo"]
    return resolver_proxy.get_francetv_live_stream(plugin,
                                                   id_sivideo.split('@')[0])
Esempio n. 18
0
    def label(self):
        """
        The listitem label property.

        .. seealso:: A full list of label formating options can be found at.\n
                     http://kodi.wiki/view/Label_Formatting

        :example:
            >>> item = Listitem()
            >>> item.label = "Video Title"
        """
        return ensure_unicode(self.listitem.getLabel())
Esempio n. 19
0
def get_sorted_menu(plugin, menu_id):
    # The current menu to build contains
    # all the items present in the 'menu_id'
    # skeleton file
    current_menu = importlib.import_module('resources.lib.skeletons.' +
                                           menu_id).menu

    # Notify user for the new M3U Live TV feature
    if menu_id == "live_tv" and \
            cqu.get_kodi_version() >= 18 and \
            plugin.setting.get_boolean('show_live_tv_m3u_info'):

        r = xbmcgui.Dialog().yesno(plugin.localize(LABELS['Information']),
                                   plugin.localize(30605),
                                   plugin.localize(30606))
        if not r:
            plugin.setting['show_live_tv_m3u_info'] = False

    # Keep in memory the first menu taken
    # in order to provide a prefix when the user
    # add a favourite
    fav.guess_fav_prefix(menu_id)

    # First, we have to sort the current menu items
    # according to each item order and we have
    # to hide each disabled item
    menu = []
    for item_id, item_infos in current_menu.items():

        add_item = True

        # If the item is enable
        if not Script.setting.get_boolean(item_id):
            add_item = False

        # If the desired language is not avaible
        if 'available_languages' in item_infos:
            desired_language = utils.ensure_unicode(
                Script.setting[item_id + '.language'])
            if desired_language not in item_infos['available_languages']:
                add_item = False

        if add_item:
            # Get order value in settings file
            item_order = Script.setting.get_int(item_id + '.order')

            item = (item_order, item_id, item_infos)

            menu.append(item)

    # We sort the menu according to the item_order values
    return sorted(menu, key=lambda x: x[0])
def get_live_url(plugin, item_id, **kwargs):

    resp2 = urlquick.get(URL_CLIENT_VALUE,
                         headers={'User-Agent': web_utils.get_random_ua()})
    client_id_value = re.compile(r'clientKey\:\"(.*?)\"').findall(
        resp2.text)[0]

    final_region = kwargs.get('language', Script.setting['icitele.language'])
    region = utils.ensure_unicode(final_region)

    resp = urlquick.get(URL_LIVE % LIVE_ICI_TELE_REGIONS[region],
                        headers={
                            'User-Agent': web_utils.get_random_ua(),
                            'Authorization': 'Client-Key %s' % client_id_value
                        })
    json_parser = json.loads(resp.text)
    return json_parser["url"]
Esempio n. 21
0
def get_live_url(plugin, item_id, video_id, item_dict, **kwargs):
    final_region = Script.setting['la_1ere.language']

    # If we come from the M3U file and the language
    # is set in the M3U URL, then we overwrite
    # Catch Up TV & More language setting
    if type(item_dict) is not dict:
        item_dict = eval(item_dict)
    if 'language' in item_dict:
        final_region = item_dict['language']

    resp = urlquick.get(URL_LIVES_JSON,
                        headers={'User-Agent': web_utils.get_random_ua()},
                        max_age=-1)
    json_parser = json.loads(resp.text)

    region = utils.ensure_unicode(final_region)
    id_sivideo = json_parser[LIVE_LA1ERE_REGIONS[region]]["id_sivideo"]
    return resolver_proxy.get_francetv_live_stream(plugin,
                                                   id_sivideo.split('@')[0])
Esempio n. 22
0
def get_live_url(plugin, item_id, video_id, **kwargs):

    final_region = kwargs.get('language', Script.setting['cbc.language'])
    region = utils.ensure_unicode(final_region)

    resp = urlquick.get(URL_LIVES_INFO, max_age=-1)
    url_live_stream = 'https:' + re.compile(r'LLC_URL\=r\+\"(.*?)\?').findall(
        resp.text)[0]

    headers = {'User-Agent': web_utils.get_random_ua()}
    resp2 = urlquick.get(url_live_stream, headers=headers, max_age=-1)
    json_parser = json.loads(resp2.text)

    stream_datas_url = ''
    for live_datas in json_parser["entries"]:
        if LIVE_CBC_REGIONS[region] in live_datas['cbc$callSign']:
            stream_datas_url = live_datas["content"][0]["url"]

    resp3 = urlquick.get(stream_datas_url, headers=headers, max_age=-1)
    return re.compile(r'video src\=\"(.*?)\"').findall(resp3.text)[0]
Esempio n. 23
0
def get_live_url(plugin, item_id, video_id, item_dict, **kwargs):
    final_language = Script.setting['tvp3.language']

    # If we come from the M3U file and the language
    # is set in the M3U URL, then we overwrite
    # Catch Up TV & More language setting
    if type(item_dict) is not dict:
        item_dict = eval(item_dict)
    if 'language' in item_dict:
        final_language = item_dict['language']

    resp = urlquick.get(URL_LIVE,
                        headers={'User-Agent': web_utils.get_random_ua()},
                        max_age=-1)
    root = resp.parse()

    live_id = ''
    for live_datas in root.findall(".//div"):
        if live_datas.get('data-stationname') is not None:
            if item_id == 'tvpinfo':
                if 'info' in live_datas.find('.//img').get('alt'):
                    live_id = live_datas.get('data-video-id')
            elif item_id == 'tvppolonia':
                if 'Polonia' in live_datas.get('data-title'):
                    live_id = live_datas.get('data-video-id')
            elif item_id == 'tvppolandin':
                if 'News and entertainment' in live_datas.get('data-title'):
                    live_id = live_datas.get('data-video-id')
            elif item_id == 'tvp3':
                if LIVE_TVP3_REGIONS[utils.ensure_unicode(
                        final_language)] in live_datas.find('.//img').get(
                            'alt'):
                    live_id = live_datas.get('data-video-id')
    if live_id == '':
        # Add Notification
        return False
    lives_html = urlquick.get(
        URL_STREAM % live_id,
        headers={'User-Agent': web_utils.get_random_ua()},
        max_age=-1)
    return re.compile(r'src:\'(.*?)\'').findall(lives_html.text)[0]
Esempio n. 24
0
def list_programs(plugin, item_id):
    """
    Build categories listing
    - Tous les programmes
    - Séries
    - Informations
    - ...
    """
    region = utils.ensure_unicode(Script.setting['france3.region'])
    region = LIVE_FR3_REGIONS[region]
    resp = urlquick.get(URL_JT_JSON % region)
    json_parser = json.loads(resp.text).keys()

    for list_jt_name in json_parser:
        if list_jt_name != 'mea':
            item = Listitem()
            item.label = list_jt_name
            item.set_callback(list_videos,
                              item_id=item_id,
                              list_jt_name=list_jt_name)
            yield item
Esempio n. 25
0
    def __create_playlist(self, urls):
        """
        Create playlist for kodi and return back the first item of that playlist to play.

        :param list urls: Set of urls that will be used in the creation of the playlist.
                          List may consist of url or listitem object.

        :returns The first listitem of the playlist.
        :rtype: xbmcgui.ListItem
        """
        # Create Playlist
        playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
        title = self._title

        # Loop each item to create playlist
        for count, url in enumerate(filter(None, urls), 1):
            # Kodi original listitem object
            if isinstance(url, xbmcgui.ListItem):
                listitem = url
            # Custom listitem object
            elif isinstance(url, Listitem):
                # noinspection PyProtectedMember
                listitem = url._close()[1]
            else:
                # Not already a listitem object
                listitem = xbmcgui.ListItem()
                if isinstance(url, (list, tuple)):
                    title, url = url
                    title = ensure_unicode(title)

                # Create listitem with new title
                listitem.setLabel(u"%s Part %i" % (title, count))
                listitem.setPath(url)

            # Populate Playlis
            playlist.add(listitem.getPath(), listitem)

        # Return the first playlist item
        return playlist[0]
def list_videos(plugin, item_id, list_jt_name):

    region = utils.ensure_unicode(Script.setting['la_1ere.region'])
    region = LIVE_LA1ERE_REGIONS[region]
    resp = urlquick.get(URL_JT_JSON % region)
    json_parser = json.loads(resp.text)

    for video_datas in json_parser[list_jt_name]:
        video_title = video_datas["titre"] + ' - ' + video_datas["date"]
        video_image = video_datas["url_image"]
        id_diffusion = video_datas["id"]
        date_value = video_datas["date"].split(' ')
        day = date_value[1]
        try:
            month = CORRECT_MONTH[date_value[2]]
        except Exception:
            month = '00'
        year = date_value[3]
        date_value = '-'.join((year, month, day))

        item = Listitem()
        item.label = video_title
        item.art['thumb'] = video_image
        item.info.date(date_value, '%Y-%m-%d')

        item.context.script(
            get_video_url,
            plugin.localize(LABELS['Download']),
            item_id=item_id,
            id_diffusion=id_diffusion,
            video_label=LABELS[item_id] + ' - ' + item.label,
            download_mode=True)

        item.set_callback(
            get_video_url,
            item_id=item_id,
            id_diffusion=id_diffusion,
            item_dict=cqu.item2dict(item))
        yield item
def download_video(video_url):
    """Callback function of the 'Download' context menu

    Args:
        video_url (str): URL of the video to download
    """

    #  print('URL Video to download ' + video_url)

    #  Now that we have video URL we can try to download this one

    YDStreamExtractor = __import__('YDStreamExtractor')

    info = {'url': video_url, 'quality': get_quality_YTDL(download_mode=True)}

    path = ensure_unicode(Script.setting.get_string('dl_folder'))
    filename = ''
    if Script.setting.get_boolean('dl_item_filename'):
        filename = get_selected_item_label()
    bg = Script.setting.get_boolean('dl_background')
    YDStreamExtractor.handleDownload(info, bg=bg, path=path, filename=filename)

    return False
def get_item_label(item_id, item_infos={}, append_selected_lang=True):
    """Get (translated) label of 'item_id'

    Args:
        item_id (str)
        item_infos (dict): Information from the skeleton 'menu' dict
        append_selected_lang (bool, optional): Append selected language by the user in the label
    Returns:
        str: (translated) label of 'item_id'
    """
    if 'label' in item_infos:
        label = item_infos['label']
    else:
        label = item_id

    if isinstance(label, int):
        label = Script.localize(label)

    if append_selected_lang and 'available_languages' in item_infos:
        label = '{} ({})'.format(
            label,
            utils.ensure_unicode(
                Script.setting['{}.language'.format(item_id)]))
    return label
Esempio n. 29
0
 def __setitem__(self, key, value):  # type: (str, str) -> None
     if value:
         self.raw_dict[key] = ensure_unicode(value)
     else:
         logger.debug("Ignoring empty property: '%s'", key)
Esempio n. 30
0
     'order': 4
 },
 'tva': {
     'route': '/resources/lib/channels/ca/tva:tva_root',
     'label': 'TVA',
     'thumb': 'channels/ca/tva.png',
     'fanart': 'channels/ca/tva_fanart.jpg',
     'enabled': True,
     'order': 5
 },
 'icitele': {
     'route':
     '/resources/lib/channels/ca/icitele:list_programs',
     'label':
     'ICI Télé (' +
     utils.ensure_unicode(Script.setting['icitele.language']) + ')',
     'thumb':
     'channels/ca/icitele.png',
     'fanart':
     'channels/ca/icitele_fanart.jpg',
     'enabled':
     True,
     'order':
     6
 },
 'icitoutv': {
     'route': '/resources/lib/channels/ca/icitoutv:list_categories',
     'label': 'ICI Tou.tv',
     'thumb': 'channels/ca/icitoutv.png',
     'fanart': 'channels/ca/icitoutv_fanart.jpg',
     'enabled': True,
Esempio n. 31
0
 def __setitem__(self, key, value):
     if value:
         self.raw_dict[key] = ensure_unicode(value)
     else:
         logger.debug("Ignoring empty property: '%s'", key)
Esempio n. 32
0
from codequick import Script, utils

# The following dictionaries describe
# the addon's tree architecture.
# * Key: item id
# * Value: item infos
#     - route (folder)/resolver (playable URL): Callback function to run once this item is selected
#     - thumb: Item thumb path relative to "media" folder
#     - fanart: Item fanart path relative to "media" folder

root = 'live_tv'

menu = {
    'euronews': {
        'resolver': '/resources/lib/channels/wo/euronews:get_live_url',
        'label': 'Euronews (' + utils.ensure_unicode(Script.setting['euronews.language']) + ')',
        'thumb':
        'channels/wo/euronews.png',
        'fanart':
        'channels/wo/euronews_fanart.jpg',
        'available_languages': [
            'FR', 'EN', 'AR', 'DE', 'IT', 'ES', 'PT', 'RU', 'TR', 'FA', 'GR',
            'HU'
        ],
        'enabled': True,
        'order': 2
    },
    'arte': {
        'resolver': '/resources/lib/channels/wo/arte:get_live_url',
        'label': 'Arte (' + utils.ensure_unicode(Script.setting['arte.language']) + ')',
        'thumb': 'channels/wo/arte.png',
def get_sorted_menu(plugin, menu_id):
    """Get ordered 'menu_id' menu without disabled and hidden items

    Args:
        plugin (codequick.script.Script)
        menu_id (str): Menu to get (e.g. root)
    Returns:
        list<tuple> List of items (item_order, item_id, item_infos)
    """

    # The current menu to build contains
    # all the items present in the 'menu_id'
    # skeleton file
    current_menu = importlib.import_module('resources.lib.skeletons.' +
                                           menu_id).menu

    # Notify user for the new M3U Live TV feature
    if menu_id == "live_tv" and \
            get_kodi_version() >= 18 and \
            plugin.setting.get_boolean('show_live_tv_m3u_info'):

        r = xbmcgui.Dialog().yesno(plugin.localize(30600),
                                   plugin.localize(30605),
                                   plugin.localize(30606))
        if not r:
            plugin.setting['show_live_tv_m3u_info'] = False

    # Keep in memory the first menu taken
    # in order to provide a prefix when the user
    # add a favourite
    fav.guess_fav_prefix(menu_id)

    # First, we have to sort the current menu items
    # according to each item order and we have
    # to hide each disabled item
    menu = []
    for item_id, item_infos in list(current_menu.items()):

        add_item = True

        # If the item is disabled in skeleton file
        # (e.g. if a channel is not available anymore)
        if item_infos['enabled'] is False:
            add_item = False

        # If the item is hidden by the user setting
        if is_item_hidden(item_id, menu_id):
            add_item = False

        # If the desired language is not available
        if 'available_languages' in item_infos:
            desired_language = utils.ensure_unicode(Script.setting[item_id + '.language'])
            if desired_language not in item_infos['available_languages']:
                add_item = False

        if add_item:
            item_order = get_item_order(item_id, menu_id, item_infos)

            item = (item_order, item_id, item_infos)

            menu.append(item)

    # We sort the menu according to the item_order values
    return sorted(menu, key=lambda x: x[0])