davydovcloud-setup/services/tools/cli/create_hardlinks.py
2025-06-17 00:44:34 +03:00

119 lines
3.7 KiB
Python
Executable File

#!/usr/bin/env python3
import os
import sys
import argparse
from argparse import ArgumentParser
from args_utils import dir_arg_type
from base import BaseCli
CLI_DESCRIPTION='''
Create hard links of files from source to destination.
'''
class CreateHardlinksCli(BaseCli):
def configure_args(self, parser: ArgumentParser):
parser.add_argument(
'-s',
'--source',
required=True,
help="Source folder"
)
parser.add_argument(
'-d',
'--destination',
required=True,
help="Destination folder",
)
parser.add_argument(
'-v',
'--verbose',
help="Increase verbosity",
default=False,
action='store_true'
)
def process_args(self, parser: ArgumentParser):
args = parser.parse_args()
return args
def __init__(self):
parser = ArgumentParser(description=CLI_DESCRIPTION)
self.configure_args(parser)
self.args = self.process_args(parser)
super().__init__(debug=self.args.verbose)
def __create_file_ln__(self, src, dest):
if os.path.exists(dest):
self.debug(f"Hard link already exists: {dest} -> {src}")
else:
os.link(src, dest)
self.debug(f"Created hard link: {dest} -> {src}")
def create_hardlinks(self, src, dest):
if not os.path.exists(dest):
os.makedirs(dest)
self.info(f"Created destination directory: {dest}")
if os.path.isfile(src):
self.info('Source is a file. Hardlinking and quitting.')
dest_file = os.path.join(dest, os.path.basename(src))
self.__create_file_ln__(src, dest_file)
return
for dirpath, dirnames, filenames in os.walk(src):
relative_path = os.path.relpath(dirpath, src)
dest_dir = os.path.join(dest, relative_path)
if not os.path.exists(dest_dir):
os.makedirs(dest_dir)
self.debug(f"Created directory: {dest_dir}")
for filename in filenames:
src_file = os.path.join(dirpath, filename)
dest_file = os.path.join(dest_dir, filename)
self.__create_file_ln__(src_file, dest_file)
def print_tree(self, directory, level=0):
"""Print the directory tree."""
if level == 0:
self.info('Hardlinked Result:')
indent = " " * (level * 4)
print(f"{indent}{os.path.basename(directory)}/")
for item in os.listdir(directory):
path = os.path.join(directory, item)
if os.path.isdir(path):
self.print_tree(path, level + 1)
else:
print(f"{indent} {item}")
def count_files_in_directory(self, directory):
if not os.path.isdir(directory):
self.warning(f"Can't count files in {directory}, because it is a file")
return 0
total_files = 0
for dirpath, dirnames, filenames in os.walk(directory):
total_files += len(filenames)
return total_files
def start(self):
self.create_hardlinks(
self.args.source,
self.args.destination
)
self.print_tree(self.args.destination)
src_files = self.count_files_in_directory(self.args.source)
dest_files = self.count_files_in_directory(self.args.destination)
self.info(f'Files in source direcotry: {src_files}')
self.info(f'Files in destination directory: {dest_files}')
def main():
cli = CreateHardlinksCli()
cli.start()
if __name__ == "__main__":
main()