def grab_tv_guide(menu_id, menu):
    xmltv_url = get_xmltv_url(menu_id)
    Script.log('xmltv url of {}: {}'.format(menu_id, xmltv_url))

    xmltv_fn = os.path.basename(urlparse(xmltv_url).path)
    Script.log('xmltv filename of {}: {}'.format(menu_id, xmltv_fn))

    xmltv_fp = os.path.join(Script.get_info('profile'), xmltv_fn)

    # Remove old xmltv files of this country
    dirs, files = xbmcvfs.listdir(Script.get_info('profile'))
    for fn in files:
        if xmltv_infos[menu_id]['keyword'] in fn and fn != xmltv_fn:
            Script.log('Remove old xmltv file: {}'.format(fn))
            xbmcvfs.delete(os.path.join(Script.get_info('profile'), fn))

    # Check if we need to download a fresh xmltv file
    if not xbmcvfs.exists(xmltv_fp):
        Script.log("xmltv file of {} for today does not exist, let's download it".format(menu_id))
        r = urlquick.get(xmltv_url)
        with open(xmltv_fp, 'wb') as f:
            f.write(r.content)

    # Grab programmes in xmltv file
    programmes = read_current_programmes(xmltv_fp)

    # Use the channel as key
    tv_guide = {}
    for programme in programmes:
        programme = programme_post_treatment(programme)
        tv_guide[programme['channel']] = programme

    return tv_guide
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)
Example #3
0
def reset_artwork():
    ''' Remove all existing texture.
    '''
    thumbnails = xbmc.translatePath('special://thumbnails/')

    if xbmcvfs.exists(thumbnails):
        dirs, ignore = xbmcvfs.listdir(thumbnails)

        for directory in dirs:
            ignore, thumbs = xbmcvfs.listdir(
                os.path.join(thumbnails, directory))

            for thumb in thumbs:
                LOG.debug("DELETE thumbnail %s", thumb)
                xbmcvfs.delete(os.path.join(thumbnails, directory, thumb))

    with Database('texture') as texdb:
        texdb.cursor.execute(
            "SELECT tbl_name FROM sqlite_master WHERE type='table'")

        for table in texdb.cursor.fetchall():
            name = table[0]

            if name != 'version':
                texdb.cursor.execute("DELETE FROM " + name)

    LOG.info("[ reset artwork ]")
Example #4
0
def get_fav_dict_from_json():
    """Get favourites dict from favourites.json

    Returns:
        dict: Favourites dict
    """

    def get_fresh_dict():
        return {
            'items': {},
            'format_version': FAV_FORMAT_VERSION
        }

    if not xbmcvfs.exists(FAV_JSON_FP):
        return get_fresh_dict()
    try:
        with open(FAV_JSON_FP) as f:
            fav_dict = json.load(f)
            current_fav_format = fav_dict.get('format_version', 0)
            if current_fav_format < FAV_FORMAT_VERSION:
                fav_dict = migrate_fav_format(current_fav_format, fav_dict)
            return fav_dict
    except Exception:
        Script.log('Failed to load favourites json data')
        xbmcvfs.delete(FAV_JSON_FP)
        return get_fresh_dict()
Example #5
0
 def _get_database(self):
     '''get reference to our sqllite _database - performs basic integrity check'''
     addon = xbmcaddon.Addon(ADDON_ID)
     dbpath = addon.getAddonInfo('profile')
     dbfile = xbmc.translatePath("%s/simplecache.db" % dbpath)
     if not xbmcvfs.exists(dbpath):
         xbmcvfs.mkdirs(dbpath)
     del addon
     try:
         connection = sqlite3.connect(dbfile,
                                      timeout=30,
                                      isolation_level=None)
         connection.execute('SELECT * FROM simplecache LIMIT 1')
         return connection
     except Exception as error:
         # our _database is corrupt or doesn't exist yet, we simply try to recreate it
         if xbmcvfs.exists(dbfile):
             xbmcvfs.delete(dbfile)
         try:
             connection = sqlite3.connect(dbfile,
                                          timeout=30,
                                          isolation_level=None)
             connection.execute("""CREATE TABLE IF NOT EXISTS simplecache(
                 id TEXT UNIQUE, expires INTEGER, data TEXT, checksum INTEGER)"""
                                )
             return connection
         except Exception as error:
             self._log_msg(
                 "Exception while initializing _database: %s" % str(error),
                 xbmc.LOGWARNING)
             self.close()
             return None
