Ejemplo n.º 1
0
Archivo: finder.py Proyecto: Byron/bit
    def update(self, known_only=False):
        """Update our set of dropboxes to represent the latest state on disk
        @param known_only if True will not actually search for new dropboxes, but only check if existing dropboxes
        have had their configuration changed or were removed
        @return self"""
        def update_stat(dbpath, stat, db):
            try:
                new_stat = dbpath.stat()
            except OSError:
                del self.dropboxes[dbpath]
                self._dropbox_removed(db)
            else:
                if new_stat.st_size != stat.st_size or new_stat.st_mtime != stat.st_mtime:
                    self.dropboxes[dbpath] = (new_stat, db)
                    self._dropbox_changed(stat, new_stat, db)
                # end handle change
            # end handle dropbox doesn't exist
        # end utility to test stat

        if known_only:
            for dbpath, (stat, db) in self.dropboxes.iteritems():
                update_stat(dbpath, stat, db)
            # end for each stat, db
        else:
            seen_paths = set()
            for search_base in self.paths:
                if search_base.endswith(os.path.sep):
                    search_base = Path(search_base[:-1])
                # end assure we don't end with slash
                if not search_base.isdir():
                    log.warn("Skipping unaccessible search base at '%s'", search_base)
                    continue
                # end 
                log.debug("Searching for dropboxes under '%s' (depth=%i, glob='%s')", 
                                                search_base, self.max_depth, self.config_file_glob)

                num_dropboxes = 0  # Amount of dropboxes found for this search base
                for root, dirs, files in os.walk(search_base):
                    if root[len(search_base):].count(os.path.sep) == self.max_depth - 1:
                        del dirs[:]
                    # end handle aborting recursion

                    for match in (f for f in files if fnmatch(f, self.config_file_glob)):
                        dbpath = Path(root) / match
                        seen_paths.add(dbpath)
                        num_dropboxes += 1
                        if dbpath in self.dropboxes:
                            # check for change
                            stat, db = self.dropboxes[dbpath]
                            update_stat(dbpath, stat, db)
                        else:
                            # handle new dropbox
                            try:
                                stat = dbpath.stat()
                            except OSError:
                                log.error("Couldn't stat dropbox configuration at '%s' even though it was found during search", dbpath)
                            else:
                                dropbox = self.DropboxType(dbpath)
                                self.dropboxes[dbpath] = (stat, dropbox)
                                self._dropbox_added(stat, dropbox)
                            # end handle inaccessible config file (invalid ACL ?)
                        # end handle update or new
                    # end handle each match
                # end for each root, dir, files
                if num_dropboxes == 0:
                    log.warn("Didn't find a single dropbox in search base '%s'", search_base)
                # end info log
            # end for each search_base

            # Check for deleted
            for deleted_db_path in (set(self.dropboxes.keys()) - seen_paths):
                stat, db = self.dropboxes[deleted_db_path]
                del self.dropboxes[deleted_db_path]
                self._dropbox_removed(stat, db)
            # end for each deleted
        # end handle known only
        return self