def login_wrapper(*args, **kwargs):

        with PersistentDict("creds") as db:
            username = db.get("username")
            password = db.get("password")

        # token is 5 days old ?
        with PersistentDict("headers") as db:
            headers = db.get("headers")
        if headers:
            return func(*args, **kwargs)
        elif username and password:
            login(username, password)
            return func(*args, **kwargs)
        else:
            Script.notify(
                'Login Error',
                'You need to login with Jio Username and password to use this add-on'
            )
            executebuiltin(
                "RunPlugin(plugin://plugin.video.jiotv/resources/lib/main/login/)"
            )
            return False
    def resolveKey(self):
        global headers
        key = self.path.split('/')[-1]
        effective_url = "https://tv.media.jio.com/streams_live/{0}/{1}".format(
            self.channel_name, key)
        if not headers:
            headers = utils.getHeaders()
        resp = ChannelRequestHandler.make_requests(
            effective_url, headers, max_age=urlquick.MAX_AGE)

        if resp.status_code == 411 or resp.status_code == 451:
            Script.notify(
                "Error", "JioTV can not be accessed from outside India")
            self.proxy.send_error(resp.status_code)
        elif resp.status_code >= 400:
            self.proxy.send_error(resp.status_code)
        else:
            self.proxy.send_response(resp.status_code, 'OK')
            self.proxy.send_header('Content-Type', 'application/octet-stream')
            self.proxy.send_header('Connection', 'keep-alive')
            self.proxy.send_header('Content-Length', len(resp.content))
            self.proxy.end_headers()
            self.proxy.wfile.write(resp.content)
def import_needed_module():
    # Import needed module according to the
    # base URL and query string (Fix for Kodi favorite item and search)
    modules_to_import = [get_module_in_url(sys.argv[0])]
    if 'codequick/search' in sys.argv[0]:
        modules_to_import.append(get_module_in_query(sys.argv[2]))
    for module_to_import in modules_to_import:
        if module_to_import == '':
            # No additionnal module to load
            continue

        # Need to load additional module
        try:
            Script.log(
                '[cq_utils.import_needed_module] Import module {} on the fly'.
                format(module_to_import),
                lvl=Script.INFO)
            importlib.import_module(module_to_import)
        except Exception:
            Script.log(
                '[cq_utils.import_needed_module] Failed to import module {} on the fly'
                .format(module_to_import),
                lvl=Script.WARNING)
Beispiel #4
0
def get_item_label(item_id):
    """Get (translated) label of 'item_id'

    Args:
        item_id (str)
    Returns:
        str: (translated) label of 'item_id'
    """
    label = item_id
    if item_id in LABELS:
        label = LABELS[item_id]
        if isinstance(label, int):
            label = Script.localize(label)
    return label
def item_post_treatment(item, is_playable=False, is_downloadable=False):
    """Add needed context menus to 'item'

    Args:
        is_playable (bool): If 'item' is playable
        is_downloadable (bool): If 'item' is downloadable
    Returns:
        str: (translated) label of 'item_id'
    """

    # Add `Download` context menu to 'item' if 'item' is downloadable
    if is_downloadable:
        item.context.script(item.path,
                            Script.localize(30503),
                            download_mode=True,
                            **item.params)

    # Add `Add to add-on favourites` context menu to 'item'
    item.context.script(fav.add_item_to_favourites,
                        Script.localize(30800),
                        is_playable=is_playable)

    return
