-
Notifications
You must be signed in to change notification settings - Fork 7
/
setup.py
169 lines (129 loc) · 5.26 KB
/
setup.py
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
import json
import os
import re
import subprocess
import sys
from setup.cli import query_yes_no
from setup.colorConsole import ColorPrint, cyan, magenta
def print_header():
header = """
###################################################
######### Raspi Captive Portal #########
######### A Raspberry Pi Access Point #########
######### & Captive Portal setup script #########
###################################################
"""
ColorPrint.print(cyan, header)
def check_super_user():
print()
ColorPrint.print(cyan, "▶ Check sudo")
# Is root?
if os.geteuid() != 0:
print("You need root privileges to run this script.")
print('Please try again using "sudo"')
sys.exit(1)
else:
print("Running as root user, continue.")
def install_node():
print()
ColorPrint.print(cyan, "▶ Node.js & npm")
# Already installed?
installed = False
data = {}
try:
res = subprocess.run(["npm", "version", "--json"], capture_output=True, check=True)
data = json.loads(res.stdout)
if data["npm"] and data["node"]:
installed = True
except Exception: # pylint: disable=broad-except
installed = False
if installed:
print(f'You have Node.js v{data["node"]} and npm v{data["npm"]} installed.')
majorVersion = data["node"].split(".")[0]
if int(majorVersion) < 16:
answer = query_yes_no(
"Would you still like to try installing Node.js v18.x (LTS)?",
default="yes",
)
installed = not answer
# Install
if not installed:
# https://github.com/nodesource/distributions/blob/master/README.md#installation-instructions
subprocess.run(
"curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -",
shell=True,
check=True,
)
subprocess.run("sudo apt-get install -y nodejs", shell=True, check=True)
# npm might not be installed alongside Node.js
# see: https://github.com/nodejs/help/issues/554#issuecomment-290041018
subprocess.run("sudo apt-get install npm", shell=True, check=True)
def setup_access_point():
print()
ColorPrint.print(cyan, "▶ Setup Access Point (WiFi)")
print("We will now set up the Raspi as Access Point to connect to via WiFi.")
print("The following commands will execute as sudo user.")
print('Please make sure you look through the file "./access-point/setup-access-point.sh"')
print("first before approving.")
answer = query_yes_no("Continue?", default="yes")
if not answer:
return sys.exit(0)
subprocess.run("sudo chmod a+x ./access-point/setup-access-point.sh", shell=True, check=True)
subprocess.run("./access-point/setup-access-point.sh", shell=True, check=True)
def install_server_dependencies():
print()
ColorPrint.print(cyan, "▶ Install Node.js dependencies for backend")
subprocess.call("npm install", shell=True, cwd="./server")
def build_server():
print()
ColorPrint.print(cyan, "▶ Build Node.js server (typescript)")
print("This might take some time...")
subprocess.call("npm run build", shell=True, cwd="./server")
def setup_server_service():
print()
ColorPrint.print(cyan, "▶ Configure Node.js server to start at boot")
# Replace path in file
server_path = os.path.join(os.getcwd(), "server")
server_config_path = "./access-point/access-point-server.service"
with open(server_config_path, "r", encoding="utf-8") as f:
filedata = f.read()
filedata = re.sub(r"WorkingDirectory=.*", f"WorkingDirectory={server_path}", filedata)
with open(server_config_path, "w", encoding="utf-8") as f:
f.write(filedata)
print("We will now register the Node.js app as a Linux service and configure")
print("it to start at boot time.")
print("The following commands will execute as sudo user.")
print('Please make sure you look through the file "./access-point/setup-server.sh"')
print("first before approving.")
answer = query_yes_no("Continue?", default="yes")
if not answer:
return sys.exit(0)
subprocess.run("sudo chmod a+x ./setup-server.sh", shell=True, cwd="./access-point", check=True)
subprocess.run("./setup-server.sh", shell=True, cwd="./access-point", check=True)
def done():
print()
ColorPrint.print(cyan, "▶ Done")
final_msg = (
"Awesome, we are done here. Grab your phone and look for the\n"
'"Splines Raspi AP" WiFi (password: "splinesraspi").'
"\n"
"When you reboot the Raspi, wait 2 minutes, then the WiFi network\n"
"and the server should be up and running again automatically.\n"
"\n"
"If you like this project, consider giving a GitHub star ⭐\n"
"If there are any problems, checkout the troubleshooting section here:\n"
"https://github.com/Splines/raspi-captive-portal or open a new issue\n"
"on GitHub."
)
ColorPrint.print(magenta, final_msg)
def execute_all():
print_header()
check_super_user()
install_node()
setup_access_point()
install_server_dependencies()
build_server()
setup_server_service()
done()
if __name__ == "__main__":
execute_all()