Ejemplo n.º 1
0
    def get_user_stats(self, msg):

        if msg.avgspeed > 0:
            self.speed.set_text(human_speed(msg.avgspeed))

        self.filesshared.set_text(humanize(msg.files))
        self.dirsshared.set_text(humanize(msg.dirs))
Ejemplo n.º 2
0
    def get_user_stats(self, msg):

        if msg.user in self.users:
            tab = self.users[msg.user]
            tab.speed.set_text(_("Speed: %s") % human_speed(msg.avgspeed))
            tab.filesshared.set_text(_("Files: %s") % humanize(msg.files))
            tab.dirsshared.set_text(_("Directories: %s") % humanize(msg.dirs))
Ejemplo n.º 3
0
    def add_user_row(self, userdata):

        username = userdata.username
        status = userdata.status
        country = userdata.country or ""  # country can be None, ensure string is used
        status_image = self.frame.get_status_image(status)
        flag_image = self.frame.get_flag_image(country)

        # Request user's IP address, so we can get the country
        self.frame.np.queue.append(slskmessages.GetPeerAddress(username))

        avgspeed = userdata.avgspeed
        files = userdata.files
        hspeed = human_speed(avgspeed)
        hfiles = humanize(files)

        iterator = self.usersmodel.insert_with_valuesv(
            -1, self.column_numbers, [
                GObject.Value(GObject.TYPE_OBJECT, status_image),
                GObject.Value(GObject.TYPE_OBJECT, flag_image), username,
                hspeed, hfiles, status,
                GObject.Value(GObject.TYPE_UINT64, avgspeed),
                GObject.Value(GObject.TYPE_UINT64, files), country
            ])

        self.users[username] = iterator
Ejemplo n.º 4
0
    def get_user_stats(self, msg):
        if msg.user not in self.recommendation_users:
            return

        self.recommendation_users_model.set(
            self.recommendation_users[msg.user], 2, human_speed(msg.avgspeed),
            3, humanize(msg.files), 5, msg.avgspeed, 6, msg.files)
Ejemplo n.º 5
0
    def add_user_results(self, msg, user, country):

        if user in self.users:
            return

        self.users.add(user)

        counter = len(self.all_data) + 1

        inqueue = msg.inqueue
        ulspeed = msg.ulspeed
        h_speed = human_speed(ulspeed)

        if msg.freeulslots:
            imdl = "Y"
            inqueue = 0
        else:
            imdl = "N"

        h_queue = humanize(inqueue)

        color_id = (imdl == "Y" and "search" or "searchq")
        color = config.sections["ui"][color_id] or None

        update_ui, counter = self.add_result_list(msg.list, counter, user,
                                                  country, inqueue, ulspeed,
                                                  h_speed, imdl, h_queue,
                                                  color)

        if config.sections["ui"]["private_search_results"] and msg.privatelist:
            update_ui_private, counter = self.add_result_list(msg.privatelist,
                                                              counter,
                                                              user,
                                                              country,
                                                              inqueue,
                                                              ulspeed,
                                                              h_speed,
                                                              imdl,
                                                              h_queue,
                                                              color,
                                                              private=True)

            if not update_ui and update_ui_private:
                update_ui = True

        if update_ui:
            # If this search wasn't initiated by us (e.g. wishlist), and the results aren't spoofed, show tab
            if not self.showtab:
                self.searches.show_tab(self, self.id, self.text, self.mode)
                self.showtab = True

            # Update number of results
            self.update_result_counter()

            # Update tab notification
            self.frame.searches.request_changed(self.Main)
            self.frame.request_tab_icon(self.frame.SearchTabLabel)
Ejemplo n.º 6
0
    def get_user_stats(self, user, avgspeed, files):

        if user not in self.users:
            return

        self.usersmodel.set_value(self.users[user], 3, human_speed(avgspeed))
        self.usersmodel.set_value(self.users[user], 4, humanize(files))
        self.usersmodel.set_value(self.users[user], 6,
                                  GObject.Value(GObject.TYPE_UINT64, avgspeed))
        self.usersmodel.set_value(self.users[user], 7,
                                  GObject.Value(GObject.TYPE_UINT64, files))