Example #6
0
def download_xmltv_file(country_id, day_delta=0):
    """Try to download XMLTV file of country_id for today + day_delta.

    Args:
        country_id (str)
        day_delta (int): 0: Today, 1: Tomorrow,...
    Returns:
        str: xmltv filepath.
    """
    # Retrieve URL
    xmltv_url = get_xmltv_url(country_id, day_delta=day_delta)
    Script.log('xmltv url of {} country with day_delta {}: {}'.format(
        country_id, day_delta, xmltv_url))

    # Compute dst filepath
    xmltv_fn = os.path.basename(urlparse(xmltv_url).path)
    Script.log('xmltv filename: {}'.format(xmltv_fn))
    xmltv_fp = os.path.join(Script.get_info('profile'), xmltv_fn)

    # Remove old xmltv files of this country
    dirs, files = xbmcvfs.listdir(Script.get_info('profile'))
    today = datetime.date.today()
    for fn in files:
        if xmltv_infos[country_id]['keyword'] not in fn:
            continue
        try:
            file_date_s = fn.split(
                xmltv_infos[country_id]['keyword'])[1].split('.xml')[0]
            file_date = datetime_strptime(file_date_s, '%Y%m%d').date()
            if file_date < today:
                Script.log('Remove old xmltv file: {}'.format(fn))
                xbmcvfs.delete(os.path.join(Script.get_info('profile'), fn))
        except Exception:
            pass

    # Check if we need to download a fresh xmltv file
    need_to_downlod_xmltv_file = False
    if not xbmcvfs.exists(xmltv_fp):
        Script.log(
            "xmltv file of {} for today does not exist, let's download it".
            format(country_id))
        need_to_downlod_xmltv_file = True
    else:
        # Check if we have the last version of the file
        current_file_md5 = compute_md5(xmltv_fp)
        remote_file_md5 = get_remote_xmltv_md5(country_id, day_delta=day_delta)
        print(current_file_md5)
        print(remote_file_md5)
        if current_file_md5 != remote_file_md5:
            Script.log(
                "A new version of xmltv file of {} for today exists, let's download it"
                .format(country_id))
            need_to_downlod_xmltv_file = True

    if need_to_downlod_xmltv_file:
        r = urlquick.get(xmltv_url, max_age=-1)
        with open(xmltv_fp, 'wb') as f:
            f.write(r.content)
    return xmltv_fp
Example #7
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), '')
Example #8
0
def remLoginData(info=True):
    xbmcvfs.delete(CookieFile)
    writeConfig('accounts', '')
    writeConfig('login_name', '')
    writeConfig('login_pass', '')

    if info:
        var.addon.setSetting('login_acc', '')
        writeConfig('accounts.lst', '')
        Dialog.notification(pluginname, getString(30211), xbmcgui.NOTIFICATION_INFO)
Example #9
0
 def remove_widevine(self):
     """Removes Widevine CDM"""
     widevinecdm = self._widevine_path()
     if widevinecdm and xbmcvfs.exists(widevinecdm):
         log('Remove Widevine CDM at {path}', path=widevinecdm)
         xbmcvfs.delete(widevinecdm)
         xbmcgui.Dialog().notification(localize(30037), localize(30052))  # Success! Widevine successfully removed.
         return True
     xbmcgui.Dialog().notification(localize(30004), localize(30053))  # Error. Widevine CDM not found.
     return False
Example #10
0
def delete_recursive(path, dirs):
    ''' Delete files and dirs recursively.
    '''
    for directory in dirs:
        dirs2, files = xbmcvfs.listdir(os.path.join(path, directory))

        for file in files:
            xbmcvfs.delete(os.path.join(path, directory, file))

        delete_recursive(os.path.join(path, directory), dirs2)
        xbmcvfs.rmdir(os.path.join(path, directory))
