Exemplo n.º 1
0
 def _entry_iterator(self, path):
     for entry in _scandir.scandir(path):
         if entry.is_dir():
             for _entry in self._entry_iterator(entry.path):
                 yield _entry
         else:
             yield entry
Exemplo n.º 2
0
    def test_scandir(self):
        import bookmarks._scandir as scandir
        import os

        p = os.path.abspath(os.path.join(__file__, os.pardir))

        it = scandir.scandir(unicode(p))
        for entry in it:
            self.assertIsInstance(entry, scandir.DirEntry)
            self.assertIsInstance(entry.name, unicode)
            self.assertIsInstance(entry.path, unicode)
Exemplo n.º 3
0
def count_assets(bookmark_path, ASSET_IDENTIFIER):
    n = 0
    for entry in _scandir.scandir(bookmark_path):
        if entry.name.startswith(u'.'):
            continue
        if not entry.is_dir():
            continue

        filepath = entry.path.replace(u'\\', u'/')

        if ASSET_IDENTIFIER:
            identifier = u'{}/{}'.format(filepath, ASSET_IDENTIFIER)
            if not QtCore.QFileInfo(identifier).exists():
                continue
        n += 1
    return n
Exemplo n.º 4
0
    def func_wrapper(*args, **kwargs):
        lockfile_info = QtCore.QFileInfo(get_lockfile_path())
        for entry in _scandir.scandir(lockfile_info.path()):
            if entry.is_dir():
                continue

            match = re.match(ur'session_[0-9]+\.lock', entry.name.lower())
            if not match:
                continue

            path = entry.path.replace(u'\\', u'/')
            pid = path.strip(u'.lock').split(u'_').pop()
            pid = int(pid)
            if pid not in psutil.pids():
                QtCore.QFile(path).remove()
        return func(*args, **kwargs)
Exemplo n.º 5
0
def walk(path):
    """This is a custom generator expression using scandir's `walk`.
    We're using the C module for performance's sake without python-native
    fallbacks. The method yields each found DirEntry.

    The used _scandir module itself is customized to contain the addittional
    ``DirEntry.relativepath(unicode: basepath)`` method and ``DirEntry.dirpath``
    attribute.

    Yields:
        DirEntry:   A ctype class.

    """
    try:
        it = _scandir.scandir(path=path)
    except OSError:
        return

    while True:
        try:
            try:
                entry = next(it)
            except StopIteration:
                break
        except OSError:
            return

        try:
            is_dir = entry.is_dir()
        except OSError:
            is_dir = False

        if not is_dir:
            yield entry

        try:
            is_symlink = entry.is_symlink()
        except OSError:
            is_symlink = False
        if not is_symlink:
            for entry in walk(entry.path):
                yield entry
Exemplo n.º 6
0
    def _entry_iterator(self, path):
        """We're using the saved keys to find and return the DirEntries
        corresponding to the saved favourites.

        """
        favourites = settings.local_settings.favourites()

        d = []

        for k in favourites:
            file_info = QtCore.QFileInfo(k)
            for entry in _scandir.scandir(file_info.path()):
                path = entry.path.replace(u'\\', u'/').lower()
                if path == k:
                    d.append(entry)
                    continue
                _k = common.proxy_path(path)
                if k.lower() == _k.lower():
                    d.append(entry)
        for entry in d:
            yield entry
Exemplo n.º 7
0
    def get_mode(self):
        """Return the current application mode."""
        lockfile_info = QtCore.QFileInfo(get_lockfile_path())
        for entry in _scandir.scandir(lockfile_info.path()):
            if entry.is_dir():
                continue
            path = entry.path
            if not path.endswith(u'.lock'):
                continue
            with open(path, 'r') as f:
                data = f.read()
            try:
                data = int(data.strip())
                if data == common.SynchronisedMode:
                    log.debug(u'Current application mode is `SoloMode`')
                    return common.SoloMode
            except:
                log.error(u'Error getting the current application mode.')

        log.debug(u'Current application mode is `SynchronisedMode`')
        return common.SynchronisedMode