Ejemplo n.º 7
0
    def add_user_results(self, msg, user, country):

        if user in self.users:
            return

        self.users.add(user)

        if msg.freeulslots:
            inqueue = 0
            h_queue = ""
        else:
            inqueue = msg.inqueue or 1  # Ensure value is always >= 1
            h_queue = humanize(inqueue)

        h_speed = ""
        ulspeed = msg.ulspeed or 0

        if ulspeed > 0:
            h_speed = human_speed(ulspeed)

        color_id = "search" if msg.freeulslots else "searchq"
        color = config.sections["ui"][color_id] or None

        update_ui = self.add_result_list(msg.list, user, country, inqueue,
                                         ulspeed, h_speed, h_queue, color)

        if msg.privatelist:
            update_ui_private = self.add_result_list(msg.privatelist,
                                                     user,
                                                     country,
                                                     inqueue,
                                                     ulspeed,
                                                     h_speed,
                                                     h_queue,
                                                     color,
                                                     private=True)

            if not update_ui and update_ui_private:
                update_ui = True

        if update_ui:
            # If this search wasn't initiated by us (e.g. wishlist), and the results aren't spoofed, show tab
            if not self.showtab:
                self.searches.show_tab(self, self.text)
                self.showtab = True

            self.searches.request_tab_hilite(self.Main)

        # Update number of results, even if they are all filtered
        self.update_result_counter()
Ejemplo n.º 8
0
    def get_user_stats(self, msg):

        user = msg.user
        iterator = self.user_iterators.get(user)

        if iterator is None:
            return

        hspeed = human_speed(msg.avgspeed)
        hfiles = humanize(msg.files)

        self.usersmodel.set_value(iterator, 3, hspeed)
        self.usersmodel.set_value(iterator, 4, hfiles)
        self.usersmodel.set_value(iterator, 11, GObject.Value(GObject.TYPE_UINT64, msg.avgspeed))
        self.usersmodel.set_value(iterator, 12, GObject.Value(GObject.TYPE_UINT64, msg.files))
Ejemplo n.º 9
0
    def similar_users(self, msg):
        self.recommendation_users_model.clear()
        self.recommendation_users = {}

        for user in msg.users:
            iterator = self.recommendation_users_model.insert_with_valuesv(
                -1, self.recommendation_users_column_numbers, [
                    GObject.Value(GObject.TYPE_OBJECT,
                                  self.frame.images["offline"]), user,
                    human_speed(0), "0", 0, 0, 0
                ])
            self.recommendation_users[user] = iterator

            # Request user status, speed and number of shared files
            self.frame.np.watch_user(user, force_update=True)
Ejemplo n.º 10
0
    def on_file_properties(self, *args):

        if not self.frame.np.transfers:
            return

        data = []
        model, paths = self.widget.get_selection().get_selected_rows()

        for path in paths:
            iterator = model.get_iter(path)
            transfer = model.get_value(iterator, 18)

            if not isinstance(transfer, Transfer):
                continue

            user = model.get_value(iterator, 0)
            filename = model.get_value(iterator, 2)
            fullname = model.get_value(iterator, 10)
            size = speed = length = queue = immediate = num = country = bitratestr = ""

            size = str(human_size(transfer.size))

            if transfer.speed:
                speed = str(human_speed(transfer.speed))

            bitratestr = str(transfer.bitrate)
            length = str(transfer.length)

            directory = fullname.rsplit("\\", 1)[0]

            data.append({
                "user": user,
                "fn": fullname,
                "position": num,
                "filename": filename,
                "directory": directory,
                "size": size,
                "speed": speed,
                "queue": queue,
                "immediate": immediate,
                "bitrate": bitratestr,
                "length": length,
                "country": country
            })

        if paths:
            FileProperties(self.frame, data).show()
Ejemplo n.º 11
0
    def get_user_stats(self, user, avgspeed, files):

        iterator = self.users.get(user)

        if iterator is None:
            return

        h_speed = ""

        if avgspeed > 0:
            h_speed = human_speed(avgspeed)

        self.usersmodel.set_value(iterator, 3, h_speed)
        self.usersmodel.set_value(iterator, 4, humanize(files))
        self.usersmodel.set_value(iterator, 6,
                                  GObject.Value(GObject.TYPE_UINT, avgspeed))
        self.usersmodel.set_value(iterator, 7,
                                  GObject.Value(GObject.TYPE_UINT, files))
