Exemplo n.º 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]
Exemplo n.º 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]
Exemplo n.º 3
0
 def test_istag(self):
     self.assertTrue(dpath.istag('//tag'))
     self.assertTrue(dpath.istag('//tag/madoka'))
     self.assertFalse(dpath.istag('/tag'))
     self.assertFalse(dpath.istag('/tag/hi'))
     self.assertFalse(dpath.istag('tag'))
     self.assertFalse(dpath.istag('tag/bye'))
Exemplo n.º 4
0
def _fix_path(root, path):
    """Fixes path

    If path is a tag, return as is.  Otherwise rebase path to root.

    Args:
        root: A string.  Absolute path where FUSE is mounted.
        path: A string.  Path relative to root.

    """
    if dpath.istag(path):
        return path
    else:
        return _rebase_path(root, path)
Exemplo n.º 5
0
def _fix_path(root, path):
    """Fixes path

    If path is a tag, return as is.  Otherwise rebase path to root.

    Args:
        root: A string.  Absolute path where FUSE is mounted.
        path: A string.  Path relative to root.

    """
    if dpath.istag(path):
        return path
    else:
        return _rebase_path(root, path)
Exemplo n.º 6
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
Exemplo n.º 7
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
Exemplo n.º 8
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)
Exemplo n.º 9
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)
Exemplo n.º 10
0
 def rmtag(self, tag):
     if dpath.istag(tag):
         shutil.rmtree(dpath.pathfromtag(tag, self.root))
     else:
         shutil.rmtree(tag)
Exemplo n.º 11
0
 def mktag(self, tag):
     if dpath.istag(tag):
         os.mkdir(dpath.pathfromtag(tag, self.root))
     else:
         os.mkdir(tag)
Exemplo n.º 12
0
 def rmtag(self, tag):
     if dpath.istag(tag):
         shutil.rmtree(dpath.pathfromtag(tag, self.root))
     else:
         shutil.rmtree(tag)
Exemplo n.º 13
0
 def mktag(self, tag):
     if dpath.istag(tag):
         os.mkdir(dpath.pathfromtag(tag, self.root))
     else:
         os.mkdir(tag)