Exemplo n.º 1
0
 def create(self, heading=None, message=None):
     if self.enable is False:
         return
     self.heading = heading if heading is not None else self.heading
     self.message = message if message is not None else self.message
     self.dialog = xbmcgui.DialogProgressBG()
     self.dialog.create(heading=self.heading, message=self.message)
    def _create_dialog(self):
        dialog = xbmcgui.DialogProgressBG() if self._background else xbmcgui.DialogProgress()
        dialog.create(self._heading, self._message)

        self.__percent = 0

        return dialog
Exemplo n.º 3
0
def ProgressBGDialog(percent=0, control=None, message='', header=ADDON_NAME):
    if percent == 0 and control is None:
        control = xbmcgui.DialogProgressBG()
        control.create(header, message)
    elif control:
        if percent == 100 or control.isFinished(): return control.close()
        else: control.update(percent, header, message)
    return control
Exemplo n.º 4
0
def progressbg(message='', heading=None, percent=0):
    heading = _make_heading(heading)

    dialog = xbmcgui.DialogProgressBG()
    dialog.create(heading, message)
    dialog.update(int(percent))

    return dialog
Exemplo n.º 5
0
def busyDialog(percent=0, control=None):
    if percent == 0 and control is None:
        control = xbmcgui.DialogProgressBG()
        control.create(ADDON_NAME)
        control.update(percent)
    if control is not None:
        if percent == 100 or control.isFinished: return control.close()
        else: control.update(percent)
    return control
Exemplo n.º 6
0
 def __create_dialog(self, line1, line2, line3):
     if self.background:
         pd = xbmcgui.DialogProgressBG()
         msg = line1 + line2 + line3
         pd.create(self.heading, msg)
     else:
         pd = xbmcgui.DialogProgress()
         pd.create(self.heading, line1, line2, line3)
     return pd
Exemplo n.º 7
0
 def DialogProgressBG_Create(self, title, message, *args):
     dialog = xbmcgui.DialogProgressBG()
     dialogId = id(dialog)
     self._objects[dialogId] = dialog
     if args and isinstance(args[0], list):
         self._objects["%s-i18n" % dialogId] = {}
         for translation in args[0]:
             self._objects["%s-i18n" % dialogId][translation] = getLocalizedLabel(translation)
     dialog.create(title, getLocalizedLabel(message))
     return dialogId
Exemplo n.º 8
0
    def __init__(self, message='', heading=None, percent=0, background=False):
        heading = _make_heading(heading)
        self._background = background

        if self._background:
            self._dialog = xbmcgui.DialogProgressBG()
        else:
            self._dialog = xbmcgui.DialogProgress()

        self._dialog.create(heading, *self._get_args(message))
        self.update(percent)
Exemplo n.º 9
0
def validate_client():
    p_dialog = xbmcgui.DialogProgressBG()
    try:
        p_dialog.create('Elementum [COLOR FFFF6B00]Jackett[/COLOR]',
                        utils.translation(32005))
        get_client()
        if get_setting("settings_validated") == "Success":
            utils.notify(utils.translation(32006), image=utils.get_icon_path())
        utils.ADDON.openSettings()
    finally:
        p_dialog.close()
        del p_dialog