Ejemplo n.º 12
0
    def add_user_row(self, userdata):

        username = userdata.username
        status = userdata.status
        country = userdata.country or ""  # country can be None, ensure string is used
        status_icon = get_status_icon(status) or get_status_icon(0)
        flag_icon = get_flag_icon_name(country)

        # Request user's IP address, so we can get the country and ignore messages by IP
        self.frame.np.queue.append(slskmessages.GetPeerAddress(username))

        h_speed = ""
        avgspeed = userdata.avgspeed

        if avgspeed > 0:
            h_speed = human_speed(avgspeed)

        files = userdata.files
        h_files = humanize(files)

        weight = Pango.Weight.NORMAL
        underline = Pango.Underline.NONE

        if self.room in self.frame.np.chatrooms.private_rooms:
            if username == self.frame.np.chatrooms.private_rooms[
                    self.room]["owner"]:
                weight = Pango.Weight.BOLD
                underline = Pango.Underline.SINGLE

            elif username in self.frame.np.chatrooms.private_rooms[
                    self.room]["operators"]:
                weight = Pango.Weight.BOLD
                underline = Pango.Underline.NONE

        iterator = self.usersmodel.insert_with_valuesv(
            -1, self.column_numbers, [
                status_icon, flag_icon, username, h_speed, h_files, status,
                GObject.Value(GObject.TYPE_UINT, avgspeed),
                GObject.Value(GObject.TYPE_UINT, files), country, weight,
                underline
            ])

        self.users[username] = iterator
Ejemplo n.º 13
0
    def get_user_stats(self, msg):

        iterator = self.recommendation_users.get(msg.user)

        if iterator is None:
            return

        h_speed = ""
        avgspeed = msg.avgspeed

        if avgspeed > 0:
            h_speed = human_speed(avgspeed)

        files = msg.files
        h_files = humanize(msg.files)

        self.recommendation_users_model.set_value(iterator, 2, h_speed)
        self.recommendation_users_model.set_value(iterator, 3, h_files)
        self.recommendation_users_model.set_value(
            iterator, 5, GObject.Value(GObject.TYPE_UINT, avgspeed))
        self.recommendation_users_model.set_value(
            iterator, 6, GObject.Value(GObject.TYPE_UINT, files))
Ejemplo n.º 14
0
    def get_user_stats(self, msg):

        user = msg.user
        iterator = self.user_iterators.get(user)

        if iterator is None:
            return

        h_speed = ""
        avgspeed = msg.avgspeed

        if avgspeed > 0:
            h_speed = human_speed(avgspeed)

        files = msg.files
        h_files = humanize(files)

        self.usersmodel.set_value(iterator, 3, h_speed)
        self.usersmodel.set_value(iterator, 4, h_files)
        self.usersmodel.set_value(iterator, 11,
                                  GObject.Value(GObject.TYPE_UINT64, avgspeed))
        self.usersmodel.set_value(iterator, 12,
                                  GObject.Value(GObject.TYPE_UINT64, files))
Ejemplo n.º 15
0
    def update_current_file(self):
        """ Updates the UI with properties for the selected file """

        properties = self.properties[self.current_index]
        self.navigation_buttons.set_visible(len(self.properties) > 1)

        self.filename_value.set_text(str(properties["filename"]))
        self.folder_value.set_text(str(properties["directory"]))
        self.filesize_value.set_text("%s (%s B)" % (human_size(properties["size"]), humanize(properties["size"])))
        self.username_value.set_text(str(properties["user"]))

        path = properties.get("path") or ""
        bitrate = properties.get("bitrate") or ""
        length = properties.get("length") or ""
        queue_position = properties.get("queue_position") or 0
        speed = properties.get("speed") or 0
        country = properties.get("country") or ""

        self.path_value.set_text(str(path))
        self.path.set_visible(bool(path))

        self.bitrate_value.set_text(str(bitrate))
        self.bitrate.set_visible(bool(bitrate))

        self.length_value.set_text(str(length))
        self.length.set_visible(bool(length))

        self.queue_value.set_text(str(humanize(queue_position)))
        self.queue.set_visible(bool(queue_position))

        self.speed_value.set_text(str(human_speed(speed)))
        self.speed.set_visible(bool(speed))

        self.country_value.set_text(str(country))
        self.country.set_visible(bool(country))

        self.update_title()