Exemplo n.º 8
0
    def add_custom_fonts(self):
        """Load the fonts used by Bookmarks to the font database.

        """
        if u'bmRobotoMedium' in self.families():
            return

        p = u'{}/../rsc/fonts'.format(__file__)
        p = os.path.normpath(os.path.abspath(p))

        if not os.path.isdir(p):
            raise OSError('{} could not be found'.format(p))

        for entry in _scandir.scandir(p):
            if not entry.name.endswith(u'ttf'):
                continue
            idx = self.addApplicationFont(entry.path)
            if idx < 0:
                raise RuntimeError(
                    u'Failed to add required font to the application')
            family = self.applicationFontFamilies(idx)
            if not family:
                raise RuntimeError(
                    u'Failed to add required font to the application')
Exemplo n.º 9
0
    def set_task_folder(self, val):
        """Slot used to save task folder to the model instance and the local
        settings.

        Each subfolder inside the root folder, defined by``parent_path``,
        corresponds to a `key`. We use these keys to save model data associated
        with these folders.

        It's important to make sure the key we're about to set corresponds to an
        existing folder. We will use a reasonable default if the folder does not
        exist.

        """
        log.debug('set_task_folder({})'.format(val), self)
        try:
            k = u'activepath/task_folder'
            stored_value = settings.local_settings.value(k)
            stored_value = stored_value.lower(
            ) if stored_value else stored_value
            self._task_folder = self._task_folder.lower(
            ) if self._task_folder else self._task_folder
            val = val.lower() if val else val

            # Nothing to do for us when the parent is not set
            if not self.parent_path:
                return

            if self._task_folder is None and stored_value:
                self._task_folder = stored_value.lower()

            # We are in sync with a valid value set already
            if stored_value is not None and self._task_folder == val == stored_value:
                val = None
                return

            # We only have to update the local settings, the model is
            # already set
            if self._task_folder == val and val != stored_value:
                settings.local_settings.setValue(k, val)
                return

            if val is not None and val == self._task_folder:
                val = None
                return

            # Let's check the asset folder before setting
            # the key to make sure we're pointing at a valid folder
            path = u'/'.join(self.parent_path)
            entries = [f.name.lower() for f in _scandir.scandir(path)]
            if not entries:
                val = None
                self._task_folder = val
                return

            # The key is valid
            if val in entries:
                self._task_folder = val
                settings.local_settings.setValue(k, val)
                return

            # The new proposed task_folder does not exist but the old one is
            # valid. We'll just stick with the old value instead...
            if val not in entries and self._task_folder in entries:
                val = self._task_folder.lower()
                settings.local_settings.setValue(k, self._task_folder)
                return

            # And finally, let's try to revert to a fall-back...
            if val not in entries and u'scenes' in entries:
                val = u'scenes'
                self._task_folder = val
                settings.local_settings.setValue(k, val)
                return

            # All else... let's select the first folder
            val = entries[0].lower()
            self._task_folder = val
            settings.local_settings.setValue(k, val)
        except:
            log.error(u'Could not set task folder')
        finally:
            if not self.model_data():
                self.__initdata__()
            else:
                self.sort_data()
Exemplo n.º 10
0
    def __initdata__(self):
        """Bookmarks and assets are static. But files will be any number of """
        task_folder = self.task_folder()
        self.INTERNAL_MODEL_DATA[task_folder] = common.DataDict({
            common.FileItem:
            common.DataDict(),
            common.SequenceItem:
            common.DataDict()
        })

        flags = (QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled
                 | QtCore.Qt.ItemIsDropEnabled | QtCore.Qt.ItemIsEditable)
        data = self.model_data()

        if not self.parent_path:
            return

        # Thumbnail image
        default_thumbnail = images.ImageCache.get_rsc_pixmap(
            u'folder_sm', common.SECONDARY_TEXT, self.ROW_SIZE.height())
        default_thumbnail = default_thumbnail.toImage()

        parent_path = u'/'.join(self.parent_path)
        entries = sorted(([f for f in _scandir.scandir(parent_path)]),
                         key=lambda x: x.name)

        for entry in entries:
            if entry.name.startswith(u'.'):
                continue
            if not entry.is_dir():
                continue
            idx = len(data)
            data[idx] = common.DataDict({
                QtCore.Qt.DisplayRole:
                entry.name,
                QtCore.Qt.EditRole:
                entry.name,
                QtCore.Qt.StatusTipRole:
                entry.path.replace(u'\\', u'/'),
                QtCore.Qt.ToolTipRole:
                u'',
                QtCore.Qt.ToolTipRole:
                defaultpaths.get_description(entry.name),
                QtCore.Qt.SizeHintRole:
                self.ROW_SIZE,
                #
                common.FlagsRole:
                flags,
                common.ParentPathRole:
                self.parent_path,
                #
                common.FileInfoLoaded:
                False,
                common.ThumbnailLoaded:
                True,
                common.TodoCountRole:
                0,
                #
                common.IdRole:
                idx,
            })
            thread = self.threads[common.InfoThread][0]
            thread.add_to_queue(weakref.ref(data[idx]))