Exemplo n.º 10
0
    def discover_all_servers(self):
        progress_dialog = xbmcgui.DialogProgressBG()
        progress_dialog.create(heading=CONFIG['name'] + ' ' + i18n('Server Discovery'),
                               message=i18n('Please wait...'))

        try:
            percent = 0
            self.server_list = {}
            # First discover the servers we should know about from myplex
            if self.is_myplex_signedin():
                LOG.debug('Adding myPlex as a server location')
                progress_dialog.update(percent=percent, message=i18n('myPlex discovery...'))

                self.server_list = self.get_myplex_servers()

                if self.server_list:
                    LOG.debug('MyPlex discovery completed successfully')
                else:
                    LOG.debug('MyPlex discovery found no servers')

            # Now grab any local devices we can find
            if self.settings.discovery() == '1':
                LOG.debug('local GDM discovery setting enabled.')
                LOG.debug('Attempting GDM lookup on multicast')
                percent += 40
                progress_dialog.update(percent=percent, message=i18n('GDM discovery...'))
                self.gdm_discovery()

            # Get any manually configured servers
            elif self.settings.ip_address():
                percent += 40
                progress_dialog.update(percent=percent, message=i18n('User provided...'))
                self.user_provided_discovery()

            percent += 40
            progress_dialog.update(percent=percent, message=i18n('Caching results...'))

            for server_uuid in list(self.server_list.keys()):
                self.server_list[server_uuid].settings = None  # can't pickle xbmcaddon.Addon()

            self.cache.write_cache(self.server_list_cache, self.server_list)

            servers = list(map(lambda x: (self.server_list[x].get_name(), x),
                               self.server_list.keys()))

            server_names = ', '.join(map(lambda x: x[0], servers))

            LOG.debug('serverList is: %s ' % servers)
        finally:
            progress_dialog.update(percent=100, message=i18n('Finished'))
            progress_dialog.close()

        self._discovery_notification(server_names)
Exemplo n.º 11
0
 def __create_dialog(self, line1, line2, line3):
     if self.background:
         pd = xbmcgui.DialogProgressBG()
         msg = line1 + line2 + line3
         pd.create(self.heading, msg)
     else:
         if xbmc.getCondVisibility('Window.IsVisible(progressdialog)'):
             pd = CustomProgressDialog.ProgressDialog()
         else:
             pd = xbmcgui.DialogProgress()
         pd.create(self.heading, line1, line2, line3)
     return pd
Exemplo n.º 12
0
 def __init__(self, session, album_playlist, track_playlist, video_playlist,
              limit, diffDays):
     self.session = session
     self.album_playlist = album_playlist
     self.track_playlist = track_playlist
     self.video_playlist = video_playlist
     self.found_albums = []
     self.found_tracks = []
     self.found_videos = []
     self.artistQueue = _Queue(maxsize=99999)
     self.artistCount = 0
     self.searchLimit = limit
     self.diffDays = diffDays
     self.abortThreads = True
     self.runningThreads = {}
     self.progress = xbmcgui.DialogProgressBG()
Exemplo n.º 13
0
        def wrapper(self, item=None, *args, **kwargs):

            dialog = xbmcgui.DialogProgressBG()

            if item and type(item) == dict:

                dialog.create(translate('addon_name'),
                              "%s %s" % (translate('gathering'), item['Name']))
                LOG.info("Processing %s: %s", item['Name'], item['Id'])
            else:
                dialog.create(translate('addon_name'), message)
                LOG.info("Processing %s", message)

            if item:
                args = (item, ) + args

            result = func(self, dialog=dialog, *args, **kwargs)
            dialog.close()

            return result
Exemplo n.º 14
0
def search(payload, method="general"):
    payload = parse_payload(method, payload)

    log.debug("Searching with payload (%s): %s", method, repr(payload))

    p_dialog = xbmcgui.DialogProgressBG()
    p_dialog.create('Elementum [COLOR FFFF6B00]Jackett[/COLOR]',
                    utils.translation(32602))

    try:
        request_start_time = time.time()
        results = search_jackett(payload, method)
        request_end_time = time.time()
        request_time = round(request_end_time - request_start_time, 2)

        log.debug("All results: %s" % repr(results))

        log.info("Jackett returned %d results in %s seconds", len(results),
                 request_time)
    finally:
        p_dialog.close()
        del p_dialog

    return results