Ejemplo n.º 16
0
    def on_file_properties(self, *args):

        data = []

        for transfer in self.selected_transfers:
            user = transfer.user
            fullname = transfer.filename
            filename = fullname.split("\\")[-1]
            size = speed = length = queue = immediate = num = country = bitratestr = ""

            size = str(human_size(transfer.size))

            if transfer.speed:
                speed = str(human_speed(transfer.speed))

            bitratestr = str(transfer.bitrate)
            length = str(transfer.length)

            directory = fullname.rsplit("\\", 1)[0]

            data.append({
                "user": user,
                "fn": fullname,
                "position": num,
                "filename": filename,
                "directory": directory,
                "size": size,
                "speed": speed,
                "queue": queue,
                "immediate": immediate,
                "bitrate": bitratestr,
                "length": length,
                "country": country
            })

        if data:
            FileProperties(self.frame, data).show()
Ejemplo n.º 17
0
 def get_hspeed(speed):
     return human_speed(speed) if speed > 0 else ""
Ejemplo n.º 18
0
    def update_specific(self, transfer=None):

        currentbytes = transfer.currentbytes
        place = transfer.place or 0
        hplace = ""

        if place > 0:
            hplace = str(place)

        hspeed = helapsed = ""

        if currentbytes is None:
            currentbytes = 0

        status = transfer.status or ""
        hstatus = self.translate_status(status)

        try:
            size = int(transfer.size)
            if size < 0 or size > maxsize:
                size = 0
        except TypeError:
            size = 0

        hsize = "%s / %s" % (human_size(currentbytes), human_size(size))

        if transfer.modifier:
            hsize += " (%s)" % transfer.modifier

        speed = transfer.speed or 0
        elapsed = transfer.timeelapsed or 0
        left = transfer.timeleft or ""

        if speed > 0:
            speed = float(speed)
            hspeed = human_speed(speed)

        if elapsed > 0:
            helapsed = self.frame.np.transfers.get_time(elapsed)

        try:
            icurrentbytes = int(currentbytes)
            percent = min(((100 * icurrentbytes) / int(size)), 100)

        except Exception:
            icurrentbytes = 0
            percent = 100

        # Modify old transfer
        if transfer.iter is not None:
            initer = transfer.iter

            self.transfersmodel.set_value(initer, 3, hstatus)
            self.transfersmodel.set_value(initer, 4, hplace)
            self.transfersmodel.set_value(
                initer, 5, GObject.Value(GObject.TYPE_UINT64, percent))
            self.transfersmodel.set_value(initer, 6, hsize)
            self.transfersmodel.set_value(initer, 7, hspeed)
            self.transfersmodel.set_value(initer, 8, helapsed)
            self.transfersmodel.set_value(initer, 9, left)
            self.transfersmodel.set_value(initer, 11, status)
            self.transfersmodel.set_value(
                initer, 12, GObject.Value(GObject.TYPE_UINT64, size))
            self.transfersmodel.set_value(
                initer, 13, GObject.Value(GObject.TYPE_UINT64, currentbytes))
            self.transfersmodel.set_value(
                initer, 14, GObject.Value(GObject.TYPE_UINT64, speed))
            self.transfersmodel.set_value(
                initer, 15, GObject.Value(GObject.TYPE_UINT64, elapsed))
            self.transfersmodel.set_value(
                initer, 17, GObject.Value(GObject.TYPE_UINT64, place))

        else:
            fn = transfer.filename
            user = transfer.user
            shortfn = fn.split("\\")[-1]
            filecount = 1

            if self.tree_users != "ungrouped":
                # Group by folder or user

                empty_int = 0
                empty_str = ""

                if user not in self.users:
                    # Create Parent if it doesn't exist
                    # ProgressRender not visible (last column sets 4th column)
                    self.users[user] = self.transfersmodel.insert_with_values(
                        None, -1, self.column_numbers, [
                            user, empty_str, empty_str, empty_str, empty_str,
                            empty_int, empty_str, empty_str, empty_str,
                            empty_str, empty_str, empty_str, empty_int,
                            empty_int, empty_int, empty_int, filecount,
                            empty_int, lambda: None
                        ])

                parent = self.users[user]

                if self.tree_users == "folder_grouping":
                    # Group by folder
                    """ Paths can be empty if files are downloaded individually, make sure we
                    don't add files to the wrong user in the TreeView """
                    path = transfer.path
                    user_path = user + path
                    reverse_path = '/'.join(reversed(path.split('/')))

                    if user_path not in self.paths:
                        self.paths[
                            user_path] = self.transfersmodel.insert_with_values(
                                self.users[user], -1, self.column_numbers, [
                                    user, reverse_path, empty_str, empty_str,
                                    empty_str, empty_int, empty_str, empty_str,
                                    empty_str, empty_str, empty_str, empty_str,
                                    empty_int, empty_int, empty_int, empty_int,
                                    filecount, empty_int, lambda: None
                                ])

                    parent = self.paths[user_path]
            else:
                # No grouping
                # We use this list to get the total number of users
                self.users.setdefault(user, set()).add(transfer)
                parent = None

            # Add a new transfer
            if self.tree_users == "folder_grouping":
                # Group by folder, path not visible
                path = ""
            else:
                path = '/'.join(reversed(transfer.path.split('/')))

            iterator = self.transfersmodel.insert_with_values(
                parent, -1, self.column_numbers,
                (user, path, shortfn, hstatus, hplace,
                 GObject.Value(GObject.TYPE_UINT64,
                               percent), hsize, hspeed, helapsed, left, fn,
                 status, GObject.Value(GObject.TYPE_UINT64, size),
                 GObject.Value(GObject.TYPE_UINT64, icurrentbytes),
                 GObject.Value(GObject.TYPE_UINT64, speed),
                 GObject.Value(GObject.TYPE_UINT64, elapsed),
                 GObject.Value(GObject.TYPE_UINT64, filecount),
                 GObject.Value(GObject.TYPE_UINT64, place), transfer))
            transfer.iter = iterator

            # Expand path
            if parent is not None:
                transfer_path = self.transfersmodel.get_path(iterator)

                if self.tree_users == "folder_grouping":
                    # Group by folder, we need the user path to expand it
                    user_path = self.transfersmodel.get_path(self.users[user])
                else:
                    user_path = None

                self.expand(transfer_path, user_path)
