Skip to content

Instantly share code, notes, and snippets.

@hansek
Created June 15, 2026 22:08
Show Gist options
  • Select an option

  • Save hansek/01c5b691f9bf94b81885922043157e84 to your computer and use it in GitHub Desktop.

Select an option

Save hansek/01c5b691f9bf94b81885922043157e84 to your computer and use it in GitHub Desktop.
NaseMS.cz photos backup
#!/usr/bin/env zsh
set -euo pipefail
BASE_URL="https://nasems.cz"
GALLERY_URL="${BASE_URL}/prihlaseno/fotogalerie"
OUT_DIR="${1:-nasems-data}"
PHOTOS_DIR="${OUT_DIR}/fotky"
mkdir -p "$OUT_DIR" "$PHOTOS_DIR"
command -v curl >/dev/null || { echo "Chybí curl"; exit 1; }
command -v jq >/dev/null || { echo "Chybí jq. Nainstaluj: sudo apt install jq"; exit 1; }
command -v file >/dev/null || { echo "Chybí file"; exit 1; }
if [[ -z "${NASEMS_SID:-}" ]]; then
echo "Chybí env proměnná NASEMS_SID"
echo "Použij:"
echo " export NASEMS_SID='hodnota_cookie_bez___Host-SID='"
exit 1
fi
COMMON_HEADERS=(
-H "Host: nasems.cz"
-H "Accept-Language: en-US,en;q=0.9,cs-CZ;q=0.8,cs;q=0.7"
-H "Cache-Control: no-cache"
-H "Pragma: no-cache"
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36"
-H "Cookie: __Host-SID=${NASEMS_SID}"
)
IMAGE_HEADERS=(
-H "Host: nasems.cz"
-H "Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"
-H "Accept-Language: en-US,en;q=0.9,cs-CZ;q=0.8,cs;q=0.7"
-H "Cache-Control: no-cache"
-H "Pragma: no-cache"
-H "Sec-Fetch-Dest: image"
-H "Sec-Fetch-Mode: no-cors"
-H "Sec-Fetch-Site: same-origin"
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36"
-H "Cookie: __Host-SID=${NASEMS_SID}"
)
sanitize_dirname() {
local name="$1"
echo "$name" \
| sed -E 's/<[^>]+>//g' \
| sed -E 's/&nbsp;/ /g; s/&amp;/\&/g; s/&quot;/"/g; s/&#039;/'\''/g' \
| tr '/\\:*?"<>|' '-' \
| sed -E 's/[[:space:]]+/ /g; s/^ //; s/ $//' \
| cut -c 1-120
}
extract_gallery_title() {
local json_file="$1"
jq -r '.result // empty' "$json_file" \
| grep -oE "<label>[^<]+</label>" \
| head -n 1 \
| sed -E 's#</?label>##g' \
| sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//' || true
}
extract_fullsize_urls() {
local json_file="$1"
jq -r '.result // empty' "$json_file" \
| grep -oE '<a[^>]+href="https://nasems\.cz/fotografie/[A-Za-z0-9]+"' \
| grep -oE 'https://nasems\.cz/fotografie/[A-Za-z0-9]+' \
| sort \
| uniq || true
}
download_photo() {
local photo_url="$1"
local tmp="$2"
curl -f -L --compressed \
"$photo_url" \
"${IMAGE_HEADERS[@]}" \
-o "$tmp"
local mime
local ext
mime="$(file --mime-type -b "$tmp")"
case "$mime" in
image/jpeg) ext="jpg" ;;
image/png) ext="png" ;;
image/webp) ext="webp" ;;
image/gif) ext="gif" ;;
*) ext="unknown" ;;
esac
mv "$tmp" "${tmp}.${ext}"
}
echo "1) Stahuji hlavní stránku fotogalerie..."
curl -f -L --compressed \
"$GALLERY_URL" \
"${COMMON_HEADERS[@]}" \
-H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" \
-o "${OUT_DIR}/fotogalerie.html"
echo "2) Vytahuji ID galerií..."
: > "${OUT_DIR}/slozky.txt"
grep -Eo "data-slozka=['\"][0-9]+['\"]" "${OUT_DIR}/fotogalerie.html" \
| grep -Eo '[0-9]+' \
>> "${OUT_DIR}/slozky.txt" || true
grep -Eo "slozka['\"]?[=: ]+['\"]?[0-9]+" "${OUT_DIR}/fotogalerie.html" \
| grep -Eo '[0-9]+' \
>> "${OUT_DIR}/slozky.txt" || true
sort -n "${OUT_DIR}/slozky.txt" | uniq > "${OUT_DIR}/slozky.tmp"
mv "${OUT_DIR}/slozky.tmp" "${OUT_DIR}/slozky.txt"
SLOZKY_COUNT="$(wc -l < "${OUT_DIR}/slozky.txt" | tr -d ' ')"
echo "Nalezeno galerií: ${SLOZKY_COUNT}"
if [[ "$SLOZKY_COUNT" == "0" ]]; then
echo "Nenalezeny žádné galerie."
grep -oE '.{0,80}slozka.{0,80}' "${OUT_DIR}/fotogalerie.html" | head -n 10 || true
exit 1
fi
echo "3) Stahuji detaily galerií a fotky..."
while IFS= read -r SLOZKA_ID || [[ -n "$SLOZKA_ID" ]]; do
[[ -z "$SLOZKA_ID" ]] && continue
JSON_FILE="${OUT_DIR}/slozka-${SLOZKA_ID}.json"
echo
echo "Galerie ${SLOZKA_ID}: načítám detail"
curl -f -L --compressed \
"$GALLERY_URL" \
"${COMMON_HEADERS[@]}" \
-H "Accept: */*" \
-H "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" \
-H "Origin: ${BASE_URL}" \
-H "Referer: ${GALLERY_URL}" \
-H "X-Requested-With: XMLHttpRequest" \
--data-urlencode "ajax=ajax" \
--data-urlencode "what=fotogalerie" \
--data-urlencode "action=load_html_fotogalerie_slozka" \
--data-urlencode "slozka=${SLOZKA_ID}" \
-o "$JSON_FILE"
TITLE="$(extract_gallery_title "$JSON_FILE")"
if [[ -z "$TITLE" ]]; then
TITLE="galerie-${SLOZKA_ID}"
fi
SAFE_TITLE="$(sanitize_dirname "$TITLE")"
if [[ -z "$SAFE_TITLE" ]]; then
SAFE_TITLE="galerie-${SLOZKA_ID}"
fi
GALLERY_DIR="${PHOTOS_DIR}/${SLOZKA_ID} - ${SAFE_TITLE}"
mkdir -p "$GALLERY_DIR"
URLS_FILE="${OUT_DIR}/fotky-${SLOZKA_ID}.txt"
extract_fullsize_urls "$JSON_FILE" > "$URLS_FILE"
PHOTOS_COUNT="$(wc -l < "$URLS_FILE" | tr -d ' ')"
echo "Název: ${TITLE}"
echo "Fotky: ${PHOTOS_COUNT}"
echo "Složka: ${GALLERY_DIR}"
if [[ "$PHOTOS_COUNT" == "0" ]]; then
echo "VAROVÁNÍ: žádné fullsize fotky nenalezeny"
continue
fi
i=1
while IFS= read -r PHOTO_URL || [[ -n "$PHOTO_URL" ]]; do
[[ -z "$PHOTO_URL" ]] && continue
tmp="${GALLERY_DIR}/$(printf "%04d-image" "$i")"
echo " Fotka $(printf "%04d" "$i")"
download_photo "$PHOTO_URL" "$tmp"
((i++))
done < "$URLS_FILE"
done < "${OUT_DIR}/slozky.txt"
echo
echo "Hotovo."
echo "Data: ${OUT_DIR}"
echo "Fotky: ${PHOTOS_DIR}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment