seed
1 #!/usr/bin/python3 2 3 import html 4 from urllib.parse import quote_plus 5 import time 6 from util import * 7 from config import * 8 9 sys.excepthook = lambda t,v,tb: print('<pre>'+html.escape(''.join(traceback.format_exception(t,v,tb)))+'</pre>') 10 11 def print_error(msg): 12 print('<p class="error-message">'+html.escape(msg)+'</p>') 13 14 def print_info(msg): 15 print('<p>'+html.escape(msg)+'</p>') 16 17 HTML_HEAD=''' 18 <!doctype html> 19 <html lang="en"> 20 <head> 21 <meta charset="utf-8"> 22 <meta name="viewport" content="width=device-width, initial-scale=1"> 23 <title>Cradicle - Seed</title> 24 <link href="/css/bootstrap/bootstrap.min.css" rel="stylesheet"> 25 <style> 26 .bd-placeholder-img { 27 font-size: 1.125rem; 28 text-anchor: middle; 29 -webkit-user-select: none; 30 -moz-user-select: none; 31 user-select: none; 32 } 33 34 @media (min-width: 768px) { 35 .bd-placeholder-img-lg { 36 font-size: 3.5rem; 37 } 38 } 39 40 .b-example-divider { 41 height: 3rem; 42 background-color: rgba(0, 0, 0, .1); 43 border: solid rgba(0, 0, 0, .15); 44 border-width: 1px 0; 45 box-shadow: inset 0 .5em 1.5em rgba(0, 0, 0, .1), inset 0 .125em .5em rgba(0, 0, 0, .15); 46 } 47 48 .b-example-vr { 49 flex-shrink: 0; 50 width: 1.5rem; 51 height: 100vh; 52 } 53 54 .bi { 55 vertical-align: -.125em; 56 fill: currentColor; 57 } 58 59 .nav-scroller { 60 position: relative; 61 z-index: 2; 62 height: 2.75rem; 63 overflow-y: hidden; 64 } 65 66 .nav-scroller .nav { 67 display: flex; 68 flex-wrap: nowrap; 69 padding-bottom: 1rem; 70 margin-top: -1px; 71 overflow-x: auto; 72 text-align: center; 73 white-space: nowrap; 74 -webkit-overflow-scrolling: touch; 75 } 76 </style> 77 <link rel="stylesheet" href="/assets/fontawesome/css/all.min.css"> 78 <link rel="icon" type="image/png" href="/favicon.png"> 79 ''' 80 81 print(HTML_HEAD) 82 83 form = FormData() 84 rid = form.getvalue('rid') 85 node = form.getvalue('node') 86 tor = form.getvalue('tor') 87 88 ret,out,err = exec_command(crad_bin,["self","--alias"]) 89 self_alias = 'unknown user' 90 if not ret: 91 self_alias = html.escape(out.strip()) 92 ret,out,err = exec_command(crad_bin,["self","--did"]) 93 self_did = '' 94 if not ret: 95 self_did = html.escape(out.strip()) 96 97 node_on = False 98 ret,out,err = exec_command(rad_node_status_wrapped_bin,['--only','nid']) 99 if not ret: 100 node_on = True 101 tor_on = False 102 ret,out,err = exec_command(crad_bin,['self','--network-mode']) 103 if not ret and out.strip() == 'tor': 104 tor_on = True 105 106 if tor == 'on' and not tor_on: 107 set_config_tor(True) 108 if node_on and node != 'off': 109 node = 'restart' 110 elif tor == 'off' and tor_on: 111 set_config_tor(False) 112 if node_on and node != 'off': 113 node = 'restart' 114 115 if node == 'on' and not node_on: 116 exec_command_bg(radicle_node_wrapped_bin,[]) 117 time.sleep(8) 118 elif node == 'off' and node_on: 119 ret,out,err = exec_command(rad_node_stop_wrapped_bin,[]) 120 elif node == 'restart': 121 if node_on: 122 ret,out,err = exec_command(rad_node_stop_wrapped_bin,[]) 123 exec_command_bg(radicle_node_wrapped_bin,[]) 124 time.sleep(8) 125 126 ret,out,err = exec_command(rad_node_status_wrapped_bin,['--only','nid']) 127 if not ret: 128 node_on = True 129 node_switch_url='&node=off' 130 node_title='click to disconnect from network' 131 else: 132 node_on = False 133 node_switch_url ='&node=on' 134 node_title ='click to connect to network' 135 136 tor_on = False 137 tor_switch_url = '&tor=on' 138 tor_title = 'click to route through Tor network' 139 ret,out,err = exec_command(crad_bin,["self","--network-mode"]) 140 if not ret and out.strip() == 'tor': 141 tor_on = True 142 tor_switch_url = '&tor=off' 143 tor_title = 'click to disconnect from Tor network' 144 145 class_node_icon = ' icon-off' 146 class_tor_icon = ' icon-off' 147 if node_on: 148 class_node_icon = ' icon-on' 149 if tor_on: 150 class_tor_icon = ' icon-on' 151 152 HTML_DASHBOARD_START=f''' 153 <link href="/css/dashboard.css" rel="stylesheet"> 154 </head> 155 <body> 156 <header class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0 shadow"> 157 <a class="navbar-brand col-md-3 col-lg-2 me-0 px-3 fs-6" href="/">Cradicle</a> 158 <button class="navbar-toggler position-absolute d-md-none collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#sidebarMenu" aria-controls="sidebarMenu" aria-expanded="false" aria-label="Toggle navigation"> 159 <span class="navbar-toggler-icon"></span> 160 </button> 161 <input class="form-control form-control-dark w-100 rounded-0 border-0" type="text" placeholder="Search" aria-label="Search"> 162 <div class="navbar-nav flex-row"> 163 <div class="nav-item text-nowrap"> 164 <a class="nav-link px-3 active" title="{node_title}" href="/cgi-bin/seed?{node_switch_url}"><i class="fa-solid fa-circle-nodes{class_node_icon}"></i></a> 165 </div> 166 <div class="nav-item text-nowrap"> 167 <a class="nav-link px-3 active" title="{tor_title}" href="/cgi-bin/seed?{tor_switch_url}"><i class="ft-onion{class_tor_icon}"></i></a> 168 </div> 169 <div class="nav-item text-nowrap"> 170 <a class="nav-link px-3 active" aria_current="page" href="/">{self_alias[:12]}-{self_did[8:20]}</a> 171 </div> 172 <div class="nav-item text-nowrap"> 173 <a class="nav-link px-3" href="/cgi-bin/settings"><i class="fa-solid fa-gear"></i> Settings</a> 174 </div> 175 <div class="nav-item text-nowrap"> 176 <a class="nav-link px-3" href="/cgi-bin/signout"><i class="fa-solid fa-sign-out"></i> Sign out</a> 177 </div> 178 </div> 179 </header> 180 <div class="container-fluid"> 181 <div class="row"> 182 <nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-dark sidebar collapse"> 183 <div class="position-sticky pt-3 sidebar-sticky"> 184 <ul class="nav flex-column"> 185 <h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted text-uppercase"> 186 <span></span> 187 </h6> 188 <ul class="nav flex-column mb-2"> 189 </ul> 190 </div> 191 </nav> 192 <main class="col-md-9 ms-sm-auto col-lg-10"> 193 <div class="container px-1 py-3"> 194 ''' 195 HTML_DASHBOARD_END = ''' 196 </div> 197 </main> 198 </div> 199 </div> 200 ''' 201 202 HTML_AUTH_START = ''' 203 <link href="/css/signin.css" rel="stylesheet"> 204 </head> 205 <body class="text-center"> 206 <main class="form-signin w-100 m-auto"> 207 <form action="/" method="post"> 208 <div class="mb-4" width="100%" style="font-size:2.5rem; font-weight:bold; color:#2470dc;">Cradicle</div> 209 ''' 210 211 HTML_AUTH_END_CREATE=''' 212 <div class="form-floating"> 213 <input type="text" class="form-control" id="floatingInput" name="alias" placeholder="user"> 214 <label for="floatingInput">Alias</label> 215 </div> 216 <div class="form-floating" style="margin-top:10px;"> 217 <input type="password" class="form-control" id="floatingPassword" name="password" placeholder=""> 218 <label for="floatingPassword">Password</label> 219 </div> 220 <div class="form-floating"> 221 <input type="password" class="form-control" id="floatingPassword2" name="password2" placeholder=""> 222 <label for="floatingPassword2">Repeat Password</label> 223 </div> 224 <button class="w-100 btn btn-lg btn-primary" type="submit">Create</button> 225 </form> 226 </main> 227 ''' 228 229 HTML_AUTH_END_LOGIN=''' 230 <div class="form-floating"> 231 <input type="password" class="form-control" id="floatingPassword" name="password" placeholder=""> 232 <label for="floatingPassword">Password</label> 233 </div> 234 <button class="w-100 btn btn-lg btn-primary" type="submit">Sign in</button> 235 </form> 236 </main> 237 ''' 238 239 dashboard_content = '' 240 dashboard_content += '<h4 class="text-center">Seed a Repo</h4>' 241 242 # If RID was submitted, run crad seed 243 if rid and len(rid.strip()): 244 rid_clean = rid.strip() 245 ret,out,err = exec_command(crad_bin,['seed',rid_clean]) 246 if ret: 247 dashboard_content += f'<div class="error-message">{html.escape(err)}</div>' 248 else: 249 dashboard_content += f'<div class="alert alert-success">Seeded {html.escape(rid_clean)} successfully</div>' 250 251 # Seed form 252 dashboard_content += ''' 253 <form method="get" action="/cgi-bin/seed"> 254 <div class="input-group mt-3" style="max-width:600px;"> 255 <input type="text" class="form-control" name="rid" placeholder="rad:z..." aria-label="Repository ID"> 256 <button class="btn btn-primary" type="submit">Seed</button> 257 </div> 258 </form> 259 ''' 260 261 ret,out,err = exec_command(crad_bin,["self","--alias"]) 262 ret2,out2,err2 = exec_command(crad_bin,["self","--authed"]) 263 if ret: 264 print(HTML_AUTH_START) 265 print('<h1 class="h3 mb-3 fw-normal">Create a new identity</h1>') 266 print(HTML_AUTH_END_CREATE) 267 elif ret2: 268 print(HTML_AUTH_START) 269 print('<h1 class="h3 mb-3 fw-normal">Hello <i>'+html.escape(out)+'</i></h1>') 270 print(HTML_AUTH_END_LOGIN) 271 else: 272 print(HTML_DASHBOARD_START) 273 print(dashboard_content) 274 print(HTML_DASHBOARD_END) 275 276 HTML_FOOTER=''' 277 </body> 278 </html> 279 ''' 280 281 print(HTML_FOOTER)