import pathlib from pathlib import Path import os import pandas as pd import argparse def get_inode_path(p: Path): return {'inode': os.stat(p, follow_symlinks=False).st_ino, 'path':p} def more_than_one_link(filename): return os.stat(filename).st_nlink == 2 def list_inode(directory): print("hardlinks:" + str(directory)) ino_path = [] for p in directory.rglob('*'): if "eaDir" not in str(p): if Path(p).is_symlink() is False and more_than_one_link(p): ino_set = get_inode_path(Path(p)) ino_path.append(ino_set) return(ino_path) def replace_hdlink_with_symlink(table_linkPaths): for idx, row in table_linkPaths.iterrows(): link = row['path_downloads'].resolve() target = row['path_library'].resolve() target_name = target.name relpath_parent = os.path.relpath(path=target.parent, start=link.parent) print("Remove: " + str(link)) os.remove(link) link.symlink_to(os.path.join(relpath_parent, target_name)) if __name__ == "__main__": parser = argparse.ArgumentParser(description = 'convert hardlink to symlink in download folder') parser.add_argument('Download', metavar='--download', type=str, help='the path to downloadfolder (e.g. downloads/complete)') parser.add_argument('Library', metavar='--library', type=str, help='the path to library foler (e.g. Movies)') args = parser.parse_args() path_download = args.Download path_library = args.Library library_files = list_inode(Path(path_library)) download_files = list_inode(Path(path_download)) df_library = pd.DataFrame(library_files) df_library.columns = ['inode', 'path_library'] df_library.to_csv('df_library.csv') df_downloads = pd.DataFrame(download_files) df_downloads.columns = ['inode', 'path_downloads'] df_downloads.to_csv('df_downloads.csv') merged_df = pd.merge(left=df_downloads, right=df_library, on = 'inode') print(merged_df.shape) print(merged_df) # replace_hdlink_with_symlink(merged_df)