rewrite trash-put, trash-restore in perl
This commit is contained in:
parent
1d12edc767
commit
ee07e0f5c2
|
@ -1,27 +1,72 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
getfsroot() {
|
||||
printf "%s" "$(df "$1" --output=target | tail -1)"
|
||||
#!/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
use feature("signatures");
|
||||
|
||||
use File::Copy;
|
||||
use File::Path("make_path");
|
||||
use List::Util("max");
|
||||
|
||||
sub fs_root($file_name) {
|
||||
chomp(my $ret = `stat -c %m $file_name`);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
filepath="$(realpath -s "$1")"
|
||||
filename="$(basename "$1")"
|
||||
fsroot="$(getfsroot "$1")"
|
||||
[ "$fsroot" = "$(getfsroot "${XDG_DATA_HOME:-$HOME/.local/share}")" ] &&
|
||||
basedir="${XDG_DATA_HOME:-$HOME/.local/share}/Trash" ||
|
||||
basedir="${fsroot}/.Trash"
|
||||
infodir="$basedir/info"
|
||||
filedir="$basedir/files"
|
||||
sub file_info($file) {
|
||||
my $file_name = `basename $file`;
|
||||
my $file_path = `realpath -s $file`;
|
||||
my $file_fs_root = fs_root($file_name);
|
||||
|
||||
mkdir -p "$infodir" 1>/dev/null 2>&1
|
||||
mkdir -p "$filedir" 1>/dev/null 2>&1
|
||||
find "$filedir" -regex ".*$filename.*" | grep -oP '(?<=.\.~)\d+(?=~$)' | sort -n | tail -1 | (
|
||||
ext=$(($(cat /dev/stdin) + 1))
|
||||
filedest="$filedir/$filename.~$ext~"
|
||||
command mv -f "$filepath" "$filedest"
|
||||
cat <<EOF >"$infodir/$(basename "$filedest")"
|
||||
chomp($file_name, $file_path, $file_fs_root);
|
||||
return ($file_name, $file_path, $file_fs_root);
|
||||
}
|
||||
|
||||
sub trash_dirs($file_fs_root) {
|
||||
my $data_path = "$ENV{'XDG_DATA_HOME'}" // "$ENV{'HOME'}/.local/share";
|
||||
|
||||
my $trash_dir;
|
||||
if ($file_fs_root eq fs_root($data_path)) {
|
||||
$trash_dir = "$data_path/Trash/";
|
||||
} else {
|
||||
$trash_dir = "$file_fs_root/.Trash/"
|
||||
}
|
||||
|
||||
return "${trash_dir}info", "${trash_dir}files";
|
||||
}
|
||||
|
||||
sub target_file_name($file_name, $trash_file_path) {
|
||||
opendir(my $dir, "$trash_file_path") or die "$!\n";
|
||||
my $existing_suffix_nums = map(($_ =~ /^${file_name}\.~(\d)~/), readdir $dir);
|
||||
my $suffix_num = max($existing_suffix_nums) + 1;
|
||||
my $suffix = "~" . $suffix_num . "~";
|
||||
closedir($dir);
|
||||
|
||||
return "${file_name}.${suffix}";
|
||||
}
|
||||
|
||||
sub write_file($file_path, $contents) {
|
||||
open(FH, '>', $file_path) or die "$!\n";
|
||||
print FH $contents;
|
||||
}
|
||||
|
||||
# NOTE: Execution starts here
|
||||
|
||||
if ($#ARGV + 1 != 1) {
|
||||
die "Bad Arguments\n";
|
||||
}
|
||||
|
||||
stat $ARGV[0] or die "$!\n";
|
||||
my ($file_name, $file_src, $file_fs_root) = file_info($ARGV[0]);
|
||||
my ($trash_info_path, $trash_file_path) = trash_dirs($file_fs_root);
|
||||
my $target_name = target_file_name($file_name, $trash_file_path);
|
||||
chomp(my $deletion_time = `date -u +%Y%m%dUTC%T`);
|
||||
|
||||
my $info_contents = <<EOF;
|
||||
[Trash Info]
|
||||
Path=$filepath
|
||||
DeletionDate=$(date -u +%Y%m%dUTC%T)
|
||||
Path=$file_src
|
||||
DeletionDate=$deletion_time
|
||||
EOF
|
||||
)
|
||||
|
||||
make_path($trash_info_path, $trash_file_path);
|
||||
move($file_src, "$trash_file_path/$target_name") or die "$!\n";
|
||||
write_file("$trash_info_path/$target_name", $info_contents) or die "$!\n";
|
||||
|
|
|
@ -1,32 +1,81 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
#!/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
use feature("signatures");
|
||||
|
||||
getfsroot() {
|
||||
printf "%s" "$(df "$1" --output=target | tail -1)"
|
||||
}
|
||||
list() {
|
||||
# 1st arg is trash files directory
|
||||
# 2nd arg is directory to match trash files for
|
||||
[ ! "$(command ls -A "$1")" ] && exit 1
|
||||
while read -r file; do
|
||||
filepath=$(grep Path "$file" | cut -d '=' -f2) || continue
|
||||
echo "$filepath" | grep -qP "^$2/[^/]+$" || continue
|
||||
printf "%s %s %s\n" "$(basename "$file")" "$filepath" "$(date -d "$(grep DeletionDate "$file" | cut -d '=' -f2)" +'%x %X')"
|
||||
done <<EOF
|
||||
$(grep -l '[Trash Info]' "$1"/* "$1"/.* 2>/dev/null)
|
||||
EOF
|
||||
use File::Basename;
|
||||
use File::Copy;
|
||||
use Cwd;
|
||||
|
||||
sub fs_root($file_name) {
|
||||
chomp(my $ret = `stat -c %m $file_name`);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
fsroot="$(getfsroot "$PWD")"
|
||||
sub trash_dir($file_fs_root) {
|
||||
my $data_path = "$ENV{'XDG_DATA_HOME'}" // "$ENV{'HOME'}/.local/share";
|
||||
|
||||
if [ "$fsroot" = "$(getfsroot "${XDG_DATA_HOME:-$HOME/.local/share}")" ]; then
|
||||
basedir="${XDG_DATA_HOME:-$HOME/.local/share}/Trash"
|
||||
else
|
||||
basedir="${fsroot}/.Trash"
|
||||
fi
|
||||
return "$data_path/Trash/" if ($file_fs_root eq fs_root($data_path));
|
||||
return "$file_fs_root/.Trash/";
|
||||
}
|
||||
|
||||
sel="$(list "$basedir/info" "$PWD" | fzf)"
|
||||
file="$basedir/files/$(echo "$sel" | cut -d '' -f1)"
|
||||
dest="$(echo "$sel" | cut -d '' -f3)"
|
||||
mv -ib "$file" "$dest"
|
||||
rm "$basedir/info/$(echo "$sel" | cut -d '' -f1)"
|
||||
sub trashed_files($search_path, $trash_path) {
|
||||
my @ret;
|
||||
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]);
|
||||
$path =~ /^$search_path\/?$/ or next;
|
||||
|
||||
my $deletion_date = (<FH> =~ /(?<=DeletionDate=)(.+)$/)[0];
|
||||
chomp($deletion_date = `date -d ${deletion_date} +'%x %X'`);
|
||||
push(@ret, [$path, "${name}${suffix}", $deletion_date, $_]);
|
||||
}
|
||||
|
||||
return @ret;
|
||||
}
|
||||
|
||||
sub fzf_files(@files) {
|
||||
my $n = 0;
|
||||
|
||||
my $str;
|
||||
for my $e (@files) {
|
||||
$str .= "\n" if $n > 0;
|
||||
$str .= "$n | $$e[2] | $$e[1]";
|
||||
$n++;
|
||||
}
|
||||
chomp($str);
|
||||
my $sel =`echo '$str' | fzf`;
|
||||
!$sel and exit;
|
||||
my $index = substr($sel, 0, index($sel, ' '));
|
||||
return $index;
|
||||
}
|
||||
|
||||
# NOTE: Execution starts here
|
||||
#
|
||||
my $target_directory;
|
||||
if ($#ARGV + 1 > 1) {
|
||||
die "Bad Arguments\n";
|
||||
} elsif ($#ARGV + 1 == 1) {
|
||||
$target_directory = shift;
|
||||
chomp($target_directory = `realpath -s $target_directory`);
|
||||
stat $target_directory or die "$!\n";
|
||||
} else {
|
||||
$target_directory = getcwd();
|
||||
}
|
||||
|
||||
my $trash_dir = trash_dir(fs_root($target_directory));
|
||||
my @files = trashed_files($target_directory, $trash_dir);
|
||||
!@files and exit;
|
||||
my $index = fzf_files(@files);
|
||||
|
||||
my $file_dest = $files[$index][0] . $files[$index][1];
|
||||
my $file_src = $trash_dir . "files/" . $files[$index][3];
|
||||
my $file_info = $trash_dir . "info/" . $files[$index][3];
|
||||
move($file_src, $file_dest) or die "$!\n";
|
||||
unlink($file_info);
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
getfsroot() {
|
||||
printf "%s" "$(df "$1" --output=target | tail -1)"
|
||||
}
|
||||
|
||||
filepath="$(realpath -s "$1")"
|
||||
filename="$(basename "$1")"
|
||||
fsroot="$(getfsroot "$1")"
|
||||
[ "$fsroot" = "$(getfsroot "${XDG_DATA_HOME:-$HOME/.local/share}")" ] &&
|
||||
basedir="${XDG_DATA_HOME:-$HOME/.local/share}/Trash" ||
|
||||
basedir="${fsroot}/.Trash"
|
||||
infodir="$basedir/info"
|
||||
filedir="$basedir/files"
|
||||
|
||||
mkdir -p "$infodir" 1>/dev/null 2>&1
|
||||
mkdir -p "$filedir" 1>/dev/null 2>&1
|
||||
find "$filedir" -regex ".*$filename.*" | grep -oP '(?<=.\.~)\d+(?=~$)' | sort -n | tail -1 | (
|
||||
ext=$(($(cat /dev/stdin) + 1))
|
||||
filedest="$filedir/$filename.~$ext~"
|
||||
command mv -f "$filepath" "$filedest"
|
||||
cat <<EOF >"$infodir/$(basename "$filedest")"
|
||||
[Trash Info]
|
||||
Path=$filepath
|
||||
DeletionDate=$(date -u +%Y%m%dUTC%T)
|
||||
EOF
|
||||
)
|
|
@ -0,0 +1,32 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
getfsroot() {
|
||||
printf "%s" "$(df "$1" --output=target | tail -1)"
|
||||
}
|
||||
list() {
|
||||
# 1st arg is trash files directory
|
||||
# 2nd arg is directory to match trash files for
|
||||
[ ! "$(command ls -A "$1")" ] && exit 1
|
||||
while read -r file; do
|
||||
filepath=$(grep Path "$file" | cut -d '=' -f2) || continue
|
||||
echo "$filepath" | grep -qP "^$2/[^/]+$" || continue
|
||||
printf "%s %s %s\n" "$(basename "$file")" "$filepath" "$(date -d "$(grep DeletionDate "$file" | cut -d '=' -f2)" +'%x %X')"
|
||||
done <<EOF
|
||||
$(grep -l '[Trash Info]' "$1"/* "$1"/.* 2>/dev/null)
|
||||
EOF
|
||||
}
|
||||
|
||||
fsroot="$(getfsroot "$PWD")"
|
||||
|
||||
if [ "$fsroot" = "$(getfsroot "${XDG_DATA_HOME:-$HOME/.local/share}")" ]; then
|
||||
basedir="${XDG_DATA_HOME:-$HOME/.local/share}/Trash"
|
||||
else
|
||||
basedir="${fsroot}/.Trash"
|
||||
fi
|
||||
|
||||
sel="$(list "$basedir/info" "$PWD" | fzf)"
|
||||
file="$basedir/files/$(echo "$sel" | cut -d '' -f1)"
|
||||
dest="$(echo "$sel" | cut -d '' -f3)"
|
||||
mv -ib "$file" "$dest"
|
||||
rm "$basedir/info/$(echo "$sel" | cut -d '' -f1)"
|
Loading…
Reference in New Issue