Example #11
0
def nuke():

    if not (xbmcgui.Dialog().yesno("IPTV Archive Downloader",
                                   addon.getLocalizedString(30057))):
        return

    xbmcvfs.delete(
        xbmc.translatePath('%sxmltv.db' %
                           plugin.addon.getAddonInfo('profile')))
    time.sleep(5)
    full_service()
Example #12
0
def nuke():

    if not (xbmcgui.Dialog().yesno(
            "IPTV Archive Downloader",
            get_string("Delete Everything and Start Again?"))):
        return

    xbmcvfs.delete(
        xbmc.translatePath('%sxmltv.db' %
                           plugin.addon.getAddonInfo('profile')))
    time.sleep(5)
    full_service()
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))
Example #14
0
def writeConfig(cfile, value=''):
    cfgfile = os.path.join(configpath, cfile)
    cfglockfile = os.path.join(configpath, cfile + '.lock')

    if not xbmcvfs.exists(configpath):
        xbmcvfs.mkdirs(configpath)

    while True:
        if not xbmcvfs.exists(cfglockfile):
            l = xbmcvfs.File(cfglockfile, 'w')
            l.write(str(time.time()))
            l.close()
            if value == '':
                xbmcvfs.delete(cfgfile)
            else:
                f = xbmcvfs.File(cfgfile, 'w')
                f.write(value.__str__())
                f.close()
            xbmcvfs.delete(cfglockfile)
            xbmcvfs.delete(cfglockfile)
            return True
        else:
            l = xbmcvfs.File(cfglockfile)
            modified = l.read()
            modified = float(modified) if modified else 0
            l.close()
            if time.time() - modified > 0.1:
                xbmcvfs.delete(cfglockfile)
Example #15
0
def ask_to_share_log():
    """
    Ask the if he wants to share his log
    directly by mail with a QR code
    or by sharing the pastebin URL by mail,
    on github or forum
    """
    r = xbmcgui.Dialog().yesno(Script.localize(LABELS['Information']),
                               Script.localize(30860))
    if not r:
        return

    if not xbmcvfs.exists(PROFILE):
        xbmcvfs.mkdirs(PROFILE)

    succes, data = read_log(LOGFILE)
    print_error = False
    error_message = ""
    if succes:
        content = clean_log(data)
        succes, data = post_log(content)
        if succes:
            imagefile = os.path.join(xbmc.translatePath(PROFILE),
                                     '%s.png' % str(data.split('/')[-1]))
            message = Script.localize(30861)
            message = message.replace("URL_TO_REPLACE", data)
            mail_url = 'mailto:[email protected]?subject=Kodi%20log&body=' + data
            qrIMG = pyqrcode.create(mail_url)
            qrIMG.png(imagefile, scale=10)

            qr = QRCode("script-loguploader-main.xml",
                        CWD,
                        "default",
                        image=imagefile,
                        text=message)
            qr.doModal()
            del qr
            xbmcvfs.delete(imagefile)
        else:
            print_error = True
            error_message = data
    else:
        print_error = True
        error_message = data

    if print_error:
        xbmcgui.Dialog().ok(Script.localize(LABELS['Information']),
                            Script.localize(30862) + ': ' + error_message)

    return
Example #16
0
def delete_folder(path):
    ''' Delete objects from kodi cache
    '''
    LOG.debug("--[ delete folder ]")
    dirs, files = xbmcvfs.listdir(path)

    delete_recursive(path, dirs)

    for file in files:
        xbmcvfs.delete(os.path.join(path, file))

    xbmcvfs.delete(path)

    LOG.info("DELETE %s", path)
Example #17
0
def safe_copy(src, dst, del_src=False):
    src = xbmc.translatePath(src)
    dst = xbmc.translatePath(dst)

    if not xbmcvfs.exists(src) or same_file(src, dst):
        return

    if xbmcvfs.exists(dst):
        xbmcvfs.delete(dst)

    log.debug('Copying: {} > {}'.format(src, dst))
    xbmcvfs.copy(src, dst)

    if del_src:
        xbmcvfs.delete(src)
