From ad2985f61d1e32bcaa987de42d148ca525cf97ac Mon Sep 17 00:00:00 2001 From: Stream Date: Sat, 9 May 2026 21:20:01 +0300 Subject: [PATCH] auto-sync: 2026-05-09 21:20:01 --- .../prototype/scripts/download_srtm_all.sh | 49 ++++++++ .../prototype/scripts/download_srtm_all2.sh | 51 ++++++++ .../prototype/scripts/download_srtm_all3.sh | 51 ++++++++ .../prototype/scripts/download_srtm_bulk.sh | 53 ++++++++ .../prototype/scripts/download_srtm_final.js | 111 +++++++++++++++++ .../scripts/download_srtm_parallel.js | 93 ++++++++++++++ .../prototype/scripts/download_srtm_retry.js | 113 ++++++++++++++++++ .../prototype/scripts/download_srtm_v4.js | 110 +++++++++++++++++ 8 files changed, 631 insertions(+) create mode 100644 tasks/enduro-trails/prototype/scripts/download_srtm_all.sh create mode 100644 tasks/enduro-trails/prototype/scripts/download_srtm_all2.sh create mode 100644 tasks/enduro-trails/prototype/scripts/download_srtm_all3.sh create mode 100644 tasks/enduro-trails/prototype/scripts/download_srtm_bulk.sh create mode 100644 tasks/enduro-trails/prototype/scripts/download_srtm_final.js create mode 100644 tasks/enduro-trails/prototype/scripts/download_srtm_parallel.js create mode 100644 tasks/enduro-trails/prototype/scripts/download_srtm_retry.js create mode 100644 tasks/enduro-trails/prototype/scripts/download_srtm_v4.js diff --git a/tasks/enduro-trails/prototype/scripts/download_srtm_all.sh b/tasks/enduro-trails/prototype/scripts/download_srtm_all.sh new file mode 100644 index 0000000..e795bfb --- /dev/null +++ b/tasks/enduro-trails/prototype/scripts/download_srtm_all.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# Download all SRTM tiles for Central Federal District + Chuvashia +set -e +SRTM_DIR="/home/slin/enduro-trails/data/srtm" +cd "$SRTM_DIR" +BASE_URL="https://s3.amazonaws.com/elevation-tiles-prod/skadi" + +TILES=( + N55E037 N55E038 N55E039 N55E040 + N54E037 N54E038 N54E039 N54E040 + N53E038 N53E039 N53E040 N53E041 + N52E038 N52E039 N52E040 N52E041 + N56E037 N56E038 N56E039 N56E040 + N57E037 N57E038 N57E039 N57E040 + N58E037 N58E038 N58E039 N58E040 + N59E038 N59E039 N59E040 N59E041 + N60E040 N60E041 N60E042 + N54E042 N54E043 N54E044 N54E045 + N53E042 N53E043 N53E044 N53E045 + N52E042 N52E043 N52E044 N52E045 + N51E038 N51E039 N51E040 N51E041 + N50E038 N50E039 N50E040 N50E041 + N55E047 N55E048 N55E049 N55E050 + N54E047 N54E048 N54E049 N54E050 + N56E047 N56E048 N56E049 N56E050 +) + +for tile in "${TILES[@]}"; do + lat="${tile:1:2}" + url="${BASE_URL}/${lat}/${tile}.hgt.gz" + + if [ -f "${tile}.hgt" ]; then + echo "SKIP ${tile}" + continue + fi + + echo "DL ${tile}" + wget --timeout=60 -q "$url" -O "${tile}.hgt.gz" 2>/dev/null + if [ -s "${tile}.hgt.gz" ]; then + gunzip -f "${tile}.hgt.gz" + echo "OK ${tile}" + else + echo "FAIL ${tile}" + rm -f "${tile}.hgt.gz" + fi +done + +echo "" +echo "Total .hgt files: $(ls *.hgt 2>/dev/null | wc -l)" diff --git a/tasks/enduro-trails/prototype/scripts/download_srtm_all2.sh b/tasks/enduro-trails/prototype/scripts/download_srtm_all2.sh new file mode 100644 index 0000000..2e324b0 --- /dev/null +++ b/tasks/enduro-trails/prototype/scripts/download_srtm_all2.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# Download all SRTM tiles for Central Federal District + Chuvashia +# Runs entirely on the server - no SSH2 stream timeout issues + +SRTM_DIR="/home/slin/enduro-trails/data/srtm" +mkdir -p "$SRTM_DIR" +cd "$SRTM_DIR" +BASE_URL="https://s3.amazonaws.com/elevation-tiles-prod/skadi" + +TILES=( + N55E037 N55E038 N55E039 N55E040 + N54E037 N54E038 N54E039 N54E040 + N53E038 N53E039 N53E040 N53E041 + N52E038 N52E039 N52E040 N52E041 + N56E037 N56E038 N56E039 N56E040 + N57E037 N57E038 N57E039 N57E040 + N58E037 N58E038 N58E039 N58E040 + N59E038 N59E039 N59E040 N59E041 + N60E040 N60E041 N60E042 + N54E042 N54E043 N54E044 N54E045 + N53E042 N53E043 N53E044 N53E045 + N52E042 N52E043 N52E044 N52E045 + N51E038 N51E039 N51E040 N51E041 + N50E038 N50E039 N50E040 N50E041 + N55E047 N55E048 N55E049 N55E050 + N54E047 N54E048 N54E049 N54E050 + N56E047 N56E048 N56E049 N56E050 +) + +for tile in "${TILES[@]}"; do + lat="${tile:1:2}" + url="${BASE_URL}/${lat}/${tile}.hgt.gz" + + if [ -f "${tile}.hgt" ]; then + echo "SKIP ${tile}" + continue + fi + + echo "DL ${tile}" + wget --timeout=60 -q "$url" -O "${tile}.hgt.gz" 2>/dev/null + if [ -s "${tile}.hgt.gz" ]; then + gunzip -f "${tile}.hgt.gz" + echo "OK ${tile}" + else + echo "FAIL ${tile}" + rm -f "${tile}.hgt.gz" + fi +done + +echo "" +echo "Total .hgt files: $(ls *.hgt 2>/dev/null | wc -l)" diff --git a/tasks/enduro-trails/prototype/scripts/download_srtm_all3.sh b/tasks/enduro-trails/prototype/scripts/download_srtm_all3.sh new file mode 100644 index 0000000..e8c7a42 --- /dev/null +++ b/tasks/enduro-trails/prototype/scripts/download_srtm_all3.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# Download all SRTM tiles for Central Federal District + Chuvashia +# No -q flag on wget to avoid issues + +SRTM_DIR="/home/slin/enduro-trails/data/srtm" +mkdir -p "$SRTM_DIR" +cd "$SRTM_DIR" +BASE_URL="https://s3.amazonaws.com/elevation-tiles-prod/skadi" + +TILES=( + N55E037 N55E038 N55E039 N55E040 + N54E037 N54E038 N54E039 N54E040 + N53E038 N53E039 N53E040 N53E041 + N52E038 N52E039 N52E040 N52E041 + N56E037 N56E038 N56E039 N56E040 + N57E037 N57E038 N57E039 N57E040 + N58E037 N58E038 N58E039 N58E040 + N59E038 N59E039 N59E040 N59E041 + N60E040 N60E041 N60E042 + N54E042 N54E043 N54E044 N54E045 + N53E042 N53E043 N53E044 N53E045 + N52E042 N52E043 N52E044 N52E045 + N51E038 N51E039 N51E040 N51E041 + N50E038 N50E039 N50E040 N50E041 + N55E047 N55E048 N55E049 N55E050 + N54E047 N54E048 N54E049 N54E050 + N56E047 N56E048 N56E049 N56E050 +) + +for tile in "${TILES[@]}"; do + lat="${tile:1:2}" + url="${BASE_URL}/${lat}/${tile}.hgt.gz" + + if [ -f "${tile}.hgt" ]; then + echo "SKIP ${tile}" + continue + fi + + echo "DL ${tile}" + wget --timeout=60 "$url" -O "${tile}.hgt.gz" >/dev/null 2>&1 + if [ -s "${tile}.hgt.gz" ]; then + gunzip -f "${tile}.hgt.gz" + echo "OK ${tile}" + else + echo "FAIL ${tile}" + rm -f "${tile}.hgt.gz" + fi +done + +echo "" +echo "Total .hgt files: $(ls *.hgt 2>/dev/null | wc -l)" diff --git a/tasks/enduro-trails/prototype/scripts/download_srtm_bulk.sh b/tasks/enduro-trails/prototype/scripts/download_srtm_bulk.sh new file mode 100644 index 0000000..71d54de --- /dev/null +++ b/tasks/enduro-trails/prototype/scripts/download_srtm_bulk.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# Download all SRTM tiles for Central Federal District + Chuvashia +set -e +SRTM_DIR="/home/slin/enduro-trails/data/srtm" +cd "$SRTM_DIR" +BASE_URL="https://s3.amazonaws.com/elevation-tiles-prod/skadi" + +TILES=( + N55E037 N55E038 N55E039 N55E040 + N54E037 N54E038 N54E039 N54E040 + N53E038 N53E039 N53E040 N53E041 + N52E038 N52E039 N52E040 N52E041 + N56E037 N56E038 N56E039 N56E040 + N57E037 N57E038 N57E039 N57E040 + N58E037 N58E038 N58E039 N58E040 + N59E038 N59E039 N59E040 N59E041 + N60E040 N60E041 N60E042 + N54E042 N54E043 N54E044 N54E045 + N53E042 N53E043 N53E044 N53E045 + N52E042 N52E043 N52E044 N52E045 + N51E038 N51E039 N51E040 N51E041 + N50E038 N50E039 N50E040 N50E041 + N55E047 N55E048 N55E049 N55E050 + N54E047 N54E048 N54E049 N54E050 + N56E047 N56E048 N56E049 N56E050 +) + +for tile in "${TILES[@]}"; do + lat="${tile:1:2}" + url="${BASE_URL}/${lat}/${tile}.hgt.gz" + + if [ -f "${tile}.hgt" ]; then + echo "SKIP ${tile}" + continue + fi + + echo "DL ${tile}" + if wget --timeout=60 -q "$url" -O "${tile}.hgt.gz" 2>/dev/null; then + if [ -s "${tile}.hgt.gz" ]; then + gunzip -f "${tile}.hgt.gz" + echo "OK ${tile}" + else + echo "FAIL ${tile} (empty)" + rm -f "${tile}.hgt.gz" + fi + else + echo "FAIL ${tile} (wget error)" + rm -f "${tile}.hgt.gz" + fi +done + +echo "" +echo "Total .hgt files: $(ls *.hgt 2>/dev/null | wc -l)" diff --git a/tasks/enduro-trails/prototype/scripts/download_srtm_final.js b/tasks/enduro-trails/prototype/scripts/download_srtm_final.js new file mode 100644 index 0000000..06b8cc1 --- /dev/null +++ b/tasks/enduro-trails/prototype/scripts/download_srtm_final.js @@ -0,0 +1,111 @@ +const { Client } = require('ssh2'); + +const TILES = [ + 'N55E037','N55E038','N55E039','N55E040', + 'N54E037','N54E038','N54E039','N54E040', + 'N53E038','N53E039','N53E040','N53E041', + 'N52E038','N52E039','N52E040','N52E041', + 'N56E037','N56E038','N56E039','N56E040', + 'N57E037','N57E038','N57E039','N57E040', + 'N58E037','N58E038','N58E039','N58E040', + 'N59E038','N59E039','N59E040','N59E041', + 'N60E040','N60E041','N60E042', + 'N54E042','N54E043','N54E044','N54E045', + 'N53E042','N53E043','N53E044','N53E045', + 'N52E042','N52E043','N52E044','N52E045', + 'N51E038','N51E039','N51E040','N51E041', + 'N50E038','N50E039','N50E040','N50E041', + 'N55E047','N55E048','N55E049','N55E050', + 'N54E047','N54E048','N54E049','N54E050', + 'N56E047','N56E048','N56E049','N56E050', +]; + +const conn = new Client(); + +conn.on('ready', () => { + console.log('SSH connected. Downloading SRTM tiles...'); + + let completed = 0; + let failed = 0; + let skipped = 0; + + function downloadNext(idx) { + if (idx >= TILES.length) { + console.log(`\n=== DONE === Completed: ${completed}, Skipped: ${skipped}, Failed: ${failed}`); + conn.end(); + return; + } + + const tile = TILES[idx]; + const lat = tile.substring(1, 3); + const url = `https://s3.amazonaws.com/elevation-tiles-prod/skadi/${lat}/${tile}.hgt.gz`; + const remoteHgt = `/home/slin/enduro-trails/data/srtm/${tile}.hgt`; + const remoteGz = `/home/slin/enduro-trails/data/srtm/${tile}.hgt.gz`; + + // Check if already exists + conn.exec(`test -f ${remoteHgt} && echo EXISTS || echo MISSING`, (err, stream) => { + if (err) { failed++; downloadNext(idx + 1); return; } + let out = ''; + stream.on('data', d => out += d); + stream.on('close', () => { + if (out.trim() === 'EXISTS') { + skipped++; + console.log(`[${idx+1}/${TILES.length}] SKIP ${tile} (exists)`); + downloadNext(idx + 1); + return; + } + + // Download - use wget with progress but capture only last line + const cmd = `cd /home/slin/enduro-trails/data/srtm && wget --timeout=60 -q "${url}" -O ${remoteGz} 2>/dev/null; test -s ${remoteGz} && echo DL_OK || echo DL_FAIL`; + + conn.exec(cmd, (err, stream) => { + if (err) { failed++; downloadNext(idx + 1); return; } + let out2 = ''; + stream.on('data', d => out2 += d); + stream.on('close', () => { + const dlResult = out2.trim(); + if (dlResult !== 'DL_OK') { + failed++; + console.log(`[${idx+1}/${TILES.length}] FAIL ${tile} (download)`); + conn.exec(`rm -f ${remoteGz}`, () => {}); + downloadNext(idx + 1); + return; + } + + // Extract + conn.exec(`cd /home/slin/enduro-trails/data/srtm && gunzip -f ${remoteGz} && test -f ${remoteHgt} && echo EX_OK || echo EX_FAIL`, (err, stream) => { + if (err) { failed++; downloadNext(idx + 1); return; } + let out3 = ''; + stream.on('data', d => out3 += d); + stream.on('close', () => { + const exResult = out3.trim(); + if (exResult === 'EX_OK') { + completed++; + console.log(`[${idx+1}/${TILES.length}] OK ${tile}`); + } else { + failed++; + console.log(`[${idx+1}/${TILES.length}] FAIL ${tile} (extract)`); + } + downloadNext(idx + 1); + }); + }); + }); + }); + }); + }); + } + + downloadNext(0); +}); + +conn.on('error', (err) => { + console.error('SSH error:', err.message); + process.exit(1); +}); + +conn.connect({ + host: '82.22.50.71', + username: 'slin', + password: 'motoZ@yaz2010', + readyTimeout: 30000 +}); diff --git a/tasks/enduro-trails/prototype/scripts/download_srtm_parallel.js b/tasks/enduro-trails/prototype/scripts/download_srtm_parallel.js new file mode 100644 index 0000000..02caf3d --- /dev/null +++ b/tasks/enduro-trails/prototype/scripts/download_srtm_parallel.js @@ -0,0 +1,93 @@ +const { Client } = require('ssh2'); + +const TILES = [ + 'N55E037','N55E038','N55E039','N55E040', + 'N54E037','N54E038','N54E039','N54E040', + 'N53E038','N53E039','N53E040','N53E041', + 'N52E038','N52E039','N52E040','N52E041', + 'N56E037','N56E038','N56E039','N56E040', + 'N57E037','N57E038','N57E039','N57E040', + 'N58E037','N58E038','N58E039','N58E040', + 'N59E038','N59E039','N59E040','N59E041', + 'N60E040','N60E041','N60E042', + 'N54E042','N54E043','N54E044','N54E045', + 'N53E042','N53E043','N53E044','N53E045', + 'N52E042','N52E043','N52E044','N52E045', + 'N51E038','N51E039','N51E040','N51E041', + 'N50E038','N50E039','N50E040','N50E041', + 'N55E047','N55E048','N55E049','N55E050', + 'N54E047','N54E048','N54E049','N54E050', + 'N56E047','N56E048','N56E049','N56E050', +]; + +const conn = new Client(); + +conn.on('ready', () => { + console.log('SSH connected. Generating server-side download script...'); + + // Generate a bash script to download all tiles in parallel batches + const scriptLines = [ + '#!/bin/bash', + 'cd /home/slin/enduro-trails/data/srtm', + 'BASE_URL="https://s3.amazonaws.com/elevation-tiles-prod/skadi"', + 'MAX_JOBS=4', + 'JOBS=0', + '', + 'download_tile() {', + ' local tile="$1"', + ' local lat="${tile:1:2}"', + ' local url="${BASE_URL}/${lat}/${tile}.hgt.gz"', + ' local gz="${tile}.hgt.gz"', + ' local hgt="${tile}.hgt"', + ' if [ -f "$hgt" ]; then', + ' echo "SKIP $tile"', + ' return', + ' fi', + ' wget --timeout=60 -q "$url" -O "$gz" 2>/dev/null', + ' if [ -s "$gz" ]; then', + ' gunzip -f "$gz"', + ' echo "OK $tile"', + ' else', + ' echo "FAIL $tile"', + ' rm -f "$gz"', + ' fi', + '}', + '', + 'export -f download_tile', + 'export BASE_URL', + '', + 'echo "Starting downloads..."', + ]; + + for (const tile of TILES) { + scriptLines.push(`download_tile ${tile} &`); + scriptLines.push('JOBS=$((JOBS + 1))'); + scriptLines.push('if [ $JOBS -ge $MAX_JOBS ]; then wait; JOBS=0; fi'); + } + scriptLines.push('wait'); + scriptLines.push('echo "DONE: $(ls *.hgt 2>/dev/null | wc -l) .hgt files"'); + + const script = scriptLines.join('\n'); + + conn.exec(script, (err, stream) => { + if (err) { console.error('Exec error:', err); conn.end(); return; } + stream.on('data', d => process.stdout.write(d)); + stream.stderr.on('data', d => process.stderr.write(d)); + stream.on('close', (code) => { + console.log('\nScript exited:', code); + conn.end(); + }); + }); +}); + +conn.on('error', (err) => { + console.error('SSH error:', err.message); + process.exit(1); +}); + +conn.connect({ + host: '82.22.50.71', + username: 'slin', + password: 'motoZ@yaz2010', + readyTimeout: 30000 +}); diff --git a/tasks/enduro-trails/prototype/scripts/download_srtm_retry.js b/tasks/enduro-trails/prototype/scripts/download_srtm_retry.js new file mode 100644 index 0000000..7f21489 --- /dev/null +++ b/tasks/enduro-trails/prototype/scripts/download_srtm_retry.js @@ -0,0 +1,113 @@ +const { Client } = require('ssh2'); + +const TILES = [ + 'N55E037','N55E038','N55E039','N55E040', + 'N54E037','N54E038','N54E039','N54E040', + 'N53E038','N53E039','N53E040','N53E041', + 'N52E038','N52E039','N52E040','N52E041', + 'N56E037','N56E038','N56E039','N56E040', + 'N57E037','N57E038','N57E039','N57E040', + 'N58E037','N58E038','N58E039','N58E040', + 'N59E038','N59E039','N59E040','N59E041', + 'N60E040','N60E041','N60E042', + 'N54E042','N54E043','N54E044','N54E045', + 'N53E042','N53E043','N53E044','N53E045', + 'N52E042','N52E043','N52E044','N52E045', + 'N51E038','N51E039','N51E040','N51E041', + 'N50E038','N50E039','N50E040','N50E041', + 'N55E047','N55E048','N55E049','N55E050', + 'N54E047','N54E048','N54E049','N54E050', + 'N56E047','N56E048','N56E049','N56E050', +]; + +const conn = new Client(); + +conn.on('ready', () => { + console.log('SSH connected. Downloading with retry...'); + + let completed = 0; + let failed = 0; + let skipped = 0; + + function downloadNext(idx) { + if (idx >= TILES.length) { + console.log(`\n=== DONE === Completed: ${completed}, Skipped: ${skipped}, Failed: ${failed}`); + conn.end(); + return; + } + + const tile = TILES[idx]; + const lat = tile.substring(1, 3); + const url = `https://s3.amazonaws.com/elevation-tiles-prod/skadi/${lat}/${tile}.hgt.gz`; + const remoteHgt = `/home/slin/enduro-trails/data/srtm/${tile}.hgt`; + const remoteGz = `/home/slin/enduro-trails/data/srtm/${tile}.hgt.gz`; + + // Check if already exists + conn.exec(`test -f ${remoteHgt} && echo EXISTS || echo MISSING`, (err, stream) => { + if (err) { failed++; downloadNext(idx + 1); return; } + let out = ''; + stream.on('data', d => out += d); + stream.on('close', () => { + if (out.trim() === 'EXISTS') { + skipped++; + console.log(`[${idx+1}/${TILES.length}] SKIP ${tile} (exists)`); + downloadNext(idx + 1); + return; + } + + // Download WITHOUT -q flag to see errors + const cmd = `cd /home/slin/enduro-trails/data/srtm && wget --timeout=60 "${url}" -O ${remoteGz} 2>&1 | tail -3 && test -s ${remoteGz} && echo DL_OK || echo DL_FAIL`; + + conn.exec(cmd, (err, stream) => { + if (err) { failed++; downloadNext(idx + 1); return; } + let out2 = ''; + stream.on('data', d => out2 += d); + stream.on('close', () => { + const lines = out2.trim().split('\n'); + const lastLine = lines[lines.length - 1] || ''; + if (lastLine !== 'DL_OK') { + failed++; + console.log(`[${idx+1}/${TILES.length}] FAIL ${tile}`); + // Clean up failed download + conn.exec(`rm -f ${remoteGz}`, () => {}); + downloadNext(idx + 1); + return; + } + + // Extract + conn.exec(`cd /home/slin/enduro-trails/data/srtm && gunzip -f ${remoteGz} && test -f ${remoteHgt} && echo EX_OK || echo EX_FAIL`, (err, stream) => { + if (err) { failed++; downloadNext(idx + 1); return; } + let out3 = ''; + stream.on('data', d => out3 += d); + stream.on('close', () => { + const exResult = out3.trim(); + if (exResult === 'EX_OK') { + completed++; + console.log(`[${idx+1}/${TILES.length}] OK ${tile}`); + } else { + failed++; + console.log(`[${idx+1}/${TILES.length}] FAIL ${tile} (extract)`); + } + downloadNext(idx + 1); + }); + }); + }); + }); + }); + }); + } + + downloadNext(0); +}); + +conn.on('error', (err) => { + console.error('SSH error:', err.message); + process.exit(1); +}); + +conn.connect({ + host: '82.22.50.71', + username: 'slin', + password: 'motoZ@yaz2010', + readyTimeout: 30000 +}); diff --git a/tasks/enduro-trails/prototype/scripts/download_srtm_v4.js b/tasks/enduro-trails/prototype/scripts/download_srtm_v4.js new file mode 100644 index 0000000..e5232fa --- /dev/null +++ b/tasks/enduro-trails/prototype/scripts/download_srtm_v4.js @@ -0,0 +1,110 @@ +const { Client } = require('ssh2'); + +const TILES = [ + 'N55E037','N55E038','N55E039','N55E040', + 'N54E037','N54E038','N54E039','N54E040', + 'N53E038','N53E039','N53E040','N53E041', + 'N52E038','N52E039','N52E040','N52E041', + 'N56E037','N56E038','N56E039','N56E040', + 'N57E037','N57E038','N57E039','N57E040', + 'N58E037','N58E038','N58E039','N58E040', + 'N59E038','N59E039','N59E040','N59E041', + 'N60E040','N60E041','N60E042', + 'N54E042','N54E043','N54E044','N54E045', + 'N53E042','N53E043','N53E044','N53E045', + 'N52E042','N52E043','N52E044','N52E045', + 'N51E038','N51E039','N51E040','N51E041', + 'N50E038','N50E039','N50E040','N50E041', + 'N55E047','N55E048','N55E049','N55E050', + 'N54E047','N54E048','N54E049','N54E050', + 'N56E047','N56E048','N56E049','N56E050', +]; + +const conn = new Client(); + +conn.on('ready', () => { + console.log('SSH connected. Downloading SRTM tiles...'); + + let completed = 0; + let failed = 0; + let skipped = 0; + + function downloadNext(idx) { + if (idx >= TILES.length) { + console.log(`\n=== DONE === Completed: ${completed}, Skipped: ${skipped}, Failed: ${failed}`); + conn.end(); + return; + } + + const tile = TILES[idx]; + const lat = tile.substring(1, 3); + const url = `https://s3.amazonaws.com/elevation-tiles-prod/skadi/${lat}/${tile}.hgt.gz`; + const remoteHgt = `/home/slin/enduro-trails/data/srtm/${tile}.hgt`; + const remoteGz = `/home/slin/enduro-trails/data/srtm/${tile}.hgt.gz`; + + // Check if already exists + conn.exec(`test -f ${remoteHgt} && echo EXISTS || echo MISSING`, (err, stream) => { + if (err) { failed++; downloadNext(idx + 1); return; } + let out = ''; + stream.on('data', d => out += d); + stream.on('close', () => { + if (out.trim() === 'EXISTS') { + skipped++; + console.log(`[${idx+1}/${TILES.length}] SKIP ${tile} (exists)`); + downloadNext(idx + 1); + return; + } + + // Download with wget, then extract + const cmd = `cd /home/slin/enduro-trails/data/srtm && wget --timeout=60 -q "${url}" -O ${remoteGz} && test -s ${remoteGz} && echo DL_OK || echo DL_FAIL`; + + conn.exec(cmd, (err, stream) => { + if (err) { failed++; downloadNext(idx + 1); return; } + let out2 = ''; + stream.on('data', d => out2 += d); + stream.on('close', () => { + const dlResult = out2.trim(); + if (dlResult !== 'DL_OK') { + failed++; + console.log(`[${idx+1}/${TILES.length}] FAIL ${tile} (download)`); + downloadNext(idx + 1); + return; + } + + // Extract + conn.exec(`cd /home/slin/enduro-trails/data/srtm && gunzip -f ${remoteGz} && test -f ${remoteHgt} && echo EX_OK || echo EX_FAIL`, (err, stream) => { + if (err) { failed++; downloadNext(idx + 1); return; } + let out3 = ''; + stream.on('data', d => out3 += d); + stream.on('close', () => { + const exResult = out3.trim(); + if (exResult === 'EX_OK') { + completed++; + console.log(`[${idx+1}/${TILES.length}] OK ${tile}`); + } else { + failed++; + console.log(`[${idx+1}/${TILES.length}] FAIL ${tile} (extract)`); + } + downloadNext(idx + 1); + }); + }); + }); + }); + }); + }); + } + + downloadNext(0); +}); + +conn.on('error', (err) => { + console.error('SSH error:', err.message); + process.exit(1); +}); + +conn.connect({ + host: '82.22.50.71', + username: 'slin', + password: 'motoZ@yaz2010', + readyTimeout: 30000 +});