Exemplo n.º 15
0
def search(payload, method="general"):
    """ Main search entrypoint

    Args:
        payload (dict): Search payload from Elementum.
        method   (str): Type of search, can be ``general``, ``movie``, ``show``, ``season`` or ``anime``

    Returns:
        list: All filtered results in the format Elementum expects
    """
    log.debug("Searching with payload (%s): %s" % (method, repr(payload)))

    if 'anime' in payload and payload['anime']:
        method = 'anime'

    if method == 'general':
        if 'query' in payload:
            payload['title'] = payload['query']
            payload['titles'] = {
                'source': payload['query']
            }
        else:
            payload = {
                'title': payload,
                'titles': {
                    'source': payload
                },
            }

    payload['titles'] = dict((k.lower(), v) for k, v in iteritems(payload['titles']))

    # If titles[] exists in payload and there are special chars in titles[source]
    #   then we set a flag to possibly modify the search query
    payload['has_special'] = 'titles' in payload and \
                             bool(payload['titles']) and \
                             'source' in payload['titles'] and \
                             any(c in payload['titles']['source'] for c in special_chars)
    if payload['has_special']:
        log.debug("Query title contains special chars, so removing any quotes in the search query")

    if 'proxy_url' not in payload:
        payload['proxy_url'] = ''
    if 'internal_proxy_url' not in payload:
        payload['internal_proxy_url'] = ''
    if 'elementum_url' not in payload:
        payload['elementum_url'] = ''
    if 'silent' not in payload:
        payload['silent'] = False
    if 'skip_auth' not in payload:
        payload['skip_auth'] = False

    global request_time
    global provider_cache
    global provider_names
    global provider_results
    global available_providers

    provider_cache = {}
    provider_names = []
    provider_results = []
    available_providers = 0
    request_time = time.time()

    providers = get_enabled_providers(method)

    if len(providers) == 0:
        if not payload['silent']:
            notify(translation(32060), image=get_icon_path())
        log.error("No providers enabled")
        return []

    log.info("Burstin' with %s" % ", ".join([definitions[provider]['name'] for provider in providers]))

    if use_kodi_language:
        kodi_language = xbmc.getLanguage(xbmc.ISO_639_1)
        if not kodi_language:
            log.warning("Kodi returned empty language code...")
        elif 'titles' not in payload or not payload['titles']:
            log.info("No translations available...")
        elif payload['titles'] and kodi_language not in payload['titles']:
            log.info("No '%s' translation available..." % kodi_language)

    p_dialog = xbmcgui.DialogProgressBG()
    if not payload['silent']:
        p_dialog.create('Elementum [COLOR FFFF6B00]Burst[/COLOR]', translation(32061))

    providers_time = time.time()

    for provider in providers:
        available_providers += 1
        provider_names.append(definitions[provider]['name'])
        task = Thread(target=run_provider, args=(provider, payload, method, providers_time, timeout))
        task.start()

    total = float(available_providers)

    # Exit if all providers have returned results or timeout reached, check every 100ms
    while time.time() - providers_time < timeout and available_providers > 0:
        timer = time.time() - providers_time
        log.debug("Timer: %ds / %ds" % (timer, timeout))
        if timer > timeout:
            break
        message = translation(32062) % available_providers if available_providers > 1 else translation(32063)
        if not payload['silent']:
            p_dialog.update(int((total - available_providers) / total * 100), message=message)
        time.sleep(0.25)

    if not payload['silent']:
        p_dialog.close()
    del p_dialog

    if available_providers > 0:
        message = ', '.join(provider_names)
        message = message + translation(32064)
        log.warning(message)
        if not payload['silent']:
            notify(message, ADDON_ICON)

    log.debug("all provider_results of %d: %s" % (len(provider_results), repr(provider_results)))

    filtered_results = apply_filters(provider_results)

    log.debug("all filtered_results of %d: %s" % (len(filtered_results), repr(filtered_results)))

    log.info("Providers returned %d results in %s seconds" % (len(filtered_results), round(time.time() - request_time, 2)))

    return filtered_results
Exemplo n.º 16
0
monitor = xbmc.Monitor
wait = monitor().waitForAbort
aborted = monitor().abortRequested
cleanmovietitle = xbmc.getCleanMovieTitle

transPath = xbmc.translatePath
skinPath = transPath('special://skin/')
addonPath = transPath(addonInfo('path'))
legalfilename = xbmc.makeLegalFilename

dataPath = transPath(addonInfo('profile'))