Example #18
0
def sync_list_intern(src_file, dest_file):
    PLog('sync_list_intern:')

    # 1. Vorprüfung: Setting Sync / externe Merkliste
    if SETTINGS.getSetting('pref_merksync') == 'false' or SETTINGS.getSetting(
            'pref_merkextern') == 'false':
        PLog("Sync_OFF")
        return
    # 2. Vorprüfung: externe Merkliste ist gleichzeitig interne Merkliste?
    if src_file == WATCHFILE:
        PLog("Sync_Block_WATCHFILE")
        return

    f = xbmcvfs.File(src_file)
    s1 = f.size()
    f.close()
    ret1 = False
    ret2 = False
    if s1 > 100:  # Mindestbreite bis dirID=, Eintrag immer > 100 Zeichen
        ret1 = xbmcvfs.delete(dest_file)
        PLog('xbmcvfs.delete: ' + str(ret1))
        ret2 = xbmcvfs.copy(src_file, dest_file)
        PLog('xbmcvfs.copy: ' + str(ret2))
        f = xbmcvfs.File(dest_file)
        s2 = f.size()
        f.close()  # Größenvergleich
        PLog("s1: %d, s2: %d" % (s1, s2))

    if ret1 and ret2 and s2 == s1:  # ohne Rückgabe
        PLog("Sync_OK")
    else:
        PLog("Sync_Error, s1: %d" % s1)
    return
Example #19
0
def sync_list_intern(src_file, dest_file):
    PLog('sync_list_intern:')

    # Vorprüfung Setting Sync / externe Merkliste
    if SETTINGS.getSetting('pref_merksync') == 'false' or SETTINGS.getSetting(
            'pref_merkextern') == 'false':
        PLog("Sync_OFF")
        return

    f = xbmcvfs.File(src_file)
    s1 = f.size()
    f.close()
    if s1 > 100:  # Mindestbreite bis dirID=, Eintrag immer größer
        ret1 = xbmcvfs.delete(dest_file)
        PLog('xbmcvfs.delete: ' + str(ret1))
        ret2 = xbmcvfs.copy(src_file, dest_file)
        PLog('xbmcvfs.copy: ' + str(ret2))
        f = xbmcvfs.File(dest_file)
        s2 = f.size()
        f.close()  # Größenvergleich
        PLog("s1: %d, s2: %d" % (s1, s2))

    if ret1 and ret2 and s2 == s1:  # ohne Rückgabe
        PLog("Sync_OK")
    else:
        PLog("Sync_Error")
    return
def get_fav_dict_from_json():
    """Get favourites dict from favourites.json

    Returns:
        dict: Favourites dict
    """

    if not xbmcvfs.exists(FAV_JSON_FP):
        return {}
    try:
        with open(FAV_JSON_FP) as f:
            return json.load(f)
    except Exception:
        Script.log('Failed to load favourites json data')
        xbmcvfs.delete(FAV_JSON_FP)
        return {}
Example #21
0
 def deleteLast(self, lastPath):
     log('deleteLast')
     #some file systems don't release the file lock instantly.
     for count in range(3):
         if self.myMonitor.waitForAbort(1): return 
         try: 
             if xbmcvfs.delete(lastPath): return
         except: pass
Example #22
0
    def delete_cache(self, url):

        ''' Delete cached artwork.
        '''
        from database import Database

        with Database('texture') as texturedb:
            try:
                texturedb.cursor.execute(QUTEX.get_cache, (url,))
                cached = texturedb.cursor.fetchone()[0]
            except TypeError:
                LOG.debug("Could not find cached url: %s", url)
            else:
                thumbnails = xbmc.translatePath("special://thumbnails/%s" % cached)
                xbmcvfs.delete(thumbnails)
                texturedb.cursor.execute(QUTEX.delete_cache, (url,))
                LOG.info("DELETE cached %s", cached)