Ejemplo n.º 19
0
    def update_parent_row(self, initer):

        speed = 0.0
        percent = totalsize = position = 0
        hspeed = helapsed = left = ""
        elapsed = 0
        filecount = 0
        salientstatus = ""
        extensions = {}

        iterator = self.transfersmodel.iter_children(initer)

        while iterator is not None:

            status = self.transfersmodel.get_value(iterator, 11)

            if salientstatus in (
                    '', "Finished",
                    "Filtered"):  # we prefer anything over ''/finished
                salientstatus = status

            filename = self.transfersmodel.get_value(iterator, 2)
            parts = filename.rsplit('.', 1)

            if len(parts) == 2:
                ext = parts[1]
                try:
                    extensions[ext.lower()] += 1
                except KeyError:
                    extensions[ext.lower()] = 1

            filecount += self.transfersmodel.get_value(iterator, 16)

            if status == "Filtered":
                # We don't want to count filtered files when calculating the progress
                iterator = self.transfersmodel.iter_next(iterator)
                continue

            elapsed += self.transfersmodel.get_value(iterator, 15)
            totalsize += self.transfersmodel.get_value(iterator, 12)
            position += self.transfersmodel.get_value(iterator, 13)

            if status == "Transferring":
                speed += float(self.transfersmodel.get_value(iterator, 14))
                left = self.transfersmodel.get_value(iterator, 9)

            if status in ("Transferring", "Banned", "Getting address",
                          "Establishing connection"):
                salientstatus = status

            iterator = self.transfersmodel.iter_next(iterator)

        if totalsize > 0:
            percent = min(((100 * position) / totalsize), 100)
        else:
            percent = 100

        if speed > 0:
            hspeed = human_speed(speed)
            left = self.frame.np.transfers.get_time(
                (totalsize - position) / speed)

        if elapsed > 0:
            helapsed = self.frame.np.transfers.get_time(elapsed)

        if not extensions:
            extensions = ""
        elif len(extensions) == 1:
            extensions = " (" + self.extension_list_template % {
                'ext': next(iter(extensions))
            } + ")"
        else:
            extensions = " (" + ", ".join(
                (str(count) + " " + ext
                 for (ext, count) in extensions.items())) + ")"

        self.transfersmodel.set_value(
            initer, 2,
            self.files_template % {'number': filecount} + extensions)
        self.transfersmodel.set_value(initer, 3,
                                      self.translate_status(salientstatus))
        self.transfersmodel.set_value(
            initer, 5, GObject.Value(GObject.TYPE_UINT64, percent))
        self.transfersmodel.set_value(
            initer, 6,
            "%s / %s" % (human_size(position), human_size(totalsize)))
        self.transfersmodel.set_value(initer, 7, hspeed)
        self.transfersmodel.set_value(initer, 8, helapsed)
        self.transfersmodel.set_value(initer, 9, left)
        self.transfersmodel.set_value(initer, 11, salientstatus)
        self.transfersmodel.set_value(
            initer, 12, GObject.Value(GObject.TYPE_UINT64, totalsize))
        self.transfersmodel.set_value(
            initer, 13, GObject.Value(GObject.TYPE_UINT64, position))
        self.transfersmodel.set_value(
            initer, 14, GObject.Value(GObject.TYPE_UINT64, speed))
        self.transfersmodel.set_value(
            initer, 15, GObject.Value(GObject.TYPE_UINT64, elapsed))
        self.transfersmodel.set_value(
            initer, 16, GObject.Value(GObject.TYPE_UINT64, filecount))
