Пример #1
0
    def find(self, tags):
        """Return a list of files with all of the given tags.

        Parameters
        ----------
        tags : list
            List of tags.  List is not changed.

        Returns
        -------
        list
            List of absolute paths, to the hard link under the first tag
            given.

        """
        logger.debug("find(%r)", tags)
        assert len(tags) > 0
        tagpaths = (dpath.pathfromtag(tag, self.root) if dpath.istag(tag) else
                    tag for tag in tags)
        inodes = (set(os.lstat(x) for x in dpath.listdir(path))
                  for path in tagpaths)
        inodes = functools.reduce(set.intersection, inodes)
        logger.debug("found unique inodes %r", inodes)
        map = dict((os.lstat(x), x) for x in dpath.listdir(
            dpath.pathfromtag(tags[0], self.root)))
        logger.debug("using map %r", map)
        return [map[x] for x in inodes]
Пример #2
0
    def find(self, tags):
        """Return a list of files with all of the given tags.

        Parameters
        ----------
        tags : list
            List of tags.  List is not changed.

        Returns
        -------
        list
            List of absolute paths, to the hard link under the first tag
            given.

        """
        logger.debug("find(%r)", tags)
        assert len(tags) > 0
        tagpaths = (dpath.pathfromtag(tag, self.root)
                    if dpath.istag(tag) else tag for tag in tags)
        inodes = (set(os.lstat(x) for x in dpath.listdir(path))
                  for path in tagpaths)
        inodes = functools.reduce(set.intersection, inodes)
        logger.debug("found unique inodes %r", inodes)
        map = dict(
            (os.lstat(x), x)
            for x in dpath.listdir(dpath.pathfromtag(tags[0], self.root)))
        logger.debug("using map %r", map)
        return [map[x] for x in inodes]
Пример #3
0
 def create(self, path, mode):
     logger.debug("create(%r, %r)", path, mode)
     node, path = self._getnode(path)
     if len(path) == 1 and isinstance(node, tree.TagNode):
         t = list(node.tags)
         file = path[0]
         path = os.path.join(dpath.pathfromtag(t.pop(0), self.root), file)
         fd = os.open(path, os.O_WRONLY | os.O_CREAT, mode)
         for tag in t:
             self.root.tag(path, tag)
         return fd
     else:
         fd = os.open(_getpath(node, path), os.O_WRONLY | os.O_CREAT, mode)
         return fd
Пример #4
0
    def tag(self, file, tag):
        """Tag file with tag.

        If `file` is already tagged, nothing happens.  This includes if
        the file is hardlinked under another name.

        Parameters
        ----------
        file : str
             Path to the file, relative to the working directory.
        tag : str
            Tag, relative to the library root, starting with '/'.

        Raises
        ------
        IsADirectoryError
            file is an unconverted directory.
        NotADirectoryError
            tag is not a directory/tag.

        """

        file = os.path.normpath(file)  # get rid of trailing slashes
        if os.path.isdir(file) and not os.path.islink(file):
            raise IsADirectoryError(
                '{} is a directory; convert it first'.format(file))
        if dpath.istag(tag):
            p_dest = dpath.pathfromtag(tag, self.root)
        else:
            if not os.path.isdir(tag):
                raise NotADirectoryError(
                    '{} is not a directory/tag'.format(tag))
            p_dest = tag
        logger.info(
            'Checking if %r is already tagged with %r', file, tag)
        for f in dpath.listdir(p_dest):
            if os.path.samefile(f, file):
                return
        logger.info('Check okay')
        name = os.path.basename(file)
        while True:
            dest = os.path.join(p_dest, dpath.resolve_name(p_dest, name))
            logger.debug('linking %r %r', file, dest)
            try:
                os.link(file, dest)
            except FileExistsError:
                continue
            else:
                break
