Example #1
0
    def _delayed_recalc(self):
        self._timeout = None

        tv = self.get_tree_view()
        assert tv is not None
        range_ = tv.get_visible_range()
        if not range_:
            return

        start, end = range_
        start = start[0]
        end = end[0]

        # compute the cell width for all drawn cells in range +/- 3
        for key, value in listitems(self._texts):
            if not (start - 3) <= key <= (end + 3):
                del self._texts[key]
            elif isinstance(value, string_types):
                self._texts[key] = self._cell_width(value)

        # resize if too small or way too big and above the minimum
        width = self.get_width()
        needed_width = max([self._get_min_width()] + listvalues(self._texts))
        if width < needed_width:
            self._resize(needed_width)
        elif width - needed_width >= self._cell_width("0"):
            self._resize(needed_width)
Example #2
0
    def _delayed_recalc(self):
        self._timeout = None

        tv = self.get_tree_view()
        assert tv is not None
        range_ = tv.get_visible_range()
        if not range_:
            return

        start, end = range_
        start = start[0]
        end = end[0]

        # compute the cell width for all drawn cells in range +/- 3
        for key, value in listitems(self._texts):
            if not (start - 3) <= key <= (end + 3):
                del self._texts[key]
            elif isinstance(value, string_types):
                self._texts[key] = self._cell_width(value)

        # resize if too small or way too big and above the minimum
        width = self.get_width()
        needed_width = max([self._get_min_width()] + listvalues(self._texts))
        if width < needed_width:
            self._resize(needed_width)
        elif width - needed_width >= self._cell_width("0"):
            self._resize(needed_width)
Example #3
0
    def sanitize(self, filename=None):
        """Fill in metadata defaults. Find ~mountpoint, ~#mtime, ~#filesize
        and ~#added. Check for null bytes in tags.

        Does not raise.
        """

        # Replace nulls with newlines, trimming zero-length segments
        for key, val in listitems(self):
            self[key] = val
            if isinstance(val, string_types) and '\0' in val:
                self[key] = '\n'.join(filter(lambda s: s, val.split('\0')))
            # Remove unnecessary defaults
            if key in NUMERIC_ZERO_DEFAULT and val == 0:
                del self[key]

        if filename:
            self["~filename"] = filename
        elif "~filename" not in self:
            raise ValueError("Unknown filename!")

        assert isinstance(self["~filename"], fsnative)

        if self.is_file:
            self["~filename"] = normalize_path(
                self["~filename"], canonicalise=True)
            # Find mount point (terminating at "/" if necessary)
            head = self["~filename"]
            while "~mountpoint" not in self:
                head, tail = os.path.split(head)
                # Prevent infinite loop without a fully-qualified filename
                # (the unit tests use these).
                head = head or fsnative(u"/")
                if ismount(head):
                    self["~mountpoint"] = head
        else:
            self["~mountpoint"] = fsnative(u"/")

        # Fill in necessary values.
        self.setdefault("~#added", int(time.time()))

        # For efficiency, do a single stat here. See Issue 504
        try:
            stat = os.stat(self['~filename'])
            self["~#mtime"] = stat.st_mtime
            self["~#filesize"] = stat.st_size

            # Issue 342. This is a horrible approximation (due to headers) but
            # on FLACs, the most common case, this should be close enough
            if "~#bitrate" not in self:
                try:
                    # kbps = bytes * 8 / seconds / 1000
                    self["~#bitrate"] = int(stat.st_size /
                                            (self["~#length"] * (1000 / 8)))
                except (KeyError, ZeroDivisionError):
                    pass
        except OSError:
            self["~#mtime"] = 0
Example #4
0
    def sanitize(self, filename=None):
        """Fill in metadata defaults. Find ~mountpoint, ~#mtime, ~#filesize
        and ~#added. Check for null bytes in tags.

        Does not raise.
        """

        # Replace nulls with newlines, trimming zero-length segments
        for key, val in listitems(self):
            self[key] = val
            if isinstance(val, string_types) and '\0' in val:
                self[key] = '\n'.join(filter(lambda s: s, val.split('\0')))
            # Remove unnecessary defaults
            if key in NUMERIC_ZERO_DEFAULT and val == 0:
                del self[key]

        if filename:
            self["~filename"] = filename
        elif "~filename" not in self:
            raise ValueError("Unknown filename!")

        assert isinstance(self["~filename"], fsnative)

        if self.is_file:
            self["~filename"] = normalize_path(self["~filename"],
                                               canonicalise=True)
            # Find mount point (terminating at "/" if necessary)
            head = self["~filename"]
            while "~mountpoint" not in self:
                head, tail = os.path.split(head)
                # Prevent infinite loop without a fully-qualified filename
                # (the unit tests use these).
                head = head or fsnative(u"/")
                if ismount(head):
                    self["~mountpoint"] = head
        else:
            self["~mountpoint"] = fsnative(u"/")

        # Fill in necessary values.
        self.setdefault("~#added", int(time.time()))

        # For efficiency, do a single stat here. See Issue 504
        try:
            stat = os.stat(self['~filename'])
            self["~#mtime"] = stat.st_mtime
            self["~#filesize"] = stat.st_size

            # Issue 342. This is a horrible approximation (due to headers) but
            # on FLACs, the most common case, this should be close enough
            if "~#bitrate" not in self:
                try:
                    # kbps = bytes * 8 / seconds / 1000
                    self["~#bitrate"] = int(stat.st_size / (self["~#length"] *
                                                            (1000 / 8)))
                except (KeyError, ZeroDivisionError):
                    pass
        except OSError:
            self["~#mtime"] = 0