Ejemplo n.º 20
0
    def get_user_stats(self, msg):

        self.speed.set_text(_("Speed: %s") % human_speed(msg.avgspeed))
        self.filesshared.set_text(_("Files: %s") % humanize(msg.files))
        self.dirsshared.set_text(_("Directories: %s") % humanize(msg.dirs))
Ejemplo n.º 21
0
    def add_user_results(self, msg, user, country):

        if user in self.users:
            return

        self.users.add(user)

        counter = len(self.all_data) + 1

        inqueue = msg.inqueue
        ulspeed = msg.ulspeed
        h_speed = human_speed(ulspeed)

        if msg.freeulslots:
            imdl = "Y"
            inqueue = 0
        else:
            imdl = "N"

        color_id = (imdl == "Y" and "search" or "searchq")
        color = config.sections["ui"][color_id] or None

        h_queue = humanize(inqueue)

        update_ui = False
        maxstoredresults = config.sections["searches"]["max_stored_results"]

        for result in msg.list:

            if counter > maxstoredresults:
                break

            fullpath = result[1]
            fullpath_lower = fullpath.lower()

            if any(word in fullpath_lower
                   for word in self.searchterm_words_ignore):
                """ Filter out results with filtered words (e.g. nicotine -music) """
                log.add_search(
                    _("Filtered out excluded search result " + fullpath +
                      " from user " + user))
                continue

            if not any(word in fullpath_lower
                       for word in self.searchterm_words_include):
                """ Some users may send us wrong results, filter out such ones """
                log.add_search(
                    _("Filtered out inexact or incorrect search result " +
                      fullpath + " from user " + user))
                continue

            fullpath_split = reversed(fullpath.split('\\'))
            name = next(fullpath_split)
            directory = '\\'.join(fullpath_split)

            size = result[2]
            h_size = human_size(size)
            h_bitrate, bitrate, h_length, length = get_result_bitrate_length(
                size, result[4])

            is_result_visible = self.append([
                GObject.Value(GObject.TYPE_UINT64, counter), user,
                GObject.Value(GObject.TYPE_OBJECT,
                              self.frame.get_flag_image(country)), imdl,
                h_speed, h_queue, directory, name, h_size, h_bitrate, h_length,
                GObject.Value(GObject.TYPE_UINT64, bitrate), fullpath, country,
                GObject.Value(GObject.TYPE_UINT64, size),
                GObject.Value(GObject.TYPE_UINT64, ulspeed),
                GObject.Value(GObject.TYPE_UINT64, inqueue),
                GObject.Value(GObject.TYPE_UINT64, length),
                GObject.Value(GObject.TYPE_STRING, color)
            ])

            if is_result_visible:
                update_ui = True

            counter += 1

        if update_ui:
            # If this search wasn't initiated by us (e.g. wishlist), and the results aren't spoofed, show tab
            if not self.showtab:
                self.searches.show_tab(self, self.id, self.text, self.mode)
                self.showtab = True

            # Update number of results
            self.update_result_counter()

            # Update tab notification
            self.frame.searches.request_changed(self.Main)
            self.frame.request_tab_icon(self.frame.SearchTabLabel)