Beispiel #6
0
def migrate_from_pickled_fav():
    """
    This function moves existing pickled favourites in
    the new json file used for the favourites.
    The new format (json) appeared in 0.2.17~beta04
    All user with version >= 0.2.17 will use favourites in the JSON format
    Maybe we can remove the migration check on version 0.2.20?
    """

    # Move all pickled existing favs in json file
    fav_pickle_fp = os.path.join(Script.get_info('profile'),
                                 "favourites.pickle")
    if xbmcvfs.exists(fav_pickle_fp):
        Script.log('Start favourites migration from pickle file to json file')
        new_fav_dict = {}
        with storage.PersistentDict("favourites.pickle") as db:
            new_fav_dict = dict(db)
        # Fix old fav
        for item_hash, item_dict in new_fav_dict.items():
            if 'params' in item_dict and isinstance(item_dict['params'],
                                                    listing.Params):
                new_fav_dict[item_hash]['params'] = dict(
                    new_fav_dict[item_hash]['params'])
                try:
                    del new_fav_dict[item_hash]['params']['item_dict'][
                        'params']
                except Exception:
                    pass
            if 'properties' in item_dict:
                if isinstance(item_dict['properties'], listing.Property):
                    new_fav_dict[item_hash]['properties'] = dict(
                        new_fav_dict[item_hash]['properties'])
        fav_json_fp = os.path.join(Script.get_info('profile'),
                                   "favourites.json")
        with open(fav_json_fp, 'w') as f:
            json.dump(new_fav_dict, f, indent=4)
        xbmcvfs.delete(fav_pickle_fp)
def grab_programmes(country_id, day_delta):
    """Retrieve programmes of channels of country_id at day today + day_detla.

    Args:
        country_id (str)
        day_delta (int)
    Returns:
        list: Programmes.
    """
    if country_id not in xmltv_infos:
        return []
    try:
        # Download, if needed, xmltv file
        xmltv_fp = download_xmltv_file(country_id, day_delta=day_delta)

        # Grab programmes in xmltv file
        programmes = read_programmes(xmltv_fp, only_current_programmes=False)
        programmes_post_treated = []
        for programme in programmes:
            programmes_post_treated.append(programme_post_treatment_iptvmanager(programme))
        return programmes_post_treated
    except Exception as e:
        Script.log('xmltv module failed with error: {}'.format(e), lvl=Script.ERROR)
        return []
Beispiel #8
0
def get_video_url(plugin,
                  item_id,
                  next_url,
                  download_mode=False,
                  video_label=None):

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

    if json_parser["detail"]["informations"]['consumptionPlatform'] == 'HAPI':
        Script.notify("INFO", plugin.localize(LABELS['drm_notification']),
                      Script.NOTIFY_INFO)
        return False

    stream_url = ''
    for stream_datas in json_parser["detail"]["informations"]["videoURLs"]:
        if stream_datas["encryption"] == 'clear':
            stream_url = stream_datas["videoURL"]

    if download_mode:
        return download.download_video(stream_url, video_label)
    return stream_url
Beispiel #9
0
 def buildPlay(self, playbackUrl, licenceUrl=None, playbackProto="mpd", label="", drm=False):
     is_helper = inputstreamhelper.Helper("mpd", drm=drm)
     if is_helper.check_inputstream():
         stream_headers = HotstarAPI._getPlayHeaders(
             playbackUrl=playbackUrl)
         subtitleUrl = re.sub(
             "(.*)(master[\w+\_\-]*?\.[\w+]{3})([\w\/\?=~\*\-]*)", "\g<1>subtitle/lang_en/subtitle.vtt\g<3>", playbackUrl) + "|User-Agent=Hotstar%3Bin.startv.hotstar%2F3.3.0+%28Android%2F8.1.0%29"
         Script.log(subtitleUrl, lvl=Script.DEBUG)
         if licenceUrl and "/hms/wv/" in licenceUrl:
             drm = "com.widevine.alpha"
         return Listitem().from_dict(**{
             "label": label,
             "callback": playbackUrl,
             "properties": {
                 "IsPlayable": True,
                 "inputstream": is_helper.inputstream_addon,
                 "inputstream.adaptive.manifest_type": playbackProto,
                 "inputstream.adaptive.license_type": drm,
                 "inputstream.adaptive.stream_headers": urlencode(stream_headers),
                 "inputstream.adaptive.license_key": licenceUrl and licenceUrl + '|%s&Content-Type=application/octet-stream|R{SSM}|' % urlencode(stream_headers)
             },
             "subtitles": [subtitleUrl]
         })
     return False
    def getM3U8(self):
        m3u8 = self.path.split('/')[-1]
        effective_url = "{4}{0}/{1}{2}/{3}".format(
            self.hlsrx, self.channel_name,  '_HLS' if self.ishls else '', m3u8, SERVER)
        resp = ChannelRequestHandler.make_requests(effective_url)
        if resp.status_code == 411 or resp.status_code == 451:
            Script.notify(
                "Error", "JioTV can not be accessed from outside India")
            self.proxy.send_error(resp.status_code)
        else:
            if self.ishls:
                resp_text = self.refine(resp.text, quality=m3u8[:1])
            else:
                rq = int(re.search('(.*?_)(\d+)\.m3u8', m3u8).group(2))
                quality = rq >= self.maxq and self.maxq
                resp_text = self.refine(resp.text, quality)

            self.proxy.send_response(resp.status_code, 'OK')
            resp.headers.pop("Content-Length")
            for k, v in resp.headers.items():
                self.proxy.send_header(k, v)
            self.proxy.send_header('Content-Length', len(resp_text))
            self.proxy.end_headers()
            self.proxy.wfile.write(resp_text)