Exemplo n.º 11
0
    def __initdata__(self):
        """Collects the data needed to populate the bookmarks model by querrying
        the path stored in ``self.parent_path``.

        Note:
            Getting asset information is relatively cheap,
            hence the model does not have any threads associated with it.

        """
        def dflags():
            """The default flags to apply to the item."""
            return (QtCore.Qt.ItemNeverHasChildren | QtCore.Qt.ItemIsEnabled
                    | QtCore.Qt.ItemIsSelectable)

        if not self.parent_path:
            return
        if not all(self.parent_path):
            return

        task_folder = self.task_folder()
        dtype = self.data_type()

        self.INTERNAL_MODEL_DATA[task_folder] = common.DataDict({
            common.FileItem:
            common.DataDict(),
            common.SequenceItem:
            common.DataDict()
        })

        favourites = settings.local_settings.favourites()
        sfavourites = set(favourites)

        activeasset = settings.local_settings.value(u'activepath/asset')
        server, job, root = self.parent_path
        bookmark_path = u'{}/{}/{}'.format(server, job, root)

        # Let's get the identifier from the bookmark database
        db = bookmark_db.get_db(server, job, root)
        ASSET_IDENTIFIER = db.value(1, u'identifier', table='properties')

        nth = 1
        c = 0
        for entry in _scandir.scandir(bookmark_path):
            if entry.name.startswith(u'.'):
                continue
            if not entry.is_dir():
                continue

            filepath = entry.path.replace(u'\\', u'/')

            if ASSET_IDENTIFIER:
                identifier = u'{}/{}'.format(filepath, ASSET_IDENTIFIER)
                if not QtCore.QFileInfo(identifier).exists():
                    continue

            # Progress bar
            c += 1
            if not c % nth:
                self.progressMessage.emit(u'Found {} assets...'.format(c))
                QtWidgets.QApplication.instance().processEvents(
                    QtCore.QEventLoop.ExcludeUserInputEvents)

            filename = entry.name
            flags = dflags()

            if filepath.lower() in sfavourites:
                flags = flags | common.MarkedAsFavourite

            if activeasset:
                if activeasset.lower() == filename.lower():
                    flags = flags | common.MarkedAsActive

            idx = len(self.INTERNAL_MODEL_DATA[task_folder][dtype])
            name = re.sub(ur'[_]{1,}', u' ', filename).strip(u'_')
            self.INTERNAL_MODEL_DATA[task_folder][dtype][
                idx] = common.DataDict({
                    QtCore.Qt.DisplayRole:
                    name,
                    QtCore.Qt.EditRole:
                    filename,
                    QtCore.Qt.StatusTipRole:
                    filepath,
                    QtCore.Qt.SizeHintRole:
                    self.ROW_SIZE,
                    #
                    common.EntryRole: [
                        entry,
                    ],
                    common.FlagsRole:
                    flags,
                    common.ParentPathRole: (server, job, root, filename),
                    common.DescriptionRole:
                    u'',
                    common.TodoCountRole:
                    0,
                    common.FileDetailsRole:
                    u'',
                    common.SequenceRole:
                    None,
                    common.FramesRole: [],
                    common.FileInfoLoaded:
                    False,
                    common.StartpathRole:
                    None,
                    common.EndpathRole:
                    None,
                    #
                    common.ThumbnailLoaded:
                    False,
                    #
                    common.TypeRole:
                    common.FileItem,
                    #
                    common.SortByNameRole:
                    common.namekey(filepath),
                    common.SortByLastModifiedRole:
                    0,
                    common.SortBySizeRole:
                    0,
                    #
                    common.IdRole:
                    idx
                })

        # Explicitly emit signal to notify the other dependent model
        self.activeChanged.emit(self.active_index())