Пример #5
0
    def tag(self, file, tag):
        """Tag file with tag.

        If `file` is already tagged, nothing happens.  This includes if
        the file is hardlinked under another name.

        Parameters
        ----------
        file : str
             Path to the file, relative to the working directory.
        tag : str
            Tag, relative to the library root, starting with '/'.

        Raises
        ------
        IsADirectoryError
            file is an unconverted directory.
        NotADirectoryError
            tag is not a directory/tag.

        """

        file = os.path.normpath(file)  # get rid of trailing slashes
        if os.path.isdir(file) and not os.path.islink(file):
            raise IsADirectoryError(
                '{} is a directory; convert it first'.format(file))
        if dpath.istag(tag):
            p_dest = dpath.pathfromtag(tag, self.root)
        else:
            if not os.path.isdir(tag):
                raise NotADirectoryError(
                    '{} is not a directory/tag'.format(tag))
            p_dest = tag
        logger.info('Checking if %r is already tagged with %r', file, tag)
        for f in dpath.listdir(p_dest):
            if os.path.samefile(f, file):
                return
        logger.info('Check okay')
        name = os.path.basename(file)
        while True:
            dest = os.path.join(p_dest, dpath.resolve_name(p_dest, name))
            logger.debug('linking %r %r', file, dest)
            try:
                os.link(file, dest)
            except FileExistsError:
                continue
            else:
                break
Пример #6
0
    def untag(self, file, tag):
        """Remove tag from file.

        If file is not tagged, nothing happens.  Remove *all* hard
        links to the file in the directory corresponding to the given
        tag.  Log a warning when an OSError is caught.

        Parameters
        ----------
        file : str
             Path to the file, relative to the working directory.
        tag : str
            Tag, relative to the library root, starting with '/'.

        Raises
        ------
        NotADirectoryError
            tag is not a directory/tag.

        """
        logger.debug('untag(%r, %r)', file, tag)
        assert isinstance(file, str)
        assert isinstance(tag, str)
        if dpath.istag(tag):
            p_dest = dpath.pathfromtag(tag, self.root)
        else:
            if not os.path.isdir(tag):
                raise NotADirectoryError(
                    '{} is not a directory/tag'.format(tag))
            p_dest = tag
        inode = os.lstat(file)
        logger.debug('file inode is %r', inode)
        for f in dpath.listdir(p_dest):
            logger.debug('checking %r', f)
            st = os.lstat(f)
            logger.debug('inode is %r', st)
            if os.path.samestat(inode, st):
                logger.debug('unlinking %r', f)
                try:
                    os.unlink(f)
                except OSError as e:
                    logger.warning('Caught OSError: %s', e)
Пример #7
0
    def untag(self, file, tag):
        """Remove tag from file.

        If file is not tagged, nothing happens.  Remove *all* hard
        links to the file in the directory corresponding to the given
        tag.  Log a warning when an OSError is caught.

        Parameters
        ----------
        file : str
             Path to the file, relative to the working directory.
        tag : str
            Tag, relative to the library root, starting with '/'.

        Raises
        ------
        NotADirectoryError
            tag is not a directory/tag.

        """
        logger.debug('untag(%r, %r)', file, tag)
        assert isinstance(file, str)
        assert isinstance(tag, str)
        if dpath.istag(tag):
            p_dest = dpath.pathfromtag(tag, self.root)
        else:
            if not os.path.isdir(tag):
                raise NotADirectoryError(
                    '{} is not a directory/tag'.format(tag))
            p_dest = tag
        inode = os.lstat(file)
        logger.debug('file inode is %r', inode)
        for f in dpath.listdir(p_dest):
            logger.debug('checking %r', f)
            st = os.lstat(f)
            logger.debug('inode is %r', st)
            if os.path.samestat(inode, st):
                logger.debug('unlinking %r', f)
                try:
                    os.unlink(f)
                except OSError as e:
                    logger.warning('Caught OSError: %s', e)
Пример #8
0
 def rmtag(self, tag):
     if dpath.istag(tag):
         shutil.rmtree(dpath.pathfromtag(tag, self.root))
     else:
         shutil.rmtree(tag)
Пример #9
0
 def mktag(self, tag):
     if dpath.istag(tag):
         os.mkdir(dpath.pathfromtag(tag, self.root))
     else:
         os.mkdir(tag)
Пример #10
0
 def rmtag(self, tag):
     if dpath.istag(tag):
         shutil.rmtree(dpath.pathfromtag(tag, self.root))
     else:
         shutil.rmtree(tag)
Пример #11
0
 def mktag(self, tag):
     if dpath.istag(tag):
         os.mkdir(dpath.pathfromtag(tag, self.root))
     else:
         os.mkdir(tag)
Пример #12
0
 def test_pathfromtag(self):
     r = os.getcwd()
     o = os.path.join(r, 'tag')
     self.assertEquals(dpath.pathfromtag('//tag', r), o)