def compare_and_save_fs_db(repo, fs_dir, do_checksum): if not os.path.exists(fs_dir): log.critical("Path '{}' does not exist.".format(fs_dir)) return if not common.db_length(repo.db_file): log.critical("Database is empty.") return status_files = {fname: open(repo.get_status_fname(fname), "w+") for fname, descr in config.STATUS_FILES_DESC.items()} lists_of_files = compare_fs_db(repo, fs_dir, do_checksum) log.warn("Done, {} files compared.".format(sum(map(len, lists_of_files.values())))) for fname, flist in lists_of_files.items(): log.info("{}: {}".format(config.STATUS_FILES_DESC[fname], len(flist))) status_f = status_files[fname] for entry in flist: relpath, info = entry common.print_a_file(relpath, info, status_f) for status_file in status_files.values(): status_file.close()
def update_database(repo, fs_dir, do_checksum): lists_of_files = status.compare_fs_db(repo, fs_dir, do_checksum, updating=True) new = lists_of_files[config.NEW_FILES] missing = lists_of_files[config.MISSING_FILES] good = lists_of_files[config.GOOD_FILES] different = lists_of_files[config.DIFFERENT_FILES] moved = lists_of_files[config.MOVED_FILES] # only skip MISSING to_save = list(good) to_update = list(different) if not do_checksum: # force checksum for database entry to_update += new else: to_save += new for fname, old_info in to_update: fs_fullpath = os.path.join(fs_dir, fname) info = common.get_file_info(fs_fullpath, do_checksum=True) to_save.append((fname, info)) for fname, info in moved: del info["moved_from"] to_save.append((fname, info)) # sort to match DB order to_save = sorted(to_save, key=lambda entry: entry[0]) tmp_db_file = "{}.tmp".format(repo.db_file) with open(tmp_db_file, "w+") as tmp_db_f: for fname, info in to_save: common.print_a_file(fname, info, tmp_db_f) try: os.remove(repo.db_file) except OSError: pass os.rename(tmp_db_file, repo.db_file) log.warn("Database updated.") log.info("{} entries untouched".format(len(good))) log.info("{} entries added".format(len(missing))) log.info("{} entries updated".format(len(different))) log.info("{} entries removed".format(len(new))) log.info("{} entries moved".format(len(moved))) status.do_clean(repo)