blob: 8e2cd00d0c71b233097ef1e0a3bb188aaac788e8 (
plain) (
blame)
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
|
#!/usr/bin/env bash
set -eEuo pipefail
usage() {
cat <<'EOF'
Usage:
grab.sh -l <download_link> -r <rclone_remote> -u <upload_dir> -n <ntfy_topic> [options]
Required args:
-l, --link Direct download link for aria2c
-r, --remote Rclone remote name (example: gdrive)
-u, --upload-dir Destination directory on the remote (example: Movies/2026)
-n, --ntfy-topic ntfy topic to publish notifications to
Optional args:
-s, --ntfy-server ntfy server base URL (default: https://ntfy.sh)
--ntfy-token Bearer token for ntfy auth (or set NTFY_TOKEN env var)
-i, --item-name Name to include in notification titles/messages
-d, --delete-after Delete downloaded files after a successful upload
-h, --help Show this help message
Examples:
grab.sh -l "https://example.com/file.mkv" -r gdrive -u "Incoming" -n "my-topic" -i "Movie Night"
grab.sh --link "https://example.com/file.zip" --remote myremote --upload-dir "Backups/zips" --ntfy-topic "alerts" --delete-after --item-name "Backup Zip"
EOF
}
DOWNLOAD_LINK=""
RCLONE_REMOTE=""
UPLOAD_DIR=""
NTFY_TOPIC=""
NTFY_SERVER="https://ntfy.sh"
NTFY_TOKEN="${NTFY_TOKEN:-}"
ITEM_NAME=""
DELETE_AFTER="false"
CURRENT_STEP="initializing"
TMP_DIR=""
send_ntfy() {
local title="$1"
local message="$2"
local priority="${3:-default}"
local tags="${4:-}"
local url="${NTFY_SERVER%/}/${NTFY_TOPIC}"
local final_title="$title"
local final_message="$message"
if [[ -n "$ITEM_NAME" ]]; then
final_title="${ITEM_NAME} - ${title}"
final_message="Item: ${ITEM_NAME}\n${message}"
fi
local -a headers
headers=(
-H "Title: ${final_title}"
-H "Priority: ${priority}"
)
if [[ -n "$tags" ]]; then
headers+=( -H "Tags: ${tags}" )
fi
if [[ -n "$NTFY_TOKEN" ]]; then
headers+=( -H "Authorization: Bearer ${NTFY_TOKEN}" )
fi
if ! curl -fsS -m 15 -X POST "${headers[@]}" -d "$final_message" "$url" >/dev/null; then
echo "Warning: failed to publish ntfy notification (${title})." >&2
fi
}
on_error() {
local exit_code="$1"
local line_no="$2"
send_ntfy \
"grab.sh failed" \
"Step: ${CURRENT_STEP}\nExit code: ${exit_code}\nLine: ${line_no}" \
"high" \
"x,warning"
if [[ "$DELETE_AFTER" == "true" && -n "$TMP_DIR" && -d "$TMP_DIR" ]]; then
rm -rf "$TMP_DIR"
fi
}
while [[ $# -gt 0 ]]; do
case "$1" in
-l|--link)
DOWNLOAD_LINK="${2:-}"
shift 2
;;
-r|--remote)
RCLONE_REMOTE="${2:-}"
shift 2
;;
-u|--upload-dir)
UPLOAD_DIR="${2:-}"
shift 2
;;
-n|--ntfy-topic)
NTFY_TOPIC="${2:-}"
shift 2
;;
-s|--ntfy-server)
NTFY_SERVER="${2:-}"
shift 2
;;
--ntfy-token)
NTFY_TOKEN="${2:-}"
shift 2
;;
-i|--item-name)
ITEM_NAME="${2:-}"
shift 2
;;
-d|--delete-after)
DELETE_AFTER="true"
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown argument: $1" >&2
usage
exit 1
;;
esac
done
if [[ -z "$DOWNLOAD_LINK" || -z "$RCLONE_REMOTE" || -z "$UPLOAD_DIR" || -z "$NTFY_TOPIC" ]]; then
echo "Error: missing required arguments." >&2
usage
exit 1
fi
for cmd in aria2c rclone mktemp find curl; do
if ! command -v "$cmd" >/dev/null 2>&1; then
echo "Error: required command '$cmd' is not installed or not in PATH." >&2
exit 1
fi
done
trap 'on_error $? $LINENO' ERR
TMP_DIR="$(mktemp -d -p "$PWD" "grab.XXXXXX")"
DESTINATION="${RCLONE_REMOTE}:${UPLOAD_DIR%/}"
CURRENT_STEP="job-start"
CURRENT_STEP="download"
echo "Downloading with aria2c..."
send_ntfy "Download started" "Starting aria2c download." "default" "arrow_down"
aria2c \
--dir "$TMP_DIR" \
--auto-file-renaming=false \
--allow-overwrite=true \
"$DOWNLOAD_LINK"
CURRENT_STEP="verify-download"
if ! find "$TMP_DIR" -mindepth 1 -print -quit >/dev/null 2>&1; then
send_ntfy "Download empty" "Download directory is empty; upload aborted." "high" "warning"
echo "Error: download appears empty; nothing to upload." >&2
exit 1
fi
CURRENT_STEP="upload"
echo "Uploading to ${DESTINATION}..."
send_ntfy "Upload started" "Starting rclone copy to ${DESTINATION}." "default" "arrow_up"
rclone copy "$TMP_DIR" "$DESTINATION" --progress
send_ntfy "Upload complete" "rclone upload finished successfully." "default" "white_check_mark"
if [[ "$DELETE_AFTER" == "true" ]]; then
CURRENT_STEP="cleanup"
rm -rf "$TMP_DIR"
echo "Downloaded files deleted from: $TMP_DIR"
else
echo "Downloaded files kept at: $TMP_DIR"
fi
CURRENT_STEP="done"
echo "Done. Downloaded from '$DOWNLOAD_LINK' and uploaded to '$DESTINATION'."
send_ntfy "grabar done" "All steps completed successfully." "default" "tada"
|