-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathsetup.sh
More file actions
executable file
·792 lines (694 loc) · 29.6 KB
/
setup.sh
File metadata and controls
executable file
·792 lines (694 loc) · 29.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
#!/bin/bash
# Solarpunk Utopia - Complete Setup Script
# Usage: curl -sL https://raw.githubusercontent.com/lizTheDeveloper/solarpunk_utopia/main/setup.sh | bash
# Note: Don't use 'set -e' - we want to show errors but not exit the terminal
# This is important for new users who might be sourcing this script
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}Solarpunk Utopia - Setup Script${NC}"
echo -e "${GREEN}========================================${NC}"
echo ""
# Detect Termux
IS_TERMUX=false
if [ -n "$TERMUX_VERSION" ] || [ -n "$PREFIX" ] && [[ "$PREFIX" == *"com.termux"* ]]; then
IS_TERMUX=true
fi
# Detect OS
OS="$(uname -s)"
case "${OS}" in
Linux*) PLATFORM=Linux;;
Darwin*) PLATFORM=Mac;;
*) PLATFORM="UNKNOWN:${OS}"
esac
if [ "$IS_TERMUX" = true ]; then
echo -e "${BLUE}Detected platform: Termux (Android)${NC}"
# Try to enable wake lock to prevent sleep during installation
echo -e "${YELLOW}Setting up wake lock...${NC}"
# First, try to install termux-api package
pkg install -y termux-api 2>/dev/null || true
# Try to acquire wake lock
if termux-wake-lock 2>/dev/null; then
echo -e "${GREEN}✓ Wake lock enabled (phone won't sleep during installation)${NC}"
else
echo -e "${RED}✗ Wake lock failed${NC}"
echo -e "${YELLOW}To prevent installation interruption:${NC}"
echo -e " 1. Install 'Termux:API' app from F-Droid:"
echo -e " https://f-droid.org/en/packages/com.termux.api/"
echo -e " 2. In Termux, run: pkg install termux-api"
echo -e " 3. Keep screen on during installation (Settings → Display → Screen timeout)"
echo -e ""
echo -e "${YELLOW}Continuing installation in 10 seconds...${NC}"
sleep 10
fi
else
echo -e "${BLUE}Detected platform: ${PLATFORM}${NC}"
fi
# Install system dependencies
install_dependencies() {
echo -e "${BLUE}Installing system dependencies...${NC}"
if [ "$IS_TERMUX" = true ]; then
# Termux (Android)
pkg update -y
pkg install -y python git nodejs
elif [ "$PLATFORM" = "Linux" ]; then
# Debian/Ubuntu
if command -v apt-get &> /dev/null; then
sudo apt-get update
sudo apt-get install -y python3 python3-pip python3-venv git curl nodejs npm
# RHEL/CentOS/Fedora
elif command -v dnf &> /dev/null; then
sudo dnf install -y python3 python3-pip git curl nodejs npm
elif command -v yum &> /dev/null; then
sudo yum install -y python3 python3-pip git curl nodejs npm
fi
elif [ "$PLATFORM" = "Mac" ]; then
# Check for Homebrew
if ! command -v brew &> /dev/null; then
echo -e "${YELLOW}Installing Homebrew...${NC}"
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
fi
brew install python3 node git
fi
}
# Clone repository if not exists
clone_repo() {
if [ ! -d "solarpunk_utopia" ]; then
echo -e "${BLUE}Cloning repository...${NC}"
git clone https://github.com/lizTheDeveloper/solarpunk_utopia.git
cd solarpunk_utopia
else
echo -e "${BLUE}Repository exists, updating...${NC}"
cd solarpunk_utopia
git pull origin main
fi
}
# Setup Python virtual environment
setup_python() {
echo -e "${BLUE}Setting up Python virtual environment...${NC}"
# Check Python version - require 3.11 (3.12 has issues with tokenizers/Rust)
PYTHON_CMD=""
# First, try to find python3.11
if command -v python3.11 &> /dev/null; then
PYTHON_CMD="python3.11"
echo -e "${GREEN}Found Python 3.11${NC}"
elif command -v python3 &> /dev/null; then
PY_VERSION=$(python3 --version 2>&1 | sed -n 's/Python \([0-9]*\.[0-9]*\).*/\1/p')
if [[ "$PY_VERSION" == "3.11"* ]]; then
PYTHON_CMD="python3"
echo -e "${GREEN}Found Python 3.11${NC}"
elif [[ "$PY_VERSION" == "3.12"* ]]; then
echo -e "${YELLOW}Python 3.12 detected - need to install Python 3.11${NC}"
echo -e "${YELLOW}(Python 3.12 has compatibility issues with tokenizers/Rust)${NC}"
# Try to install Python 3.11 automatically
if [ "$IS_TERMUX" = true ]; then
# Termux uses pkg, not apt, and doesn't need sudo
echo -e "${BLUE}Installing Python via pkg...${NC}"
pkg install -y python
PYTHON_CMD="python3"
elif [ "$PLATFORM" = "Mac" ]; then
echo -e "${BLUE}Installing Python 3.11 via Homebrew...${NC}"
if command -v brew &> /dev/null; then
brew install python@3.11
# Add to PATH for this session
export PATH="/opt/homebrew/opt/python@3.11/bin:$PATH"
PYTHON_CMD="python3.11"
else
echo -e "${RED}Homebrew not found. Installing Homebrew first...${NC}"
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install python@3.11
export PATH="/opt/homebrew/opt/python@3.11/bin:$PATH"
PYTHON_CMD="python3.11"
fi
elif [ "$PLATFORM" = "Linux" ]; then
if command -v apt-get &> /dev/null; then
echo -e "${BLUE}Installing Python 3.11 via apt...${NC}"
sudo apt-get update
sudo apt-get install -y python3.11 python3.11-venv python3.11-dev
PYTHON_CMD="python3.11"
elif command -v dnf &> /dev/null; then
echo -e "${BLUE}Installing Python 3.11 via dnf...${NC}"
sudo dnf install -y python3.11
PYTHON_CMD="python3.11"
elif command -v yum &> /dev/null; then
echo -e "${BLUE}Installing Python 3.11 via yum...${NC}"
sudo yum install -y python3.11
PYTHON_CMD="python3.11"
else
echo -e "${RED}Cannot install Python 3.11 automatically on this system${NC}"
echo -e "${YELLOW}You may need to install Python 3.11 manually${NC}"
echo -e "${YELLOW}Continuing with available Python...${NC}"
PYTHON_CMD="python3"
fi
fi
# Verify installation
if ! command -v "$PYTHON_CMD" &> /dev/null; then
echo -e "${RED}Python 3.11 installation failed${NC}"
echo -e "${YELLOW}Trying to use default python3...${NC}"
PYTHON_CMD="python3"
if ! command -v "$PYTHON_CMD" &> /dev/null; then
echo -e "${RED}No Python found at all!${NC}"
echo -e "${YELLOW}Please install Python and try again${NC}"
PYTHON_CMD=""
fi
else
echo -e "${GREEN}Python 3.11 installed successfully${NC}"
fi
else
echo -e "${YELLOW}Warning: Python $PY_VERSION detected, 3.11 recommended${NC}"
echo -e "${BLUE}Attempting to install Python 3.11...${NC}"
if [ "$IS_TERMUX" = true ]; then
pkg install -y python 2>/dev/null || true
elif [ "$PLATFORM" = "Mac" ]; then
brew install python@3.11 2>/dev/null || true
export PATH="/opt/homebrew/opt/python@3.11/bin:$PATH"
elif [ "$PLATFORM" = "Linux" ]; then
if command -v apt-get &> /dev/null; then
sudo apt-get update && sudo apt-get install -y python3.11 python3.11-venv python3.11-dev 2>/dev/null || true
fi
fi
# Check if we got 3.11 installed
if command -v python3.11 &> /dev/null; then
PYTHON_CMD="python3.11"
echo -e "${GREEN}Using Python 3.11${NC}"
else
PYTHON_CMD="python3"
echo -e "${YELLOW}Continuing with Python $PY_VERSION (may have issues)${NC}"
fi
fi
else
echo -e "${RED}Error: python3 not found${NC}"
# Try to install Python
if [ "$IS_TERMUX" = true ]; then
echo -e "${BLUE}Installing Python via pkg...${NC}"
pkg install -y python
PYTHON_CMD="python3"
elif [ "$PLATFORM" = "Mac" ]; then
echo -e "${BLUE}Installing Python 3.11 via Homebrew...${NC}"
brew install python@3.11
export PATH="/opt/homebrew/opt/python@3.11/bin:$PATH"
PYTHON_CMD="python3.11"
elif [ "$PLATFORM" = "Linux" ]; then
if command -v apt-get &> /dev/null; then
sudo apt-get update
sudo apt-get install -y python3.11 python3.11-venv python3.11-dev
PYTHON_CMD="python3.11"
fi
fi
if [ -z "$PYTHON_CMD" ]; then
echo -e "${RED}Failed to install Python${NC}"
echo -e "${YELLOW}Cannot continue without Python${NC}"
echo -e "${YELLOW}Please install Python manually:${NC}"
if [ "$PLATFORM" = "Mac" ]; then
echo -e " brew install python@3.11"
elif [ "$PLATFORM" = "Linux" ]; then
echo -e " sudo apt-get install python3.11 # Debian/Ubuntu"
echo -e " sudo dnf install python3.11 # Fedora"
elif [ "$IS_TERMUX" = true ]; then
echo -e " pkg install python"
fi
# Don't return or exit - just skip rest of function
echo -e "${YELLOW}Setup incomplete - Python not available${NC}"
echo ""
return
fi
fi
echo -e "${BLUE}Using: $PYTHON_CMD ($(${PYTHON_CMD} --version))${NC}"
if [ "$IS_TERMUX" = true ]; then
# Termux: Install packages that need compilation from pkg
echo -e "${BLUE}Installing binary packages from Termux repository...${NC}"
# Check which packages are available and install them
for pkg_name in python-cryptography python-bcrypt python-numpy; do
if pkg search "^${pkg_name}$" 2>/dev/null | grep -q "${pkg_name}"; then
pkg install -y "${pkg_name}" 2>/dev/null || true
fi
done
# Set environment to skip Rust compilation
export SKIP_CYTHON=1
export SKIP_RUST_EXTENSIONS=1
export CARGO_BUILD_TARGET=""
export CRYPTOGRAPHY_DONT_BUILD_RUST=1
fi
# Check if venv exists and was created with the wrong Python version
if [ -d "venv" ]; then
if [ -f "venv/bin/python" ]; then
VENV_VERSION=$(venv/bin/python --version 2>&1 | sed -n 's/Python \([0-9]*\.[0-9]*\).*/\1/p' || echo "unknown")
if [[ "$VENV_VERSION" == "3.12"* ]]; then
echo -e "${YELLOW}Existing venv uses Python 3.12 - recreating with Python 3.11...${NC}"
rm -rf venv
elif [[ "$VENV_VERSION" != "3.11"* ]] && [[ "$VENV_VERSION" != "unknown" ]]; then
echo -e "${YELLOW}Existing venv uses Python $VENV_VERSION - recreating with Python 3.11...${NC}"
rm -rf venv
else
echo -e "${GREEN}Existing venv uses Python $VENV_VERSION - keeping it${NC}"
fi
fi
fi
if [ ! -d "venv" ]; then
echo -e "${BLUE}Creating virtual environment with $PYTHON_CMD...${NC}"
$PYTHON_CMD -m venv venv
fi
# Activate venv (use . instead of source for better compatibility)
. venv/bin/activate
# Upgrade pip
pip install --upgrade pip
# Install all requirements
echo -e "${BLUE}Installing Python dependencies...${NC}"
if [ "$IS_TERMUX" = true ]; then
# Termux: Install packages individually to handle failures gracefully
echo -e "${YELLOW}Installing packages (trying binary wheels first)...${NC}"
# Termux: Binary wheels don't work (Bionic libc vs glibc)
# Solution: Compile from source with Rust
echo -e "${BLUE}Installing pydantic (Termux requires compilation)...${NC}"
# Try binary wheel first (fast but will probably fail)
echo -ne " Trying binary wheel... "
if pip install --only-binary :all: pydantic==2.9.2 pydantic-core==2.9.0 pydantic-settings 2>/dev/null; then
echo -e "${GREEN}✓${NC}"
PYDANTIC_INSTALLED=true
else
echo -e "${YELLOW}not available (expected)${NC}"
# Install Rust compiler and build tools
echo -ne " Installing Rust compiler... "
if pkg install -y rust binutils >/dev/null 2>&1; then
echo -e "${GREEN}✓${NC}"
else
echo -e "${RED}✗${NC}"
echo -e "${YELLOW} Continuing without pydantic...${NC}"
PYDANTIC_INSTALLED=false
fi
if [ "$PYDANTIC_INSTALLED" != false ]; then
# Set Rust environment
export PATH="$HOME/.cargo/bin:$PATH"
export CARGO_HOME="$HOME/.cargo"
export RUSTUP_HOME="$HOME/.rustup"
export CARGO_BUILD_JOBS=2 # Limit parallel jobs to save memory
# Verify Rust works
echo -ne " Verifying Rust installation... "
if rustc --version >/dev/null 2>&1; then
echo -e "${GREEN}✓ $(rustc --version)${NC}"
else
echo -e "${RED}✗ Rust not in PATH${NC}"
PYDANTIC_INSTALLED=false
fi
fi
if [ "$PYDANTIC_INSTALLED" != false ]; then
# Install maturin (Rust-Python build tool)
echo -ne " Installing maturin (Rust build tool)... "
if pip install maturin setuptools-rust 2>&1 | tail -1; then
echo -e "${GREEN}✓${NC}"
else
echo -e "${RED}✗${NC}"
fi
# Compile pydantic from source
echo -e "${BLUE} Compiling pydantic from source...${NC}"
echo -e "${YELLOW} This takes 5-15 minutes. Phone may get warm.${NC}"
echo -e "${YELLOW} Keep screen on to prevent Android from killing the process.${NC}"
echo ""
# Download source first, then build
echo -e "${BLUE} Step 1/3: Downloading source...${NC}"
pip download --no-binary :all: pydantic-core pydantic pydantic-settings -d /tmp/pydantic_src 2>&1 | grep -E "(Downloading|Saved)" || true
echo -e "${BLUE} Step 2/3: Building pydantic-core (slow)...${NC}"
if pip install --no-binary :all: pydantic-core 2>&1 | tee /tmp/pydantic_build.log | grep -E "(Collecting|Building|Compiling|Finished|Successfully|error|ERROR)"; then
echo -e "${GREEN} ✓ pydantic-core built${NC}"
echo -e "${BLUE} Step 3/3: Installing pydantic...${NC}"
if pip install pydantic pydantic-settings 2>&1 | tail -5; then
echo ""
echo -e "${GREEN}✓ pydantic compiled and installed${NC}"
PYDANTIC_INSTALLED=true
else
echo -e "${RED}✗ pydantic install failed${NC}"
PYDANTIC_INSTALLED=false
fi
else
echo ""
echo -e "${RED}✗ pydantic-core compilation failed${NC}"
echo -e "${YELLOW} See /tmp/pydantic_build.log for details${NC}"
echo -e "${YELLOW} Last 10 lines:${NC}"
tail -10 /tmp/pydantic_build.log | sed 's/^/ /'
PYDANTIC_INSTALLED=false
fi
fi
fi
# Now install packages based on whether pydantic succeeded
if [ "$PYDANTIC_INSTALLED" = true ]; then
# Pydantic available - install full stack including FastAPI
PACKAGES="fastapi uvicorn aiosqlite python-multipart psutil mnemonic structlog prometheus-client httpx"
else
# No pydantic - skip FastAPI (requires pydantic)
echo -e "${YELLOW} Note: Skipping fastapi (requires pydantic)${NC}"
PACKAGES="uvicorn aiosqlite python-multipart psutil mnemonic structlog prometheus-client httpx"
fi
for pkg in $PACKAGES; do
echo -ne " Installing $pkg... "
if pip install --only-binary :all: "$pkg" 2>/dev/null; then
echo -e "${GREEN}✓${NC}"
else
# Try without binary restriction
if pip install "$pkg" 2>/dev/null; then
echo -e "${GREEN}✓${NC}"
else
echo -e "${RED}✗${NC}"
fi
fi
done
echo ""
if [ "$PYDANTIC_INSTALLED" = false ]; then
echo -e "${YELLOW}================================================${NC}"
echo -e "${YELLOW}Termux Installation Complete (Partial)${NC}"
echo -e "${YELLOW}================================================${NC}"
echo -e "${GREEN}✓ Core packages installed${NC}"
echo -e "${RED}✗ pydantic compilation failed${NC}"
echo ""
echo -e "${GREEN}What works:${NC}"
echo -e " ✓ DTN Bundle System (offline messaging)"
echo -e " ✓ ValueFlows (gift economy)"
echo -e " ✓ Mesh networking (BATMAN-adv)"
echo -e " ✓ AI agents (LLM backends via httpx)"
echo -e " ✓ Database (aiosqlite)"
echo ""
echo -e "${YELLOW}What doesn't work:${NC}"
echo -e " ✗ FastAPI (requires pydantic)"
echo -e " ✗ REST API endpoints"
echo ""
echo -e "${YELLOW}To retry pydantic compilation:${NC}"
echo -e " ./scripts/compile_pydantic_termux.sh"
echo -e " Or check /tmp/pydantic_build.log for errors"
echo ""
else
echo -e "${GREEN}================================================${NC}"
echo -e "${GREEN}Termux Installation Complete!${NC}"
echo -e "${GREEN}================================================${NC}"
echo -e "${GREEN}✓ All packages installed (including pydantic)${NC}"
echo ""
fi
else
# Non-Termux: Try bulk install first, fall back to individual
if pip install -r requirements.txt 2>/dev/null; then
echo -e "${GREEN}✓ All packages installed${NC}"
else
echo -e "${YELLOW}Bulk install failed, trying packages individually...${NC}"
# Install packages one by one from requirements.txt
while IFS= read -r line; do
# Skip comments and empty lines
[[ "$line" =~ ^#.*$ ]] && continue
[[ -z "$line" ]] && continue
# Extract package name (before ==)
pkg=$(echo "$line" | cut -d'=' -f1 | xargs)
echo -ne " Installing $pkg... "
if pip install "$line" 2>/dev/null; then
echo -e "${GREEN}✓${NC}"
else
echo -e "${RED}✗${NC}"
fi
done < requirements.txt
fi
fi
# Install test dependencies (skip on Termux to save space/time)
if [ "$IS_TERMUX" != true ]; then
pip install pytest pytest-asyncio freezegun aiohttp
else
echo -e "${YELLOW}Skipping test dependencies on Termux (install manually if needed: pip install pytest)${NC}"
fi
# Install sub-project requirements (skip on Termux to avoid recompiling packages)
if [ "$IS_TERMUX" != true ]; then
for req in valueflows_node/requirements.txt mesh_network/requirements.txt discovery_search/requirements.txt; do
if [ -f "$req" ]; then
pip install -r "$req" 2>/dev/null || true
fi
done
else
echo -e "${YELLOW}Skipping sub-project requirements on Termux (already installed from main requirements)${NC}"
fi
}
# Setup frontend
setup_frontend() {
if [ "$IS_TERMUX" = true ]; then
echo -e "${YELLOW}Skipping frontend setup on Termux (use Android app or run manually)${NC}"
echo -e "${YELLOW}To build frontend manually: cd frontend && npm install && npm run build${NC}"
return
fi
echo -e "${BLUE}Setting up frontend...${NC}"
if [ -d "frontend" ]; then
cd frontend
npm install
npm run build
cd ..
fi
}
# Initialize database
init_database() {
echo -e "${BLUE}Initializing database...${NC}"
mkdir -p app/data
# Check if required packages are installed
. venv/bin/activate
echo -ne "Checking for aiosqlite... "
if python -c "import aiosqlite" 2>/dev/null; then
echo -e "${GREEN}✓${NC}"
else
echo -e "${RED}✗${NC}"
echo -e "${YELLOW}aiosqlite not installed - skipping database initialization${NC}"
echo -e "${YELLOW}Install with: pip install aiosqlite${NC}"
return
fi
# Run initialization
echo -ne "Creating database schema... "
python -c "
import asyncio
from app.database.db import init_db
asyncio.run(init_db())
" 2>/dev/null && {
echo -e "${GREEN}✓${NC}"
} || {
echo -e "${YELLOW}⚠️ failed${NC}"
echo -e "${YELLOW}Database will be initialized on first run${NC}"
}
}
# Create systemd service files
create_systemd_services() {
if [ "$IS_TERMUX" = true ]; then
echo -e "${YELLOW}Skipping systemd setup (Termux uses background processes)${NC}"
return
fi
if [ "$PLATFORM" != "Linux" ]; then
echo -e "${YELLOW}Skipping systemd setup (not on Linux)${NC}"
return
fi
echo -e "${BLUE}Creating systemd service files...${NC}"
INSTALL_DIR="$(pwd)"
# Main DTN service
sudo tee /etc/systemd/system/solarpunk-dtn.service > /dev/null << EOF
[Unit]
Description=Solarpunk DTN Bundle System
After=network.target
[Service]
Type=simple
User=$USER
WorkingDirectory=$INSTALL_DIR
ExecStart=$INSTALL_DIR/venv/bin/python -m app.main
Restart=always
RestartSec=5
Environment=PYTHONPATH=$INSTALL_DIR
[Install]
WantedBy=multi-user.target
EOF
# Frontend service (if using nginx)
sudo tee /etc/systemd/system/solarpunk-frontend.service > /dev/null << EOF
[Unit]
Description=Solarpunk Frontend Server
After=network.target
[Service]
Type=simple
User=$USER
WorkingDirectory=$INSTALL_DIR/frontend
ExecStart=/usr/bin/npm run preview -- --host 0.0.0.0 --port 3000
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
echo -e "${GREEN}Systemd services created${NC}"
}
# Configure firewall
configure_firewall() {
if [ "$IS_TERMUX" = true ]; then
echo -e "${YELLOW}Skipping firewall setup (not available on Termux)${NC}"
return
fi
if [ "$PLATFORM" != "Linux" ]; then
return
fi
echo -e "${BLUE}Configuring firewall...${NC}"
# UFW (Ubuntu)
if command -v ufw &> /dev/null; then
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 3000/tcp # Frontend
sudo ufw allow 8000/tcp # DTN API
sudo ufw allow 8001/tcp # ValueFlows
sudo ufw allow 8002/tcp # Bridge Management
sudo ufw allow 8005/tcp # AI Inference
echo -e "${GREEN}Firewall configured (ufw)${NC}"
# firewalld (RHEL/CentOS)
elif command -v firewall-cmd &> /dev/null; then
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --permanent --add-port=3000/tcp
sudo firewall-cmd --permanent --add-port=8000/tcp
sudo firewall-cmd --permanent --add-port=8001/tcp
sudo firewall-cmd --permanent --add-port=8002/tcp
sudo firewall-cmd --permanent --add-port=8005/tcp
sudo firewall-cmd --reload
echo -e "${GREEN}Firewall configured (firewalld)${NC}"
fi
}
# Run tests
run_tests() {
if [ "$IS_TERMUX" = true ]; then
echo -e "${YELLOW}Skipping tests on Termux (run manually if needed: pytest tests/)${NC}"
return
fi
echo -e "${BLUE}Running tests...${NC}"
. venv/bin/activate
# Run tests (excluding integration tests that need running services)
python -m pytest tests/ --ignore=tests/integration -q --tb=no 2>/dev/null || {
echo -e "${YELLOW}Some tests failed (this is expected for integration tests)${NC}"
}
}
# Start services
start_services() {
echo -e "${BLUE}Starting services...${NC}"
if [ "$IS_TERMUX" = true ]; then
# Termux: Start services with nohup (wake-lock already enabled at script start)
echo -e "${YELLOW}Starting services in background with nohup...${NC}"
nohup ./run_all_services.sh > /dev/null 2>&1 &
echo -e "${GREEN}Services started in background (wake-lock active)${NC}"
elif [ "$PLATFORM" = "Linux" ] && command -v systemctl &> /dev/null; then
sudo systemctl start solarpunk-dtn
sudo systemctl start solarpunk-frontend
sudo systemctl enable solarpunk-dtn
sudo systemctl enable solarpunk-frontend
echo -e "${GREEN}Services started via systemd${NC}"
else
# Fallback to manual start
./run_all_services.sh &
echo -e "${GREEN}Services started in background${NC}"
fi
}
# Setup Termux auto-start on boot
setup_termux_boot() {
if [ "$IS_TERMUX" != true ]; then
return
fi
echo -e "${BLUE}Setting up auto-start on boot...${NC}"
# Check if Termux:Boot is installed
if [ ! -d "$HOME/.termux/boot" ]; then
mkdir -p "$HOME/.termux/boot"
fi
# Create boot startup script
cat > "$HOME/.termux/boot/start-solarpunk.sh" << 'BOOTEOF'
#!/data/data/com.termux/files/usr/bin/sh
# Auto-start Solarpunk services on phone boot
# Enable wake lock to prevent CPU sleep
termux-wake-lock 2>/dev/null
# Navigate to project directory
cd ~/solarpunk_utopia || cd /data/data/com.termux/files/home/solarpunk_utopia
# Start all services in background
nohup ./run_all_services.sh > /dev/null 2>&1 &
BOOTEOF
chmod +x "$HOME/.termux/boot/start-solarpunk.sh"
echo -e "${GREEN}Boot script created at ~/.termux/boot/start-solarpunk.sh${NC}"
echo -e "${YELLOW}Install 'Termux:Boot' from F-Droid to enable auto-start on boot${NC}"
}
# Print summary
print_summary() {
# Get external IP (with timeout to avoid hanging)
EXTERNAL_IP=""
if [ "$IS_TERMUX" = true ]; then
EXTERNAL_IP="localhost" # Termux runs locally
elif command -v curl &> /dev/null; then
# Try with timeout if available, otherwise skip
if command -v timeout &> /dev/null; then
EXTERNAL_IP=$(timeout 3 curl -s -4 ifconfig.me 2>/dev/null || echo "localhost")
else
EXTERNAL_IP="localhost"
fi
else
EXTERNAL_IP="localhost"
fi
echo ""
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}Setup Complete!${NC}"
echo -e "${GREEN}========================================${NC}"
echo ""
echo -e "${YELLOW}Service Endpoints:${NC}"
echo -e " Frontend: http://${EXTERNAL_IP}:3000"
echo -e " DTN Bundle API: http://${EXTERNAL_IP}:8000"
echo -e " API Documentation: http://${EXTERNAL_IP}:8000/docs"
echo -e " ValueFlows API: http://${EXTERNAL_IP}:8001"
echo -e " Bridge Management: http://${EXTERNAL_IP}:8002"
if command -v ollama &> /dev/null; then
echo -e " ${GREEN}AI Inference: http://${EXTERNAL_IP}:8005${NC}"
echo -e " ${GREEN}AI Status: http://${EXTERNAL_IP}:8005/status${NC}"
fi
echo ""
echo -e "${YELLOW}Management Commands:${NC}"
echo -e " Start services: ./run_all_services.sh"
echo -e " Stop services: ./stop_all_services.sh"
echo -e " View logs: tail -f logs/dtn_bundle_system.log"
echo -e " Run tests: source venv/bin/activate && pytest tests/ -v"
echo ""
if [ "$IS_TERMUX" = true ]; then
echo -e "${YELLOW}Termux Tips:${NC}"
echo -e " Services are running with wake-lock enabled"
echo -e " Access locally: http://localhost:3000"
echo -e " Restart services: ./run_all_services.sh"
echo -e " Stop services: ./stop_all_services.sh"
echo ""
echo -e "${YELLOW}IMPORTANT: Prevent Android from killing Termux:${NC}"
echo -e " Settings → Apps → Termux → Battery → Unrestricted"
echo -e " (Otherwise Android will kill services when in background)"
echo ""
elif [ "$PLATFORM" = "Linux" ]; then
echo -e "${YELLOW}Systemd Commands:${NC}"
echo -e " sudo systemctl status solarpunk-dtn"
echo -e " sudo systemctl restart solarpunk-dtn"
echo -e " sudo journalctl -u solarpunk-dtn -f"
echo ""
fi
echo -e "${GREEN}Solarpunk Utopia is ready!${NC}"
}
# Main execution
main() {
# If running from curl pipe, we need to clone first
if [ ! -f "requirements.txt" ]; then
install_dependencies
clone_repo
fi
setup_python
setup_frontend
init_database
if [ "$IS_TERMUX" = false ] && [ "$PLATFORM" = "Linux" ]; then
create_systemd_services
configure_firewall
fi
if [ "$IS_TERMUX" = true ]; then
setup_termux_boot
fi
run_tests
# Optionally setup local inference
if [ "$IS_TERMUX" = true ] || [ "$PLATFORM" = "Mac" ]; then
if [ -f "setup_local_inference.sh" ]; then
chmod +x setup_local_inference.sh
./setup_local_inference.sh || true
fi
fi
start_services
print_summary
}
# Run main function
main "$@"