window = xbmcgui.Window(10000)
dialog = xbmcgui.Dialog()
progressDialog = xbmcgui.DialogProgress()
progressDialogGB = xbmcgui.DialogProgressBG()
windowDialog = xbmcgui.WindowDialog()
button = xbmcgui.ControlButton
image = xbmcgui.ControlImage
alphanum_input = xbmcgui.INPUT_ALPHANUM
password_input = xbmcgui.INPUT_PASSWORD
hide_input = xbmcgui.ALPHANUM_HIDE_INPUT
verify = xbmcgui.PASSWORD_VERIFY
item = xbmcgui.ListItem

openFile = xbmcvfs.File
read = openFile.read
readbytes = openFile.readBytes
makeFile = xbmcvfs.mkdir
makeFiles = xbmcvfs.mkdirs
deleteFile = xbmcvfs.delete
Exemplo n.º 17
0
addonInfo = xbmcaddon.Addon().getAddonInfo

infoLabel = xbmc.getInfoLabel

condVisibility = xbmc.getCondVisibility

jsonrpc = xbmc.executeJSONRPC

window = xbmcgui.Window(10000)

dialog = xbmcgui.Dialog()

progressDialog = xbmcgui.DialogProgress()

progressDialogBG = xbmcgui.DialogProgressBG()

windowDialog = xbmcgui.WindowDialog()

button = xbmcgui.ControlButton

image = xbmcgui.ControlImage

getCurrentDialogId = xbmcgui.getCurrentWindowDialogId()

getCurrentWinId = xbmcgui.getCurrentWindowId()

keyboard = xbmc.Keyboard

monitor = xbmc.Monitor()
Exemplo n.º 18
0
    def service(self):
        ''' If error is encountered, it will rerun this function.
            Start new "daemon threads" to process library updates.
            (actual daemon thread is not supported in Kodi)
        '''
        self.download_threads = [
            thread for thread in self.download_threads if not thread.is_done
        ]
        self.writer_threads['updated'] = [
            thread for thread in self.writer_threads['updated']
            if not thread.is_done
        ]
        self.writer_threads['userdata'] = [
            thread for thread in self.writer_threads['userdata']
            if not thread.is_done
        ]
        self.writer_threads['removed'] = [
            thread for thread in self.writer_threads['removed']
            if not thread.is_done
        ]

        if not self.player.isPlayingVideo() or settings(
                'syncDuringPlay.bool') or xbmc.getCondVisibility(
                    'VideoPlayer.Content(livetv)'):

            self.worker_downloads()
            self.worker_sort()

            self.worker_updates()
            self.worker_userdata()
            self.worker_remove()
            self.worker_notify()

        if self.pending_refresh:
            window('jellyfin_sync.bool', True)

            if self.total_updates > self.progress_display:
                queue_size = self.worker_queue_size()

                if self.progress_updates is None:

                    self.progress_updates = xbmcgui.DialogProgressBG()
                    self.progress_updates.create(translate('addon_name'),
                                                 translate(33178))
                    self.progress_updates.update(
                        int((float(self.total_updates - queue_size) /
                             float(self.total_updates)) * 100),
                        message="%s: %s" % (translate(33178), queue_size))
                elif queue_size:
                    self.progress_updates.update(
                        int((float(self.total_updates - queue_size) /
                             float(self.total_updates)) * 100),
                        message="%s: %s" % (translate(33178), queue_size))
                else:
                    self.progress_updates.update(int(
                        (float(self.total_updates - queue_size) /
                         float(self.total_updates)) * 100),
                                                 message=translate(33178))

            if not settings(
                    'dbSyncScreensaver.bool') and self.screensaver is None:

                xbmc.executebuiltin('InhibitIdleShutdown(true)')
                self.screensaver = get_screensaver()
                set_screensaver(value="")

        if (self.pending_refresh and not self.download_threads
                and not self.writer_threads['updated']
                and not self.writer_threads['userdata']
                and not self.writer_threads['removed']):
            self.pending_refresh = False
            self.save_last_sync()
            self.total_updates = 0
            window('jellyfin_sync', clear=True)

            if self.progress_updates:

                self.progress_updates.close()
                self.progress_updates = None

            if not settings(
                    'dbSyncScreensaver.bool') and self.screensaver is not None:

                xbmc.executebuiltin('InhibitIdleShutdown(false)')
                set_screensaver(value=self.screensaver)
                self.screensaver = None

            if xbmc.getCondVisibility('Container.Content(musicvideos)'
                                      ):  # Prevent cursor from moving
                xbmc.executebuiltin('Container.Refresh')
            else:  # Update widgets
                xbmc.executebuiltin('UpdateLibrary(video)')

                if xbmc.getCondVisibility('Window.IsMedia'):
                    xbmc.executebuiltin('Container.Refresh')
