"""Upload dating hotfix deps and rebuild web.""" from __future__ import annotations import sys from pathlib import Path import paramiko sys.stdout.reconfigure(encoding="utf-8", errors="replace") HOST = "107.173.30.245" USER = "root" PASS = "Xiao4669805" REMOTE = "/opt/nomadweb" ROOT = Path(__file__).resolve().parents[1] FILES = [ "frontend/src/lib/communityDraft.ts", "frontend/src/lib/meetupLinks.ts", "frontend/src/lib/localDraft.ts", "frontend/src/lib/savedGigs.ts", "frontend/src/lib/savedJobs.ts", "frontend/src/lib/meetupIcs.ts", "frontend/src/lib/aiHistory.ts", "frontend/src/lib/compareHistory.ts", "frontend/src/lib/nextStopPrefs.ts", "frontend/src/lib/recentDestinations.ts", "frontend/src/lib/watchLater.ts", "frontend/src/lib/toolCopy.ts", "frontend/src/lib/coworking.ts", "frontend/src/lib/authNext.ts", "frontend/src/lib/rings.ts", "frontend/src/lib/toast.tsx", "frontend/src/lib/api.ts", "frontend/src/lib/types.ts", "frontend/src/lib/i18n/dictionaries.ts", "frontend/src/components/ToolCityExits.tsx", "frontend/src/components/RecentlyViewed.tsx", "frontend/src/components/NomadDigest.tsx", "frontend/src/components/DatingClient.tsx", "frontend/src/components/DatingLikesClient.tsx", "frontend/src/components/ChatClient.tsx", "frontend/src/components/CommunityNewClient.tsx", "frontend/src/components/DiscussionDetailClient.tsx", "frontend/src/components/GigsClient.tsx", "frontend/src/components/MeetupsClient.tsx", "frontend/src/components/MeetupsHostClient.tsx", "frontend/src/components/CommunityHubClient.tsx", "frontend/src/components/MemberProfileClient.tsx", "frontend/src/components/NotificationsClient.tsx", "frontend/src/components/PricingClient.tsx", "frontend/src/components/GlobalSearch.tsx", "frontend/src/components/SiteShell.tsx", "frontend/src/components/Navbar.tsx", "frontend/src/components/Footer.tsx", "frontend/src/app/globals.css", "frontend/src/app/changelog/page.tsx", ] REBUILD = r""" set -euo pipefail exec 9>/var/lock/nomadro-deploy.lock if ! flock -n 9; then echo LOCK_BUSY; exit 75; fi export NEXT_TELEMETRY_DISABLED=1 export NEXT_PUBLIC_API_URL=https://nomadweb.nomadro.com/api/v1 export NEXT_PUBLIC_SITE_URL=https://nomadweb.nomadro.com export NODE_ENV=production cd /opt/nomadweb/frontend echo BUILD_START npm run build mkdir -p .next/standalone/.next rm -rf .next/standalone/public .next/standalone/.next/static cp -a public .next/standalone/public cp -a .next/static .next/standalone/.next/static rm -rf .next/standalone/content mkdir -p .next/standalone/content cp -a content .next/standalone/content systemctl restart nomadro-web for i in $(seq 1 30); do web=$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:3055/ || true) echo "try=$i web=$web" [ "$web" = "200" ] && exit 0 sleep 1 done exit 1 """ def ensure_dir(sftp: paramiko.SFTPClient, path: str) -> None: parts = path.strip("/").split("/") cur = "" for p in parts: cur += "/" + p try: sftp.stat(cur) except FileNotFoundError: try: sftp.mkdir(cur) except OSError: pass def main() -> int: client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(HOST, username=USER, password=PASS, timeout=30) sftp = client.open_sftp() for i, rel in enumerate(FILES, 1): local = ROOT / rel if not local.exists(): print(f"[{i}/{len(FILES)}] SKIP {rel}", flush=True) continue remote = f"{REMOTE}/{rel}" print(f"[{i}/{len(FILES)}] UPLOAD {rel}", flush=True) ensure_dir(sftp, str(Path(remote).parent).replace("\\", "/")) sftp.put(str(local), remote) sftp.close() print("BUILD...", flush=True) _, stdout, stderr = client.exec_command(REBUILD, timeout=900) while True: line = stdout.readline() if not line: break print(line.rstrip(), flush=True) err = stderr.read().decode("utf-8", errors="replace") if err.strip(): print("LOG:", err[-4000:], flush=True) code = stdout.channel.recv_exit_status() client.close() print("exit", code, flush=True) return code if __name__ == "__main__": raise SystemExit(main())