Beispiel #11
0
 def _findPlayback(playBackSets, encryption="widevine"):
     for each in playBackSets:
         Script.log("Checking combination %s for encryption %s" %
                    (each.get("tagsCombination"), encryption),
                    lvl=Script.DEBUG)
         if re.match(
                 ".*?encryption:%s.*?(ladder:tv)?.*?package:dash.*" %
                 encryption, each.get("tagsCombination")):
             Script.log(
                 "Found Stream! URL : %s LicenceURL: %s Encryption: %s" %
                 (each.get("playbackUrl"), each.get("licenceUrl"),
                  encryption),
                 lvl=Script.DEBUG)
             return (each.get("playbackUrl"), each.get("licenceUrl"), "mpd")
         elif re.match(
                 ".*?encryption:plain.*?(ladder:tv)?.*?package:dash.*",
                 each.get("tagsCombination")):
             Script.log(
                 "Found Stream! URL : %s LicenceURL: %s Encryption: %s" %
                 (each.get("playbackUrl"), each.get("licenceUrl"), "plain"),
                 lvl=Script.DEBUG)
             return (each.get("playbackUrl"), each.get("licenceUrl"), "mpd")
         elif re.match(".*?encryption:plain.*?(ladder:tv)?.*?package:hls.*",
                       each.get("tagsCombination")):
             Script.log(
                 "Found Stream! URL : %s LicenceURL: %s Encryption: %s" %
                 (each.get("playbackUrl"), each.get("licenceUrl"), "plain"),
                 lvl=Script.DEBUG)
             return (each.get("playbackUrl"), each.get("licenceUrl"), "hls")
     playbackUrl = playBackSets[0].get("playbackUrl")
     licenceUrl = playBackSets[0].get("licenceUrl")
     Script.log("No stream found for desired config. Using %s" %
                playbackUrl,
                lvl=Script.INFO)
     return (playbackUrl, licenceUrl,
             "hls" if ".m3u8" in playbackUrl else "mpd")
Beispiel #12
0
def delete_favourites(plugin):
    """
    Callback function of 'Delete favourites'
    setting button
    """

    Script.log('Delete favourites db')
    xbmcvfs.delete(
        os.path.join(Script.get_info('profile'), 'favourites.pickle'))
    Script.notify(Script.localize(30374), '')
def add_fav_context(item, item_dict, **kwargs):
    """
    Add the 'Add to add-on favourites'
    context menu to item
    """
    if kwargs.get('is_playable', False):
        item_dict['params']['is_folder'] = False
        item_dict['params']['is_playable'] = True
    else:
        item_dict['params']['is_folder'] = True
        item_dict['params']['is_playable'] = False

    item.context.script(add_item_to_favourites,
                        Script.localize(LABELS['Add to add-on favourites']),
                        item_dict=item_dict,
                        **kwargs)