Exemplo n.º 19
0
def xmltv():
    load_groups = plugin.get_storage('load_groups')
    load_channels = {}

    dialog = xbmcgui.DialogProgressBG()
    dialog.create("IPTV Recorder", get_string("Loading data..."))

    profilePath = xbmc.translatePath(plugin.addon.getAddonInfo('profile'))
    xbmcvfs.mkdirs(profilePath)

    shifts = {}
    streams_to_insert = []

    for x in ["1", "2"]:
        dialog.update(0, message=get_string("Finding streams"))
        mode = plugin.get_setting('external.m3u.' + x, str)
        if mode == "0":
            if x == "1":
                try:
                    m3uPathType = xbmcaddon.Addon('pvr.iptvsimple').getSetting(
                        'm3uPathType')
                    if m3uPathType == "0":
                        path = xbmcaddon.Addon('pvr.iptvsimple').getSetting(
                            'm3uPath')
                    else:
                        path = xbmcaddon.Addon('pvr.iptvsimple').getSetting(
                            'm3uUrl')
                except:
                    path = ""
            else:
                path = ""
        elif mode == "1":
            if x == "1":
                try:
                    m3uPathType = xbmcaddon.Addon(
                        'pvr.iptvarchive').getSetting('m3uPathType')
                    if m3uPathType == "0":
                        path = xbmcaddon.Addon('pvr.iptvarchive').getSetting(
                            'm3uPath')
                    else:
                        path = xbmcaddon.Addon('pvr.iptvarchive').getSetting(
                            'm3uUrl')
                except:
                    path = ""
            else:
                path = ""
        elif mode == "2":
            path = plugin.get_setting('external.m3u.file.' + x, str)
        else:
            path = plugin.get_setting('external.m3u.url.' + x, str)

        if path:

            m3uFile = 'special://profile/addon_data/plugin.video.iptv.archive.downloader/channels' + x + '.m3u'

            xbmcvfs.copy(path, m3uFile)
            f = open(xbmc.translatePath(m3uFile), 'rb')
            data = f.read()
            data = data.decode('utf8')
            settings_shift = float(
                plugin.get_setting('external.m3u.shift.' + x, str))
            global_shift = settings_shift

            header = re.search('#EXTM3U(.*)', data)
            if header:
                tvg_shift = re.search('tvg-shift="(.*?)"', header.group(1))
                if tvg_shift:
                    tvg_shift = tvg_shift.group(1)
                    if tvg_shift:
                        global_shift = float(tvg_shift) + settings_shift

            channels = re.findall(
                '#EXTINF:(.*?)(?:\r\n|\r|\n)(.*?)(?:\r\n|\r|\n|$)',
                data,
                flags=(re.I | re.DOTALL))
            total = len(channels)
            i = 0
            for channel in channels:

                name = None
                if ',' in re.sub('tvg-[a-z]+"[^"]*"',
                                 '',
                                 channel[0],
                                 flags=re.I):
                    name = channel[0].rsplit(',', 1)[-1].strip()
                    name = name.replace('+', '')
                    name = name.replace(':', '')
                    name = name.replace('#', '')
                    #name = name.encode("utf8")

                tvg_name = re.search('tvg-name="(.*?)"',
                                     channel[0],
                                     flags=re.I)
                if tvg_name:
                    tvg_name = tvg_name.group(1) or None
                #else:
                #tvg_name = name

                tvg_id = re.search('tvg-id="(.*?)"', channel[0], flags=re.I)
                if tvg_id:
                    tvg_id = tvg_id.group(1) or None

                tvg_logo = re.search('tvg-logo="(.*?)"',
                                     channel[0],
                                     flags=re.I)
                if tvg_logo:
                    tvg_logo = tvg_logo.group(1) or None

                shifts[tvg_id] = global_shift
                tvg_shift = re.search('tvg-shift="(.*?)"',
                                      channel[0],
                                      flags=re.I)
                if tvg_shift:
                    tvg_shift = tvg_shift.group(1)
                    if tvg_shift and tvg_id:
                        shifts[tvg_id] = float(tvg_shift) + settings_shift

                url = channel[1]
                search = plugin.get_setting('m3u.regex.search', str)
                replace = plugin.get_setting('m3u.regex.replace', str)
                if search:
                    url = re.sub(search, replace, url)

                groups = re.search('group-title="(.*?)"',
                                   channel[0],
                                   flags=re.I)
                if groups:
                    groups = groups.group(1) or None

                streams_to_insert.append(
                    (name, tvg_name, tvg_id, tvg_logo, groups, url.strip(), i))
                i += 1
                percent = 0 + int(100.0 * i / total)
                dialog.update(percent, message=get_string("Finding streams"))
    '''
    missing_streams = conn.execute('SELECT name, tvg_name FROM streams WHERE tvg_id IS null OR tvg_id IS ""').fetchall()
    sql_channels = conn.execute('SELECT id, name FROM channels').fetchall()
    lower_channels = {x[1].lower():x[0] for x in sql_channels}
    for name, tvg_name in missing_streams:
        if tvg_name:
            tvg_id = None
            _tvg_name = tvg_name.replace("_"," ").lower()
            if _tvg_name in lower_channels:
                tvg_id = lower_channels[_tvg_name]
                conn.execute("UPDATE streams SET tvg_id=? WHERE tvg_name=?", (tvg_id, tvg_name))
        elif name.lower() in lower_channels:
            tvg_id = lower_channels[name.lower()]
            conn.execute("UPDATE streams SET tvg_id=? WHERE name=?", (tvg_id, name))
    '''

    for _, _, tvg_id, _, groups, _, _ in streams_to_insert:
        if groups in load_groups:
            load_channels[tvg_id] = ""

    dialog.update(0, message=get_string("Creating database"))
    databasePath = os.path.join(profilePath, 'xmltv.db')
    conn = sqlite3.connect(databasePath, detect_types=sqlite3.PARSE_DECLTYPES)
    conn.execute('PRAGMA foreign_keys = ON')
    conn.row_factory = sqlite3.Row
    conn.execute('DROP TABLE IF EXISTS streams')
    conn.execute(
        'CREATE TABLE IF NOT EXISTS streams(uid INTEGER PRIMARY KEY ASC, name TEXT, tvg_name TEXT, tvg_id TEXT, tvg_logo TEXT, groups TEXT, url TEXT, tv_number INTEGER)'
    )

    dialog.update(0, message=get_string("Updating database"))
    conn.executemany(
        "INSERT OR IGNORE INTO streams(name, tvg_name, tvg_id, tvg_logo, groups, url, tv_number) VALUES (?, ?, ?, ?, ?, ?, ?)",
        streams_to_insert)
    conn.commit()
    conn.close()

    dialog.update(100, message=get_string("Finished loading data"))
    time.sleep(1)
    dialog.close()
    return
