Beispiel #1
0
    def directoryChangedEvent(self, childName):
        if childName:
            # If we're observing a folder and something changes (deep)
            # inside of it, notify.
            # TODO: keep a childrenByName dict so we won't have to loop
            for child in self.children.values():
                if child.name == childName:
                    childPath = os.path.join(self.path, child.name)
                    child.callCallbacks(childPath, childPath, True)
                    break
            return

        inodes = {}  # gather the inodes that _may_ have changed
        for name in os.listdir(self.path):
            childPath = os.path.join(self.path, name)
            st = os.stat(childPath)
            if st.st_ino in self.children:
                inodes[st.st_ino] = (name, st.st_mtime)

        # add inodes for files/folders that were no longer found
        for inode in set(self.children) - set(inodes):
            # This one moved away
            inodes[inode] = (self.children[inode].name, None)

        movedOrDeleted = []
        for inode, (name, modTime) in inodes.items():
            child = self.children[inode]
            oldPath = os.path.join(self.path, child.name)
            if modTime is None:
                # This file or folder moved somewhere else or got deleted. Let's find out
                # by resolving our bookmark data
                url, isStale, error = NSURL.URLByResolvingBookmarkData_options_relativeToURL_bookmarkDataIsStale_error_(
                        child.bookmarkData, 0, None, None, None)
                if url is None:
                    # file was deleted
                    newPath = None
                    child.name = None
                    wasModified = False
                else:
                    # TODO: Check whether it was moved to the trash, and treat special
                    # os.listdir() will fail on a Trash folder
                    newPath = url.path()
                    child.name = os.path.basename(newPath)  # update name
                    bookmarkData, error = url.bookmarkDataWithOptions_includingResourceValuesForKeys_relativeToURL_error_(
                            0, None, None, None)
                    assert error is None, error
                    child.bookmarkData = bookmarkData
                    wasModified = child.modTime != os.stat(newPath).st_mtime
                wasRenamed = True
                movedOrDeleted.append((inode, child, newPath))
            else:
                wasModified = child.modTime != modTime
                if wasModified:
                    child.modTime = modTime
                wasRenamed = child.name != name
                if wasRenamed:
                    child.name = name
                    newPath = os.path.join(self.path, name)
                else:
                    newPath = oldPath
            if wasRenamed or wasModified:
                child.callCallbacks(oldPath, newPath, wasModified)
        for inode, child, newPath in movedOrDeleted:
            del self.children[inode]
        return movedOrDeleted