-
Notifications
You must be signed in to change notification settings - Fork 0
/
ydata
executable file
·214 lines (198 loc) · 4.67 KB
/
ydata
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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#!/bin/sh
# vi:et lbr noet sw=2 ts=2 tw=79 wrap
# Copyright 2019-2024 David Rabkin
# The script uses local variables which are not POSIX but supported by most
# shells. See:
# https://stackoverflow.com/q/18597697
# shellcheck disable=SC3043 # Uses local variables.
# The script downloads all new video from pre-configured acoounts in
# ytda.lst. It updates IDs of downloaded files at done.txt (ytda.dne in Github).
# The script could be ran by a cron job. Uses: curl, HandBrakeCLI, mp4track,
# renamr, rsync, transcode, transcode-video, yt-dlp.
# The script is ran by cron, the environment is stricked.
export \
LANG=en_US.UTF-8 \
LC_ALL=en_US.UTF-8 \
PATH="$PATH":/usr/local/bin
# shellcheck disable=SC2034 # Variable appears unused.
readonly \
BASE_APP_VERSION=0.9.20240102 \
BASE_MIN_VERSION=0.9.20231212
# shellcheck disable=SC1091 # File not following.
. base.sh
dir="$(realdir "$0")"/../cfg/ || die
AUT="$dir"ytda.aut
SRC="$dir"ytda.lst
unset dir
readonly \
ARC=/mnt/nas-ibx/ytb/app/done.txt \
AUD="$BASE_WIP"/aud \
AUT \
CKS=/mnt/nas-ibx/ytb/app/cookies.txt \
DST=/mnt/nas-ibx/ytb \
RES="$BASE_WIP"/res \
SRC \
VID="$BASE_WIP"/vid
# Calculates output table width for renamr and transcode utilities.
calc_wid() {
WID=$(($(tput cols) - $(printf '19700101-01:01:01 I ' | wc -m)))
[ "$WID" -le 1 ] && die Terminal\'s width "$(tput cold)" is too small.
readonly WID
}
# Makes sure every file was copied successfully to destination. Pass each file
# locally and verifies there is a file with a same name at destination.
check() {
local ndst=0 nsrc=0 pipe
pipe="$BASE_WIP"/pipe
mkfifo "$pipe"
find "$RES" -type f -exec basename {} \; >"$pipe" &
while read -r name; do
nsrc=$((nsrc + 1))
[ -f "$DST/$name" ] && ndst=$((ndst + 1))
done <"$pipe"
rm "$pipe"
# Keeps the results in case of a failure.
if [ $nsrc -eq 0 ] || [ $nsrc -ne $ndst ]; then
logw "There are $nsrc files in $RES, $ndst in $DST, keeps the results."
[ "$BASE_KEEP_WIP" = true ] || keep_arc
else
log "There are $nsrc files copied to $DST."
fi
}
# Converts to general formats.
convert() {
if ! isempty "$VID"; then
cd "$RES" || die Unable to change directory to "$RES".
{
transcode \
--act \
--dir "$VID" \
--out "$RES" \
--wid "$WID" \
2>&1 1>&3 3>&- | tologe
} \
3>&1 1>&2 | tolog
rm -f ./*.log
cd - || die Unable to change directory back.
fi
isempty "$AUD" ||
{
transcode \
--act \
--dir "$AUD" \
--mp3 \
--out "$RES" \
--wid "$WID" \
2>&1 1>&3 3>&- | tologe
} \
3>&1 1>&2 | tolog
}
# Downloads Youtube files.
download() {
# shellcheck disable=SC2086 # Double quote to prevent globbing.
{
yt-dlp \
$CKS_PARAM \
--add-metadata \
--batch-file=$SRC \
--download-archive $ARC \
--format bestvideo+bestaudio \
--merge-output-format mp4 \
--output "$VID/%(uploader)s-%(upload_date)s-%(title)s.%(ext)s" \
--playlist-reverse \
2>&1 1>&3 3>&- | tologe
} \
3>&1 1>&2 | tolog
isempty "$VID" || return 0
# Stops if there are no downloaded files.
cya There is no new downloaded video.
}
# Moves result to local archive.
keep_arc() {
local arc out who
who="$(id -nu 2>&1)" || {
loge "$who".
who=none
}
arc="${BASE_WIP%.*}_arc_$who"
if out="$(rm -fr "$arc" 2>&1)"; then
mkdir "$arc"
mv "$AUD" "$RES" "$VID" "$arc"
cp "$BASE_WIP"/log "$arc"
log The results are in "$arc".
else
loge "$out".
fi
}
# Downloads, renames, converts, uploads.
main() {
validate
download
calc_wid
rename
sort
convert
upload
check
}
# Renames all downloaded files to the same manner: ASCII, lower case, no
# spaces.
rename() {
{
renamr \
--act \
--dir "$VID" \
--wid "$WID" \
2>&1 1>&3 3>&- | tologe
} \
3>&1 1>&2 | tolog
}
# Sorts files to audio and video folders by authors.
sort() {
while read -r a; do
if file_exists "$VID/$a"*; then
mv "$VID/$a"* "$AUD"
fi
done <"$AUT"
}
# Makes sure that needed software packages are installed at the host.
validate() {
local dir
validate_cmd \
HandBrakeCLI \
mp4track \
renamr \
rsync \
tput \
transcode \
transcode-video \
yt-dlp
url_exists http://youtube.com || die Check internet connection.
iswritable $DST $ARC || die Some directories are not writable.
isreadable "$AUT" "$SRC" || die Some directories are not readable.
for dir in $RES $AUD $VID; do
mkdir -p "$dir" || die Unable to create "$dir".
done
if isreadable $CKS; then
log Uses cookie $CKS.
CKS_PARAM=--cookies\ $CKS
else
CKS_PARAM=''
fi
readonly CKS_PARAM
}
# Uploads the results to the destination.
upload() {
{
rsync \
--compress \
--human-readable \
--progress \
--verbose \
"$RES"/* $DST \
2>&1 1>&3 3>&- | tologe
} \
3>&1 1>&2 | tolog
}
# Starting point
main "$@"