Exemplo n.º 20
0
    def search(self, artists, thread_count=1):
        for artist in artists:
            try:
                if VARIOUS_ARTIST_ID != '%s' % artist.id and not artist._isLocked:
                    self.artistQueue.put(artist)
            except:
                if VARIOUS_ARTIST_ID != '%s' % artist.id:
                    self.artistQueue.put(artist)
        self.artistCount = self.artistQueue.qsize()
        if self.artistCount < 1:
            log.info('No Artist to search ...')
            return
        log.info('Start: Searching new Music for %s Artists ...' %
                 self.artistCount)
        self.abortThreads = False
        threadsToStart = thread_count if thread_count < self.artistCount else self.artistCount
        self.runningThreads = {}
        self.progress = xbmcgui.DialogProgressBG()
        self.progress.create(heading=_S(Msg.i30437))
        try:
            self.progress_update(heading=_S(Msg.i30437))
            xbmc.sleep(500)
            while len(self.runningThreads.keys()) < threadsToStart:
                try:
                    worker = Thread(target=self.search_thread)
                    worker.start()
                    self.runningThreads.update({worker.ident: worker})
                except Exception as e:
                    log.logException(e)
            log.info('Waiting until all Threads are terminated')
            startTime = datetime.today()
            stopWatch = startTime
            remainingArtists = self.artistCount
            lastCount = self.artistCount
            while len(list(self.runningThreads.keys())
                      ) > 0 and not xbmc.Monitor().waitForAbort(timeout=0.05):
                remaining_workers = list(self.runningThreads.values())
                for worker in remaining_workers:
                    worker.join(5)
                    if settings.getSetting(
                            'search_artist_music_abort') == 'true':
                        log.info('Stopping all Workers ...')
                        self.abortThreads = True
                        settings.setSetting('search_artist_music_abort',
                                            'false')
                    if worker.is_alive():
                        now = datetime.today()
                        runningTime = now - startTime
                        remainingArtists = self.artistQueue.qsize()
                        log.info(
                            'Workers still running after %s seconds, %s Artists remaining ...'
                            % (runningTime.seconds, remainingArtists))
                        diff = now - stopWatch
                        if lastCount > remainingArtists:
                            # Workers are still removing artists from the queue
                            lastCount = remainingArtists
                            stopWatch = now
                        elif diff.seconds >= 60:
                            # Timeout: Stopping Threads with the Stop-Flag
                            log.info('Timeout, sending Stop to Workers ...')
                            self.abortThreads = True
                            break
                    else:
                        # Removing terminates Thread
                        self.runningThreads.pop(worker.ident, None)
                        break
                if self.abortThreads:
                    xbmcgui.Dialog().notification(
                        _S(Msg.i30437),
                        _S(Msg.i30444),
                        icon=xbmcgui.NOTIFICATION_WARNING)
                    worker_keys = list(self.runningThreads.keys())
                    for worker_key in worker_keys:
                        log.info('Waiting for Thread %s to terminate ...' %
                                 worker_key)
                        worker = self.runningThreads.pop(worker_key, None)
                        if worker != None and worker.is_alive():
                            worker.join(5)
                    xbmc.sleep(2000)
            if len(self.found_albums) > 0 or len(self.found_tracks) > 0 or len(
                    self.found_videos) > 0:
                self.progress_update(heading=_S(Msg.i30441))
                if len(self.found_albums) > 0 and self.album_playlist.id:
                    self.album_playlist._etag = None
                    try:
                        self.session.user.add_playlist_entries(
                            self.album_playlist, self.found_albums)
                    except:
                        pass
                if len(self.found_tracks) > 0 and self.track_playlist.id:
                    self.track_playlist._etag = None
                    try:
                        self.session.user.add_playlist_entries(
                            self.track_playlist, self.found_tracks)
                    except:
                        pass
                if len(self.found_videos) > 0 and self.video_playlist.id:
                    self.video_playlist._etag = None
                    try:
                        self.session.user.add_playlist_entries(
                            self.video_playlist, self.found_videos)
                    except:
                        pass
                message = '%s:%s, %s:%s, %s:%s' % (
                    _P('albums'), len(self.found_albums), _P('tracks'),
                    len(self.found_tracks), _P('videos'), len(
                        self.found_videos))
                xbmcgui.Dialog().notification(_S(Msg.i30440),
                                              message,
                                              icon=xbmcgui.NOTIFICATION_INFO)
                log.info('Found: %s' % message)
            else:
                log.info('No new Music found !')
                xbmcgui.Dialog().notification(_S(Msg.i30437),
                                              _S(Msg.i30443),
                                              icon=xbmcgui.NOTIFICATION_INFO)
        except Exception as e:
            log.logException(e, 'Error in search loop')
            xbmcgui.Dialog().notification(_S(Msg.i30437),
                                          _S(Msg.i30442),
                                          icon=xbmcgui.NOTIFICATION_ERROR)
            traceback.print_exc()
        finally:
            xbmc.sleep(2000)
            self.progress.close()
        log.info('End: Searching for new Music.')


# End of File