Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve User Experience by Implementing Multi-Select #88 #111

Merged
merged 6 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,8 @@ venv.bak/
dmypy.json

*.db-journal
*.db
*.db

/issue

test.py
Empty file.
70 changes: 39 additions & 31 deletions twinTrim/flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
import click
import time
import logging
import inquirer
from collections import defaultdict
from twinTrim.utils import handle_and_remove, parse_size
from twinTrim.flagController import handleAllFlag, find_duplicates
from beaupy import select_multiple
from twinTrim.dataStructures.fileFilter import FileFilter

#Setting up logging configuration
# Setting up logging configuration
logging.basicConfig (
filename='duplicate_file_manager.log', #log the file name
level = logging.INFO, #Set the logging level
format = '%(asctime)s - %(levelname)s - %(message)s' #log message format
filename='duplicate_file_manager.log',
level = logging.INFO,
format = '%(asctime)s - %(levelname)s - %(message)s'
)

@click.command()
Expand All @@ -26,7 +26,7 @@
@click.option("--bar-color", default='#aaaaaa', type=str, help="Color of the progress bar.")
def cli(directory, all, min_size, max_size, file_type, exclude, label_color, bar_color):
"""Find and manage duplicate files in the specified DIRECTORY."""

# Initialize the FileFilter object
file_filter = FileFilter()
file_filter.setMinFileSize(parse_size(min_size))
Expand All @@ -36,21 +36,20 @@ def cli(directory, all, min_size, max_size, file_type, exclude, label_color, bar
file_filter.addFileExclude(file_name)

if all:
logging.info("Deleting all duplicate files whithout asking.")
logging.info("Deleting all duplicate files without asking.")
handleAllFlag(directory, file_filter, label_color, bar_color)
return

start_time = time.time()
logging.info(f"Searching for duplicates in directory: {directory}")

try:
duplicates = find_duplicates(directory, file_filter, label_color, bar_color)
except Exception as e:
logging.error(f"Error finding duplicates: {str(e)}")
click.echo(click.style("Error while finding duplicates. Check the log for details.", fg='red'))
return


if not duplicates:
click.echo(click.style("No duplicate files found.", fg='green'))
logging.info("No duplicate files found.")
Expand All @@ -70,30 +69,39 @@ def cli(directory, all, min_size, max_size, file_type, exclude, label_color, bar
logging.info(f"Original file: \"{original}\" with {len(duplicates_list)} duplicates")

click.echo(click.style("They are:", fg='cyan'))
file_options = [f"{idx + 1}) {duplicate}" for idx, duplicate in enumerate(duplicates_list)]

# Prompt user to select which files to delete
selected_indices = select_multiple(
file_options, # List of files to choose from
ticked_indices=[], # Default indices that are selected
maximal_count=len(file_options)
)

# Convert the indices back to the original file paths
files_to_delete = [duplicates_list[int(option.split(")")[0]) - 1] for option in selected_indices]

for file_path in files_to_delete:
try:
handle_and_remove(file_path)
logging.info(f"Deleted duplicate file: {file_path}")
except Exception as e:
logging.error(f"Error deleting file {file_path}: {str(e)}")
click.echo(click.style(f"Error deleting file: {file_path}. Check the log for details.", fg='red'))

# Create file options with additional information
file_options = [
f"{idx + 1}) {duplicate} (Size: {os.path.getsize(duplicate)} bytes)" for idx, duplicate in enumerate(duplicates_list)
]

answers = inquirer.prompt(
[
inquirer.Checkbox(
'files',
message="Select files to delete (Use space to select, enter to confirm, or ctr + c to cancel, arrow key to navigate.)",
choices=file_options,
validate=lambda answer, current: len(answer) > 0 or "You must choose at least one file.",
),
inquirer.Confirm(
'confirm',
message="Are you sure you want to delete the selected files?",
default=True
)
])


if answers and answers['confirm']:
selected_files = answers['files']
# Convert the selected options back to the original file paths
files_to_delete = [duplicates_list[int(option.split(")")[0]) - 1] for option in selected_files]

for file_path in files_to_delete:
handle_and_remove(file_path)
else:
click.echo(click.style("File deletion canceled.", fg='yellow'))

end_time = time.time()
time_taken = end_time - start_time
click.echo(click.style(f"Time taken: {time_taken:.2f} seconds.", fg='green'))
logging.info(f"Total time taken: {time_taken:.2f} seconds.")


logging.info(f"Total time taken: {time_taken:.2f} seconds.")
Loading