Beispiel #14
0
 def _handleError(self, e, url, **kwargs):
     if e.__class__.__name__ == "ValueError":
         Script.log("Can not parse response of request url %s" % url,
                    lvl=Script.DEBUG)
         Script.notify("Internal Error", "")
     elif e.__class__.__name__ == "HTTPError":
         if e.code == 419:
             executebuiltin(
                 "RunPlugin(plugin://plugin.video.jiotvplus/resources/lib/main/login/)"
             )
         else:
             raise urlquick.HTTPError(e.filename, e.code, e.msg, e.hdrs)
     else:
         Script.log("Got unexpected response for request url %s" % url,
                    lvl=Script.DEBUG)
         Script.notify(
             "API Error",
             "Raise issue if you are continuously facing this error")
def get_item_label(item_id, item_infos={}):
    """Get (translated) label of 'item_id'

    Args:
        item_id (str)
        item_infos (dict): Information from the skeleton 'menu' dict
    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)
    return label
def grab_json_collections(plugin,
                          json_url,
                          page=0,
                          collection_position=None,
                          **kwargs):
    plugin.add_sort_methods(xbmcplugin.SORT_METHOD_UNSORTED)
    r = urlquick.get(json_url, params={'platform': 'apps', 'page': str(page)})
    j = json.loads(r.text)
    cnt = -1
    items = []
    if 'collections' in j:
        collections = j['collections']
    else:
        collections = [j]
    for collection in collections:
        cnt = cnt + 1
        next_page_item = None
        if 'cursor' in collection:
            if 'next' in collection['cursor']:
                next_ = collection['cursor']['next']
                if next_:
                    next_page_item = Listitem.next_page(
                        json_url, page=next_, collection_position=cnt)

        # If we are not in page 0, directly print items
        if collection_position is not None and cnt == collection_position:
            return list_generic_items(plugin, collection['items'],
                                      next_page_item)
        else:
            item = Listitem()
            if set_item_callback_based_on_type(item, collection['type'],
                                               collection, next_page_item):
                items.append(item)
    if 'item' in j and 'program_path' in j['item']:
        item = Listitem()
        item.label = Script.localize(30701)  # All videos
        item.set_callback(grab_json_collections,
                          URL_API_MOBILE('/generic/taxonomy/%s/contents' %
                                         j['item']['program_path']),
                          page=0,
                          collection_position=0)
        item_post_treatment(item)
        items.append(item)

    return items
Beispiel #17
0
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
    YDStreamUtils = __import__('YDStreamUtils')
    YDStreamExtractor = __import__('YDStreamExtractor')

    vid = YDStreamExtractor.getVideoInfo(
        video_url,
        quality=get_quality_YTDL(download_mode=True),
        resolve_redirects=True)

    path = Script.setting.get_string('dl_folder')
    download_ok = False
    with YDStreamUtils.DownloadProgress() as prog:
        try:
            YDStreamExtractor.setOutputCallback(prog)
            result = YDStreamExtractor.handleDownload(
                vid, bg=Script.setting.get_boolean('dl_background'), path=path)
            if result:
                if result.status == 'canceled':
                    error_message = result.message
                    Script.log('Download failed: %s' % error_message)
                else:
                    full_path_to_file = result.filepath
                    Script.log('Download success: %s' % full_path_to_file)
                    download_ok = True

        finally:
            YDStreamExtractor.setOutputCallback(None)

    if path != '' and \
            Script.setting.get_boolean('dl_item_filename') and \
            download_ok:

        try:
            filename = os.path.basename(full_path_to_file)
            _, file_extension = os.path.splitext(full_path_to_file)
            current_filepath = os.path.join(path, filename)
            video_name = get_selected_item_label()
            final_filepath = os.path.join(path, video_name + file_extension)
            xbmcvfs.rename(current_filepath, final_filepath)
        except Exception:
            Script.log('Failed to rename video file')

    return False
Beispiel #18
0
 def doLogin(self):
     with PersistentDict("userdata.pickle") as db:
         try:
             username = Settings.get_string(
                 "username",
                 "plugin.video.jiotv") or db.get("username") or Dialog(
                 ).input("Username (MobileNo / Email)")
             password = Settings.get_string(
                 "password", "plugin.video.jiotv") or db.get(
                     "password") or Dialog().input("Password")
         except RuntimeError:
             username = Dialog().input("Username (MobileNo / Email)")
             password = Dialog().input("Password")
         if username and password:
             body = {
                 "identifier":
                 username if '@' in username else "+91" + username,
                 "password": password,
                 "rememberUser": "******",
                 "upgradeAuth": "Y",
                 "returnSessionDetails": "T",
                 "deviceInfo": {
                     "consumptionDeviceName": "Jio",
                     "info": {
                         "type": "android",
                         "platform": {
                             "name": "vbox86p",
                             "version": "8.0.0"
                         },
                         "androidId": "6fcadeb7b4b10d77"
                     }
                 }
             }
             resp = urlquick.post(
                 "https://api.jio.com/v3/dip/user/unpw/verify",
                 json=body,
                 headers={
                     "x-api-key": "l7xx75e822925f184370b2e25170c5d5820a"
                 },
                 verify=False,
                 raise_for_status=False).json()
             if resp.get("ssoToken"):
                 db["data"] = resp
                 Script.notify("Login Successful",
                               "You have been logged in successfully")
             else:
                 Script.notify(
                     "Login Failed",
                     "Double check you username and password and try again")
         else:
             Script.notify("Login Required",
                           "Please login with you Jio credentials")
def clear_cache(plugin):
    # Callback function of clear cache setting button

    # Clear urlquick cache
    urlquick.cache_cleanup(-1)
    Script.notify(plugin.localize(30371), '')

    # Remove all tv guides
    dirs, files = xbmcvfs.listdir(Script.get_info('profile'))
    for fn in files:
        if '.xml' in fn and fn != 'settings.xml':
            Script.log('Remove xmltv file: {}'.format(fn))
            xbmcvfs.delete(os.path.join(Script.get_info('profile'), fn))
Beispiel #20
0
def item_post_treatment(item, **kwargs):
    """
    Optional keyworded arguments:
    - is_playable (bool) (default: False)
    - is_downloadable (bool) (default: False)
    """

    # Add `Download` context menu to the item
    # if is_downloadable is given and True
    if kwargs.get('is_downloadable', False):
        item.context.script(item.path,
                            Script.localize(LABELS['Download']),
                            download_mode=True,
                            **item.params)

    # Add `Add to favourites` context menu to the item
    add_fav_context(item, item2dict(item), **kwargs)

    return
def save_tv_integration_settings(j):
    """Save tv integration settings dict in json file

    Args:
        j (dict): Tv integration dict to save
    """
    try:
        with open(TV_INTEGRATION_SETTINGS_FP, 'w') as f:
            json.dump(j, f, indent=4)
    except Exception as e:
        Script.notify(Script.localize(30270), Script.localize(30276))
        Script.log('Failed to save TV integration settings (%s)',
                   e,
                   lvl=Script.ERROR)
Beispiel #22
0
def import_ovpn(*args, **kwargs):
    path = xbmcgui.Dialog().browse(
        1,
        Script.localize(LABELS['Import OpenVPN configuration file']),
        'files',
        mask='.ovpn|.conf',
        enableMultiple=False)

    if path and os.path.exists(path) and os.path.isfile(path):
        Script.log('OpenVPN: Import: [%s]' % path)

        keyboard = xbmc.Keyboard(
            default='',
            heading=Script.localize(
                LABELS['Choose a name for OpenVPN configuration']),
            hidden=False)
        keyboard.doModal()
        if keyboard.isConfirmed() and len(keyboard.getText()) > 0:
            name = keyboard.getText()

            ovpnfiles = {}
            with storage.PersistentDict('vpn') as db:
                ovpnfiles = db['ovpnfiles']
                db.flush()

            if name in ovpnfiles and not xbmcgui.Dialog().yesno(
                    'OpenVPN',
                    Script.localize(LABELS[
                        'This OpenVPN configuration name already exists. Overwrite?']
                                    )):
                xbmcgui.Dialog().ok(
                    'OpenVPN', Script.localize(LABELS['Import cancelled']))

            else:
                ovpnfiles[name] = path
                with storage.PersistentDict('vpn') as db:
                    db['ovpnfiles'] = ovpnfiles
                    db.flush()
        else:
            xbmcgui.Dialog().ok(
                'OpenVPN',
                Script.localize(LABELS[
                    'Import failed. You must specify a name for the OpenVPN configuration']
                                ))
def get_quality_YTDL(download_mode=False):
    """Get YoutTubeDL quality setting

    Args:
        download_mode (bool)
    Returns:
        int: YoutTubeDL quality
    """

    # If not download mode get the 'quality' setting
    if not download_mode:
        quality = Script.setting.get_string('quality')
        if quality == 'BEST':
            return 3

        if quality == 'DEFAULT':
            return 3

        if quality == 'DIALOG':
            youtubeDL_qualiy = ['SD', '720p', '1080p', 'Highest Available']
            selected_item = xbmcgui.Dialog().select(Script.localize(30709),
                                                    youtubeDL_qualiy)
            return selected_item

        return 3

    # Else we need to use the 'dl_quality' setting
    dl_quality = Script.setting.get_string('dl_quality')
    if dl_quality == 'SD':
        return 0

    if dl_quality == '720p':
        return 1

    if dl_quality == '1080p':
        return 2

    if dl_quality == 'Highest available':
        return 3

    return 3
Beispiel #24
0
def geoip():
    """Get country code based on IP address

    Returns:
        str: Country code (e.g. FR)
    """
    # better service - https://geoftv-a.akamaihd.net/ws/edgescape.json
    try:
        resp = urlquick.get('https://geoftv-a.akamaihd.net/ws/edgescape.json', max_age=-1)
        data = json.loads(resp.text)
        if 'reponse' in data:
            return data['reponse']['geo_info']['country_code']
    except Exception:
        pass
    Script.notify(Script.get_info('name'), Script.localize(30724), icon=Script.NOTIFY_WARNING)
    Script.log('Failed to get country code based on IP address', lvl=Script.WARNING)
    return None
Beispiel #25
0
def delete_ovpn(*args, **kwargs):
    ovpnfiles = {}
    with storage.PersistentDict('vpn') as db:
        try:
            ovpnfiles = db['ovpnfiles']
        except KeyError:
            db['ovpnfiles'] = ovpnfiles
        db.flush()

    if len(ovpnfiles) == 0:
        return None

    else:
        response = vpnlib.is_running(ip, port)
        Script.log('OpenVPN: Response from is_running: [%s] [%s] [%s]' %
                   (response[0], response[1], response[2]))
        if response[0]:
            # Le VPN est connecté
            Script.log('OpenVPN: VPN still connected, we disconnect it')
            disconnect_openvpn()

        configs = []
        ovpnfileslist = []
        for name, configfilepath in list(ovpnfiles.items()):
            configs.append(name)
            ovpnfileslist.append(configfilepath)

        idx = xbmcgui.Dialog().select(
            Script.localize(LABELS['Select OpenVPN configuration to delete']),
            configs)
        if idx >= 0:
            Script.log('Select: [%s]' % ovpnfileslist[idx])
            new_ovpnfiles = {}
            for name, configfilepath in list(ovpnfiles.items()):
                if configfilepath != ovpnfileslist[idx]:
                    new_ovpnfiles[name] = configfilepath
            with storage.PersistentDict('vpn') as db:
                db['ovpnfiles'] = new_ovpnfiles
                db.flush()
        else:
            return ''
Beispiel #26
0
 def _findPlayback(playBackSets, encryption="widevine"):
     for each in playBackSets:
         Script.log("Checking combination: %s" %
                    each.get("tagsCombination"),
                    lvl=Script.DEBUG)
         if re.search(
                 "encryption:%s.*?ladder:tv.*?package:dash" % encryption,
                 each.get("tagsCombination")):
             Script.log("Found Stream! URL : %s LicenceURL: %s" %
                        (each.get("playbackUrl"), each.get("licenceUrl")),
                        lvl=Script.DEBUG)
             return (each.get("playbackUrl"), each.get("licenceUrl"), "mpd")
     playbackUrl = playBackSets[0].get("playbackUrl")
     Script.log("No stream found for desired config. Using %s" %
                playbackUrl,
                lvl=Script.DEBUG)
     return (playbackUrl, None,
             "hls" if "master.m3u8" in playbackUrl else "mpd")
Beispiel #27
0
def import_ovpn(*args, **kwargs):
    path = xbmcgui.Dialog().browse(
        1,
        Script.localize(30342),
        'files',
        mask='.ovpn|.conf',
        enableMultiple=False)

    if path and os.path.exists(path) and os.path.isfile(path):
        Script.log('OpenVPN: Import: [%s]' % path)

        keyboard = xbmc.Keyboard(
            default='',
            heading=Script.localize(30348),
            hidden=False)
        keyboard.doModal()
        if keyboard.isConfirmed() and len(keyboard.getText()) > 0:
            name = keyboard.getText()

            ovpnfiles = {}
            with storage.PersistentDict('vpn') as db:
                ovpnfiles = db['ovpnfiles']
                db.flush()

            if name in ovpnfiles and not xbmcgui.Dialog().yesno(
                    'OpenVPN',
                    Script.localize(30349)):
                xbmcgui.Dialog().ok(
                    'OpenVPN', Script.localize(30350))

            else:
                ovpnfiles[name] = path
                with storage.PersistentDict('vpn') as db:
                    db['ovpnfiles'] = ovpnfiles
                    db.flush()
        else:
            xbmcgui.Dialog().ok(
                'OpenVPN',
                Script.localize(30351))
def get_item_media_path(item_media_path):
    """Get full path or URL of an item_media

    Args:
        item_media_path (str or list): Partial media path of the item (e.g. channels/fr/tf1.png)
    Returns:
        str: Full path or URL of the item_pedia
    """
    full_path = ''

    # Local image in ressources/media folder
    if type(item_media_path) is list:
        full_path = os.path.join(Script.get_info("path"), "resources", "media",
                                 *(item_media_path))

    # Remote image with complete URL
    elif 'http' in item_media_path:
        full_path = item_media_path

    # Image in our resource.images add-on
    else:
        full_path = 'resource://resource.images.catchuptvandmore/' + item_media_path

    return utils.ensure_native_str(full_path)
def get_item_media_path(item_media_path):
    """Get full path or URL of an item_media

    Args:
        item_media_path (str or list): Partial media path of the item (e.g. channels/fr/tf1.png)
    Returns:
        str: Full path or URL of the item_pedia
    """
    full_path = ''

    # Local image in ressources/media folder
    if type(item_media_path) is list:
        full_path = os.path.join(Script.get_info("path"), "resources", "media",
                                 *(item_media_path))

    # Remote image with complete URL
    elif 'http' in item_media_path:
        full_path = item_media_path

    # Remote image on our images repo
    else:
        full_path = 'https://github.com/Catch-up-TV-and-More/images/raw/master/' + item_media_path

    return utils.ensure_native_str(full_path)
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