Flink wat jaren geleden wisselde Recruitment Matters van server. Hierbij zijn afbeeldingen verloren gegaan. Oude blogs tonen vele honderden ‘image missing’s. Dat is niet fraai.
Nog minder fraai is dat Recruitment Matters hot-linkt naar andere websites. Dit is parasitair gedrag. Je laat iemand anders zonder toestemming jouw afbeeldingen hosten. Totdat ze ermee stoppen en je ook in die gevallen een ‘image missing’ te zien krijgt.
Niet fraai allemaal. Maar ook geen groot probleem, zou je zeggen, zolang Marc Drees er niet achter komt. Helaas heeft Marc het tegen alle verwachtingen in toch binnen vijf jaar opgemerkt. Hoog tijd voor een oplossing.
Eerst maar eens kijken hoe groot het probleem is. ChatGTP geeft een scriptje:
#!/bin/bash
uploads_dir="/var/www/html/wp-content/uploads/"
server_domain="recruitmentmatters.nl"
db_user="admin"
db_name="recruitmat"
db_password="welkom123"
log_file="/var/www/html/wp-content/uploads/logfile.log"
batch_size=200000
# Function to log and echo messages
log() {
local message="$(date '+%Y-%m-%d %H:%M:%S');$1;$2;$3;$4;$5"
echo "$message" >> "$log_file"
echo "$message"
}
# Ensure the log file exists and has correct permissions
touch "$log_file"
chmod 664 "$log_file"
# Write the header of the log file
echo "Timestamp;Action;PostID;PostURL;ImageURL;Status" > "$log_file"
# Fetch and process posts in batches
while true; do
results=$(mysql -u "$db_user" -p"$db_password" -D "$db_name" -e "SELECT ID, guid, post_content FROM wp_posts WHERE post_type = 'post' AND post_status = 'publish' ORDER BY ID ASC LIMIT $batch_size" -B -N)
if [[ -z "$results" ]]; then
echo "No more results to process."
break
fi
while read -r post_id guid post_content; do
echo "Processing post ID: $post_id, URL: $guid"
echo "$post_content" | grep -oP 'src="https?://\K[^"]+' | while read img_url; do
if [[ "$img_url" != *thumb* ]]; then
if [[ "$img_url" != *"$server_domain"* ]]; then
log "Hot Linked Image" "$post_id" "$guid" "$img_url" "Not Hosted on Server"
continue
fi
img_path="${img_url#*uploads/}"
full_path="${uploads_dir}${img_path}"
# Create directory if it doesn't exist
mkdir -p "$(dirname "$full_path")"
if [ ! -f "$full_path" ]; then
log "Missing Image" "$post_id" "$guid" "$img_url" "Not Found"
fi
fi
done
done <<< "$results"
last_post_id=$(echo "$results" | tail -1 | awk '{print $1}')
batch_size=$((last_post_id + 200000))
done
Kijk eens aan. Ruim duizend verdwenen afbeeldingen. En ruim 600 gehotlinkt.
Hot Linked Image | 631 |
Missing Image | 1432 |
Oké. Nu we weten hoe groot het probleem is kunnen we het oplossen. De oplossing is tweeledig. Deel één is extreem eenvoudig. Deel twee is schier onmogelijk.
Voor de missende afbeeldingen bepalen we bij welk blogs deze horen en of deze blogs ooit geïndexeerd zijn door Archive.org. Als dat zo is dan zoeken we daarvan de eerst opgeslagen versie, extraheren daaruit een identifier die we voor een afgeleide van de missende afbeelding prefixeren, teneinde deze naar een passende map op de server te trekken. Presto. ChatGTP geeft een scriptje:
log_file="/var/www/html/wp-content/logfile.log" # Specify your log file path
batch_size=20 # Number of posts to process per batch
last_processed_id=0 # ID of the last processed post (update as needed)
# Function to log messages in a structured format
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S');$1;$2;$3;$4;$5" >> "$log_file"
}
# Write the header of the log file
echo "Timestamp;Action;PostID;PostURL;ImageURL;Status" > "$log_file"
# Fetch and process posts in batches
while true; do
results=$(mysql -u "$db_user" -p"$db_password" -D "$db_name" -e "SELECT ID, guid, post_content FROM wp_posts WHERE post_type = 'post' AND post_status = 'publish' AND ID > $last_processed_id ORDER BY ID ASC LIMIT $batch_size" -B -N)
if [[ -z "$results" ]]; then
break # Exit loop if no more results
fi
while read -r post_id guid post_content; do
echo "$post_content" | grep -oP 'src="https?://\K[^"]+' | grep "$server_domain" | while read img_url; do
if [[ "$img_url" != *thumb* ]]; then
img_path="${img_url#*uploads/}"
full_path="${uploads_dir}${img_path}"
if [ ! -f "$full_path" ]; then
archive_data=$(curl -s "http://web.archive.org/cdx/search/cdx?url=${guid}&output=json&fl=timestamp&filter=statuscode:200&limit=1")
timestamp=$(echo $archive_data | jq -r '.[1][0]')
if [ -n "$timestamp" ]; then
wayback_url="https://web.archive.org/web/${timestamp}im_/${img_url}"
if wget -q -O "$full_path" "$wayback_url"; then
log "Download" "$post_id" "$guid" "$img_url" "Success"
else
log "Download" "$post_id" "$guid" "$img_url" "Failed"
fi
else
log "Archive Check" "$post_id" "$guid" "$img_url" "Not Found"
fi
fi
fi
done
last_processed_id=$post_id # Update the last processed post ID
done <<< "$results"
done
# Update the log file after completing each batch
echo "Processed up to post ID $last_processed_id"
Met AI verhelp je dus in een handomdraai grote aantallen missende plaatjes. Ongelofelijk hoe makkelijk sommige problemen tegenwoordig te verhelpen zijn.
Sommige problemen. Niet alle. Deel twee van het probleem is lastiger dan deel één. Het is mij volstrekt duister hoe ik een blogger, laten we hem Marc noemen, werkwijzen afleer die diep in de vorige eeuw al afkeuring opriepen. Onbegonnen werk.
Er zit niets anders op dan ChatGTP een scriptje op te laten hoesten dat de database frequent controleert op verwijzingen naar externe afbeeldingen om deze lokaal te trekken. Tien minuten werk. Max.
Enfin, geniet van de hernieuwde visuele glans. En besef hoe gelukkig je jezelf mag prijzen met het fraaie design. Vroeger was het dit:
Hackerzforum
says:He, jullie gebruiken mijn wachtwoord!
Dirk Goossens
says:Klopt. Maar ‘wachtwoord’ is ‘password’ in het Engels. Eigenlijk andersom dus.