2024-01-02 19:01:33 +01:00
|
|
|
#!/bin/perl
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
use feature("signatures");
|
2023-11-21 15:17:44 +01:00
|
|
|
|
2024-01-02 19:01:33 +01:00
|
|
|
use File::Basename;
|
|
|
|
use Cwd;
|
|
|
|
|
2024-01-02 19:22:21 +01:00
|
|
|
sub fs_root ($file_name) {
|
|
|
|
chomp( my $ret = `stat -c %m $file_name` );
|
2024-01-02 19:01:33 +01:00
|
|
|
return $ret;
|
|
|
|
}
|
|
|
|
|
2024-01-02 19:22:21 +01:00
|
|
|
sub trash_dir ($file_fs_root) {
|
2024-01-02 19:01:33 +01:00
|
|
|
my $data_path = "$ENV{'XDG_DATA_HOME'}" // "$ENV{'HOME'}/.local/share";
|
|
|
|
|
2024-01-02 19:22:21 +01:00
|
|
|
return "$data_path/Trash/" if ( $file_fs_root eq fs_root($data_path) );
|
2024-01-02 19:01:33 +01:00
|
|
|
return "$file_fs_root/.Trash/";
|
|
|
|
}
|
|
|
|
|
2024-01-02 19:22:21 +01:00
|
|
|
sub trashed_files ( $search_path, $trash_path ) {
|
2024-01-02 19:01:33 +01:00
|
|
|
my @ret;
|
2024-01-02 19:22:21 +01:00
|
|
|
opendir( my $dir, "$trash_path/info" ) or die "$!\n";
|
|
|
|
for ( readdir $dir ) {
|
|
|
|
$_ =~ /\.~\d~$/ or next;
|
|
|
|
open( FH, "<", "$trash_path/info/$_" ) or next;
|
|
|
|
<FH> eq "[Trash Info]\n" or next;
|
|
|
|
my ( $name, $path, $suffix ) =
|
|
|
|
fileparse( ( <FH> =~ /(?<=Path=)(.+)$/ )[0] );
|
2024-01-02 19:01:33 +01:00
|
|
|
$path =~ /^$search_path\/?$/ or next;
|
2024-01-02 19:22:21 +01:00
|
|
|
my $deletion_date = ( <FH> =~ /(?<=DeletionDate=)(.+)$/ )[0];
|
|
|
|
chomp( $deletion_date = `date -d ${deletion_date} +'%x %X'` );
|
|
|
|
push( @ret, [ $path, "${name}${suffix}", $deletion_date, $_ ] );
|
2024-01-02 19:01:33 +01:00
|
|
|
}
|
|
|
|
return @ret;
|
2022-10-22 16:35:03 +02:00
|
|
|
}
|
2024-01-02 19:01:33 +01:00
|
|
|
|
2024-01-02 19:22:21 +01:00
|
|
|
sub fzf_files (@files) {
|
2024-01-02 19:01:33 +01:00
|
|
|
my $n = 0;
|
|
|
|
my $str;
|
|
|
|
for my $e (@files) {
|
|
|
|
$str .= "\n" if $n > 0;
|
|
|
|
$str .= "$n | $$e[2] | $$e[1]";
|
|
|
|
$n++;
|
|
|
|
}
|
|
|
|
chomp($str);
|
2024-01-02 19:22:21 +01:00
|
|
|
my $sel = `echo '$str' | fzf`;
|
2024-01-02 19:01:33 +01:00
|
|
|
!$sel and exit;
|
2024-01-02 19:22:21 +01:00
|
|
|
my $index = substr( $sel, 0, index( $sel, ' ' ) );
|
2024-01-02 19:01:33 +01:00
|
|
|
return $index;
|
2022-10-22 16:35:03 +02:00
|
|
|
}
|
|
|
|
|
2024-01-02 19:01:33 +01:00
|
|
|
# NOTE: Execution starts here
|
|
|
|
#
|
|
|
|
my $target_directory;
|
2024-01-02 19:22:21 +01:00
|
|
|
if ( $#ARGV + 1 > 1 ) {
|
2024-01-02 19:01:33 +01:00
|
|
|
die "Bad Arguments\n";
|
2024-01-02 19:22:21 +01:00
|
|
|
}
|
|
|
|
elsif ( $#ARGV + 1 == 1 ) {
|
2024-01-02 19:01:33 +01:00
|
|
|
$target_directory = shift;
|
2024-01-02 19:22:21 +01:00
|
|
|
chomp( $target_directory = `realpath -s $target_directory` );
|
2024-01-02 19:01:33 +01:00
|
|
|
stat $target_directory or die "$!\n";
|
2024-01-02 19:22:21 +01:00
|
|
|
}
|
|
|
|
else {
|
2024-01-02 19:01:33 +01:00
|
|
|
$target_directory = getcwd();
|
|
|
|
}
|
2023-11-16 14:06:50 +01:00
|
|
|
|
2024-01-02 19:22:21 +01:00
|
|
|
my $trash_dir = trash_dir( fs_root($target_directory) );
|
|
|
|
my @files = trashed_files( $target_directory, $trash_dir );
|
2024-01-02 19:01:33 +01:00
|
|
|
!@files and exit;
|
|
|
|
my $index = fzf_files(@files);
|
2022-10-22 16:35:03 +02:00
|
|
|
|
2024-01-02 19:01:33 +01:00
|
|
|
my $file_dest = $files[$index][0] . $files[$index][1];
|
2024-01-02 19:22:21 +01:00
|
|
|
my $file_src = $trash_dir . "files/" . $files[$index][3];
|
2024-01-02 19:01:33 +01:00
|
|
|
my $file_info = $trash_dir . "info/" . $files[$index][3];
|
2024-01-02 19:22:21 +01:00
|
|
|
|
2024-01-04 18:14:25 +01:00
|
|
|
rename( $file_src, $file_dest ) or die "$!\n";
|
2024-01-02 19:01:33 +01:00
|
|
|
unlink($file_info);
|