-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpack.sh
More file actions
executable file
·180 lines (150 loc) · 6.26 KB
/
pack.sh
File metadata and controls
executable file
·180 lines (150 loc) · 6.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#!/usr/bin/env bash
# exit when any command fails
set -e
TIMEFORMAT="Processed in %3lR"
SCRIPT_DIR=$(dirname "$0")
source "$SCRIPT_DIR/config/config.env"
source "$SCRIPT_DIR/bin/color"
export PATH="$SCRIPT_DIR/bin:$PATH"
version=$(cat $SCRIPT_DIR/version)
echo -e $UND"Packing script $version"$DEF
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
usage=$blu"
Usage: $(basename "$0") -i <input dir> -o <output dir> -p <pack dir (optional)> -t <threads (optional)>
Escape special characters in names if necessary, e.g. brackets: \[testdirectory\]
Use double quotes if the directory has spaces, e.g. \"This is a test directory\"
-h - This help.
Mandatory parameters:
-i <input dir> - Input directory or file to pack. Can be a pathname.
-o <output dir> - Output directory where the packed files will be written.
Do NOT use a pathname here, just a dirname.
Optional parameters:
-d <disc> - For packing multiple discs separately, pass each disc's folder with -d
e.g. -d 'disc 1' -d 'disc 2' -d 'disc 3'
-p <pack dir> - Packing directory where the project (packed files, txt, nzbs) will be stored
(default '<current dir>/packing').
-t <threads> - CPU threads (default = maximum threads).
"$DEF
while getopts ":hi:o:d:p:t:" opt; do
case "$opt" in
h)
echo -e "$usage"
exit
;;
i) input="$OPTARG" ;;
o) output="$OPTARG" ;;
d) discsArray+=("$OPTARG") ;; # multiple arguments to option, put the values in array https://stackoverflow.com/a/20761965
p) packdir="$OPTARG" ;;
t) threads="$OPTARG" ;;
:)
printf $red"missing argument for -%s\n"$DEF "$OPTARG"
echo -e "$usage"
exit 1
;;
esac
done
# mandatory arguments
if [[ -z "$input" ]] || [[ -z "$output" ]]; then
echo -e $red"Arguments -i and -o must be provided"$DEF
echo -e "$usage"
exit 1
fi
if [[ ! -e "$input" ]]; then
echo -e $red"$input is not valid or doesn't exist"$DEF
exit 1
fi
if [[ "$output" == */* ]]; then
echo -e $red"Output parameter '$output' should NOT be a pathname"$DEF
exit 1
fi
# optional arguments
if ((${#discsArray[@]} == 0)); then #if array length = 0, i.e. not set
discsArray[0]="*" # default
fi
if [[ -z $packdir ]]; then
workdir="$(pwd)/packing"
else
workdir=$(realpath "$packdir") # realpath removes any trailing slashes
fi
mkdir -p "$workdir"
echo -e "Packing (working) dir: $workdir\n"
if [[ -z "$threads" ]]; then
threads=$(nproc)
fi
if (($LENGTH_FILE < 6)) || (($LENGTH_PASSWORD < 6)); then
echo "Random length for filename or password should be > 6, change it in the config.env file."
exit 1
fi
# generate random chars for filename and password
FILENAME="$FILENAME_PREFIX"$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $LENGTH_FILE | head -n 1)
PASSWORD="$PASSWORD_PREFIX"$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $LENGTH_PASSWORD | head -n 1)
input_basename=$(basename "$input")
input_dirname=$(dirname "$input")
output_basename=$(basename "$output")
# do the work from the parent dir of the input file/dir
cd "$input_dirname"
# loop the array
count=1
for folder in "${discsArray[@]}"; do
disc="d$count"
# check size of array
len=${#discsArray[@]}
if ((len > 1)); then
output="$output-$disc"
FILENAME="$FILENAME-$disc"
input_basename="$input_basename/$folder"
fi
# write the filename/password to a file, so we don't lose it!
echo Filename: $FILENAME >"$workdir/$output.txt"
echo Password: $PASSWORD >>"$workdir/$output.txt"
echo Input file/dir: "$input_basename" >>"$workdir/$output.txt"
echo Output dir: "$output" >>"$workdir/$output.txt"
cat "$workdir/$output.txt"
rm -f "$workdir/$output-filelist.txt" # cleanup any previous file list
if [[ -d "$input_basename" ]]; then
find "$input_basename" -type f | sed 's/.*/"&"/' | sort >>"$workdir/$output-filelist.txt" # sort the files first, so they are packed in order
find "$input_basename" -type d | sed 's/.*/"&"/' | sort >>"$workdir/$output-filelist.txt" # must add the directories as well to preserve the timestamps
elif [[ -f "$input_basename" ]]; then
echo "$input_basename" >>"$workdir/$output-filelist.txt"
fi
[[ "$ASK_TO_EDIT_FILELIST" == true ]] &&
read -p "Edit the $workdir/$output-filelist.txt for any exclusions, then press any key to continue (or Ctrl-C to abort)" -n1 -s
nvm use lts/gallium
echo -e $UND"\nCreating RAR files using $threads CPU threads"$DEF
rm -rf "$workdir/$output"
mkdir -p "$workdir/$output"
time rar a -r -hp$PASSWORD -mt${threads} -m0 -v${RAR_BLOCKSIZE}b -tsm -tsc -tsa \
"$workdir/$output/$FILENAME".rar @"$workdir/$output-filelist.txt"
if [[ "$TEST_RARS" == true ]]; then
echo -e $UND"\nTesting RAR files"$DEF
first_par=$(ls "$workdir/$output/$FILENAME"*.rar | head -n 1)
if ! time rar -p$PASSWORD t -mt${threads} "$first_par" | grep "All OK"; then
echo -e $BLD"RAR testing problem, aborting"$DEF
exit 1
fi
else
echo -e $UND"\nSkipped testing the RAR files"$DEF
fi
echo -e $UND"\nCreating PAR2 files with $PAR2_BINARY using $threads CPU threads"$DEF
if [[ $PAR2_BINARY == "par2" ]]; then
time $PAR2_BINARY c -t$threads -s${PAR2_BLOCKSIZE} -r${PAR2_REDUNDANCY} -l -v \
"$workdir/$output/$FILENAME" "$workdir/$output/$FILENAME".p*
fi
if [[ $PAR2_BINARY == "parpar" ]]; then
SLICES_PER_FILE=$(($RAR_BLOCKSIZE / $PAR2_BLOCKSIZE))
echo "SLICES_PER_FILE=$SLICES_PER_FILE"
time $PAR2_BINARY -t$threads -s${PAR2_BLOCKSIZE}b -r${PAR2_REDUNDANCY}% -p $SLICES_PER_FILE -o \
"$workdir/$output/$FILENAME" "$workdir/$output/$FILENAME".p*
fi
echo -e $BLD"
Files (rar and par2) are stored in: $workdir/$output
Randomized filename and password are stored in: $workdir/$output.txt
"$DEF
# remove the appended -$disc with bash native replacement
output=${output/-$disc/}
FILENAME=${FILENAME/-$disc/}
input_basename=${input_basename/"/$folder"/}
count=$((count + 1))
done