From b26edcc8150aabb9f720d51a7ac12d4a9025abc2 Mon Sep 17 00:00:00 2001 From: Stream Date: Tue, 12 May 2026 23:30:01 +0300 Subject: [PATCH] auto-sync: 2026-05-12 23:30:01 --- .../prototype/deploy_dark_style.js | 84 +++++++++++ tasks/enduro-trails/prototype/static/app.js | 9 +- .../prototype/static/style-dark.json | 136 ++++++++++++++++++ 3 files changed, 222 insertions(+), 7 deletions(-) create mode 100644 tasks/enduro-trails/prototype/deploy_dark_style.js create mode 100644 tasks/enduro-trails/prototype/static/style-dark.json diff --git a/tasks/enduro-trails/prototype/deploy_dark_style.js b/tasks/enduro-trails/prototype/deploy_dark_style.js new file mode 100644 index 0000000..ff74482 --- /dev/null +++ b/tasks/enduro-trails/prototype/deploy_dark_style.js @@ -0,0 +1,84 @@ +const { Client } = require('ssh2'); +const fs = require('fs'); +const path = require('path'); + +const conn = new Client(); +const config = { + host: '82.22.50.71', + username: 'slin', + password: 'motoZ@yaz2010', + readyTimeout: 30000 +}; + +function exec(conn, cmd) { + return new Promise((resolve, reject) => { + conn.exec(cmd, (err, stream) => { + if (err) return reject(err); + let out = '', e = ''; + stream.on('data', d => out += d); + stream.stderr.on('data', d => e += d); + stream.on('close', () => resolve({ out: out.trim(), err: e.trim() })); + }); + }); +} + +function sftp_put(sftp, localPath, remotePath) { + return new Promise((resolve, reject) => { + sftp.fastPut(localPath, remotePath, (err) => { + if (err) reject(err); else resolve(); + }); + }); +} + +const staticDir = path.join(__dirname, 'static'); +const remoteDir = '/home/slin/enduro-trails/prototype/static'; +const container = 'prototype-enduro-trails-1'; + +conn.on('ready', async () => { + console.log('✅ Connected'); + + conn.sftp(async (err, sftp) => { + if (err) { console.error('SFTP error:', err); conn.end(); return; } + + try { + // 1. Upload style-dark.json + const localDark = path.join(staticDir, 'style-dark.json'); + const remoteDark = remoteDir + '/style-dark.json'; + console.log('📤 Uploading style-dark.json...'); + await sftp_put(sftp, localDark, remoteDark); + console.log('✅ style-dark.json uploaded'); + + // 2. Upload app.js + const localApp = path.join(staticDir, 'app.js'); + const remoteApp = remoteDir + '/app.js'; + console.log('📤 Uploading app.js...'); + await sftp_put(sftp, localApp, remoteApp); + console.log('✅ app.js uploaded'); + + // 3. docker cp into container (NO restart!) + console.log('🐳 docker cp style-dark.json...'); + const cp1 = await exec(conn, `docker cp ${remoteDark} ${container}:/app/static/style-dark.json`); + console.log(' ', cp1.out || cp1.err || 'ok'); + + console.log('🐳 docker cp app.js...'); + const cp2 = await exec(conn, `docker cp ${remoteApp} ${container}:/app/static/app.js`); + console.log(' ', cp2.out || cp2.err || 'ok'); + + console.log(''); + console.log('🎉 Deploy complete! No container restart.'); + + conn.end(); + } catch (e) { + console.error('❌ Error:', e.message); + conn.end(); + process.exit(1); + } + }); +}); + +conn.on('error', (err) => { + console.error('❌ Connection error:', err.message); + process.exit(1); +}); + +conn.connect(config); diff --git a/tasks/enduro-trails/prototype/static/app.js b/tasks/enduro-trails/prototype/static/app.js index 11b9043..725f28c 100644 --- a/tasks/enduro-trails/prototype/static/app.js +++ b/tasks/enduro-trails/prototype/static/app.js @@ -88,18 +88,13 @@ function switchMapStyle() { if (!map) return; const dark = isDarkTheme(); const basePath = window.location.pathname.replace(/\/[^/]*$/, '') || ''; - const styleUrl = dark ? basePath + '/style.json' : basePath + '/style-light.json'; + const styleUrl = dark ? basePath + '/style-dark.json' : basePath + '/style.json'; - // Check if style-light.json exists - if not, keep current fetch(styleUrl, { method: 'HEAD' }).then(r => { if (r.ok) { map.setStyle(styleUrl); } else { - // No light style available, keep dark - if (!dark) { - // Try inline light style override or just skip - console.log('Light map style not available, keeping dark'); - } + console.log('Map style not available:', styleUrl); } }).catch(() => { // Network error, don't switch diff --git a/tasks/enduro-trails/prototype/static/style-dark.json b/tasks/enduro-trails/prototype/static/style-dark.json new file mode 100644 index 0000000..bc93668 --- /dev/null +++ b/tasks/enduro-trails/prototype/static/style-dark.json @@ -0,0 +1,136 @@ +{ + "version": 8, + "name": "Enduro Trails Dark", + "metadata": {}, + "center": [37.6, 55.75], + "zoom": 7, + "bearing": 0, + "pitch": 0, + "sources": { + "trails-tiles": { + "type": "vector", + "tiles": ["/api/tiles/{z}/{x}/{y}.mvt"], + "minzoom": 5, + "maxzoom": 16 + }, + "osm-raster": { + "type": "raster", + "tiles": ["https://tile.openstreetmap.org/{z}/{x}/{y}.png"], + "tileSize": 256, + "attribution": "© OpenStreetMap contributors" + } + }, + "glyphs": "https://fonts.openmaptiles.org/{fontstack}/{range}.pbf", + "layers": [ + { + "id": "background", + "type": "background", + "paint": { "background-color": "#1a1a2e" } + }, + { + "id": "osm-base", + "type": "raster", + "source": "osm-raster", + "paint": { + "raster-opacity": 1.0, + "raster-saturation": -0.6, + "raster-contrast": -0.1, + "raster-brightness-min": 0, + "raster-brightness-max": 0.35 + } + }, + { + "id": "trails-asphalt", + "type": "line", + "source": "trails-tiles", + "source-layer": "trails", + "minzoom": 6, + "filter": ["in", "highway", "primary", "secondary", "tertiary", "residential"], + "paint": { + "line-color": "#bbbbbb", + "line-width": ["interpolate", ["linear"], ["zoom"], 8, 0.5, 10, 1, 14, 2], + "line-opacity": 0.0 + }, + "layout": { "line-cap": "round", "line-join": "round", "visibility": "none" } + }, + { + "id": "trails-track", + "type": "line", + "source": "trails-tiles", + "source-layer": "trails", + "minzoom": 6, + "filter": ["==", "highway", "track"], + "paint": { + "line-color": [ + "match", ["get", "tracktype"], + "grade1", "#FFE066", + "grade2", "#FFE066", + "grade3", "#FF6633", + "grade4", "#FF6633", + "grade5", "#FF6633", + "#FF6633" + ], + "line-width": ["interpolate", ["linear"], ["zoom"], 6, 0.5, 8, 1.2, 10, 2, 12, 3.5, 16, 6], + "line-opacity": 0.95 + }, + "layout": { "line-cap": "round", "line-join": "round" } + }, + { + "id": "trails-path-bridleway", + "type": "line", + "source": "trails-tiles", + "source-layer": "trails", + "minzoom": 8, + "filter": ["in", "highway", "path", "bridleway", "footway"], + "paint": { + "line-color": "#ff4444", + "line-width": ["interpolate", ["linear"], ["zoom"], 7, 0.5, 10, 1.5, 12, 2, 16, 3], + "line-opacity": 0.9, + "line-dasharray": [3, 2] + }, + "layout": { "line-cap": "butt", "line-join": "round" } + }, + { + "id": "poi-circles", + "type": "circle", + "source": "trails-tiles", + "source-layer": "poi", + "paint": { + "circle-radius": ["interpolate", ["linear"], ["zoom"], 8, 2, 12, 6, 16, 10], + "circle-color": [ + "match", ["get", "poi_type"], + "natural=peak", "#ff4d5a", + "natural=water", "#3399e6", + "tourism=viewpoint", "#33cc33", + "historic=ruins", "#b366d9", + "natural=cave_entrance", "#f09030", + "ford=yes", "#00b3e6", + "#999999" + ], + "circle-stroke-color": "#333333", + "circle-stroke-width": 1.5, + "circle-opacity": 0.9 + } + }, + { + "id": "poi-labels", + "type": "symbol", + "source": "trails-tiles", + "source-layer": "poi", + "minzoom": 11, + "layout": { + "text-field": ["get", "name"], + "text-font": ["Open Sans Regular"], + "text-size": 11, + "text-offset": [0, 1.2], + "text-anchor": "top", + "text-optional": true + }, + "paint": { + "text-color": "#e0e0e0", + "text-halo-color": "#1a1a2e", + "text-halo-width": 2 + } + } + ] +}