@@ -10,6 +10,66 @@ GREEN='\033[0;32m'
1010YELLOW=' \033[1;33m'
1111NC=' \033[0m' # No Color
1212
13+ # Array to track temporary files for cleanup
14+ TEMP_FILES=()
15+
16+ # Array to track backup files
17+ BACKUP_FILES=()
18+
19+ # Cleanup function
20+ cleanup () {
21+ if [ ${# TEMP_FILES[@]} -gt 0 ]; then
22+ for temp_file in " ${TEMP_FILES[@]} " ; do
23+ if [ -f " $temp_file " ]; then
24+ rm -f " $temp_file "
25+ fi
26+ done
27+ fi
28+ }
29+
30+ # Set up trap to cleanup on exit or error
31+ trap cleanup EXIT ERR INT TERM
32+
33+ # Function to create backup
34+ create_backup () {
35+ local input_file=" $1 "
36+ local backup_file=" ${input_file} .backup"
37+
38+ if cp " $input_file " " $backup_file " 2> /dev/null; then
39+ BACKUP_FILES+=(" $backup_file " )
40+ return 0
41+ else
42+ echo -e " ${RED} ✗ Error: Failed to create backup${NC} "
43+ return 1
44+ fi
45+ }
46+
47+ # Function to restore from backup
48+ restore_backup () {
49+ local input_file=" $1 "
50+ local backup_file=" ${input_file} .backup"
51+
52+ if [ -f " $backup_file " ]; then
53+ mv " $backup_file " " $input_file "
54+ # Remove from backup tracking
55+ BACKUP_FILES=(" ${BACKUP_FILES[@]/ $backup_file } " )
56+ return 0
57+ fi
58+ return 1
59+ }
60+
61+ # Function to remove backup
62+ remove_backup () {
63+ local input_file=" $1 "
64+ local backup_file=" ${input_file} .backup"
65+
66+ if [ -f " $backup_file " ]; then
67+ rm -f " $backup_file "
68+ # Remove from backup tracking
69+ BACKUP_FILES=(" ${BACKUP_FILES[@]/ $backup_file } " )
70+ fi
71+ }
72+
1373# Check if ImageMagick is installed
1474if ! command -v magick & > /dev/null && ! command -v convert & > /dev/null; then
1575 echo -e " ${RED} Error: ImageMagick is not installed${NC} "
@@ -34,17 +94,41 @@ optimize_member_photo() {
3494 local filename=$( basename " $input_file " )
3595 local temp_file=" ${input_file} .tmp.jpg"
3696
97+ # Add to cleanup list
98+ TEMP_FILES+=(" $temp_file " )
99+
37100 echo -e " ${YELLOW} Processing member photo: $filename ${NC} "
38101
102+ # Check if input file exists and is readable
103+ if [ ! -f " $input_file " ]; then
104+ echo -e " ${RED} ✗ Error: File not found: $input_file ${NC} "
105+ return 1
106+ fi
107+
108+ if [ ! -r " $input_file " ]; then
109+ echo -e " ${RED} ✗ Error: File not readable: $input_file ${NC} "
110+ return 1
111+ fi
112+
113+ # Create backup before processing
114+ if ! create_backup " $input_file " ; then
115+ return 1
116+ fi
117+
39118 # Resize to 365x365 if needed, set to 72 DPI, and compress
40- $CONVERT_CMD " $input_file " \
119+ if ! $CONVERT_CMD " $input_file " \
41120 -resize 365x365^ \
42121 -gravity center \
43122 -extent 365x365 \
44123 -density 72 \
45124 -quality 85 \
46125 -strip \
47- " $temp_file "
126+ " $temp_file " 2> /dev/null; then
127+ echo -e " ${RED} ✗ Error: Failed to process image (possibly corrupt or invalid format)${NC} "
128+ rm -f " $temp_file "
129+ restore_backup " $input_file "
130+ return 1
131+ fi
48132
49133 # Check file size
50134 size=$( wc -c < " $temp_file " | tr -d ' ' )
@@ -53,13 +137,23 @@ optimize_member_photo() {
53137 if [ $size_kb -gt 100 ]; then
54138 echo -e " ${YELLOW} Warning: ${filename} is ${size_kb} KB (max 100KB)${NC} "
55139 echo -e " Attempting further compression..."
56- $CONVERT_CMD " $temp_file " -quality 75 " $temp_file "
140+ if ! $CONVERT_CMD " $temp_file " -quality 75 " $temp_file " 2> /dev/null; then
141+ echo -e " ${RED} ✗ Error: Failed to compress image${NC} "
142+ rm -f " $temp_file "
143+ restore_backup " $input_file "
144+ return 1
145+ fi
57146 size=$( wc -c < " $temp_file " | tr -d ' ' )
58147 size_kb=$(( size / 1024 ))
59148 fi
60149
61150 mv " $temp_file " " $input_file "
62- echo -e " ${GREEN} ✓ Optimized: ${size_kb} KB${NC} "
151+ # Remove from cleanup list after successful move
152+ TEMP_FILES=(" ${TEMP_FILES[@]/ $temp_file } " )
153+ # Remove backup after successful optimization
154+ remove_backup " $input_file "
155+ echo -e " ${GREEN} ✓ Optimized: ${size_kb} KB (backup removed)${NC} "
156+ return 0
63157}
64158
65159# Function to optimize publication teasers
@@ -68,14 +162,38 @@ optimize_pub_teaser() {
68162 local filename=$( basename " $input_file " )
69163 local temp_file=" ${input_file} .tmp.jpg"
70164
165+ # Add to cleanup list
166+ TEMP_FILES+=(" $temp_file " )
167+
71168 echo -e " ${YELLOW} Processing publication teaser: $filename ${NC} "
72169
170+ # Check if input file exists and is readable
171+ if [ ! -f " $input_file " ]; then
172+ echo -e " ${RED} ✗ Error: File not found: $input_file ${NC} "
173+ return 1
174+ fi
175+
176+ if [ ! -r " $input_file " ]; then
177+ echo -e " ${RED} ✗ Error: File not readable: $input_file ${NC} "
178+ return 1
179+ fi
180+
181+ # Create backup before processing
182+ if ! create_backup " $input_file " ; then
183+ return 1
184+ fi
185+
73186 # Resize to max height 200px and compress
74- $CONVERT_CMD " $input_file " \
187+ if ! $CONVERT_CMD " $input_file " \
75188 -resize x200\> \
76189 -quality 85 \
77190 -strip \
78- " $temp_file "
191+ " $temp_file " 2> /dev/null; then
192+ echo -e " ${RED} ✗ Error: Failed to process image (possibly corrupt or invalid format)${NC} "
193+ rm -f " $temp_file "
194+ restore_backup " $input_file "
195+ return 1
196+ fi
79197
80198 # Check file size
81199 size=$( wc -c < " $temp_file " | tr -d ' ' )
@@ -84,13 +202,23 @@ optimize_pub_teaser() {
84202 if [ $size_kb -gt 100 ]; then
85203 echo -e " ${YELLOW} Warning: ${filename} is ${size_kb} KB (max 100KB)${NC} "
86204 echo -e " Applying maximum compression..."
87- $CONVERT_CMD " $temp_file " -quality 70 " $temp_file "
205+ if ! $CONVERT_CMD " $temp_file " -quality 70 " $temp_file " 2> /dev/null; then
206+ echo -e " ${RED} ✗ Error: Failed to compress image${NC} "
207+ rm -f " $temp_file "
208+ restore_backup " $input_file "
209+ return 1
210+ fi
88211 size=$( wc -c < " $temp_file " | tr -d ' ' )
89212 size_kb=$(( size / 1024 ))
90213 fi
91214
92215 mv " $temp_file " " $input_file "
93- echo -e " ${GREEN} ✓ Optimized: ${size_kb} KB${NC} "
216+ # Remove from cleanup list after successful move
217+ TEMP_FILES=(" ${TEMP_FILES[@]/ $temp_file } " )
218+ # Remove backup after successful optimization
219+ remove_backup " $input_file "
220+ echo -e " ${GREEN} ✓ Optimized: ${size_kb} KB (backup removed)${NC} "
221+ return 0
94222}
95223
96224# Main script
@@ -116,25 +244,51 @@ case "$1" in
116244 all-members)
117245 echo " Optimizing all member photos..."
118246 echo " "
247+ success_count=0
248+ error_count=0
119249 for img in static/img/members/* .jpg; do
120250 if [ -f " $img " ]; then
121- optimize_member_photo " $img "
251+ if optimize_member_photo " $img " ; then
252+ (( success_count++ ))
253+ else
254+ (( error_count++ ))
255+ fi
122256 fi
123257 done
124258 echo " "
125- echo -e " ${GREEN} ✓ All member photos optimized!${NC} "
259+ if [ $error_count -eq 0 ]; then
260+ echo -e " ${GREEN} ✓ All member photos optimized! ($success_count processed)${NC} "
261+ else
262+ echo -e " ${YELLOW} ⚠ Completed with errors: $success_count succeeded, $error_count failed${NC} "
263+ exit 1
264+ fi
126265 ;;
127266
128267 all-pubs)
129268 echo " Optimizing all publication teasers..."
130269 echo " "
270+ success_count=0
271+ error_count=0
131272 for img in static/pub/* .jpg; do
132273 if [ -f " $img " ]; then
133- optimize_pub_teaser " $img "
274+ if optimize_pub_teaser " $img " ; then
275+ (( success_count++ ))
276+ else
277+ (( error_count++ ))
278+ fi
134279 fi
135280 done
136281 echo " "
137- echo -e " ${GREEN} ✓ All publication teasers optimized!${NC} "
282+ if [ $error_count -eq 0 ]; then
283+ echo -e " ${GREEN} ✓ All publication teasers optimized! ($success_count processed)${NC} "
284+ else
285+ echo -e " ${YELLOW} ⚠ Completed with errors: $success_count succeeded, $error_count failed${NC} "
286+ if [ ${# BACKUP_FILES[@]} -gt 0 ]; then
287+ echo -e " ${YELLOW} ⚠ ${# BACKUP_FILES[@]} backup file(s) retained due to errors${NC} "
288+ echo -e " To restore, run: mv <file>.backup <file>"
289+ fi
290+ exit 1
291+ fi
138292 ;;
139293
140294 * )
0 commit comments