Spaces:
Configuration error
Configuration error
| from pathlib import Path | |
| import shutil, json | |
| def list_project(path: Path, max_depth=6): | |
| out = [] | |
| if not path.exists(): | |
| return "No project found at " + str(path) | |
| def _walk(p, depth): | |
| if depth > max_depth: | |
| return | |
| for child in sorted(p.iterdir(), key=lambda x: (not x.is_dir(), x.name.lower())): | |
| out.append((" "*depth) + ("π " if child.is_dir() else "π ") + child.name) | |
| if child.is_dir(): | |
| _walk(child, depth+1) | |
| _walk(path, 0) | |
| return "\n".join(out) | |
| def read_file(path: Path): | |
| if not path.exists(): | |
| return None | |
| try: | |
| return path.read_text(encoding='utf-8', errors='ignore') | |
| except Exception as e: | |
| return None | |
| def write_file(path: Path, content: str): | |
| path.parent.mkdir(parents=True, exist_ok=True) | |
| path.write_text(content, encoding='utf-8') | |
| return True | |
| def export_project(path: Path, zip_name: str): | |
| if not path.exists(): | |
| return None | |
| base = Path(zip_name).stem | |
| shutil.make_archive(base, 'zip', root_dir=path) | |
| return base + '.zip' | |
| def scaffold_login_system(root: Path): | |
| from textwrap import dedent | |
| root.mkdir(parents=True, exist_ok=True) | |
| frontend = root / "frontend" | |
| backend = root / "backend" | |
| frontend.mkdir(exist_ok=True) | |
| backend.mkdir(exist_ok=True) | |
| (frontend / "index.html").write_text(dedent(""" | |
| <!doctype html> | |
| <html> | |
| <head> | |
| <meta charset='utf-8'/> | |
| <title>Login</title> | |
| <link rel='stylesheet' href='style.css'/> | |
| </head> | |
| <body> | |
| <div class='card'> | |
| <h2>Login</h2> | |
| <form id='form'> | |
| <input id='email' placeholder='email' required/> | |
| <input id='password' type='password' placeholder='password' required/> | |
| <button type='button' onclick='signup()'>Sign Up</button> | |
| <button type='button' onclick='login()'>Log In</button> | |
| </form> | |
| <pre id='out'></pre> | |
| </div> | |
| <script> | |
| async function signup(){ const e=document.getElementById('email').value; const p=document.getElementById('password').value; const res=await fetch('/signup',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({email:e,password:p})}); document.getElementById('out').innerText=await res.text(); } | |
| async function login(){ const e=document.getElementById('email').value; const p=document.getElementById('password').value; const res=await fetch('/login',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({email:e,password:p})}); document.getElementById('out').innerText=await res.text(); } | |
| </script> | |
| </body> | |
| </html> | |
| """)) | |
| (frontend / "style.css").write_text(dedent(""" | |
| body { background: linear-gradient(135deg,#ffd1e8,#cfe9ff); font-family: Arial, sans-serif; } | |
| .card{max-width:360px;margin:60px auto;padding:20px;border-radius:12px;background:rgba(255,255,255,0.8);box-shadow:0 8px 30px rgba(0,0,0,0.08);} | |
| input{display:block;width:100%;margin:8px 0;padding:10px;border-radius:8px;border:1px solid #ddd} | |
| button{margin-right:8px;padding:8px 12px;border-radius:8px;border:none;background:#ff8fc1;color:white} | |
| pre{background:#fff;padding:8px;border-radius:6px;border:1px solid #eee} | |
| """)) | |
| (backend / "app.py").write_text(dedent(""" | |
| from wsgiref.simple_server import make_server | |
| import json, os | |
| DB='users.json' | |
| def app(environ, start_response): | |
| path = environ.get('PATH_INFO','/') | |
| try: | |
| size = int(environ.get('CONTENT_LENGTH') or 0) | |
| except Exception: | |
| size = 0 | |
| body = environ['wsgi.input'].read(size) if size else b'' | |
| if path == '/signup' or path == '/login': | |
| try: | |
| data = json.loads(body.decode('utf-8')) | |
| except Exception: | |
| data = {} | |
| email = data.get('email'); password = data.get('password') | |
| if not email or not password: | |
| start_response('400 Bad Request', [('Content-Type','text/plain')]) | |
| return [b'Missing email or password'] | |
| users = {} | |
| if os.path.exists(DB): | |
| try: | |
| users = json.loads(open(DB,'r').read()) | |
| except Exception: | |
| users={} | |
| if path == '/signup': | |
| if email in users: | |
| start_response('400 Bad Request', [('Content-Type','text/plain')]) | |
| return [b'User exists'] | |
| users[email] = {'password': password} | |
| open(DB,'w').write(json.dumps(users)) | |
| start_response('200 OK', [('Content-Type','text/plain')]) | |
| return [b'Signed up'] | |
| else: | |
| u = users.get(email) | |
| if not u or u.get('password') != password: | |
| start_response('401 Unauthorized', [('Content-Type','text/plain')]) | |
| return [b'Invalid credentials'] | |
| start_response('200 OK', [('Content-Type','text/plain')]) | |
| return [b'Logged in'] | |
| if path == '/' or path.endswith('.html') or path.endswith('.css') or path.endswith('.js'): | |
| local = os.path.join(os.path.dirname(__file__), '..', 'frontend', path.lstrip('/')) | |
| if os.path.exists(local): | |
| start_response('200 OK', [('Content-Type','text/html')]) | |
| return [open(local,'rb').read()] | |
| start_response('404 Not Found', [('Content-Type','text/plain')]) | |
| return [b'Not Found'] | |
| if __name__=='__main__': | |
| print('Starting tiny server on http://localhost:8000 (for local testing)') | |
| make_server('',8000,app).serve_forever() | |
| """)) | |
| (root := root := root if isinstance(root, Path) else root).absolute() | |
| (root / 'README.md').write_text('Login system scaffold: frontend + backend (tiny WSGI server).') | |
| return True | |