Example #23
0
def downloadVideo(title, vid):
    global downloadDir
    if not downloadDir:
        xbmcgui.Dialog().notification('Download:', translation(30110), _icon,
                                      5000, False)
        return
    url, hstr = getStreamUrl(vid).split('|')
    if six.PY2:
        vidfile = xbmc.makeLegalFilename(
            (downloadDir + title.decode('utf-8') + '.mp4').encode('utf-8'))
    else:
        vidfile = xbmcvfs.makeLegalFilename(downloadDir + title + '.mp4')
    if not xbmcvfs.exists(vidfile):
        tmp_file = tempfile.mktemp(dir=downloadDir, suffix='.mp4')
        if six.PY2:
            tmp_file = xbmc.makeLegalFilename(tmp_file)
        else:
            tmp_file = xbmcvfs.makeLegalFilename(tmp_file)
        pDialog.create('Dailymotion',
                       '{0}[CR]{1}'.format(translation(30044), title))
        dfile = requests.get(url,
                             headers=dict(urllib_parse.parse_qsl(hstr)),
                             stream=True)
        totalsize = float(dfile.headers['content-length'])
        handle = open(tmp_file, "wb")
        chunks = 0
        for chunk in dfile.iter_content(chunk_size=2097152):
            if chunk:  # filter out keep-alive new chunks
                handle.write(chunk)
                chunks += 1
                percent = int(float(chunks * 209715200) / totalsize)
                pDialog.update(percent)
                if pDialog.iscanceled():
                    handle.close()
                    xbmcvfs.delete(tmp_file)
                    break
        handle.close()
        try:
            xbmcvfs.rename(tmp_file, vidfile)
            return vidfile
        except:
            return tmp_file
    else:
        xbmcgui.Dialog().notification('Download:', translation(30109), _icon,
                                      5000, False)
Example #24
0
 def deleteFile(self, file):
     log("deleteFile")
     for i in range(3):
         try: 
             if xbmcvfs.delete(file): return True
         except: pass
         if self.myMonitor.waitForAbort(1): break
     if xbmcvfs.exists(file): return False
     return True
Example #25
0
def grab_tv_guide(menu_id):
    try:
        xmltv_url = get_xmltv_url(menu_id)
        Script.log('xmltv url of {}: {}'.format(menu_id, xmltv_url))

        xmltv_fn = os.path.basename(urlparse(xmltv_url).path)
        Script.log('xmltv filename of {}: {}'.format(menu_id, xmltv_fn))

        xmltv_fp = os.path.join(Script.get_info('profile'), xmltv_fn)

        # Remove old xmltv files of this country
        dirs, files = xbmcvfs.listdir(Script.get_info('profile'))
        for fn in files:
            if xmltv_infos[menu_id]['keyword'] in fn and fn != xmltv_fn:
                Script.log('Remove old xmltv file: {}'.format(fn))
                xbmcvfs.delete(os.path.join(Script.get_info('profile'), fn))

        # Check if we need to download a fresh xmltv file
        if not xbmcvfs.exists(xmltv_fp):
            Script.log(
                "xmltv file of {} for today does not exist, let's download it".
                format(menu_id))
            r = urlquick.get(xmltv_url)
            with open(xmltv_fp, 'wb') as f:
                f.write(r.content)

        # Grab programmes in xmltv file
        programmes = read_current_programmes(xmltv_fp)

        # Use the channel as key
        tv_guide = {}
        for programme in programmes:
            programme = programme_post_treatment(programme)
            tv_guide[programme['channel']] = programme

        return tv_guide
    except Exception as e:
        Script.notify(Script.localize(LABELS['TV guide']),
                      Script.localize(
                          LABELS['An error occurred while getting TV guide']),
                      display_time=7000)
        Script.log('xmltv module failed with error: {}'.format(
            e, lvl=Script.ERROR))
        return {}
Example #26
0
def get_credentials():

    path = xbmc.translatePath(
        "special://profile/addon_data/plugin.video.jellyfin/")

    if not xbmcvfs.exists(path):
        xbmcvfs.mkdirs(path)

    try:
        with open(os.path.join(path, 'data.json'), 'rb') as infile:
            credentials = json.load(infile, encoding='utf8')
    except Exception:

        try:
            with open(os.path.join(path, 'data.txt'), 'rb') as infile:
                credentials = json.load(infile, encoding='utf-8')
                save_credentials(credentials)

            xbmcvfs.delete(os.path.join(path, 'data.txt'))
        except Exception:
            credentials = {}

    credentials['Servers'] = credentials.get('Servers', [])

    # Migration for #145
    # TODO: CLEANUP for 1.0.0 release
    for server in credentials['Servers']:
        # Functionality removed in #60
        if 'RemoteAddress' in server:
            del server['RemoteAddress']
        if 'ManualAddress' in server:
            server['address'] = server['ManualAddress']
            del server['ManualAddress']
            # If manual is present, local should always be here, but better to be safe
            if 'LocalAddress' in server:
                del server['LocalAddress']
        elif 'LocalAddress' in server:
            server['address'] = server['LocalAddress']
            del server['LocalAddress']
        if 'LastConnectionMode' in server:
            del server['LastConnectionMode']

    return credentials