Example #5
0
    def rescan(self):
        """Rescan all folders for changed/new/removed modules.

        The caller should release all references to removed modules.

        Returns a tuple: (removed, added)
        """

        print_d("Rescanning..")

        info = {}

        # get what is there atm
        for folder in self.__folders:
            for name, path, deps in get_importables(folder, True):
                # take the basename as module key, later modules win
                info[name] = (path, deps)

        # python can not unload a module, so we can only add new ones
        # or reload if the path is the same and mtime changed,
        # but we can still pretend we removed something

        removed = []
        added = []

        # remove those that are gone and changed ones
        for name, mod in listitems(self.__modules):
            # not here anymore, remove
            if name not in info:
                del self.__modules[name]
                removed.append(name)
                continue

            # check if any dependency has changed
            path, new_deps = info[name]
            if mod.has_changed(new_deps):
                del self.__modules[name]
                removed.append(name)

        self.__failures.clear()

        # add new ones
        for (name, (path, deps)) in iteritems(info):
            if name in self.__modules:
                continue

            try:
                # add a real module, so that pickle works
                # https://github.com/quodlibet/quodlibet/issues/1093
                parent = "quodlibet.fake"
                if parent not in sys.modules:
                    sys.modules[parent] = imp.new_module(parent)
                vars(sys.modules["quodlibet"])["fake"] = sys.modules[parent]

                mod = load_module(name, parent + ".plugins",
                                  dirname(path), reload=True)
                if mod is None:
                    continue

            except Exception as err:
                text = format_exception(*sys.exc_info())
                self.__failures[name] = ModuleImportError(name, err, text)
            else:
                added.append(name)
                self.__modules[name] = Module(name, mod, deps, path)

        print_d("Rescanning done: %d added, %d removed, %d error(s)" %
                (len(added), len(removed), len(self.__failures)))

        return removed, added
Example #6
0
    def rescan(self):
        """Rescan all folders for changed/new/removed modules.

        The caller should release all references to removed modules.

        Returns a tuple: (removed, added)
        """

        print_d("Rescanning..")

        info = {}

        # get what is there atm
        for folder in self.__folders:
            for name, path, deps in get_importables(folder, True):
                # take the basename as module key, later modules win
                info[name] = (path, deps)

        # python can not unload a module, so we can only add new ones
        # or reload if the path is the same and mtime changed,
        # but we can still pretend we removed something

        removed = []
        added = []

        # remove those that are gone and changed ones
        for name, mod in listitems(self.__modules):
            # not here anymore, remove
            if name not in info:
                del self.__modules[name]
                removed.append(name)
                continue

            # check if any dependency has changed
            path, new_deps = info[name]
            if mod.has_changed(new_deps):
                del self.__modules[name]
                removed.append(name)

        self.__failures.clear()

        # add new ones
        for (name, (path, deps)) in iteritems(info):
            if name in self.__modules:
                continue

            try:
                # add a real module, so that pickle works
                # https://github.com/quodlibet/quodlibet/issues/1093
                parent = "quodlibet.fake"
                if parent not in sys.modules:
                    sys.modules[parent] = imp.new_module(parent)
                vars(sys.modules["quodlibet"])["fake"] = sys.modules[parent]

                mod = load_module(name,
                                  parent + ".plugins",
                                  dirname(path),
                                  reload=True)
                if mod is None:
                    continue

            except Exception as err:
                text = format_exception(*sys.exc_info())
                self.__failures[name] = ModuleImportError(name, err, text)
            else:
                added.append(name)
                self.__modules[name] = Module(name, mod, deps, path)

        print_d("Rescanning done: %d added, %d removed, %d error(s)" %
                (len(added), len(removed), len(self.__failures)))

        return removed, added