-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathp5-check.sh
More file actions
352 lines (287 loc) · 10.8 KB
/
p5-check.sh
File metadata and controls
352 lines (287 loc) · 10.8 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
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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
#!/bin/sh
# Copyright Mat X 2025 - All Rights Reserved
# Check if files in a given folder were archived by Archiware P5
# Modified for Xcode app integration with progress reporting
# Path to nsdchat
chatcmd="/usr/local/aw/bin/nsdchat -c"
# Check if nsdchat exists
if [ ! -f "/usr/local/aw/bin/nsdchat" ]; then
echo "ERROR:NSDCHAT_NOT_FOUND" >&2
exit 2
fi
# Verify nsdchat is executable
if [ ! -x "/usr/local/aw/bin/nsdchat" ]; then
echo "ERROR:NSDCHAT_NOT_EXECUTABLE" >&2
exit 3
fi
# Get the current timestamp
now=$(date +"%Y-%m-%d_%H%M%S")
# Lightweight log file
logfile="/private/tmp/p5-check.log"
# Progress file for Swift to monitor
progressfile="/private/tmp/p5-progress-${now}.txt"
# start fresh
: > "$logfile"
: > "$progressfile"
# Function for logging with timestamp
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$logfile"
}
# Function to report progress (for Swift UI to monitor)
report_progress() {
local progress_val="$1"
local message="$2"
if [ -n "$progress_val" ]; then
echo "progress: $progress_val" >> "$progressfile"
fi
if [ -n "$message" ]; then
echo "message: $message" >> "$progressfile"
fi
# Also log it
log "Progress: $progress_val% - $message"
}
log "=== Script started at $now ==="
report_progress 0 "Initializing..."
# Ask user for drag-drop folder if not provided
if [ -z "${1:-}" ]; then
log "No folder argument provided; expecting an argument."
echo "ERROR:NO_FOLDER_PROVIDED" >&2
exit 1
else
storage_path="$1"
log "Using provided path: $storage_path"
fi
# Validate path
if [ ! -d "$storage_path" ]; then
log "Error: Invalid folder path: $storage_path"
echo "ERROR:INVALID_FOLDER_PATH:$storage_path" >&2
exit 1
fi
report_progress 5 "Validating folder access..."
# Create/clear temp files up front
tmpdir="/private/tmp"
files_txt="$tmpdir/files-${now}.txt"
files2_txt="$tmpdir/files2-${now}.txt"
files_handle="$tmpdir/files-handle-${now}.txt"
files_nohandle="$tmpdir/files-nohandle-${now}.txt"
files_status="$tmpdir/files-status-${now}.txt"
files_size="$tmpdir/files-size-${now}.txt"
files_size_converted="$tmpdir/files-size-converted-${now}.txt"
files_btime="$tmpdir/files-btime-${now}.txt"
files_btime_converted="$tmpdir/files-btime-converted-${now}.txt"
files_volume="$tmpdir/files-volume-${now}.txt"
files_barcode="$tmpdir/files-barcode-${now}.txt"
output_csv="$tmpdir/output-${now}.csv"
output_final="$tmpdir/output_final-${now}.csv"
# Ensure all temp files exist (clear them)
for tmpfile in "$files_txt" "$files2_txt" "$files_handle" "$files_nohandle" \
"$files_status" "$files_size" "$files_size_converted" \
"$files_btime" "$files_btime_converted" "$files_volume" \
"$files_barcode" "$output_csv" "$output_final"; do
: > "$tmpfile"
done
log "Temp files created/cleared in $tmpdir"
report_progress 10 "Building file list..."
# Build file list (exclude meta files)
log "Building file list..."
find "$storage_path" -type f \
-not -name '*.DS_Store' \
-not -name '.*' \
-not -name '*.p5c' \
-not -name '*.p5a' \
-print > "$files_txt" 2>/dev/null
total=$(wc -l < "$files_txt" 2>/dev/null | tr -d ' ')
log "Total files found: $total"
if [ "$total" -eq 0 ]; then
log "Warning: No files found in $storage_path"
report_progress 100 "No files found to check"
echo "No files found in folder" > "$files_nohandle"
summary="/Users/Shared/${now}-Files-To-Archive-$(basename "$storage_path").txt"
cp "$files_nohandle" "$summary"
echo "RESULT:SUMMARY:$summary" >&1
exit 0
fi
report_progress 15 "Found $total files. Querying P5..."
# Process: get handle for each file
log "Querying P5 handles (writing results to $files_handle and $files_nohandle)..."
i=0
query_start=15
query_end=60
while IFS= read -r file; do
i=$((i + 1))
# Calculate progress (15% to 60% for this phase)
if [ "$total" -gt 0 ]; then
progress=$((query_start + (i * (query_end - query_start) / total)))
# Update every 10 files or on significant progress changes
if [ $((i % 10)) -eq 0 ] || [ $((i % (total / 10 + 1))) -eq 0 ]; then
report_progress "$progress" "Checking file $i of $total..."
fi
fi
# Query P5 for handle
handle=$($chatcmd ArchiveEntry handle localhost "{${file}}" 2>/dev/null || true)
if [ -n "$handle" ]; then
echo "$handle" >> "$files_handle"
printf '%s\t%s\n' "$file" "$handle" >> "${files_handle}.map"
else
echo "$file" >> "$files_nohandle"
fi
done < "$files_txt"
report_progress 60 "Handles collected. Processing archive details..."
# Derive files2.txt as those that have handles
if [ -s "$files_nohandle" ]; then
grep -v -F -f "$files_nohandle" "$files_txt" > "$files2_txt" 2>/dev/null || : > "$files2_txt"
else
cp "$files_txt" "$files2_txt"
fi
handles_count=$(wc -l < "$files_handle" 2>/dev/null | tr -d ' ')
nohandle_count=$(wc -l < "$files_nohandle" 2>/dev/null | tr -d ' ')
log "Handles collected: $handles_count"
log "No-handle entries: $nohandle_count"
# If there are handles, fetch detailed information
if [ -s "$files_handle" ] && [ "$handles_count" -gt 0 ]; then
report_progress 65 "Fetching archive status..."
log "Fetching status for each handle..."
while IFS= read -r handle; do
$chatcmd ArchiveEntry "$handle" status 2>/dev/null >> "$files_status" || echo "" >> "$files_status"
done < "$files_handle"
report_progress 70 "Fetching file sizes..."
log "Fetching size for each handle..."
while IFS= read -r handle; do
$chatcmd ArchiveEntry "$handle" size 2>/dev/null >> "$files_size" || echo "0" >> "$files_size"
done < "$files_handle"
report_progress 75 "Converting sizes..."
log "Converting sizes to GB..."
awk '{printf "%.3f\n", ($1+0)/1024/1024/1024}' "$files_size" > "$files_size_converted" 2>/dev/null || : > "$files_size_converted"
report_progress 80 "Fetching backup times..."
log "Fetching btime for each handle..."
while IFS= read -r handle; do
$chatcmd ArchiveEntry "$handle" btime 2>/dev/null >> "$files_btime" || echo "0" >> "$files_btime"
done < "$files_handle"
report_progress 85 "Converting timestamps..."
log "Converting btime to readable date..."
while IFS= read -r nixtime; do
if [ -n "$nixtime" ] && [ "$nixtime" -ne 0 ] 2>/dev/null; then
date -r "$nixtime" "+%Y-%m-%d %H:%M:%S" 2>/dev/null || echo ""
else
echo ""
fi
done < "$files_btime" > "$files_btime_converted"
report_progress 90 "Fetching volume information..."
log "Fetching volume names..."
while IFS= read -r handle; do
$chatcmd ArchiveEntry "$handle" volume 2>/dev/null >> "$files_volume" || echo "" >> "$files_volume"
done < "$files_handle"
report_progress 92 "Fetching barcodes..."
log "Fetching barcode for each volume..."
while IFS= read -r vol; do
if [ -z "$vol" ]; then
echo "" >> "$files_barcode"
else
$chatcmd Volume "$vol" barcode 2>/dev/null >> "$files_barcode" || echo "" >> "$files_barcode"
fi
done < "$files_volume"
else
log "No handles found — skipping handle-based queries."
report_progress 90 "No archived files found"
fi
report_progress 95 "Generating reports..."
# Build CSV: combine all data
log "Combining temp files into CSV: $output_csv"
# DEBUG: Check file line counts
log "DEBUG: Line counts before CSV generation:"
log "DEBUG: files2.txt: $(wc -l < "$files2_txt" 2>/dev/null || echo 0) lines"
log "DEBUG: files_handle: $(wc -l < "$files_handle" 2>/dev/null || echo 0) lines"
log "DEBUG: files_status: $(wc -l < "$files_status" 2>/dev/null || echo 0) lines"
# Ensure all files exist
for f in "$files2_txt" "$files_handle" "$files_status" "$files_size" "$files_size_converted" "$files_btime_converted" "$files_barcode"; do
[ -f "$f" ] || : > "$f"
done
# DEBUG: Show first few lines of key files
log "DEBUG: First 3 lines of files2.txt:"
head -3 "$files2_txt" >> "$logfile" 2>&1
log "DEBUG: First 3 lines of files_handle:"
head -3 "$files_handle" >> "$logfile" 2>&1
log "DEBUG: First 3 lines of files_status:"
head -3 "$files_status" >> "$logfile" 2>&1
paste -d ',' \
"$files2_txt" \
"$files_handle" \
"$files_status" \
"$files_size" \
"$files_size_converted" \
"$files_btime_converted" \
"$files_barcode" > "$output_csv" 2>/dev/null
# DEBUG: Check CSV line count
csv_lines=$(wc -l < "$output_csv" 2>/dev/null || echo 0)
log "DEBUG: CSV generated with $csv_lines lines (should be $handles_count + 1 with header)"
# Prepend header
{
echo 'File Path,P5 Handle,Status,Size,Size GB,Archived Date,Barcode'
cat "$output_csv"
} > "$output_final"
mv "$output_final" "$output_csv"
# Copy outputs to /Users/Shared
summary="/Users/Shared/${now}-Files-To-Archive-$(basename "$storage_path").txt"
archived_csv="/Users/Shared/${now}-Archived-$(basename "$storage_path").csv"
backup_tar="/Users/Shared/${now}-$(basename "$storage_path").bak.tar.gz"
if [ -s "$files_nohandle" ]; then
cp "$files_nohandle" "$summary"
log "Wrote not-archived list to $summary"
else
echo "All files archived. $storage_path" > "$summary"
log "All files archived; wrote confirmation to $summary"
fi
cp "$output_csv" "$archived_csv"
log "Wrote archived CSV to $archived_csv"
report_progress 98 "Creating backup archive..."
# Create backup tar containing the temp files we generated
log "Creating backup archive $backup_tar"
tar zcf "$backup_tar" \
"$files_txt" \
"$files2_txt" \
"$files_handle" \
"$files_nohandle" \
"$files_status" \
"$files_size" \
"$files_size_converted" \
"$files_btime" \
"$files_btime_converted" \
"$files_volume" \
"$files_barcode" \
"$output_csv" \
2>>"$logfile" && log "Backup saved to $backup_tar" || log "Warning: tar failed"
# Move log file to Shared folder for permanent record
final_log="/Users/Shared/p5-check-$(basename "$storage_path")-${now}.log"
if [ -f "$logfile" ]; then
cp "$logfile" "$final_log"
log "Log file copied to $final_log"
fi
# Output result paths for Swift to parse (on stdout)
echo "RESULT:SUMMARY:$summary"
echo "RESULT:CSV:$archived_csv"
echo "RESULT:BACKUP:$backup_tar"
echo "RESULT:LOG:$final_log"
echo "RESULT:TOTAL:$total"
echo "RESULT:ARCHIVED:$handles_count"
echo "RESULT:NOT_ARCHIVED:$nohandle_count"
report_progress 100 "Complete!"
# Clean up temporary files
log "Cleaning up temporary files..."
rm -f \
"$files_txt" \
"$files2_txt" \
"$files_handle" \
"${files_handle}.map" \
"$files_nohandle" \
"$files_status" \
"$files_size" \
"$files_size_converted" \
"$files_btime" \
"$files_btime_converted" \
"$files_volume" \
"$files_barcode" \
"$output_csv" \
"$output_final" \
"$progressfile" 2>/dev/null || true
log "=== Script finished: Checked $total files. Archived: $handles_count. Not archived: $nohandle_count ==="
exit 0