Example #27
0
 def deleleAPK(self, path):
     count = 0
     #some file systems don't release the file lock instantly.
     while not self.myMonitor.abortRequested() and count < 3:
         count += 1
         if self.myMonitor.waitForAbort(1): return
         try:
             if xbmcvfs.delete(path): return
         except:
             pass
Example #28
0
def safe_copy(src, dst, del_src=False):
    src = xbmc.translatePath(src)
    dst = xbmc.translatePath(dst)

    if not xbmcvfs.exists(src) or same_file(src, dst):
        return

    if xbmcvfs.exists(dst):
        if xbmcvfs.delete(dst):
            log.debug('Deleted: {}'.format(dst))
        else:
            log.debug('Failed to delete: {}'.format(dst))

    if xbmcvfs.copy(src, dst):
        log.debug('Copied: {} > {}'.format(src, dst))
    else:
        log.debug('Failed to copy: {} > {}'.format(src, dst))

    if del_src:
        xbmcvfs.delete(src)
Example #29
0
def writeConfig(cfile, value):
    cfgfile = OSPJoin(writeConfig.configPath, cfile)
    cfglockfile = OSPJoin(writeConfig.configPath, cfile + '.lock')

    if not xbmcvfs.exists(writeConfig.configPath):
        xbmcvfs.mkdirs(writeConfig.configPath)

    while True:
        if not xbmcvfs.exists(cfglockfile):
            l = xbmcvfs.File(cfglockfile, 'w')
            l.write(str(time.time()))
            l.close()
            if value == '':
                xbmcvfs.delete(cfgfile)
            else:
                f = xbmcvfs.File(cfgfile, 'w')
                f.write(value.__str__())
                f.close()
            xbmcvfs.delete(cfglockfile)
            return True
        else:
            try:
                l = xbmcvfs.File(cfglockfile)
                modified = float(l.read())
                l.close()
                if time.time() - modified > 0.1:
                    xbmcvfs.delete(cfglockfile)
            except:
                pass
Example #30
0
def reset():
    ''' Reset both the jellyfin database and the kodi database.
    '''
    from views import Views
    views = Views()

    if not dialog("yesno", heading="{jellyfin}", line1=translate(33074)):
        return

    window('jellyfin_should_stop.bool', True)
    count = 10

    while window('jellyfin_sync.bool'):

        LOG.info("Sync is running...")
        count -= 1

        if not count:
            dialog("ok", heading="{jellyfin}", line1=translate(33085))

            return

        if xbmc.Monitor().waitForAbort(1):
            return

    reset_kodi()
    reset_jellyfin()
    views.delete_playlists()
    views.delete_nodes()

    if dialog("yesno", heading="{jellyfin}", line1=translate(33086)):
        reset_artwork()

    addon_data = xbmc.translatePath(
        "special://profile/addon_data/plugin.video.jellyfin/")

    if dialog("yesno", heading="{jellyfin}", line1=translate(33087)):

        xbmcvfs.delete(os.path.join(addon_data, "settings.xml"))
        xbmcvfs.delete(os.path.join(addon_data, "data.json"))
        LOG.info("[ reset settings ]")

    if xbmcvfs.exists(os.path.join(addon_data, "sync.json")):
        xbmcvfs.delete(os.path.join(addon_data, "sync.json"))

    settings('enableMusic.bool', False)
    settings('MinimumSetup', "")
    settings('MusicRescan.bool', False)
    settings('SyncInstallRunDone.bool', False)
    dialog("ok", heading="{jellyfin}", line1=translate(33088))
    xbmc.executebuiltin('RestartApp')